@mars-sea/dsh-commandcode-provider 0.6.0 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/client.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","names":["numberField","booleanField","useState","Button","createSnapshotStore"],"sources":["../src/client/sessions.ts","../src/client/settings.ts","../src/client/usage.ts","../src/usage-wire.ts","../src/client/section.tsx","../src/client/locales.ts","../src/client/index.ts"],"sourcesContent":["/**\n * Friendly-error wrapper for the harness's image-session gate.\n *\n * The host rejects switching to a text-only model while the session already\n * contains images with a `model-unavailable` error\n * (`dsh-host-apiproxy`'s `session.selectModel` handler). That rejection is\n * intentional and cannot be relaxed from the plugin side — the adapter's\n * `inputModalities` is exactly what makes the guard work. What we CAN do is\n * make the error message friendlier: wrap the shared\n * `connection.api.sessions.selectModel` face so a `model-unavailable`\n * rejection shows a clear, actionable hint (with the requested model name)\n * instead of the raw English harness message.\n *\n * The wrapper is deliberately narrow: only the `model-unavailable` code is\n * rewritten, only when the message matches the image-session gate, and only\n * the message text changes — the error code and details pass through\n * untouched so any caller that switches on `error.code` keeps working.\n *\n * The wire types are spelled structurally here (not imported from\n * `@deepseek-ai/dsh-host-apiproxy`) so this client bundle does not drag an\n * extra peer dependency into the package; the shapes are stable and the\n * client build inlines them anyway.\n *\n * This module is deliberately free of React and other client-platform\n * imports so the node test runner can exercise it directly.\n */\n\n/** The `model-unavailable` error details: provider + model id. */\ninterface ModelUnavailableDetails {\n provider: string\n model: string\n}\n\n/** The narrow slice of the RPC error we need to inspect and rewrite. */\ninterface RpcErrorLike {\n code: string\n message: string\n details?: ModelUnavailableDetails\n}\n\n/**\n * The narrow slice of a unary RPC result we need to inspect and rewrite.\n * The wire shape from `sessions.selectModel` (via `AbstractApiClient.callUnary`)\n * is the full envelope `{ rpcId, result: { ok, error? } }` — the error lives\n * under `result.result`, not at the top level. `RpcResultLike` models that.\n */\ninterface RpcResultLike {\n rpcId: string\n result:\n | { ok: true; value?: unknown }\n | { ok: false; error: RpcErrorLike }\n}\n\n/** One selectModel call: payload in, envelope out. */\ntype SelectModelCall = (\n payload: { sessionId: string; provider: string; model: string; reasoningEffort?: string },\n signal?: AbortSignal,\n) => Promise<RpcResultLike>\n\n/** The shared sessions wire face we wrap. */\ninterface SessionsLike {\n selectModel: SelectModelCall\n}\n\n/** Whether a selectModel rejection is the harness's image-session gate. */\nexport function isImageSessionRejection(\n result: RpcResultLike,\n): result is RpcResultLike & { result: { ok: false; error: RpcErrorLike } } {\n return (\n !result.result.ok &&\n result.result.error.code === 'model-unavailable' &&\n result.result.error.message.includes('does not accept image input')\n )\n}\n\n/** Wrap the shared sessions API so selectModel failures read friendlier. */\nexport function withFriendlyImageError(sessions: SessionsLike): SessionsLike {\n const selectModel = sessions.selectModel.bind(sessions)\n return {\n ...sessions,\n selectModel: async (payload, signal) => {\n const result = await selectModel(payload, signal)\n if (!isImageSessionRejection(result)) return result\n const model = result.result.error.details?.model ?? payload.model\n return {\n ...result,\n result: {\n ...result.result,\n error: {\n ...result.result.error,\n message:\n `当前会话已包含图片,而模型 ${model} 不支持图片输入;`\n + '请选择支持图片的模型,或先移除会话中的图片。',\n },\n },\n }\n },\n }\n}\n\n/** The connection handle shape we read `api.sessions` from. */\nexport interface ConnectionLike {\n api: { sessions: SessionsLike }\n}\n\n/** Install the wrapper on a connection's shared sessions face. */\nexport function installFriendlyImageError(connection: ConnectionLike): void {\n connection.api.sessions = withFriendlyImageError(connection.api.sessions)\n}\n","/**\n * Browser controller for the \"Command Code\" settings page.\n *\n * The page lives at the same settings-nav level as General / Models / Plugins\n * (a `settings.section` entry, id `commandcode`). It exists because the\n * Models page renders an unknown-adapter-family card for the `commandcode`\n * provider and deliberately disables its submit — the API key cannot be\n * configured there. This page owns the connection facts the plugin resolves\n * per request:\n *\n * - API key -> written through the credentials domain under the reference\n * the plugin resolves (`apiKeyEnv`, default\n * `COMMANDCODE_API_KEY`). The literal never rides a response,\n * so the control only reports whether one is configured.\n * - API base -> the `llm-commandcode` settings namespace (`apiBase`), same\n * namespace the Models page card addresses.\n * - Working dir, request/stream timeouts -> the same namespace.\n *\n * The controller mirrors the plugin-card pattern from the harness's own\n * settings UI: it binds the `llm-commandcode` namespace through the\n * `settingsScope` service, keeps a staged draft of edits, and writes them on\n * save through `scope.set` / the credentials domain. The Host stays the\n * single fact source; the snapshot is republished after each accepted write.\n *\n * This module is deliberately free of JSX — it only produces the state face\n * the React component renders.\n */\n\nimport type { SettingsScope } from '@deepseek-ai/dsh-client-runtime/client'\n\n/** The settings namespace the plugin registers (host half, src/index.ts). */\nexport const COMMANDCODE_NS = 'llm-commandcode'\n/** Default credential reference the plugin resolves when none is named. */\nexport const DEFAULT_API_KEY_REF = 'COMMANDCODE_API_KEY'\n\n/** The narrow slice of the wire face this controller needs. */\nexport interface SettingsPageApi {\n credentials: {\n describe(request: { refs: string[] }): Promise<{\n result: { ok: true; value: { credentials: Record<string, { configured: boolean; writable: boolean }> } } | { ok: false; error: { message: string } }\n }>\n set(request: { ref: string; value: string }): Promise<{ result: { ok: true; value?: unknown } | { ok: false; error: { message: string } } }>\n }\n}\n\n/** The Host-description observable the page reads the process cwd from. */\nexport interface HostDescriptionSource {\n getSnapshot(): { cwd?: string } | undefined\n subscribe(fn: () => void): () => void\n}\n\n/** One editable text field's staged state (blank = keep stored value). */\nexport interface StagedField {\n /** Live draft text the input shows. */\n text: string\n /** Whether the user explicitly cleared the field (reset to inherited). */\n clear: boolean\n /** Whether the user layer carries this field (marks it overridden). */\n overridden: boolean\n /** Whether the staged draft fails to parse (blocks save). */\n invalid: boolean\n}\n\n/** One extra account row's staged state (the default account uses `apiKey`). */\nexport interface AccountItemState {\n /** Stable id — the account's credential reference. */\n id: string\n /** Credential reference this account's key lives under. */\n ref: string\n /** Label draft text (the stored/generated label until edited). */\n label: string\n /** The API key draft (write-only; starts blank, never echoes the stored key). */\n keyText: string\n /** Whether a key is stored for this account (Host-reported). */\n configured: boolean\n /** Whether the credentials domain can store the key. */\n writable: boolean\n /** Staged for addition (not yet saved). */\n added: boolean\n}\n\n/** The page's full state face, projected from the scope + drafts + credential. */\nexport interface SettingsPageState {\n /** Whether the namespace snapshot is ready. */\n available: boolean\n /** Whether the Host document accepts writes. */\n writable: boolean\n /** Whether the API key is currently configured (Host-reported). */\n apiKeyConfigured: boolean\n /** Whether ANY account (default or extra) has a stored key — gates the usage card. */\n anyAccountConfigured: boolean\n /** Whether the credentials domain can store the key. */\n apiKeyWritable: boolean\n /** The API key draft (write-only; starts blank, never echoes the stored key). */\n apiKey: StagedField\n /** apiBase draft. */\n apiBase: StagedField\n /** workingDir draft. */\n workingDir: StagedField\n /**\n * The working directory a blank `workingDir` resolves to: the Host\n * process cwd (`host.describe().cwd`). Shown as the field's placeholder so\n * the user sees what \"leave it empty\" means — no configuration needed.\n */\n defaultWorkingDir: string | undefined\n /** requestTimeoutMs draft. */\n requestTimeoutMs: StagedField\n /** streamIdleTimeoutMs draft. */\n streamIdleTimeoutMs: StagedField\n /**\n * filterModelsByPlan draft, staged as `'true'`/`'false'`/`''` (unset). The\n * component renders it as a toggle; `''` means \"inherit the default\" (on).\n */\n filterModelsByPlan: StagedField\n /**\n * The manually selected active account, staged as a slot id (`default`\n * or an extra account's credential reference); `''` means \"auto — first\n * usable account\". The component renders it as a select.\n */\n activeAccount: StagedField\n /** Extra accounts (multi-account rotation), in rotation order. */\n accounts: AccountItemState[]\n /** Refs of stored accounts staged for removal (the usage card hides them). */\n accountsRemoving: string[]\n /** Whether any staged edit differs from the stored section. */\n dirty: boolean\n /** Whether a staged numeric field fails to parse (save blocked). */\n invalid: boolean\n /** Whether a save is in flight. */\n saving: boolean\n /** Whether the last save failed (drafts retained for correction). */\n failed: boolean\n}\n\n/** Parsed outcome of one field's draft. */\ntype Parsed = { kind: 'set'; value: string | number | boolean } | { kind: 'clear' } | { kind: 'invalid' }\n\n/** One field's staged draft (internal; the public face adds derived flags). */\ninterface Staged {\n text: string\n clear: boolean\n}\n\n/** A field conversion spec. */\ninterface FieldSpec {\n field: string\n format(value: unknown): string\n parse(text: string): Parsed\n}\n\n/** A free-text field; an empty draft clears it. */\nfunction textField(field: string): FieldSpec {\n return {\n field,\n format: (value) => (typeof value === 'string' ? value : ''),\n parse: (text) => {\n const trimmed = text.trim()\n return trimmed === '' ? { kind: 'clear' } : { kind: 'set', value: trimmed }\n },\n }\n}\n\n/** A whole-number field; an empty draft clears it, anything non-numeric blocks save. */\nfunction numberField(field: string): FieldSpec {\n return {\n field,\n format: (value) => (typeof value === 'number' ? String(value) : ''),\n parse: (text) => {\n const trimmed = text.trim()\n if (trimmed === '') return { kind: 'clear' }\n const parsed = Number(trimmed)\n return Number.isFinite(parsed) ? { kind: 'set', value: parsed } : { kind: 'invalid' }\n },\n }\n}\n\n/**\n * A boolean field, staged as the strings `'true'`/`'false'` (an empty draft\n * clears it). The component renders a toggle and only ever stages these two\n * strings; anything else blocks save.\n */\nfunction booleanField(field: string): FieldSpec {\n return {\n field,\n format: (value) => (typeof value === 'boolean' ? String(value) : ''),\n parse: (text) => {\n const trimmed = text.trim()\n if (trimmed === '') return { kind: 'clear' }\n if (trimmed === 'true') return { kind: 'set', value: true }\n if (trimmed === 'false') return { kind: 'set', value: false }\n return { kind: 'invalid' }\n },\n }\n}\n\n/** The fields this page edits inside the `llm-commandcode` namespace. */\nconst SECTION_FIELDS: FieldSpec[] = [\n textField('apiBase'),\n textField('workingDir'),\n numberField('requestTimeoutMs'),\n numberField('streamIdleTimeoutMs'),\n booleanField('filterModelsByPlan'),\n textField('activeAccount'),\n]\n\n/**\n * Controller bridging the `llm-commandcode` scope and the credentials domain\n * onto the page. Public API mirrors the harness's CardForm actions, so the\n * component stays thin.\n */\nexport class CommandCodeSettingsController {\n private readonly scope: SettingsScope<Record<string, unknown>>\n private readonly api: SettingsPageApi\n private readonly specs = new Map(SECTION_FIELDS.map((spec) => [spec.field, spec]))\n private readonly staged = new Map<string, Staged>()\n private readonly listeners = new Set<() => void>()\n private readonly disposers: Array<() => void> = []\n private disposed = false\n private defaultWorkingDir: string | undefined\n /** The credential reference the default account resolves. */\n private credentialRef = DEFAULT_API_KEY_REF\n /** Host-reported configured/writable state per credential reference. */\n private readonly credentialStates = new Map<string, { configured: boolean; writable: boolean }>()\n /** Staged account additions (not yet saved). */\n private addedAccounts: Array<{ label: string; ref: string }> = []\n /** Staged removals of stored extra accounts, by credential reference. */\n private readonly removedRefs = new Set<string>()\n /** Staged label drafts, by credential reference. */\n private readonly labelDrafts = new Map<string, string>()\n /** Staged key drafts, by credential reference (blank = keep stored key). */\n private readonly keyDrafts = new Map<string, string>()\n private saving = false\n private failed = false\n\n /**\n * @param scope - bound scope for the `llm-commandcode` namespace.\n * @param api - credentials wire face.\n * @param hostDescription - the Host-description observable whose `cwd` is\n * shown as the placeholder a blank `workingDir` field resolves to.\n */\n constructor(\n scope: SettingsScope<Record<string, unknown>>,\n api: SettingsPageApi,\n hostDescription?: HostDescriptionSource,\n ) {\n this.scope = scope\n this.api = api\n this.disposers.push(scope.subscribe(() => {\n this.recomputeCredentialRef()\n void this.describeAll()\n this.publish()\n }))\n if (hostDescription !== undefined) {\n this.defaultWorkingDir = hostDescription.getSnapshot()?.cwd\n this.disposers.push(hostDescription.subscribe(() => {\n if (this.disposed) return\n const cwd = hostDescription.getSnapshot()?.cwd\n if (cwd !== this.defaultWorkingDir) {\n this.defaultWorkingDir = cwd\n this.publish()\n }\n }))\n }\n this.recomputeCredentialRef()\n void this.describeAll()\n }\n\n /** Release every subscription held on external sources. Idempotent. */\n dispose(): void {\n if (this.disposed) return\n this.disposed = true\n for (const dispose of this.disposers) dispose()\n this.disposers.length = 0\n this.listeners.clear()\n }\n\n /**\n * The credential reference the section names, or the provider default. A\n * user who renamed `apiKeyEnv` in `settings.yaml` (or the composition\n * config) gets a page that addresses the renamed ref instead of silently\n * writing the default — mirroring the Models page's `refFor()`.\n */\n private recomputeCredentialRef(): void {\n const snapshot = this.scope.getSnapshot()\n const named = typeof snapshot.value?.apiKeyEnv === 'string' && snapshot.value.apiKeyEnv.length > 0\n ? snapshot.value.apiKeyEnv\n : DEFAULT_API_KEY_REF\n if (named === this.credentialRef) return\n this.credentialRef = named\n this.credentialStates.delete(named)\n }\n\n /** Subscribe to state projections. @returns the disposer. */\n subscribe(listener: () => void): () => void {\n this.listeners.add(listener)\n return () => this.listeners.delete(listener)\n }\n\n /** Build the current page state face. */\n state(): SettingsPageState {\n const snapshot = this.scope.getSnapshot()\n const plan = this.plan()\n const credential = this.credentialStates.get(this.credentialRef)\n const accounts = this.effectiveAccounts()\n return {\n available: snapshot.status === 'ready',\n writable: snapshot.writable,\n apiKeyConfigured: credential?.configured ?? false,\n anyAccountConfigured: (credential?.configured ?? false) || accounts.some((account) => account.configured),\n apiKeyWritable: credential?.writable ?? true,\n apiKey: {\n text: this.staged.get('apiKey')?.text ?? '',\n clear: false,\n overridden: false,\n invalid: false,\n },\n apiBase: this.field('apiBase'),\n workingDir: this.field('workingDir'),\n defaultWorkingDir: this.defaultWorkingDir,\n requestTimeoutMs: this.field('requestTimeoutMs'),\n streamIdleTimeoutMs: this.field('streamIdleTimeoutMs'),\n filterModelsByPlan: this.field('filterModelsByPlan'),\n activeAccount: this.field('activeAccount'),\n accounts,\n accountsRemoving: [...this.removedRefs],\n dirty: plan.length > 0 || this.accountsDirty(),\n invalid: plan.some((item) => item.run === undefined),\n saving: this.saving,\n failed: this.failed,\n }\n }\n\n /** Stage a new extra account (saved on the next `save()`). */\n addAccount(): void {\n const used = new Set([\n this.credentialRef,\n ...this.storedExtras().map((extra) => extra.ref),\n ...this.addedAccounts.map((extra) => extra.ref),\n ])\n let n = 2\n while (used.has(`COMMANDCODE_API_KEY_${n}`)) n += 1\n const index = this.storedExtras().length + this.addedAccounts.length + 2\n this.addedAccounts.push({ label: `Account ${index}`, ref: `COMMANDCODE_API_KEY_${n}` })\n this.failed = false\n void this.describeAll()\n this.publish()\n }\n\n /** Stage one extra account's removal (or drop an unsaved addition). */\n removeAccount(id: string): void {\n const addedIndex = this.addedAccounts.findIndex((extra) => extra.ref === id)\n if (addedIndex >= 0) this.addedAccounts.splice(addedIndex, 1)\n else this.removedRefs.add(id)\n this.labelDrafts.delete(id)\n this.keyDrafts.delete(id)\n // A pinned active account that is going away must not linger as a ghost\n // selection: stage its clear alongside the removal (the host would fall\n // back to rotation order, but the stored value would be meaningless).\n const stagedActive = this.staged.get('activeAccount')\n const activeValue = stagedActive !== undefined\n ? stagedActive.clear ? '' : stagedActive.text\n : typeof this.sectionValue('activeAccount') === 'string' ? this.sectionValue('activeAccount') as string : ''\n if (activeValue === id) {\n this.staged.set('activeAccount', { text: '', clear: true })\n }\n this.failed = false\n this.publish()\n }\n\n /** Stage one extra account's label draft. */\n editAccountLabel(id: string, text: string): void {\n this.labelDrafts.set(id, text)\n this.failed = false\n this.publish()\n }\n\n /** Stage one extra account's key draft (blank keeps the stored key). */\n editAccountKey(id: string, text: string): void {\n this.keyDrafts.set(id, text)\n this.failed = false\n this.publish()\n }\n\n /** Stage one field's draft text. */\n edit(field: string, text: string): void {\n this.staged.set(field, { text, clear: false })\n this.failed = false\n this.publish()\n }\n\n /** Reset one section field to its inherited (composition) value. */\n resetField(field: string): void {\n if (field === 'apiKey') {\n this.staged.delete('apiKey')\n this.failed = false\n this.publish()\n return\n }\n const spec = this.spec(field)\n this.staged.set(field, { text: spec.format(this.baseValue(field)), clear: true })\n this.failed = false\n this.publish()\n }\n\n /** Discard every staged edit. */\n discard(): void {\n if (this.staged.size === 0 && !this.accountsStaged() && !this.failed) return\n this.staged.clear()\n this.clearAccountStaging()\n this.failed = false\n this.publish()\n }\n\n /** Write every staged edit, then re-read the Host's accepted state. */\n async save(): Promise<void> {\n const plan = this.plan()\n const accountRuns = this.accountPlan()\n if ((plan.length === 0 && accountRuns.length === 0) || this.saving) return\n const runs: Array<() => Promise<boolean>> = []\n for (const item of plan) {\n if (item.run === undefined) return\n runs.push(item.run)\n }\n this.saving = true\n this.failed = false\n this.publish()\n let landed = true\n // Keys land first so a saved accounts list never names a ref whose key\n // write failed silently; the accounts list itself writes last. Stop at\n // the first failure: running later writes after a failed one would\n // persist a partial state the staged drafts no longer describe.\n for (const run of [...runs, ...accountRuns]) {\n if (!(await run())) {\n landed = false\n break\n }\n }\n this.saving = false\n this.failed = !landed\n if (landed) {\n this.staged.clear()\n this.clearAccountStaging()\n } else {\n // A failed save may still have landed earlier writes (e.g. the accounts\n // list made it while a key write did not). Reconcile the staging with\n // the stored section so a landed account is not simultaneously stored\n // AND staged-for-addition (which a retry would persist twice).\n this.reconcileAccountStaging()\n }\n this.publish()\n }\n\n /**\n * Drop account staging the stored section already reflects: additions whose\n * ref is now stored, removals whose ref is gone, and label drafts matching\n * the stored label. Key drafts are kept — a landed key write is idempotent\n * on retry, and the draft carries the user's intent when it was the\n * accounts write that failed.\n */\n private reconcileAccountStaging(): void {\n const stored = new Set(this.storedExtras().map((extra) => extra.ref))\n this.addedAccounts = this.addedAccounts.filter((extra) => !stored.has(extra.ref))\n for (const ref of [...this.removedRefs]) {\n if (!stored.has(ref)) this.removedRefs.delete(ref)\n }\n for (const [ref, text] of [...this.labelDrafts]) {\n const storedLabel = this.storedExtras().find((extra) => extra.ref === ref)?.label\n if (storedLabel === undefined || storedLabel === text.trim()) this.labelDrafts.delete(ref)\n }\n }\n\n // -------------------------------------------------------------------------\n // Internals\n // -------------------------------------------------------------------------\n\n private spec(field: string): FieldSpec {\n const spec = this.specs.get(field)\n if (spec === undefined) throw new Error(`commandcode settings page has no field ${field}`)\n return spec\n }\n\n /** One field's rendered state: draft text, whether it is user-overridden, invalid. */\n private field(field: string): StagedField {\n const spec = this.spec(field)\n const staged = this.staged.get(field)\n if (staged === undefined) {\n return {\n text: spec.format(this.sectionValue(field)),\n clear: false,\n overridden: this.stored(field),\n invalid: false,\n }\n }\n const parsed = staged.clear ? { kind: 'clear' as const } : spec.parse(staged.text)\n return {\n text: staged.text,\n clear: staged.clear,\n overridden: parsed.kind === 'set',\n invalid: parsed.kind === 'invalid',\n }\n }\n\n private sectionValue(field: string): unknown {\n return this.scope.getSnapshot().value?.[field]\n }\n\n private baseValue(field: string): unknown {\n const base = this.scope.getSnapshot().base\n return typeof base === 'object' && base !== null && !Array.isArray(base)\n ? (base as Record<string, unknown>)[field]\n : undefined\n }\n\n private userLayer(): Record<string, unknown> | undefined {\n const user = this.scope.getSnapshot().user\n return typeof user === 'object' && user !== null && !Array.isArray(user)\n ? (user as Record<string, unknown>)\n : undefined\n }\n\n private stored(field: string): boolean {\n const user = this.userLayer()\n return user !== undefined && Object.prototype.hasOwnProperty.call(user, field)\n }\n\n /**\n * The writes a save would perform, in staged order. A field whose draft is\n * not a value its spec accepts carries no write (the save refuses).\n */\n private plan(): Array<{ field: string; run: (() => Promise<boolean>) | undefined }> {\n const plan: Array<{ field: string; run: (() => Promise<boolean>) | undefined }> = []\n for (const [field, staged] of this.staged) {\n if (field === 'apiKey') {\n const value = staged.text.trim()\n if (value !== '') {\n plan.push({ field, run: () => this.writeKey(value) })\n }\n continue\n }\n const spec = this.spec(field)\n if (staged.clear) {\n if (this.stored(field)) plan.push({ field, run: () => this.clear(field) })\n continue\n }\n if (staged.text === spec.format(this.sectionValue(field))) continue\n const parsed = spec.parse(staged.text)\n if (parsed.kind === 'invalid') plan.push({ field, run: undefined })\n else if (parsed.kind === 'clear') plan.push({ field, run: () => this.clear(field) })\n else plan.push({ field, run: () => this.store(field, parsed.value) })\n }\n return plan\n }\n\n private async clear(field: string): Promise<boolean> {\n await this.scope.unset(field)\n return !this.stored(field)\n }\n\n private async store(field: string, value: string | number | boolean): Promise<boolean> {\n await this.scope.set(field, value)\n return this.userLayer()?.[field] === value\n }\n\n /** Write the staged default key, then re-read whether the Host holds it. */\n private async writeKey(value: string): Promise<boolean> {\n return this.writeKeyTo(this.credentialRef, value)\n }\n\n /** Write one account's key, then re-read the Host's credential states. */\n private async writeKeyTo(ref: string, value: string): Promise<boolean> {\n try {\n const response = await this.api.credentials.set({ ref, value })\n if (!response.result.ok) return false\n } catch {\n return false\n }\n await this.describeAll()\n return this.credentialStates.get(ref)?.configured ?? false\n }\n\n /** Ask the credentials domain about every reference this page writes. */\n private async describeAll(): Promise<void> {\n const refs = [\n this.credentialRef,\n ...this.storedExtras().map((extra) => extra.ref),\n ...this.addedAccounts.map((extra) => extra.ref),\n ]\n let response: Awaited<ReturnType<SettingsPageApi['credentials']['describe']>>\n try {\n response = await this.api.credentials.describe({ refs })\n } catch {\n return\n }\n if (!response.result.ok) return\n let changed = false\n for (const ref of refs) {\n const view = response.result.value.credentials[ref]\n const next = {\n configured: view?.configured ?? false,\n writable: view?.writable ?? true,\n }\n const prev = this.credentialStates.get(ref)\n if (prev === undefined || prev.configured !== next.configured || prev.writable !== next.writable) {\n this.credentialStates.set(ref, next)\n changed = true\n }\n }\n if (changed) this.publish()\n }\n\n // -----------------------------------------------------------------------\n // Multi-account staging\n // -----------------------------------------------------------------------\n\n /** The stored extra accounts from the settings section (`accounts`). */\n private storedExtras(): Array<{ label: string; ref: string }> {\n const raw = this.scope.getSnapshot().value?.accounts\n if (!Array.isArray(raw)) return []\n const out: Array<{ label: string; ref: string }> = []\n for (const entry of raw) {\n if (typeof entry !== 'object' || entry === null || Array.isArray(entry)) continue\n const record = entry as Record<string, unknown>\n const ref = record.apiKeyEnv\n if (typeof ref !== 'string' || ref === '') continue\n const label = record.label\n out.push({ label: typeof label === 'string' && label !== '' ? label : ref, ref })\n }\n return out\n }\n\n /** Every extra account row: stored (minus staged removals) + staged adds. */\n private effectiveAccounts(): AccountItemState[] {\n const stored = this.storedExtras()\n .filter((extra) => !this.removedRefs.has(extra.ref))\n .map((extra) => ({ ...extra, added: false }))\n const added = this.addedAccounts.map((extra) => ({ ...extra, added: true }))\n return [...stored, ...added].map((extra) => ({\n id: extra.ref,\n ref: extra.ref,\n label: this.labelDrafts.get(extra.ref) ?? extra.label,\n keyText: this.keyDrafts.get(extra.ref) ?? '',\n configured: this.credentialStates.get(extra.ref)?.configured ?? false,\n writable: this.credentialStates.get(extra.ref)?.writable ?? true,\n added: extra.added,\n }))\n }\n\n /** Whether any account-level staging (add/remove/label/key) exists. */\n private accountsStaged(): boolean {\n return this.addedAccounts.length > 0\n || this.removedRefs.size > 0\n || this.labelDrafts.size > 0\n || this.keyDrafts.size > 0\n }\n\n /** Whether the staged account edits differ from the stored section. */\n private accountsDirty(): boolean {\n if (this.addedAccounts.length > 0 || this.removedRefs.size > 0) return true\n for (const [ref, text] of this.labelDrafts) {\n const base = this.storedExtras().find((extra) => extra.ref === ref)?.label\n if (base !== undefined && text.trim() !== '' && text !== base) return true\n }\n for (const text of this.keyDrafts.values()) {\n if (text.trim() !== '') return true\n }\n return false\n }\n\n /** Reset every account-level staged edit. */\n private clearAccountStaging(): void {\n this.addedAccounts = []\n this.removedRefs.clear()\n this.labelDrafts.clear()\n this.keyDrafts.clear()\n }\n\n /** The account-level writes a save performs (empty when nothing staged). */\n private accountPlan(): Array<() => Promise<boolean>> {\n if (!this.accountsDirty()) return []\n const runs: Array<() => Promise<boolean>> = []\n for (const [ref, text] of this.keyDrafts) {\n const value = text.trim()\n if (value !== '' && !this.removedRefs.has(ref)) {\n runs.push(() => this.writeKeyTo(ref, value))\n }\n }\n runs.push(() => this.writeAccounts())\n return runs\n }\n\n /** Persist the staged accounts list into the settings section. */\n private async writeAccounts(): Promise<boolean> {\n const base = [\n ...this.storedExtras().filter((extra) => !this.removedRefs.has(extra.ref)),\n ...this.addedAccounts,\n ]\n // Defensive dedupe by ref: a partially landed earlier save can leave an\n // account both stored and staged-for-addition; never persist duplicates.\n const seen = new Set<string>()\n const list = base.filter((extra) => !seen.has(extra.ref) && (seen.add(extra.ref), true)).map((extra) => {\n const draft = this.labelDrafts.get(extra.ref)?.trim()\n return { label: draft !== undefined && draft !== '' ? draft : extra.label, apiKeyEnv: extra.ref }\n })\n await this.scope.set('accounts', list)\n const after = this.storedExtras()\n return after.length === list.length\n && list.every((item, index) => after[index]?.ref === item.apiKeyEnv)\n }\n\n private publish(): void {\n if (this.disposed) return\n for (const listener of this.listeners) listener()\n }\n}\n","/**\n * Browser controller for the settings page's account-usage card.\n *\n * The card renders the same account/usage/credit facts the `/commandcode`\n * command prints, fetched Host-side through the `commandcode/report` Remote\n * (the browser never holds the API key). This controller owns the fetch\n * lifecycle — idle/loading/ready/error, one in-flight request at a time,\n * stale-response dropping — and the display formatting, so the React\n * component stays a thin renderer and node tests can drive everything.\n *\n * Deliberately JSX-free, mirroring `./settings.ts`.\n *\n * @module dsh-commandcode-provider/client/usage\n */\n\nimport type { CommandCodeAccountsReport } from '../usage-wire.ts'\nimport type { RemoteResult } from '@deepseek-ai/dsh-typert-protocol'\n\n/**\n * Merge the plugin's Remote endpoint into the harness's typed client Remote\n * surface (the same declaration pattern the harness's generated\n * typert.remote-client files use), so `ctx.remote.commandcode.report()` is\n * typed once the contribution is mounted.\n */\ndeclare module '@deepseek-ai/dsh-typert-protocol' {\n interface TypertRemoteMap {\n 'commandcode/report': () => Promise<RemoteResult<CommandCodeAccountsReport>>\n }\n interface TypertRemoteNamespaceMap {\n commandcode: {\n report: () => Promise<RemoteResult<CommandCodeAccountsReport>>\n }\n }\n}\n\n/** The narrow slice of the mounted Remote this controller calls. */\nexport interface UsageRemote {\n report(): Promise<\n | { ok: true; value: CommandCodeAccountsReport }\n | { ok: false; error: { message: string } }\n >\n}\n\n/** The card's fetch lifecycle. */\nexport type UsageStatus =\n /** Never fetched (no API key configured yet, or not requested). */\n | 'idle'\n /** A fetch is in flight; `report` retains the last good data if any. */\n | 'loading'\n /** The last fetch succeeded. */\n | 'ready'\n /** The last fetch failed (no key, unreachable host, old plugin). */\n | 'error'\n\n/** The card's full state face. */\nexport interface UsagePageState {\n status: UsageStatus\n /** The last successfully fetched report (retained across refetches). */\n report: CommandCodeAccountsReport | undefined\n /** The last failure's message (error status). */\n error: string | undefined\n /** Millis timestamp of the last successful fetch. */\n fetchedAt: number | undefined\n}\n\nconst IDLE: UsagePageState = { status: 'idle', report: undefined, error: undefined, fetchedAt: undefined }\n\n/**\n * Controller bridging the `commandcode/report` Remote onto the card. Public\n * API mirrors {@link CommandCodeSettingsController}: `state()` projections,\n * `subscribe`, and one `refresh()` action.\n */\nexport class CommandCodeUsageController {\n private readonly remote: UsageRemote\n private readonly listeners = new Set<() => void>()\n private current: UsagePageState = IDLE\n private generation = 0\n private inFlight = false\n private disposed = false\n\n constructor(remote: UsageRemote) {\n this.remote = remote\n }\n\n /** Release every subscription. Idempotent; in-flight results are dropped. */\n dispose(): void {\n this.disposed = true\n this.generation += 1\n this.listeners.clear()\n }\n\n /** Subscribe to state projections. @returns the disposer. */\n subscribe(listener: () => void): () => void {\n this.listeners.add(listener)\n return () => this.listeners.delete(listener)\n }\n\n /** The current card state face. */\n state(): UsagePageState {\n return this.current\n }\n\n /**\n * Fetch (or refetch) the report. Concurrent refreshes collapse onto one\n * request; a superseded fetch's late result is dropped, never published.\n */\n async refresh(): Promise<void> {\n if (this.disposed || this.inFlight) return\n const generation = ++this.generation\n this.inFlight = true\n this.current = { ...this.current, status: 'loading', error: undefined }\n this.publish()\n try {\n const response = await this.remote.report()\n if (this.disposed || generation !== this.generation) return\n if (response.ok) {\n this.current = { status: 'ready', report: response.value, error: undefined, fetchedAt: Date.now() }\n } else {\n this.current = { ...this.current, status: 'error', error: response.error.message }\n }\n } catch (error: unknown) {\n if (this.disposed || generation !== this.generation) return\n this.current = {\n ...this.current,\n status: 'error',\n error: error instanceof Error ? error.message : String(error),\n }\n } finally {\n if (generation === this.generation) this.inFlight = false\n }\n this.publish()\n }\n\n private publish(): void {\n if (this.disposed) return\n for (const listener of this.listeners) listener()\n }\n}\n\n// ---------------------------------------------------------------------------\n// Display formatting (shared by the component, covered by node tests)\n// ---------------------------------------------------------------------------\n\n/** Format a dollar amount compactly (2 decimals). */\nexport function formatMoney(value: number): string {\n return `$${value.toFixed(2)}`\n}\n\n/** Format a dollar amount precisely (4 decimals) for small totals. */\nexport function formatMoneyExact(value: number): string {\n return `$${value.toFixed(4)}`\n}\n\n/** Format a large token count compactly (1.9M style). */\nexport function formatTokensCompact(value: number): string {\n if (value >= 1e9) return `${(value / 1e9).toFixed(1)}B`\n if (value >= 1e6) return `${(value / 1e6).toFixed(1)}M`\n if (value >= 1e3) return `${(value / 1e3).toFixed(1)}K`\n return String(value)\n}\n\n/** One window's fill ratio in [0, 1]; 0 when uncapped. */\nexport function windowRatio(used: number, cap: number): number {\n if (cap <= 0) return 0\n return Math.max(0, Math.min(1, used / cap))\n}\n\n/** Format a millis timestamp as a local short date-time; empty when unset. */\nexport function formatResetAt(ms: number): string {\n if (ms <= 0) return ''\n return new Date(ms).toLocaleString()\n}\n","/**\n * Wire contract for the Command Code account-usage Remote\n * (`commandcode/report`).\n *\n * The settings page renders the same account/usage/credit facts the\n * `/commandcode` command prints, but the browser never holds the API key —\n * the report must be produced Host-side and cross the Connection RPC carrier.\n * The harness exposes plugin-defined Host methods through the Typert Gateway:\n * the Host half registers a strict invocation descriptor against a Cordis\n * service (`src/usage-remote.ts`), and the browser half mounts the matching\n * Remote contribution on `ctx.remote` (`src/client/index.ts`).\n *\n * This module is the single source both halves share: the result validator\n * (a hand-rolled {@link TypertSchema}, so neither half needs a schema library)\n * and the exact descriptor object, so the endpoint can never drift apart.\n * It is deliberately dependency-free — the client bundle inlines it, and only\n * `import type` edges leave it (erased at build).\n *\n * @module dsh-commandcode-provider/usage-wire\n */\n\nimport type { CommandCodeUsageReport } from './adapter.ts'\nimport type { InvocationDescriptor, TypertRemoteContribution, TypertSchema } from '@deepseek-ai/dsh-typert-protocol'\n\n/** One account's usage entry in the multi-account report. */\nexport interface CommandCodeAccountUsage {\n /** Stable slot id (`default`, `account-2`, …). */\n id: string\n /** Display label (user-provided or generated). */\n label: string\n /** Whether an API key resolved for this account. */\n configured: boolean\n /** Whether this account currently serves requests (first usable slot). */\n active: boolean\n /** Rotation mark: `''` (usable), `'rate-limit'`, or `'invalid-credential'`. */\n mark: string\n /** Known cooldown end in millis; 0 when unknown or not cooling down. */\n cooldownUntil: number\n /** The per-account report; `failures`-only when the fetch itself failed. */\n report: CommandCodeUsageReport\n}\n\n/** The settings page's account card data: one entry per configured account. */\nexport interface CommandCodeAccountsReport {\n accounts: CommandCodeAccountUsage[]\n}\n\n/** The npm package identity both contribution registrations claim. */\nexport const USAGE_REMOTE_PACKAGE = '@mars-sea/dsh-commandcode-provider'\n\n/** Canonical `<namespace>/<method>` endpoint of the usage report Remote. */\nexport const USAGE_REPORT_ENDPOINT = 'commandcode/report'\n\n/** Reject one boundary value with a field-naming error. */\nfunction reject(field: string): never {\n throw new TypeError(`commandcode/report result: invalid ${field}`)\n}\n\n/** Read one required finite number field (`field` is the dotted error label). */\nfunction numberField(source: Record<string, unknown>, key: string, field: string): number {\n const value = source[key]\n if (typeof value !== 'number' || !Number.isFinite(value)) reject(field)\n return value\n}\n\n/** Read one required string field (`field` is the dotted error label). */\nfunction stringField(source: Record<string, unknown>, key: string, field: string): string {\n const value = source[key]\n if (typeof value !== 'string') reject(field)\n return value\n}\n\n/** Read one required boolean field (`field` is the dotted error label). */\nfunction booleanField(source: Record<string, unknown>, key: string, field: string): boolean {\n const value = source[key]\n if (typeof value !== 'boolean') reject(field)\n return value\n}\n\n/** Narrow an unknown value to a plain record, or reject. */\nfunction record(value: unknown, field: string): Record<string, unknown> {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) reject(field)\n return value as Record<string, unknown>\n}\n\n/** Validate one window-limit block (`fiveHour` / `weekly`). */\nfunction windowLimit(value: unknown, field: string): { used: number; cap: number; exceeded: boolean; resetAt: number } {\n const source = record(value, field)\n return {\n used: numberField(source, 'used', `${field}.used`),\n cap: numberField(source, 'cap', `${field}.cap`),\n exceeded: booleanField(source, 'exceeded', `${field}.exceeded`),\n resetAt: numberField(source, 'resetAt', `${field}.resetAt`),\n }\n}\n\n/**\n * Parse one untrusted boundary value into a {@link CommandCodeUsageReport}.\n * Optional sections stay optional; every present field is shape-checked so a\n * malformed frame fails the boundary instead of rendering garbage.\n */\nfunction parseUsageReport(value: unknown): CommandCodeUsageReport {\n const source = record(value, 'report')\n const failures = source.failures\n if (!Array.isArray(failures) || failures.some((entry) => typeof entry !== 'string')) reject('failures')\n const report: CommandCodeUsageReport = { failures: failures as string[] }\n\n if (source.account !== undefined) {\n const account = record(source.account, 'account')\n report.account = {\n id: stringField(account, 'id', 'account.id'),\n name: stringField(account, 'name', 'account.name'),\n userName: stringField(account, 'userName', 'account.userName'),\n }\n }\n\n if (source.usage !== undefined) {\n const usage = record(source.usage, 'usage')\n report.usage = {\n totalCount: numberField(usage, 'totalCount', 'usage.totalCount'),\n totalCost: numberField(usage, 'totalCost', 'usage.totalCost'),\n successRate: numberField(usage, 'successRate', 'usage.successRate'),\n completedCount: numberField(usage, 'completedCount', 'usage.completedCount'),\n failedCount: numberField(usage, 'failedCount', 'usage.failedCount'),\n totalTokensIn: numberField(usage, 'totalTokensIn', 'usage.totalTokensIn'),\n totalTokensOut: numberField(usage, 'totalTokensOut', 'usage.totalTokensOut'),\n totalCredits: numberField(usage, 'totalCredits', 'usage.totalCredits'),\n periodBasis: stringField(usage, 'periodBasis', 'usage.periodBasis'),\n }\n }\n\n if (source.credits !== undefined) {\n const credits = record(source.credits, 'credits')\n report.credits = {\n monthlyCredits: numberField(credits, 'monthlyCredits', 'credits.monthlyCredits'),\n purchasedCredits: numberField(credits, 'purchasedCredits', 'credits.purchasedCredits'),\n freeCredits: numberField(credits, 'freeCredits', 'credits.freeCredits'),\n fiveHour: windowLimit(credits.fiveHour, 'credits.fiveHour'),\n weekly: windowLimit(credits.weekly, 'credits.weekly'),\n }\n }\n\n if (source.plan !== undefined) {\n const plan = record(source.plan, 'plan')\n const monthly = plan.monthlyCredits\n if (monthly !== null && (typeof monthly !== 'number' || !Number.isFinite(monthly))) reject('plan.monthlyCredits')\n report.plan = {\n planId: stringField(plan, 'planId', 'plan.planId'),\n name: stringField(plan, 'name', 'plan.name'),\n status: stringField(plan, 'status', 'plan.status'),\n monthlyCredits: monthly as number | null,\n currentPeriodEnd: numberField(plan, 'currentPeriodEnd', 'plan.currentPeriodEnd'),\n }\n }\n\n return report\n}\n\n/** Parse one untrusted boundary value into a {@link CommandCodeAccountUsage}. */\nfunction parseAccountUsage(value: unknown): CommandCodeAccountUsage {\n const source = record(value, 'account')\n return {\n id: stringField(source, 'id', 'account.id'),\n label: stringField(source, 'label', 'account.label'),\n configured: booleanField(source, 'configured', 'account.configured'),\n active: booleanField(source, 'active', 'account.active'),\n mark: stringField(source, 'mark', 'account.mark'),\n cooldownUntil: numberField(source, 'cooldownUntil', 'account.cooldownUntil'),\n report: parseUsageReport(source.report),\n }\n}\n\n/** Parse the wire result into a {@link CommandCodeAccountsReport}. */\nfunction parseAccountsReport(value: unknown): CommandCodeAccountsReport {\n const source = record(value, 'result')\n const accounts = source.accounts\n if (!Array.isArray(accounts)) reject('accounts')\n return { accounts: accounts.map(parseAccountUsage) }\n}\n\n/**\n * The strict result codec both halves attach to the descriptor. Hand-rolled:\n * the client bundle may not require a schema library, and `TypertSchema` is\n * deliberately minimal so one `parse` function satisfies it.\n */\nexport const usageReportSchema: TypertSchema<CommandCodeAccountsReport> = {\n parse: parseAccountsReport,\n}\n\n/**\n * The one invocation descriptor, shared verbatim by the Host registration and\n * the Client mount. `service` names the Cordis key the Gateway resolves the\n * receiver from; `namespace`/`method` name the wire endpoint.\n */\nexport const USAGE_REPORT_DESCRIPTOR: InvocationDescriptor = {\n id: `${USAGE_REMOTE_PACKAGE}#${USAGE_REPORT_ENDPOINT}`,\n service: 'commandcodeUsage',\n namespace: 'commandcode',\n method: 'report',\n invocation: { kind: 'direct' },\n parameters: [],\n result: {\n mode: 'strict',\n typeSymbol: `${USAGE_REMOTE_PACKAGE}#CommandCodeAccountsReport`,\n schema: usageReportSchema,\n },\n}\n\n/** The Host-face contribution registered on `ctx.typert`. */\nexport const USAGE_HOST_CONTRIBUTION = {\n package: USAGE_REMOTE_PACKAGE,\n face: 'host' as const,\n schemas: [],\n invocations: [USAGE_REPORT_DESCRIPTOR],\n}\n\n/** The Client-face contribution mounted on `ctx.remote`. */\nexport const USAGE_REMOTE_CONTRIBUTION: TypertRemoteContribution = {\n package: USAGE_REMOTE_PACKAGE,\n descriptors: [USAGE_REPORT_DESCRIPTOR],\n}\n","/**\n * React component for the \"Command Code\" settings page (browser half).\n *\n * Renders as a `settings.section` entry — a page at the same settings-nav\n * level as General / Models / Plugins. The shell supplies the nav row and\n * renders this body inside the content column. All copy comes from the\n * `settings.commandcode` locale namespace; all state comes from the\n * `CommandCodeSettingsController` injected by the slot registration.\n *\n * The layout mirrors the harness's settings pages: a max-width content\n * column, labelled fields with hints, a reset affordance, and a\n * save/discard footer. Styles are injected once by the client entry\n * (see src/client/index.ts) and class-prefixed `cc-` to stay local.\n */\n\nimport { useEffect, useState } from 'react'\nimport { Button } from '@deepseek-ai/dsh-client-ui-primitives'\nimport type { Translate } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { CommandCodeCredits } from '../adapter.ts'\nimport type { CommandCodeAccountUsage } from '../usage-wire.ts'\nimport type { SettingsCommandCodeKey } from './locales.ts'\nimport type { AccountItemState, SettingsPageState, StagedField } from './settings.ts'\nimport type { UsagePageState } from './usage.ts'\nimport { formatMoney, formatMoneyExact, formatResetAt, formatTokensCompact, windowRatio } from './usage.ts'\n\n/** Props composed by the slot registration: locale seat + injected face. */\nexport interface CommandCodeSettingsProps {\n t: Translate<SettingsCommandCodeKey>\n useCommandCodeSettings<T>(selector: (state: SettingsPageState) => T): T\n useCommandCodeUsage<T>(selector: (state: UsagePageState) => T): T\n edit(field: string, text: string): void\n resetField(field: string): void\n save(): void\n discard(): void\n refreshUsage(): void\n addAccount(): void\n removeAccount(id: string): void\n editAccountLabel(id: string, text: string): void\n editAccountKey(id: string, text: string): void\n}\n\n/** One labelled field row in the page body. */\nfunction Field({\n id,\n label,\n hint,\n state,\n disabled,\n numeric,\n placeholder,\n onEdit,\n onReset,\n t,\n}: {\n id: string\n label: string\n hint: string\n state: StagedField\n disabled: boolean\n numeric?: boolean\n placeholder?: string | undefined\n onEdit(text: string): void\n onReset(): void\n t: Translate<SettingsCommandCodeKey>\n}) {\n return (\n <div className=\"cc-field\">\n <div className=\"cc-fieldHead\">\n <label className=\"cc-label\" htmlFor={id}>{label}</label>\n <span className=\"cc-badges\">\n {state.overridden ? <span className=\"cc-badge\">{t('overridden')}</span> : null}\n <button type=\"button\" className=\"cc-reset\" disabled={disabled} onClick={onReset}>{t('reset')}</button>\n </span>\n </div>\n <input\n id={id}\n className={state.invalid ? 'cc-input cc-inputInvalid' : 'cc-input'}\n type=\"text\"\n inputMode={numeric ? 'numeric' : undefined}\n value={state.text}\n placeholder={placeholder}\n disabled={disabled}\n onChange={(event) => onEdit(event.target.value)}\n />\n <p className={state.invalid ? 'cc-invalid' : 'cc-hint'}>\n {state.invalid ? t('invalidNumber') : hint}\n </p>\n </div>\n )\n}\n\n/**\n * One boolean field row rendered as a toggle. The staged text is `'true'` /\n * `'false'` / `''` (unset → `defaultChecked`); toggling stages the string the\n * boolean field spec parses back into a real boolean on save.\n */\nfunction ToggleField({\n id,\n label,\n hint,\n state,\n disabled,\n defaultChecked,\n onEdit,\n onReset,\n t,\n}: {\n id: string\n label: string\n hint: string\n state: StagedField\n disabled: boolean\n defaultChecked: boolean\n onEdit(text: string): void\n onReset(): void\n t: Translate<SettingsCommandCodeKey>\n}) {\n const checked = state.text === '' ? defaultChecked : state.text === 'true'\n return (\n <div className=\"cc-field\">\n <div className=\"cc-fieldHead\">\n <label className=\"cc-label\" htmlFor={id}>{label}</label>\n <span className=\"cc-badges\">\n {state.overridden ? <span className=\"cc-badge\">{t('overridden')}</span> : null}\n <button type=\"button\" className=\"cc-reset\" disabled={disabled} onClick={onReset}>{t('reset')}</button>\n </span>\n </div>\n <label className=\"cc-toggleRow\">\n <input\n id={id}\n className=\"cc-toggle\"\n type=\"checkbox\"\n role=\"switch\"\n checked={checked}\n disabled={disabled}\n onChange={(event) => onEdit(event.target.checked ? 'true' : 'false')}\n />\n <span className=\"cc-hint\">{hint}</span>\n </label>\n </div>\n )\n}\n\n/** The API-key control: write-only, reports configured state, never echoes the key. */\nfunction SecretKeyField({\n label,\n hint,\n state,\n disabled,\n configured,\n configuredLabel,\n unconfiguredLabel,\n onEdit,\n}: {\n label: string\n hint: string\n state: StagedField\n disabled: boolean\n configured: boolean\n configuredLabel: string\n unconfiguredLabel: string\n onEdit(text: string): void\n}) {\n return (\n <div className=\"cc-field\">\n <div className=\"cc-fieldHead\">\n <label className=\"cc-label\" htmlFor=\"cc-api-key\">{label}</label>\n <span className=\"cc-badges\">\n <span className={configured ? 'cc-badge' : 'cc-badgeMuted'}>\n {configured ? configuredLabel : unconfiguredLabel}\n </span>\n </span>\n </div>\n <input\n id=\"cc-api-key\"\n className=\"cc-input\"\n type=\"password\"\n autoComplete=\"off\"\n value={state.text}\n disabled={disabled}\n onChange={(event) => onEdit(event.target.value)}\n />\n <p className=\"cc-hint\">{hint}</p>\n </div>\n )\n}\n\n/** One stat tile in the account card's summary grid. */\nfunction UsageStat({ label, value, sub }: { label: string; value: string; sub?: string | undefined }) {\n return (\n <div className=\"cc-usageStat\">\n <span className=\"cc-usageStatLabel\">{label}</span>\n <span className=\"cc-usageStatValue\">{value}</span>\n {sub !== undefined && sub !== '' ? <span className=\"cc-usageStatSub\">{sub}</span> : null}\n </div>\n )\n}\n\n/** One window-limit row: label, used/cap, a fill bar, and the reset time. */\nfunction UsageWindow({\n label,\n limit: { used, cap, exceeded, resetAt },\n t,\n}: {\n label: string\n limit: CommandCodeCredits['fiveHour']\n t: Translate<SettingsCommandCodeKey>\n}) {\n const ratio = windowRatio(used, cap)\n const reset = formatResetAt(resetAt)\n return (\n <div className=\"cc-usageWindow\">\n <div className=\"cc-usageWindowHead\">\n <span className=\"cc-usageWindowLabel\">{label}</span>\n {exceeded ? <span className=\"cc-usageExceeded\">{t('usageExceeded')}</span> : null}\n <span className=\"cc-usageWindowValue\">{cap > 0 ? `${formatMoney(used)} / ${formatMoney(cap)}` : formatMoney(used)}</span>\n </div>\n <div className=\"cc-usageBar\" role=\"progressbar\" aria-valuemin={0} aria-valuemax={100} aria-valuenow={Math.round(ratio * 100)}>\n <div className={exceeded ? 'cc-usageBarFill cc-usageBarFillWarn' : 'cc-usageBarFill'} style={{ width: `${ratio * 100}%` }} />\n </div>\n {reset !== '' ? <p className=\"cc-usageWindowReset\">{t('usageReset')} {reset}</p> : null}\n </div>\n )\n}\n\n/** One account's rotation state as a short badge next to its label. */\nfunction AccountMark({ entry, t }: { entry: CommandCodeAccountUsage; t: Translate<SettingsCommandCodeKey> }) {\n if (entry.active) return <span className=\"cc-usagePlan\">{t('usageActive')}</span>\n if (entry.mark === 'invalid-credential') return <span className=\"cc-usagePlanStatus\">{t('usageInvalidKey')}</span>\n if (entry.cooldownUntil > 0) {\n return <span className=\"cc-usagePlanStatus\">{t('usageCooldown')} {formatResetAt(entry.cooldownUntil)}</span>\n }\n if (entry.mark === 'rate-limit') return <span className=\"cc-usagePlanStatus\">{t('usageCooldown')}</span>\n return null\n}\n\n/**\n * One pool account's facts (identity, totals, credits, window limits)\n * rendered inside the account-usage card.\n */\nfunction AccountReport({ entry, t, onRemove }: {\n entry: CommandCodeAccountUsage\n t: Translate<SettingsCommandCodeKey>\n /** Present only for removable (non-default) accounts on a writable page. */\n onRemove?: (() => void) | undefined\n}) {\n const report = entry.report\n const account = report.account\n const accountName = account === undefined ? '' : account.userName || account.name\n const credits = report.credits\n const plan = report.plan\n const planName = plan?.name ?? ''\n const planStatus = plan !== undefined && plan.status !== '' && plan.status !== 'active' ? plan.status : ''\n\n return (\n <div className=\"cc-accountReport\">\n <div className=\"cc-usageHead\">\n <h4 className=\"cc-usageTitle\">{entry.label}</h4>\n <AccountMark entry={entry} t={t} />\n {accountName !== '' ? <span className=\"cc-usageAccount\">{accountName}</span> : null}\n {planName !== '' ? <span className=\"cc-usagePlan\">{planName}</span> : null}\n {planStatus !== '' ? <span className=\"cc-usagePlanStatus\">{planStatus}</span> : null}\n <span className=\"cc-usageMetaSpacer\" />\n {onRemove !== undefined ? (\n <button type=\"button\" className=\"cc-usageRefresh\" onClick={onRemove}>{t('accountRemove')}</button>\n ) : null}\n </div>\n\n {!entry.configured ? <p className=\"cc-usageHint\">{t('usageUnconfigured')}</p> : null}\n\n {report.usage !== undefined ? (\n <div className=\"cc-usageStats\">\n <UsageStat\n label={t('usageRequests')}\n value={String(report.usage.completedCount)}\n sub={`${t('usageFailed')} ${report.usage.failedCount}`}\n />\n <UsageStat label={t('usageSuccessRate')} value={`${report.usage.successRate}%`} />\n <UsageStat\n label={t('usageCost')}\n value={formatMoneyExact(report.usage.totalCost)}\n sub={`${formatMoney(report.usage.totalCredits)} credits`}\n />\n <UsageStat\n label={t('usageTokens')}\n value={formatTokensCompact(report.usage.totalTokensIn + report.usage.totalTokensOut)}\n sub={`${formatTokensCompact(report.usage.totalTokensIn)} ${t('usageTokensIn')} / ${formatTokensCompact(report.usage.totalTokensOut)} ${t('usageTokensOut')}`}\n />\n </div>\n ) : null}\n\n {credits !== undefined ? (\n <div className=\"cc-usageStats\">\n <UsageStat label={t('usageMonthly')} value={formatMoney(credits.monthlyCredits)} />\n <UsageStat label={t('usagePurchased')} value={formatMoney(credits.purchasedCredits)} />\n <UsageStat label={t('usageFree')} value={formatMoney(credits.freeCredits)} />\n </div>\n ) : null}\n\n {credits !== undefined ? (\n <div className=\"cc-usageWindows\">\n <UsageWindow label={t('usageFiveHour')} limit={credits.fiveHour} t={t} />\n <UsageWindow label={t('usageWeekly')} limit={credits.weekly} t={t} />\n </div>\n ) : null}\n\n {plan !== undefined && plan.currentPeriodEnd > 0 ? (\n <div className=\"cc-usageMeta\">\n <p className=\"cc-usageUpdated\">{t('usagePeriodEnd')} {new Date(plan.currentPeriodEnd).toLocaleDateString()}</p>\n <span className=\"cc-usageMetaSpacer\" />\n {report.failures.length > 0 ? <p className=\"cc-usagePartial\" title={report.failures.join('; ')}>{t('usagePartial')}</p> : null}\n </div>\n ) : report.failures.length > 0 ? (\n <div className=\"cc-usageMeta\">\n <span className=\"cc-usageMetaSpacer\" />\n <p className=\"cc-usagePartial\" title={report.failures.join('; ')}>{t('usagePartial')}</p>\n </div>\n ) : null}\n </div>\n )\n}\n\n/** The status dot on an account tab: cooling/invalid warn, everything else ok. */\nfunction AccountTabDot({ entry }: { entry: CommandCodeAccountUsage }) {\n const cls = entry.mark === 'invalid-credential'\n ? 'cc-tabDot cc-tabDotError'\n : entry.mark !== '' || entry.cooldownUntil > 0\n ? 'cc-tabDot cc-tabDotWarn'\n : 'cc-tabDot cc-tabDotOk'\n return <span className={cls} />\n}\n\n/**\n * The account-usage card: the `/commandcode` dashboard's facts rendered as\n * a native settings card. With several accounts the card is a carousel — a\n * tab strip (label + status dot) switches between accounts so the page stays\n * short; each account's report carries its own remove affordance (the\n * default account is not removable). Accounts staged for removal in the\n * management card are hidden here immediately. Data arrives through the\n * `commandcode/report` Remote; the API keys never leave the Host.\n */\nfunction UsageCard({ t, usage, apiKeyConfigured, removingIds, removableIds, canManage, onRefresh, onRemoveAccount }: {\n t: Translate<SettingsCommandCodeKey>\n usage: UsagePageState\n apiKeyConfigured: boolean\n /** Ids of accounts staged for removal (hidden from the carousel). */\n removingIds: string[]\n /**\n * Ids of accounts the settings document can actually remove (the stored\n * extra accounts' refs). Composition-only accounts (literal-key slots with\n * positional `account-N` ids) are NOT removable from the page — the\n * settings document cannot name them — so they get no remove button.\n */\n removableIds: string[]\n /** Whether the page accepts writes (the remove affordance follows it). */\n canManage: boolean\n onRefresh(): void\n onRemoveAccount(id: string): void\n}) {\n // First paint with a configured key fetches automatically; later fetches\n // are explicit (refresh button) or follow a landed save.\n useEffect(() => {\n if (apiKeyConfigured && usage.status === 'idle') onRefresh()\n }, [apiKeyConfigured, usage.status, onRefresh])\n\n const loading = usage.status === 'loading'\n const report = usage.report\n // Locally remembered removals: the usage controller keeps the old report\n // until the post-save refresh lands, and removedRefs clears at save-land —\n // without this the just-removed account would pop back in for one refresh\n // round-trip. Cleared when a fresh report arrives (fetchedAt changes).\n const [locallyRemoved, setLocallyRemoved] = useState<readonly string[]>([])\n useEffect(() => {\n setLocallyRemoved([])\n }, [usage.fetchedAt])\n const hidden = new Set([...removingIds, ...locallyRemoved])\n const seenIds = new Set<string>()\n const entries = (report?.accounts ?? []).filter((entry) => {\n if (hidden.has(entry.id)) return false\n // Hand-edited settings can name the same credential ref twice; dedupe so\n // the tab strip never carries duplicate keys/selections.\n if (seenIds.has(entry.id)) return false\n seenIds.add(entry.id)\n return true\n })\n const [selectedId, setSelectedId] = useState<string | undefined>(undefined)\n // The selected tab: the explicit choice while it still exists, else the\n // serving (active) account, else the first entry.\n const selected = entries.find((entry) => entry.id === selectedId)\n ?? entries.find((entry) => entry.active)\n ?? entries[0]\n const removeSelected = canManage && selected !== undefined && removableIds.includes(selected.id)\n ? () => {\n const id = selected.id\n setLocallyRemoved((prev) => [...prev, id])\n onRemoveAccount(id)\n }\n : undefined\n\n return (\n <div className=\"cc-usageCard\" aria-label={t('usageTitle')}>\n <div className=\"cc-usageHead\">\n <h3 className=\"cc-usageTitle\">{t('usageTitle')}</h3>\n <span className=\"cc-usageMetaSpacer\" />\n <button type=\"button\" className=\"cc-usageRefresh\" disabled={loading || !apiKeyConfigured} onClick={onRefresh}>\n {loading ? t('usageRefreshing') : t('usageRefresh')}\n </button>\n </div>\n\n {!apiKeyConfigured ? <p className=\"cc-usageHint\">{t('usageNoKey')}</p> : null}\n {apiKeyConfigured && report === undefined && loading ? <p className=\"cc-usageHint\">{t('usageLoading')}</p> : null}\n {usage.status === 'error' ? (\n <p className=\"cc-usageError\" role=\"status\">\n <span>{t('usageError')}{usage.error !== undefined && usage.error !== '' ? ` — ${usage.error}` : ''}</span>\n </p>\n ) : null}\n\n {entries.length > 1 ? (\n <div className=\"cc-tabs\" role=\"tablist\" aria-label={t('accountsTitle')}>\n {entries.map((entry) => (\n <button\n key={entry.id}\n type=\"button\"\n role=\"tab\"\n aria-selected={selected?.id === entry.id}\n className={selected?.id === entry.id ? 'cc-tab cc-tabActive' : 'cc-tab'}\n onClick={() => setSelectedId(entry.id)}\n >\n <AccountTabDot entry={entry} />\n {entry.label}\n </button>\n ))}\n </div>\n ) : null}\n\n {selected !== undefined ? (\n <AccountReport\n key={selected.id}\n entry={selected}\n t={t}\n onRemove={removeSelected}\n />\n ) : null}\n\n {report !== undefined && usage.fetchedAt !== undefined ? (\n <div className=\"cc-usageMeta\">\n <span className=\"cc-usageMetaSpacer\" />\n <p className=\"cc-usageUpdated\">{t('usageUpdated')} {new Date(usage.fetchedAt).toLocaleTimeString()}</p>\n </div>\n ) : null}\n </div>\n )\n}\n\n/**\n * One extra account row: label, key, configured badge. Saved accounts are\n * removed from the usage card above; a NOT-YET-SAVED addition never appears\n * there (the usage report is Host-side), so it keeps its own remove button —\n * otherwise the only way to undo a mistaken Add would be discarding every\n * other staged edit.\n */\nfunction AccountRow({ account, disabled, t, onLabel, onKey, onRemove }: {\n account: AccountItemState\n disabled: boolean\n t: Translate<SettingsCommandCodeKey>\n onLabel(text: string): void\n onKey(text: string): void\n onRemove(): void\n}) {\n const locked = !account.writable\n return (\n <div className=\"cc-field\">\n <div className=\"cc-fieldHead\">\n <label className=\"cc-label\" htmlFor={`cc-account-label-${account.id}`}>{t('accountLabel')}</label>\n <span className=\"cc-badges\">\n {account.added ? <span className=\"cc-badge\">{t('unsaved')}</span> : null}\n <span className={account.configured ? 'cc-badge' : 'cc-badgeMuted'}>\n {account.configured ? t('apiKeySet') : t('apiKeyUnset')}\n </span>\n {account.added ? (\n <button type=\"button\" className=\"cc-reset\" disabled={disabled} onClick={onRemove}>{t('accountRemove')}</button>\n ) : null}\n </span>\n </div>\n <input\n id={`cc-account-label-${account.id}`}\n className=\"cc-input\"\n type=\"text\"\n value={account.label}\n disabled={disabled}\n onChange={(event) => onLabel(event.target.value)}\n />\n <input\n id={`cc-account-key-${account.id}`}\n className=\"cc-input\"\n type=\"password\"\n autoComplete=\"off\"\n placeholder={t('accountKey')}\n value={account.keyText}\n disabled={disabled || locked}\n onChange={(event) => onKey(event.target.value)}\n />\n <p className=\"cc-hint\">{locked ? t('apiKeyLocked') : t('accountKeyHint')}</p>\n </div>\n )\n}\n\n/** The multi-account card: the active-account selector + extra accounts in rotation order + add button. */\nfunction AccountsCard({ t, state, disabled, onAdd, onRemove, onLabel, onKey, onActive, onActiveReset }: {\n t: Translate<SettingsCommandCodeKey>\n state: SettingsPageState\n disabled: boolean\n onAdd(): void\n onRemove(id: string): void\n onLabel(id: string, text: string): void\n onKey(id: string, text: string): void\n onActive(text: string): void\n onActiveReset(): void\n}) {\n const active = state.activeAccount\n return (\n <div className=\"cc-card\" aria-label={t('accountsTitle')}>\n <div className=\"cc-field\">\n <div className=\"cc-fieldHead\">\n <label className=\"cc-label\">{t('accountsTitle')}</label>\n <span className=\"cc-badges\">\n <button type=\"button\" className=\"cc-reset\" disabled={disabled} onClick={onAdd}>{t('accountAdd')}</button>\n </span>\n </div>\n <p className=\"cc-hint\">{t('accountsHint')}</p>\n </div>\n <div className=\"cc-field\">\n <div className=\"cc-fieldHead\">\n <label className=\"cc-label\" htmlFor=\"cc-active-account\">{t('activeAccount')}</label>\n <span className=\"cc-badges\">\n {active.overridden ? <span className=\"cc-badge\">{t('overridden')}</span> : null}\n <button type=\"button\" className=\"cc-reset\" disabled={disabled} onClick={onActiveReset}>{t('reset')}</button>\n </span>\n </div>\n <select\n id=\"cc-active-account\"\n className=\"cc-input\"\n value={active.text}\n disabled={disabled}\n onChange={(event) => onActive(event.target.value)}\n >\n <option value=\"\">{t('activeAccountAuto')}</option>\n <option value=\"default\">{t('accountDefault')}</option>\n {state.accounts.filter((account) => !account.added).map((account) => (\n <option key={account.id} value={account.ref}>{account.label}</option>\n ))}\n </select>\n <p className=\"cc-hint\">{t('activeAccountHint')}</p>\n </div>\n {state.accounts.map((account) => (\n <AccountRow\n key={account.id}\n account={account}\n disabled={disabled}\n t={t}\n onLabel={(text) => onLabel(account.id, text)}\n onKey={(text) => onKey(account.id, text)}\n onRemove={() => onRemove(account.id)}\n />\n ))}\n </div>\n )\n}\n\n/** The settings page body: connection facts for the Command Code provider. */\nexport function CommandCodeSettingsPage(props: CommandCodeSettingsProps) {\n const { t } = props\n const state = props.useCommandCodeSettings((snapshot) => snapshot)\n const usage = props.useCommandCodeUsage((snapshot) => snapshot)\n const disabled = !state.writable\n const keyLocked = !state.apiKeyWritable\n return (\n <section className=\"cc-section\" aria-label={t('title')}>\n <h2 className=\"cc-title\">{t('title')}</h2>\n <p className=\"cc-intro\">{t('intro')}</p>\n {!state.writable ? <p className=\"cc-readOnly\" role=\"status\">{t('readOnly')}</p> : null}\n <UsageCard\n t={t}\n usage={usage}\n apiKeyConfigured={state.anyAccountConfigured}\n removingIds={state.accountsRemoving}\n removableIds={state.accounts.map((account) => account.id)}\n canManage={state.writable}\n onRefresh={props.refreshUsage}\n onRemoveAccount={props.removeAccount}\n />\n <AccountsCard\n t={t}\n state={state}\n disabled={disabled}\n onAdd={props.addAccount}\n onRemove={props.removeAccount}\n onLabel={props.editAccountLabel}\n onKey={props.editAccountKey}\n onActive={(text) => props.edit('activeAccount', text)}\n onActiveReset={() => props.resetField('activeAccount')}\n />\n <div className=\"cc-card\">\n <SecretKeyField\n label={t('apiKey')}\n hint={keyLocked ? t('apiKeyLocked') : t('apiKeyHint')}\n state={state.apiKey}\n disabled={disabled || keyLocked}\n configured={state.apiKeyConfigured}\n configuredLabel={t('apiKeySet')}\n unconfiguredLabel={t('apiKeyUnset')}\n onEdit={(text) => props.edit('apiKey', text)}\n />\n <Field\n id=\"cc-api-base\"\n label={t('apiBase')}\n hint={t('apiBaseHint')}\n state={state.apiBase}\n disabled={disabled}\n onEdit={(text) => props.edit('apiBase', text)}\n onReset={() => props.resetField('apiBase')}\n t={t}\n />\n <Field\n id=\"cc-working-dir\"\n label={t('workingDir')}\n hint={t('workingDirHint')}\n state={state.workingDir}\n disabled={disabled}\n placeholder={state.defaultWorkingDir}\n onEdit={(text) => props.edit('workingDir', text)}\n onReset={() => props.resetField('workingDir')}\n t={t}\n />\n <Field\n id=\"cc-request-timeout\"\n label={t('requestTimeoutMs')}\n hint={t('requestTimeoutMsHint')}\n state={state.requestTimeoutMs}\n disabled={disabled}\n numeric\n onEdit={(text) => props.edit('requestTimeoutMs', text)}\n onReset={() => props.resetField('requestTimeoutMs')}\n t={t}\n />\n <Field\n id=\"cc-stream-idle-timeout\"\n label={t('streamIdleTimeoutMs')}\n hint={t('streamIdleTimeoutMsHint')}\n state={state.streamIdleTimeoutMs}\n disabled={disabled}\n numeric\n onEdit={(text) => props.edit('streamIdleTimeoutMs', text)}\n onReset={() => props.resetField('streamIdleTimeoutMs')}\n t={t}\n />\n <ToggleField\n id=\"cc-filter-models-by-plan\"\n label={t('filterModelsByPlan')}\n hint={t('filterModelsByPlanHint')}\n state={state.filterModelsByPlan}\n disabled={disabled}\n defaultChecked\n onEdit={(text) => props.edit('filterModelsByPlan', text)}\n onReset={() => props.resetField('filterModelsByPlan')}\n t={t}\n />\n </div>\n <div className=\"cc-footer\">\n {state.failed ? <p className=\"cc-failed\" role=\"status\">{t('saveFailed')}</p> : null}\n <Button variant=\"ghost\" size=\"sm\" disabled={!state.dirty || state.saving} onClick={props.discard}>\n {t('discard')}\n </Button>\n <Button\n variant=\"primary\"\n size=\"sm\"\n disabled={!state.dirty || state.invalid || state.saving}\n onClick={props.save}\n >\n {t(state.saving ? 'saving' : 'save')}\n </Button>\n </div>\n </section>\n )\n}\n","/**\n * Locale copy for the \"Command Code\" settings page, and the declaration that\n * merges the page's namespace into the framework's `LocaleNamespaceMap` so\n * `ctx.locale.register` / `ctx.slots.register(..., { locale })` are typed.\n *\n * zh is the source of truth for the key set (repo convention); en must carry\n * the exact same keys — a mismatch is a compile error at the register site.\n */\ndeclare module '@deepseek-ai/dsh-client-ui-slots' {\n interface LocaleNamespaceMap {\n /** Copy of the Command Code settings page. */\n 'settings.commandcode': SettingsCommandCodeKey\n }\n}\n\n/** Dictionary keys of the Command Code settings page. */\nexport type SettingsCommandCodeKey =\n | 'nav'\n | 'title'\n | 'intro'\n | 'apiKey'\n | 'apiKeyHint'\n | 'apiKeySet'\n | 'apiKeyUnset'\n | 'apiKeyLocked'\n | 'apiBase'\n | 'apiBaseHint'\n | 'workingDir'\n | 'workingDirHint'\n | 'requestTimeoutMs'\n | 'requestTimeoutMsHint'\n | 'streamIdleTimeoutMs'\n | 'streamIdleTimeoutMsHint'\n | 'filterModelsByPlan'\n | 'filterModelsByPlanHint'\n | 'accountsTitle'\n | 'accountsHint'\n | 'accountAdd'\n | 'accountRemove'\n | 'accountLabel'\n | 'accountKey'\n | 'accountKeyHint'\n | 'accountDefault'\n | 'activeAccount'\n | 'activeAccountAuto'\n | 'activeAccountHint'\n | 'overridden'\n | 'reset'\n | 'invalidNumber'\n | 'readOnly'\n | 'unsaved'\n | 'save'\n | 'saving'\n | 'saveFailed'\n | 'discard'\n | 'cancel'\n | 'usageTitle'\n | 'usageRefresh'\n | 'usageRefreshing'\n | 'usageLoading'\n | 'usageNoKey'\n | 'usageError'\n | 'usageRequests'\n | 'usageFailed'\n | 'usageSuccessRate'\n | 'usageCost'\n | 'usageTokens'\n | 'usageTokensIn'\n | 'usageTokensOut'\n | 'usageMonthly'\n | 'usagePurchased'\n | 'usageFree'\n | 'usageFiveHour'\n | 'usageWeekly'\n | 'usageExceeded'\n | 'usageReset'\n | 'usagePartial'\n | 'usageUpdated'\n | 'usagePeriodEnd'\n | 'usageActive'\n | 'usageCooldown'\n | 'usageInvalidKey'\n | 'usageUnconfigured'\n\nexport const zh: Record<SettingsCommandCodeKey, string> = {\n nav: 'Command Code',\n title: 'Command Code',\n intro:\n '配置 Command Code Provider 连接。API 密钥仅保存在本机凭据服务中,不会回显;'\n + '其他字段写入用户设置,下次请求即生效。',\n apiKey: 'API 密钥',\n apiKeyHint: '在 commandcode.ai 控制台创建。留空保存不会覆盖已存储的密钥。',\n apiKeySet: '已配置',\n apiKeyUnset: '未配置',\n apiKeyLocked: '密钥由只读来源提供',\n apiBase: 'API 地址',\n apiBaseHint: '默认 https://api.commandcode.ai,一般无需修改。',\n workingDir: '工作目录',\n workingDirHint: '可选。留空时使用占位符显示的进程工作目录;仅在需要固定路径时填写。',\n requestTimeoutMs: '请求超时(毫秒)',\n requestTimeoutMsHint: '等待响应首个字节的超时;默认 60000。',\n streamIdleTimeoutMs: '流空闲超时(毫秒)',\n streamIdleTimeoutMsHint: '生成流停滞多久视为断连;默认 300000(长思考模型可静默数分钟,默认值刻意放宽)。',\n filterModelsByPlan: '隐藏套餐外模型',\n filterModelsByPlanHint: '开启后,模型选择器只列出当前套餐可用的模型;账户持有按需余额时会显示全部。',\n accountsTitle: '多账户轮换',\n accountsHint: '当前账户达到用量限额(429)或密钥失效(401)时,请求自动切换到下一个账户;全部耗尽时会提示最早的重置时间。',\n accountAdd: '添加账户',\n accountRemove: '移除',\n accountLabel: '账户备注名',\n accountKey: 'API 密钥',\n accountKeyHint: '该账户的 API 密钥。留空保存不会覆盖已存储的密钥。',\n accountDefault: '默认账户',\n activeAccount: '当前使用账户',\n activeAccountAuto: '自动(第一个可用账户)',\n activeAccountHint: '手动指定优先使用的账户,保存后下次请求即生效;所选账户耗尽时仍会自动切换到其他可用账户。',\n overridden: '已覆盖',\n reset: '重置',\n invalidNumber: '无效数字',\n readOnly: '当前配置为只读。',\n unsaved: '未保存',\n save: '保存',\n saving: '保存中',\n saveFailed: '保存失败,请重试。',\n discard: '放弃',\n cancel: '取消',\n usageTitle: '账户用量',\n usageRefresh: '刷新',\n usageRefreshing: '刷新中…',\n usageLoading: '正在获取账户用量…',\n usageNoKey: '配置 API 密钥后,这里会显示账户的用量与额度状态。',\n usageError: '用量获取失败',\n usageRequests: '请求',\n usageFailed: '失败',\n usageSuccessRate: '成功率',\n usageCost: '花费',\n usageTokens: 'Token',\n usageTokensIn: '入',\n usageTokensOut: '出',\n usageMonthly: '月额度',\n usagePurchased: '已购',\n usageFree: '赠送',\n usageFiveHour: '5 小时窗口',\n usageWeekly: '每周窗口',\n usageExceeded: '已超限',\n usageReset: '重置于',\n usagePartial: '部分端点数据不可用',\n usageUpdated: '更新于',\n usagePeriodEnd: '账期截止',\n usageActive: '当前使用',\n usageCooldown: '限额冷却中',\n usageInvalidKey: '密钥无效',\n usageUnconfigured: '该账户尚未配置 API 密钥。',\n}\n\nexport const en: Record<SettingsCommandCodeKey, string> = {\n nav: 'Command Code',\n title: 'Command Code',\n intro:\n 'Configure the Command Code Provider connection. The API key is stored only'\n + ' in the local credential service and never echoed; other fields are written'\n + ' to user settings and take effect on the next request.',\n apiKey: 'API key',\n apiKeyHint: 'Create one in the commandcode.ai console. Saving with this field'\n + ' blank keeps the stored key.',\n apiKeySet: 'Configured',\n apiKeyUnset: 'Not configured',\n apiKeyLocked: 'Key provided by a read-only source',\n apiBase: 'API base URL',\n apiBaseHint: 'Defaults to https://api.commandcode.ai; usually leave as-is.',\n workingDir: 'Working directory',\n workingDirHint: 'Optional. Leave blank to use the process cwd shown as the'\n + ' placeholder; fill in only to pin a specific path.',\n requestTimeoutMs: 'Request timeout (ms)',\n requestTimeoutMsHint: 'Time to wait for the first response byte; default 60000.',\n streamIdleTimeoutMs: 'Stream idle timeout (ms)',\n streamIdleTimeoutMsHint: 'How long a stalled stream is treated as dead; default 300000'\n + ' (deliberately generous — long-thinking models can stay silent for minutes).',\n filterModelsByPlan: 'Hide out-of-plan models',\n filterModelsByPlanHint: 'When on, the model picker lists only models your subscription'\n + ' includes; any on-demand credit balance shows the full catalog.',\n accountsTitle: 'Account rotation',\n accountsHint: 'When the active account hits its usage limit (429) or its key'\n + ' fails (401), requests switch to the next account; when every account is'\n + ' exhausted the error names the earliest window reset.',\n accountAdd: 'Add account',\n accountRemove: 'Remove',\n accountLabel: 'Account label',\n accountKey: 'API key',\n accountKeyHint: 'This account’s API key. Saving with the field blank keeps the stored key.',\n accountDefault: 'Default account',\n activeAccount: 'Active account',\n activeAccountAuto: 'Auto (first usable account)',\n activeAccountHint: 'Pin the preferred account; applies to the next request after saving.'\n + ' If the selected account is exhausted, requests still rotate to another usable account.',\n overridden: 'Overridden',\n reset: 'Reset',\n invalidNumber: 'Invalid number',\n readOnly: 'Settings are read-only.',\n unsaved: 'Unsaved',\n save: 'Save',\n saving: 'Saving',\n saveFailed: 'Save failed, please retry.',\n discard: 'Discard',\n cancel: 'Cancel',\n usageTitle: 'Account usage',\n usageRefresh: 'Refresh',\n usageRefreshing: 'Refreshing…',\n usageLoading: 'Fetching account usage…',\n usageNoKey: 'Configure an API key to see this account’s usage and credit state here.',\n usageError: 'Could not fetch usage',\n usageRequests: 'Requests',\n usageFailed: 'failed',\n usageSuccessRate: 'Success rate',\n usageCost: 'Spend',\n usageTokens: 'Tokens',\n usageTokensIn: 'in',\n usageTokensOut: 'out',\n usageMonthly: 'Monthly',\n usagePurchased: 'Purchased',\n usageFree: 'Free',\n usageFiveHour: '5-hour window',\n usageWeekly: 'Weekly window',\n usageExceeded: 'Exceeded',\n usageReset: 'Resets',\n usagePartial: 'Some endpoint data unavailable',\n usageUpdated: 'Updated',\n usagePeriodEnd: 'Period ends',\n usageActive: 'Active',\n usageCooldown: 'Cooling down',\n usageInvalidKey: 'Invalid key',\n usageUnconfigured: 'No API key configured for this account yet.',\n}\n","/**\n * Browser half of the dsh-commandcode-provider bundle.\n *\n * Two responsibilities:\n *\n * 1. A \"Command Code\" settings page (a `settings.section` entry at the same\n * nav level as General / Models / Plugins). The Models page renders an\n * unknown-adapter-family card for the `commandcode` provider and disables\n * its submit, so the API key cannot be configured there; this page is the\n * dedicated surface. It writes the API key through the credentials domain\n * (the `COMMANDCODE_API_KEY` reference the plugin resolves) and the\n * connection facts through the `llm-commandcode` settings namespace, so a\n * saved key or endpoint reaches the very next request.\n *\n * 2. The friendly-error wrapper for the harness's image-session gate — see\n * `./sessions.ts`. The wrapper is deliberately narrow: only the\n * `model-unavailable` code is rewritten, only when the message matches the\n * image-session gate, and only the message text changes.\n *\n * The wire types are spelled structurally in `./sessions.ts` (not imported\n * from `@deepseek-ai/dsh-host-apiproxy`) so this client bundle does not drag\n * an extra peer dependency into the package; the shapes are stable and the\n * client build inlines them anyway.\n */\n\nimport type { Context } from '@deepseek-ai/cordis'\nimport { createSnapshotStore } from '@deepseek-ai/dsh-client-runtime/client'\n// Type-only imports that pull in the client-service augmentations\n// (`slots`/`remote`/`locale` on Context) and the `settings.section` SlotMap\n// entry (`settingsScope` arrives through dsh-client-ui-settings).\nimport type {} from '@deepseek-ai/dsh-api-remotes/client'\nimport type {} from '@deepseek-ai/dsh-client-locale/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-settings/client'\nimport { installFriendlyImageError } from './sessions.ts'\nimport { CommandCodeSettingsController, COMMANDCODE_NS, type SettingsPageState } from './settings.ts'\nimport { CommandCodeUsageController, type UsagePageState, type UsageRemote } from './usage.ts'\nimport { USAGE_REMOTE_CONTRIBUTION } from '../usage-wire.ts'\nimport { CommandCodeSettingsPage } from './section.tsx'\nimport { zh, en } from './locales.ts'\n\nexport { isImageSessionRejection, withFriendlyImageError } from './sessions.ts'\nimport type { ConnectionLike } from './sessions.ts'\n\n/** CSS for the settings page, injected once (harness bundle convention). */\nconst PAGE_CSS = `\n.cc-section{max-width:720px;color:var(--dsw-alias-label-primary);flex-direction:column;gap:12px;display:flex}\n.cc-title{margin:0;font-size:18px;font-weight:600}\n.cc-intro{color:var(--dsw-alias-label-tertiary);margin:0;font-size:13px;line-height:1.5}\n.cc-readOnly{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px;line-height:1.5}\n.cc-card{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:12px;padding:4px 16px}\n.cc-field{flex-direction:column;gap:6px;padding:12px 0;display:flex}\n.cc-field+.cc-field{border-top:1px solid var(--dsw-alias-border-l2)}\n.cc-fieldHead{align-items:center;gap:8px;display:flex}\n.cc-label{min-width:0;color:var(--dsw-alias-label-primary);flex:1;font-size:13px;font-weight:500;line-height:1.5}\n.cc-badges{align-items:center;gap:8px;display:inline-flex}\n.cc-badge{white-space:nowrap;background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-secondary);border-radius:999px;padding:1px 8px;font-size:11px;font-weight:500;line-height:17px}\n.cc-badgeMuted{white-space:nowrap;color:var(--dsw-alias-label-tertiary);border-radius:999px;padding:1px 8px;font-size:11px;line-height:17px}\n.cc-reset{font:inherit;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;padding:0;font-size:12px;line-height:1.5}\n.cc-reset:hover:not(:disabled){color:var(--dsw-alias-label-primary)}\n.cc-reset:disabled{cursor:default;opacity:.5}\n.cc-input{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-1);height:34px;font:inherit;color:var(--dsw-alias-label-primary);border-radius:8px;padding:0 12px;font-size:13px;line-height:1.5}\n.cc-input:focus-visible{border-color:var(--dsw-alias-brand-primary);outline:none}\n.cc-input:disabled{color:var(--dsw-alias-label-tertiary);cursor:default}\n.cc-inputInvalid{border-color:var(--dsw-alias-label-error)}\n.cc-invalid{color:var(--dsw-alias-label-error);margin:0;font-size:12px;line-height:1.5}\n.cc-hint{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px;line-height:1.5}\n.cc-footer{justify-content:flex-end;align-items:center;gap:8px;display:flex}\n.cc-toggleRow{align-items:center;gap:8px;cursor:pointer;display:flex}\n.cc-toggleRow:has(.cc-toggle:disabled){cursor:default}\n.cc-toggle{appearance:none;flex-shrink:0;background:var(--dsw-alias-border-l2);border-radius:999px;width:30px;height:18px;margin:0;cursor:pointer;position:relative;transition:background .15s ease}\n.cc-toggle:checked{background:var(--dsw-alias-brand-primary)}\n.cc-toggle::after{content:'';background:#fff;border-radius:50%;width:14px;height:14px;position:absolute;top:2px;left:2px;transition:left .15s ease}\n.cc-toggle:checked::after{left:14px}\n.cc-toggle:disabled{cursor:default;opacity:.5}\n.cc-failed{min-width:0;color:var(--dsw-alias-label-error);flex:1;margin:0;font-size:12px;line-height:1.5}\n.cc-usageCard{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:12px;padding:14px 16px;flex-direction:column;gap:12px;display:flex}\n.cc-usageHead{align-items:center;gap:8px;display:flex}\n.cc-usageTitle{color:var(--dsw-alias-label-primary);flex:1;margin:0;font-size:13px;font-weight:600;line-height:1.5}\n.cc-usageAccount{max-width:40%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-secondary);border-radius:999px;padding:1px 8px;font-size:11px;font-weight:500;line-height:17px}\n.cc-usagePlan{white-space:nowrap;background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-brand-primary);border-radius:999px;padding:1px 8px;font-size:11px;font-weight:600;line-height:17px}\n.cc-usagePlanStatus{white-space:nowrap;color:var(--dsw-alias-label-error);border-radius:999px;padding:1px 8px;font-size:11px;font-weight:500;line-height:17px}\n.cc-usageRefresh{font:inherit;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;padding:0;font-size:12px;line-height:1.5}\n.cc-usageRefresh:hover:not(:disabled){color:var(--dsw-alias-label-primary)}\n.cc-usageRefresh:disabled{cursor:default;opacity:.5}\n.cc-usageHint{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px;line-height:1.5}\n.cc-usageError{align-items:center;gap:8px;color:var(--dsw-alias-label-error);margin:0;font-size:12px;line-height:1.5;display:flex}\n.cc-usageStats{grid-template-columns:repeat(auto-fit,minmax(120px,1fr));gap:8px;display:grid}\n.cc-usageStat{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-1);border-radius:8px;padding:8px 10px;flex-direction:column;gap:2px;display:flex}\n.cc-usageStatLabel{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:1.5}\n.cc-usageStatValue{color:var(--dsw-alias-label-primary);font-size:15px;font-weight:600;line-height:1.4}\n.cc-usageStatSub{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:1.5}\n.cc-usageWindows{flex-direction:column;gap:16px;display:flex}\n.cc-usageWindow{flex-direction:column;gap:6px;display:flex}\n.cc-usageWindowHead{align-items:baseline;gap:8px;display:flex}\n.cc-usageWindowLabel{color:var(--dsw-alias-label-secondary);flex:1;font-size:12px;font-weight:500;line-height:1.5}\n.cc-usageWindowValue{color:var(--dsw-alias-label-primary);font-size:12px;font-weight:500;line-height:1.5}\n.cc-usageExceeded{color:var(--dsw-alias-label-error);font-size:11px;font-weight:500;line-height:1.5}\n.cc-usageBar{overflow:hidden;background:var(--dsw-alias-bg-layer-1);border-radius:999px;height:6px}\n.cc-usageBarFill{background:var(--dsw-alias-brand-primary);border-radius:999px;height:100%;transition:width .3s ease}\n.cc-usageBarFillWarn{background:var(--dsw-alias-label-error)}\n.cc-usageWindowReset{color:var(--dsw-alias-label-tertiary);margin:0;font-size:11px;line-height:1.5}\n.cc-usageMeta{align-items:center;gap:8px;display:flex}\n.cc-accountReport{flex-direction:column;gap:12px;display:flex}\n.cc-tabs{flex-wrap:wrap;gap:6px;display:flex}\n.cc-tab{align-items:center;font:inherit;color:var(--dsw-alias-label-secondary);cursor:pointer;background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l2);border-radius:999px;padding:2px 10px;font-size:12px;line-height:18px;display:inline-flex;gap:6px}\n.cc-tab:hover:not(.cc-tabActive){color:var(--dsw-alias-label-primary)}\n.cc-tabActive{color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-brand-primary)}\n.cc-tabDotOk{background:var(--dsw-alias-brand-primary);border-radius:50%;width:6px;height:6px}\n.cc-tabDotWarn{background:#d97706;border-radius:50%;width:6px;height:6px}\n.cc-tabDotError{background:var(--dsw-alias-label-error);border-radius:50%;width:6px;height:6px}\n.cc-usageMetaSpacer{flex:1}\n.cc-usageUpdated{color:var(--dsw-alias-label-tertiary);margin:0;font-size:11px;line-height:1.5}\n.cc-usagePartial{color:var(--dsw-alias-label-error);margin:0;font-size:11px;line-height:1.5}\n`\n\n/** Inject the page stylesheet once (idempotent per tag). */\nfunction injectPageCss(): void {\n if (typeof document === 'undefined') return\n const id = '@mars-sea/dsh-commandcode-provider/CommandCodeSettingsPage.module.css'\n if (document.querySelector(`style[data-plugin-css=\"${id}\"]`) !== null) return\n const tag = document.createElement('style')\n tag.dataset.plugin = '@mars-sea/dsh-commandcode-provider'\n tag.dataset.pluginCss = id\n tag.textContent = PAGE_CSS\n document.head.appendChild(tag)\n}\n\n/**\n * Client plugin body. Gates on the services the settings page needs\n * (`slots`, `locale`, `connection`, `remote`, `settingsScope`) plus the\n * `connection` used by the friendly-error wrapper — the same inject list the\n * harness's own settings-surface plugins declare.\n */\nexport function apply(ctx: Context): void {\n injectPageCss()\n\n // Friendly image-gate error wrapper (unchanged behaviour).\n const connection = ctx.get('connection') as ConnectionLike | undefined\n if (connection !== undefined) {\n installFriendlyImageError(connection)\n }\n\n // The \"Command Code\" settings page: register the section once the\n // `settings.section` declaration is on the ledger (ui-settings-general\n // owns the shell; registration order relative to it is not constrained —\n // `slots.inject` waits for the declaration).\n ctx.effect(() => ctx.locale.register('settings.commandcode', { zh, en }), 'dsh-commandcode-provider: page copy')\n\n const api = ctx.get('connection').api\n const hostDescription = ctx.get('connection').hostDescription\n const scope = ctx.settingsScope.bind<Record<string, unknown>>({ namespace: COMMANDCODE_NS })\n const controller = new CommandCodeSettingsController(scope, { credentials: api.credentials }, hostDescription)\n ctx.effect(() => () => controller.dispose(), 'dsh-commandcode-provider: settings controller')\n const store = createSnapshotStore<SettingsPageState>(controller.state())\n controller.subscribe(() => store.set(controller.state()))\n\n // The account-usage card: mount the shared Remote contribution, then resolve\n // the `remote.commandcode` namespace through a scoped inject. Cordis only\n // serves services a fiber declares in `inject`, and the namespace service\n // exists only after the mount — a static inject would deadlock the plugin\n // (the mounter would wait for its own mount), so the inject is registered\n // dynamically once the mount lands. A Host half that predates the Remote\n // fails the call instead, and the card renders its error branch.\n let usageNamespace: (typeof ctx.remote)['commandcode'] | undefined\n let usageMountError: string | undefined\n ctx.effect(() => {\n let cancelled = false\n let unmount: (() => Promise<void>) | undefined\n void ctx.remote.$mount(USAGE_REMOTE_CONTRIBUTION).then((dispose) => {\n if (cancelled) {\n void dispose()\n return\n }\n unmount = dispose\n ctx.inject(['remote.commandcode'], (namespaceCtx) => {\n usageNamespace = namespaceCtx.remote.commandcode\n namespaceCtx.effect(() => () => {\n usageNamespace = undefined\n }, 'dsh-commandcode-provider: usage namespace')\n })\n }, (error: unknown) => {\n // A mount failure (e.g. a harness without the Remote mount) leaves the\n // namespace unset; keep the reason so the card can surface it.\n usageMountError = error instanceof Error ? error.message : String(error)\n })\n return () => {\n cancelled = true\n usageNamespace = undefined\n if (unmount !== undefined) void unmount()\n }\n }, 'dsh-commandcode-provider: usage remote')\n const usageRemote: UsageRemote = {\n report: async () => {\n const namespace = usageNamespace\n if (namespace === undefined) {\n return { ok: false, error: { message: usageMountError ?? 'commandcode/report remote is not mounted' } }\n }\n return namespace.report()\n },\n }\n const usageController = new CommandCodeUsageController(usageRemote)\n ctx.effect(() => () => usageController.dispose(), 'dsh-commandcode-provider: usage controller')\n const usageStore = createSnapshotStore<UsagePageState>(usageController.state())\n usageController.subscribe(() => usageStore.set(usageController.state()))\n\n const injected = () => ({\n hooks: { commandCodeSettings: store, commandCodeUsage: usageStore },\n edit: (field: string, text: string) => controller.edit(field, text),\n resetField: (field: string) => controller.resetField(field),\n // A landed save can change the key or endpoint the usage endpoints read,\n // so the account card refetches; a failed save keeps the old data.\n save: () => void controller.save().then(() => {\n const settled = controller.state()\n if (!settled.failed && settled.anyAccountConfigured) void usageController.refresh()\n }),\n discard: () => controller.discard(),\n refreshUsage: () => void usageController.refresh(),\n addAccount: () => controller.addAccount(),\n removeAccount: (id: string) => controller.removeAccount(id),\n editAccountLabel: (id: string, text: string) => controller.editAccountLabel(id, text),\n editAccountKey: (id: string, text: string) => controller.editAccountKey(id, text),\n })\n\n ctx.slots.inject('settings.section', () => ctx.slots.register({\n name: 'settings.section',\n id: 'commandcode',\n order: 12,\n label: () => ctx.locale.bind('settings.commandcode')('nav'),\n locale: 'settings.commandcode',\n inject: injected,\n }, CommandCodeSettingsPage))\n}\n\nexport const inject: readonly string[] = [\n 'slots',\n 'locale',\n 'connection',\n 'remote',\n 'settingsScope',\n]\n"],"mappings":"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"}
1
+ {"version":3,"file":"client.js","names":["numberField","booleanField","pkg.version","useState","Button","createSnapshotStore"],"sources":["../src/client/sessions.ts","../src/client/settings.ts","../src/client/usage.ts","../src/usage-wire.ts","../package.json","../src/client/version.ts","../src/client/section.tsx","../src/client/locales.ts","../src/client/index.ts"],"sourcesContent":["/**\n * Friendly-error wrapper for the harness's image-session gate.\n *\n * The host rejects switching to a text-only model while the session already\n * contains images with a `model-unavailable` error\n * (`dsh-host-apiproxy`'s `session.selectModel` handler). That rejection is\n * intentional and cannot be relaxed from the plugin side — the adapter's\n * `inputModalities` is exactly what makes the guard work. What we CAN do is\n * make the error message friendlier: wrap the shared\n * `connection.api.sessions.selectModel` face so a `model-unavailable`\n * rejection shows a clear, actionable hint (with the requested model name)\n * instead of the raw English harness message.\n *\n * The wrapper is deliberately narrow: only the `model-unavailable` code is\n * rewritten, only when the message matches the image-session gate, and only\n * the message text changes — the error code and details pass through\n * untouched so any caller that switches on `error.code` keeps working.\n *\n * The wire types are spelled structurally here (not imported from\n * `@deepseek-ai/dsh-host-apiproxy`) so this client bundle does not drag an\n * extra peer dependency into the package; the shapes are stable and the\n * client build inlines them anyway.\n *\n * This module is deliberately free of React and other client-platform\n * imports so the node test runner can exercise it directly.\n */\n\n/** The `model-unavailable` error details: provider + model id. */\ninterface ModelUnavailableDetails {\n provider: string\n model: string\n}\n\n/** The narrow slice of the RPC error we need to inspect and rewrite. */\ninterface RpcErrorLike {\n code: string\n message: string\n details?: ModelUnavailableDetails\n}\n\n/**\n * The narrow slice of a unary RPC result we need to inspect and rewrite.\n * The wire shape from `sessions.selectModel` (via `AbstractApiClient.callUnary`)\n * is the full envelope `{ rpcId, result: { ok, error? } }` — the error lives\n * under `result.result`, not at the top level. `RpcResultLike` models that.\n */\ninterface RpcResultLike {\n rpcId: string\n result:\n | { ok: true; value?: unknown }\n | { ok: false; error: RpcErrorLike }\n}\n\n/** One selectModel call: payload in, envelope out. */\ntype SelectModelCall = (\n payload: { sessionId: string; provider: string; model: string; reasoningEffort?: string },\n signal?: AbortSignal,\n) => Promise<RpcResultLike>\n\n/** The shared sessions wire face we wrap. */\ninterface SessionsLike {\n selectModel: SelectModelCall\n}\n\n/** Whether a selectModel rejection is the harness's image-session gate. */\nexport function isImageSessionRejection(\n result: RpcResultLike,\n): result is RpcResultLike & { result: { ok: false; error: RpcErrorLike } } {\n return (\n !result.result.ok &&\n result.result.error.code === 'model-unavailable' &&\n result.result.error.message.includes('does not accept image input')\n )\n}\n\n/** Wrap the shared sessions API so selectModel failures read friendlier. */\nexport function withFriendlyImageError(sessions: SessionsLike): SessionsLike {\n const selectModel = sessions.selectModel.bind(sessions)\n return {\n ...sessions,\n selectModel: async (payload, signal) => {\n const result = await selectModel(payload, signal)\n if (!isImageSessionRejection(result)) return result\n const model = result.result.error.details?.model ?? payload.model\n return {\n ...result,\n result: {\n ...result.result,\n error: {\n ...result.result.error,\n message:\n `当前会话已包含图片,而模型 ${model} 不支持图片输入;`\n + '请选择支持图片的模型,或先移除会话中的图片。',\n },\n },\n }\n },\n }\n}\n\n/** The connection handle shape we read `api.sessions` from. */\nexport interface ConnectionLike {\n api: { sessions: SessionsLike }\n}\n\n/** Install the wrapper on a connection's shared sessions face. */\nexport function installFriendlyImageError(connection: ConnectionLike): void {\n connection.api.sessions = withFriendlyImageError(connection.api.sessions)\n}\n","/**\n * Browser controller for the \"Command Code\" settings page.\n *\n * The page lives at the same settings-nav level as General / Models / Plugins\n * (a `settings.section` entry, id `commandcode`). It exists because the\n * Models page renders an unknown-adapter-family card for the `commandcode`\n * provider and deliberately disables its submit — the API key cannot be\n * configured there. This page owns the connection facts the plugin resolves\n * per request:\n *\n * - API key -> written through the credentials domain under the reference\n * the plugin resolves (`apiKeyEnv`, default\n * `COMMANDCODE_API_KEY`). The literal never rides a response,\n * so the control only reports whether one is configured.\n * - API base -> the `llm-commandcode` settings namespace (`apiBase`), same\n * namespace the Models page card addresses.\n * - Working dir, request/stream timeouts -> the same namespace.\n *\n * The controller mirrors the plugin-card pattern from the harness's own\n * settings UI: it binds the `llm-commandcode` namespace through the\n * `settingsScope` service, keeps a staged draft of edits, and writes them on\n * save through `scope.set` / the credentials domain. The Host stays the\n * single fact source; the snapshot is republished after each accepted write.\n *\n * This module is deliberately free of JSX — it only produces the state face\n * the React component renders.\n */\n\nimport type { SettingsScope } from '@deepseek-ai/dsh-client-runtime/client'\n\n/** The settings namespace the plugin registers (host half, src/index.ts). */\nexport const COMMANDCODE_NS = 'llm-commandcode'\n/** Default credential reference the plugin resolves when none is named. */\nexport const DEFAULT_API_KEY_REF = 'COMMANDCODE_API_KEY'\n\n/** The narrow slice of the wire face this controller needs. */\nexport interface SettingsPageApi {\n credentials: {\n describe(request: { refs: string[] }): Promise<{\n result: { ok: true; value: { credentials: Record<string, { configured: boolean; writable: boolean }> } } | { ok: false; error: { message: string } }\n }>\n set(request: { ref: string; value: string }): Promise<{ result: { ok: true; value?: unknown } | { ok: false; error: { message: string } } }>\n }\n}\n\n/** The Host-description observable the page reads the process cwd from. */\nexport interface HostDescriptionSource {\n getSnapshot(): { cwd?: string } | undefined\n subscribe(fn: () => void): () => void\n}\n\n/** One editable text field's staged state (blank = keep stored value). */\nexport interface StagedField {\n /** Live draft text the input shows. */\n text: string\n /** Whether the user explicitly cleared the field (reset to inherited). */\n clear: boolean\n /** Whether the user layer carries this field (marks it overridden). */\n overridden: boolean\n /** Whether the staged draft fails to parse (blocks save). */\n invalid: boolean\n /**\n * Why the draft is invalid — a non-number (`format`) or an out-of-range\n * number (`tooSmall`/`tooLarge`); undefined when valid.\n */\n invalidReason: InvalidReason | undefined\n}\n\n/** Why a staged draft fails validation (drives the per-field error copy). */\nexport type InvalidReason = 'format' | 'tooSmall' | 'tooLarge'\n\n/** One extra account row's staged state (the default account uses `apiKey`). */\nexport interface AccountItemState {\n /** Stable id — the account's credential reference. */\n id: string\n /** Credential reference this account's key lives under. */\n ref: string\n /** Label draft text (the stored/generated label until edited). */\n label: string\n /** The API key draft (write-only; starts blank, never echoes the stored key). */\n keyText: string\n /** Whether a key is stored for this account (Host-reported). */\n configured: boolean\n /** Whether the credentials domain can store the key. */\n writable: boolean\n /** Staged for addition (not yet saved). */\n added: boolean\n}\n\n/** The page's full state face, projected from the scope + drafts + credential. */\nexport interface SettingsPageState {\n /** Whether the namespace snapshot is ready. */\n available: boolean\n /** Whether the Host document accepts writes. */\n writable: boolean\n /** Whether the API key is currently configured (Host-reported). */\n apiKeyConfigured: boolean\n /** Whether ANY account (default or extra) has a stored key — gates the usage card. */\n anyAccountConfigured: boolean\n /** Whether the credentials domain can store the key. */\n apiKeyWritable: boolean\n /** The API key draft (write-only; starts blank, never echoes the stored key). */\n apiKey: StagedField\n /** apiBase draft. */\n apiBase: StagedField\n /** workingDir draft. */\n workingDir: StagedField\n /**\n * The working directory a blank `workingDir` resolves to: the Host\n * process cwd (`host.describe().cwd`). Shown as the field's placeholder so\n * the user sees what \"leave it empty\" means — no configuration needed.\n */\n defaultWorkingDir: string | undefined\n /** requestTimeoutMs draft. */\n requestTimeoutMs: StagedField\n /** streamIdleTimeoutMs draft. */\n streamIdleTimeoutMs: StagedField\n /**\n * filterModelsByPlan draft, staged as `'true'`/`'false'`/`''` (unset). The\n * component renders it as a toggle; `''` means \"inherit the default\" (on).\n */\n filterModelsByPlan: StagedField\n /**\n * The manually selected active account, staged as a slot id (`default`\n * or an extra account's credential reference); `''` means \"auto — first\n * usable account\". The component renders it as a select.\n */\n activeAccount: StagedField\n /** Extra accounts (multi-account rotation), in rotation order. */\n accounts: AccountItemState[]\n /** Refs of stored accounts staged for removal (the usage card hides them). */\n accountsRemoving: string[]\n /** Whether any staged edit differs from the stored section. */\n dirty: boolean\n /** Whether a staged numeric field fails to parse (save blocked). */\n invalid: boolean\n /** Whether a save is in flight. */\n saving: boolean\n /** Whether the last save failed (drafts retained for correction). */\n failed: boolean\n /**\n * Monotonic counter bumped once per accepted save. The component watches it\n * to flash the \"Saved ✓\" affordance (timing lives in the component; the\n * controller stays a plain state machine with no timers).\n */\n savedCount: number\n}\n\n/** Parsed outcome of one field's draft. */\ntype Parsed =\n | { kind: 'set'; value: string | number | boolean }\n | { kind: 'clear' }\n | { kind: 'invalid'; reason: InvalidReason }\n\n/** One field's staged draft (internal; the public face adds derived flags). */\ninterface Staged {\n text: string\n clear: boolean\n}\n\n/** A field conversion spec. */\ninterface FieldSpec {\n field: string\n format(value: unknown): string\n parse(text: string): Parsed\n}\n\n/** A free-text field; an empty draft clears it. */\nfunction textField(field: string): FieldSpec {\n return {\n field,\n format: (value) => (typeof value === 'string' ? value : ''),\n parse: (text) => {\n const trimmed = text.trim()\n return trimmed === '' ? { kind: 'clear' } : { kind: 'set', value: trimmed }\n },\n }\n}\n\n/**\n * A numeric field; an empty draft clears it, anything non-numeric blocks\n * save, and an optional inclusive `bounds` range rejects out-of-range values\n * with a specific reason (the Host schema would reject them at save time with\n * only a generic failure — catching it here names the problem while typing).\n * Decimals pass: the Host schema is `z.number()` too, and a fractional\n * millisecond value is harmless even if pointless.\n */\nfunction numberField(field: string, bounds?: { min?: number; max?: number }): FieldSpec {\n return {\n field,\n format: (value) => (typeof value === 'number' ? String(value) : ''),\n parse: (text) => {\n const trimmed = text.trim()\n if (trimmed === '') return { kind: 'clear' }\n const parsed = Number(trimmed)\n if (!Number.isFinite(parsed)) return { kind: 'invalid', reason: 'format' }\n if (bounds?.min !== undefined && parsed < bounds.min) return { kind: 'invalid', reason: 'tooSmall' }\n if (bounds?.max !== undefined && parsed > bounds.max) return { kind: 'invalid', reason: 'tooLarge' }\n return { kind: 'set', value: parsed }\n },\n }\n}\n\n/**\n * A boolean field, staged as the strings `'true'`/`'false'` (an empty draft\n * clears it). The component renders a toggle and only ever stages these two\n * strings; anything else blocks save.\n */\nfunction booleanField(field: string): FieldSpec {\n return {\n field,\n format: (value) => (typeof value === 'boolean' ? String(value) : ''),\n parse: (text) => {\n const trimmed = text.trim()\n if (trimmed === '') return { kind: 'clear' }\n if (trimmed === 'true') return { kind: 'set', value: true }\n if (trimmed === 'false') return { kind: 'set', value: false }\n return { kind: 'invalid', reason: 'format' }\n },\n }\n}\n\n/**\n * Inclusive bounds for the millisecond timeout fields, mirroring the Host\n * Config schema (`z.number().min(1).max(MAX_TIMER_DELAY_MS)` in src/index.ts;\n * `MAX_TIMER_DELAY_MS` is dsh-timeout's 2^31-1 timer ceiling). The client\n * bundle cannot import the node-side package, so the bound is pinned here —\n * the host remains the final gate.\n */\nexport const MIN_TIMEOUT_MS = 1\nexport const MAX_TIMEOUT_MS = 2147483647\n\n/** The fields this page edits inside the `llm-commandcode` namespace. */\nconst SECTION_FIELDS: FieldSpec[] = [\n textField('apiBase'),\n textField('workingDir'),\n numberField('requestTimeoutMs', { min: MIN_TIMEOUT_MS, max: MAX_TIMEOUT_MS }),\n numberField('streamIdleTimeoutMs', { min: MIN_TIMEOUT_MS, max: MAX_TIMEOUT_MS }),\n booleanField('filterModelsByPlan'),\n textField('activeAccount'),\n]\n\n/**\n * Controller bridging the `llm-commandcode` scope and the credentials domain\n * onto the page. Public API mirrors the harness's CardForm actions, so the\n * component stays thin.\n */\nexport class CommandCodeSettingsController {\n private readonly scope: SettingsScope<Record<string, unknown>>\n private readonly api: SettingsPageApi\n private readonly specs = new Map(SECTION_FIELDS.map((spec) => [spec.field, spec]))\n private readonly staged = new Map<string, Staged>()\n private readonly listeners = new Set<() => void>()\n private readonly disposers: Array<() => void> = []\n private disposed = false\n private defaultWorkingDir: string | undefined\n /** The credential reference the default account resolves. */\n private credentialRef = DEFAULT_API_KEY_REF\n /** Host-reported configured/writable state per credential reference. */\n private readonly credentialStates = new Map<string, { configured: boolean; writable: boolean }>()\n /** Staged account additions (not yet saved). */\n private addedAccounts: Array<{ label: string; ref: string }> = []\n /** Staged removals of stored extra accounts, by credential reference. */\n private readonly removedRefs = new Set<string>()\n /** Staged label drafts, by credential reference. */\n private readonly labelDrafts = new Map<string, string>()\n /** Staged key drafts, by credential reference (blank = keep stored key). */\n private readonly keyDrafts = new Map<string, string>()\n private saving = false\n private failed = false\n private savedCount = 0\n\n /**\n * @param scope - bound scope for the `llm-commandcode` namespace.\n * @param api - credentials wire face.\n * @param hostDescription - the Host-description observable whose `cwd` is\n * shown as the placeholder a blank `workingDir` field resolves to.\n */\n constructor(\n scope: SettingsScope<Record<string, unknown>>,\n api: SettingsPageApi,\n hostDescription?: HostDescriptionSource,\n ) {\n this.scope = scope\n this.api = api\n this.disposers.push(scope.subscribe(() => {\n this.recomputeCredentialRef()\n void this.describeAll()\n this.publish()\n }))\n if (hostDescription !== undefined) {\n this.defaultWorkingDir = hostDescription.getSnapshot()?.cwd\n this.disposers.push(hostDescription.subscribe(() => {\n if (this.disposed) return\n const cwd = hostDescription.getSnapshot()?.cwd\n if (cwd !== this.defaultWorkingDir) {\n this.defaultWorkingDir = cwd\n this.publish()\n }\n }))\n }\n this.recomputeCredentialRef()\n void this.describeAll()\n }\n\n /** Release every subscription held on external sources. Idempotent. */\n dispose(): void {\n if (this.disposed) return\n this.disposed = true\n for (const dispose of this.disposers) dispose()\n this.disposers.length = 0\n this.listeners.clear()\n }\n\n /**\n * The credential reference the section names, or the provider default. A\n * user who renamed `apiKeyEnv` in `settings.yaml` (or the composition\n * config) gets a page that addresses the renamed ref instead of silently\n * writing the default — mirroring the Models page's `refFor()`.\n */\n private recomputeCredentialRef(): void {\n const snapshot = this.scope.getSnapshot()\n const named = typeof snapshot.value?.apiKeyEnv === 'string' && snapshot.value.apiKeyEnv.length > 0\n ? snapshot.value.apiKeyEnv\n : DEFAULT_API_KEY_REF\n if (named === this.credentialRef) return\n this.credentialRef = named\n this.credentialStates.delete(named)\n }\n\n /** Subscribe to state projections. @returns the disposer. */\n subscribe(listener: () => void): () => void {\n this.listeners.add(listener)\n return () => this.listeners.delete(listener)\n }\n\n /** Build the current page state face. */\n state(): SettingsPageState {\n const snapshot = this.scope.getSnapshot()\n const plan = this.plan()\n const credential = this.credentialStates.get(this.credentialRef)\n const accounts = this.effectiveAccounts()\n return {\n available: snapshot.status === 'ready',\n writable: snapshot.writable,\n apiKeyConfigured: credential?.configured ?? false,\n anyAccountConfigured: (credential?.configured ?? false) || accounts.some((account) => account.configured),\n apiKeyWritable: credential?.writable ?? true,\n apiKey: {\n text: this.staged.get('apiKey')?.text ?? '',\n clear: false,\n overridden: false,\n invalid: false,\n invalidReason: undefined,\n },\n apiBase: this.field('apiBase'),\n workingDir: this.field('workingDir'),\n defaultWorkingDir: this.defaultWorkingDir,\n requestTimeoutMs: this.field('requestTimeoutMs'),\n streamIdleTimeoutMs: this.field('streamIdleTimeoutMs'),\n filterModelsByPlan: this.field('filterModelsByPlan'),\n activeAccount: this.field('activeAccount'),\n accounts,\n accountsRemoving: [...this.removedRefs],\n dirty: plan.length > 0 || this.accountsDirty(),\n invalid: plan.some((item) => item.run === undefined),\n saving: this.saving,\n failed: this.failed,\n savedCount: this.savedCount,\n }\n }\n\n /** Stage a new extra account (saved on the next `save()`). */\n addAccount(): void {\n const used = new Set([\n this.credentialRef,\n ...this.storedExtras().map((extra) => extra.ref),\n ...this.addedAccounts.map((extra) => extra.ref),\n ])\n let n = 2\n while (used.has(`COMMANDCODE_API_KEY_${n}`)) n += 1\n const index = this.storedExtras().length + this.addedAccounts.length + 2\n this.addedAccounts.push({ label: `Account ${index}`, ref: `COMMANDCODE_API_KEY_${n}` })\n this.failed = false\n void this.describeAll()\n this.publish()\n }\n\n /** Stage one extra account's removal (or drop an unsaved addition). */\n removeAccount(id: string): void {\n const addedIndex = this.addedAccounts.findIndex((extra) => extra.ref === id)\n if (addedIndex >= 0) this.addedAccounts.splice(addedIndex, 1)\n else this.removedRefs.add(id)\n this.labelDrafts.delete(id)\n this.keyDrafts.delete(id)\n // A pinned active account that is going away must not linger as a ghost\n // selection: stage its clear alongside the removal (the host would fall\n // back to rotation order, but the stored value would be meaningless).\n const stagedActive = this.staged.get('activeAccount')\n const activeValue = stagedActive !== undefined\n ? stagedActive.clear ? '' : stagedActive.text\n : typeof this.sectionValue('activeAccount') === 'string' ? this.sectionValue('activeAccount') as string : ''\n if (activeValue === id) {\n this.staged.set('activeAccount', { text: '', clear: true })\n }\n this.failed = false\n this.publish()\n }\n\n /** Stage one extra account's label draft. */\n editAccountLabel(id: string, text: string): void {\n this.labelDrafts.set(id, text)\n this.failed = false\n this.publish()\n }\n\n /** Stage one extra account's key draft (blank keeps the stored key). */\n editAccountKey(id: string, text: string): void {\n this.keyDrafts.set(id, text)\n this.failed = false\n this.publish()\n }\n\n /** Stage one field's draft text. */\n edit(field: string, text: string): void {\n this.staged.set(field, { text, clear: false })\n this.failed = false\n this.publish()\n }\n\n /** Reset one section field to its inherited (composition) value. */\n resetField(field: string): void {\n if (field === 'apiKey') {\n this.staged.delete('apiKey')\n this.failed = false\n this.publish()\n return\n }\n const spec = this.spec(field)\n this.staged.set(field, { text: spec.format(this.baseValue(field)), clear: true })\n this.failed = false\n this.publish()\n }\n\n /** Discard every staged edit. */\n discard(): void {\n if (this.staged.size === 0 && !this.accountsStaged() && !this.failed) return\n this.staged.clear()\n this.clearAccountStaging()\n this.failed = false\n this.publish()\n }\n\n /** Write every staged edit, then re-read the Host's accepted state. */\n async save(): Promise<void> {\n const plan = this.plan()\n const accountRuns = this.accountPlan()\n if ((plan.length === 0 && accountRuns.length === 0) || this.saving) return\n const runs: Array<() => Promise<boolean>> = []\n for (const item of plan) {\n if (item.run === undefined) return\n runs.push(item.run)\n }\n this.saving = true\n this.failed = false\n this.publish()\n let landed = true\n // Keys land first so a saved accounts list never names a ref whose key\n // write failed silently; the accounts list itself writes last. Stop at\n // the first failure: running later writes after a failed one would\n // persist a partial state the staged drafts no longer describe.\n for (const run of [...runs, ...accountRuns]) {\n if (!(await run())) {\n landed = false\n break\n }\n }\n this.saving = false\n this.failed = !landed\n if (landed) {\n this.savedCount += 1\n this.staged.clear()\n this.clearAccountStaging()\n } else {\n // A failed save may still have landed earlier writes (e.g. the accounts\n // list made it while a key write did not). Reconcile the staging with\n // the stored section so a landed account is not simultaneously stored\n // AND staged-for-addition (which a retry would persist twice).\n this.reconcileAccountStaging()\n }\n this.publish()\n }\n\n /**\n * Drop account staging the stored section already reflects: additions whose\n * ref is now stored, removals whose ref is gone, and label drafts matching\n * the stored label. Key drafts are kept — a landed key write is idempotent\n * on retry, and the draft carries the user's intent when it was the\n * accounts write that failed.\n */\n private reconcileAccountStaging(): void {\n const stored = new Set(this.storedExtras().map((extra) => extra.ref))\n this.addedAccounts = this.addedAccounts.filter((extra) => !stored.has(extra.ref))\n for (const ref of [...this.removedRefs]) {\n if (!stored.has(ref)) this.removedRefs.delete(ref)\n }\n for (const [ref, text] of [...this.labelDrafts]) {\n const storedLabel = this.storedExtras().find((extra) => extra.ref === ref)?.label\n if (storedLabel === undefined || storedLabel === text.trim()) this.labelDrafts.delete(ref)\n }\n }\n\n // -------------------------------------------------------------------------\n // Internals\n // -------------------------------------------------------------------------\n\n private spec(field: string): FieldSpec {\n const spec = this.specs.get(field)\n if (spec === undefined) throw new Error(`commandcode settings page has no field ${field}`)\n return spec\n }\n\n /** One field's rendered state: draft text, whether it is user-overridden, invalid. */\n private field(field: string): StagedField {\n const spec = this.spec(field)\n const staged = this.staged.get(field)\n if (staged === undefined) {\n return {\n text: spec.format(this.sectionValue(field)),\n clear: false,\n overridden: this.stored(field),\n invalid: false,\n invalidReason: undefined,\n }\n }\n const parsed = staged.clear ? { kind: 'clear' as const } : spec.parse(staged.text)\n return {\n text: staged.text,\n clear: staged.clear,\n overridden: parsed.kind === 'set',\n invalid: parsed.kind === 'invalid',\n invalidReason: parsed.kind === 'invalid' ? parsed.reason : undefined,\n }\n }\n\n private sectionValue(field: string): unknown {\n return this.scope.getSnapshot().value?.[field]\n }\n\n private baseValue(field: string): unknown {\n const base = this.scope.getSnapshot().base\n return typeof base === 'object' && base !== null && !Array.isArray(base)\n ? (base as Record<string, unknown>)[field]\n : undefined\n }\n\n private userLayer(): Record<string, unknown> | undefined {\n const user = this.scope.getSnapshot().user\n return typeof user === 'object' && user !== null && !Array.isArray(user)\n ? (user as Record<string, unknown>)\n : undefined\n }\n\n private stored(field: string): boolean {\n const user = this.userLayer()\n return user !== undefined && Object.prototype.hasOwnProperty.call(user, field)\n }\n\n /**\n * The writes a save would perform, in staged order. A field whose draft is\n * not a value its spec accepts carries no write (the save refuses).\n */\n private plan(): Array<{ field: string; run: (() => Promise<boolean>) | undefined }> {\n const plan: Array<{ field: string; run: (() => Promise<boolean>) | undefined }> = []\n for (const [field, staged] of this.staged) {\n if (field === 'apiKey') {\n const value = staged.text.trim()\n if (value !== '') {\n plan.push({ field, run: () => this.writeKey(value) })\n }\n continue\n }\n const spec = this.spec(field)\n if (staged.clear) {\n if (this.stored(field)) plan.push({ field, run: () => this.clear(field) })\n continue\n }\n if (staged.text === spec.format(this.sectionValue(field))) continue\n const parsed = spec.parse(staged.text)\n if (parsed.kind === 'invalid') plan.push({ field, run: undefined })\n else if (parsed.kind === 'clear') plan.push({ field, run: () => this.clear(field) })\n else plan.push({ field, run: () => this.store(field, parsed.value) })\n }\n return plan\n }\n\n private async clear(field: string): Promise<boolean> {\n await this.scope.unset(field)\n return !this.stored(field)\n }\n\n private async store(field: string, value: string | number | boolean): Promise<boolean> {\n await this.scope.set(field, value)\n return this.userLayer()?.[field] === value\n }\n\n /** Write the staged default key, then re-read whether the Host holds it. */\n private async writeKey(value: string): Promise<boolean> {\n return this.writeKeyTo(this.credentialRef, value)\n }\n\n /** Write one account's key, then re-read the Host's credential states. */\n private async writeKeyTo(ref: string, value: string): Promise<boolean> {\n try {\n const response = await this.api.credentials.set({ ref, value })\n if (!response.result.ok) return false\n } catch {\n return false\n }\n await this.describeAll()\n return this.credentialStates.get(ref)?.configured ?? false\n }\n\n /** Ask the credentials domain about every reference this page writes. */\n private async describeAll(): Promise<void> {\n const refs = [\n this.credentialRef,\n ...this.storedExtras().map((extra) => extra.ref),\n ...this.addedAccounts.map((extra) => extra.ref),\n ]\n let response: Awaited<ReturnType<SettingsPageApi['credentials']['describe']>>\n try {\n response = await this.api.credentials.describe({ refs })\n } catch {\n return\n }\n if (!response.result.ok) return\n let changed = false\n for (const ref of refs) {\n const view = response.result.value.credentials[ref]\n const next = {\n configured: view?.configured ?? false,\n writable: view?.writable ?? true,\n }\n const prev = this.credentialStates.get(ref)\n if (prev === undefined || prev.configured !== next.configured || prev.writable !== next.writable) {\n this.credentialStates.set(ref, next)\n changed = true\n }\n }\n if (changed) this.publish()\n }\n\n // -----------------------------------------------------------------------\n // Multi-account staging\n // -----------------------------------------------------------------------\n\n /** The stored extra accounts from the settings section (`accounts`). */\n private storedExtras(): Array<{ label: string; ref: string }> {\n const raw = this.scope.getSnapshot().value?.accounts\n if (!Array.isArray(raw)) return []\n const out: Array<{ label: string; ref: string }> = []\n for (const entry of raw) {\n if (typeof entry !== 'object' || entry === null || Array.isArray(entry)) continue\n const record = entry as Record<string, unknown>\n const ref = record.apiKeyEnv\n if (typeof ref !== 'string' || ref === '') continue\n const label = record.label\n out.push({ label: typeof label === 'string' && label !== '' ? label : ref, ref })\n }\n return out\n }\n\n /** Every extra account row: stored (minus staged removals) + staged adds. */\n private effectiveAccounts(): AccountItemState[] {\n const stored = this.storedExtras()\n .filter((extra) => !this.removedRefs.has(extra.ref))\n .map((extra) => ({ ...extra, added: false }))\n const added = this.addedAccounts.map((extra) => ({ ...extra, added: true }))\n return [...stored, ...added].map((extra) => ({\n id: extra.ref,\n ref: extra.ref,\n label: this.labelDrafts.get(extra.ref) ?? extra.label,\n keyText: this.keyDrafts.get(extra.ref) ?? '',\n configured: this.credentialStates.get(extra.ref)?.configured ?? false,\n writable: this.credentialStates.get(extra.ref)?.writable ?? true,\n added: extra.added,\n }))\n }\n\n /** Whether any account-level staging (add/remove/label/key) exists. */\n private accountsStaged(): boolean {\n return this.addedAccounts.length > 0\n || this.removedRefs.size > 0\n || this.labelDrafts.size > 0\n || this.keyDrafts.size > 0\n }\n\n /** Whether the staged account edits differ from the stored section. */\n private accountsDirty(): boolean {\n if (this.addedAccounts.length > 0 || this.removedRefs.size > 0) return true\n for (const [ref, text] of this.labelDrafts) {\n const base = this.storedExtras().find((extra) => extra.ref === ref)?.label\n if (base !== undefined && text.trim() !== '' && text !== base) return true\n }\n for (const text of this.keyDrafts.values()) {\n if (text.trim() !== '') return true\n }\n return false\n }\n\n /** Reset every account-level staged edit. */\n private clearAccountStaging(): void {\n this.addedAccounts = []\n this.removedRefs.clear()\n this.labelDrafts.clear()\n this.keyDrafts.clear()\n }\n\n /** The account-level writes a save performs (empty when nothing staged). */\n private accountPlan(): Array<() => Promise<boolean>> {\n if (!this.accountsDirty()) return []\n const runs: Array<() => Promise<boolean>> = []\n for (const [ref, text] of this.keyDrafts) {\n const value = text.trim()\n if (value !== '' && !this.removedRefs.has(ref)) {\n runs.push(() => this.writeKeyTo(ref, value))\n }\n }\n runs.push(() => this.writeAccounts())\n return runs\n }\n\n /** Persist the staged accounts list into the settings section. */\n private async writeAccounts(): Promise<boolean> {\n const base = [\n ...this.storedExtras().filter((extra) => !this.removedRefs.has(extra.ref)),\n ...this.addedAccounts,\n ]\n // Defensive dedupe by ref: a partially landed earlier save can leave an\n // account both stored and staged-for-addition; never persist duplicates.\n const seen = new Set<string>()\n const list = base.filter((extra) => !seen.has(extra.ref) && (seen.add(extra.ref), true)).map((extra) => {\n const draft = this.labelDrafts.get(extra.ref)?.trim()\n return { label: draft !== undefined && draft !== '' ? draft : extra.label, apiKeyEnv: extra.ref }\n })\n await this.scope.set('accounts', list)\n const after = this.storedExtras()\n return after.length === list.length\n && list.every((item, index) => after[index]?.ref === item.apiKeyEnv)\n }\n\n private publish(): void {\n if (this.disposed) return\n for (const listener of this.listeners) listener()\n }\n}\n","/**\n * Browser controller for the settings page's account-usage card.\n *\n * The card renders the same account/usage/credit facts the `/commandcode`\n * command prints, fetched Host-side through the `commandcode/report` Remote\n * (the browser never holds the API key). This controller owns the fetch\n * lifecycle — idle/loading/ready/error, one in-flight request at a time,\n * stale-response dropping — and the display formatting, so the React\n * component stays a thin renderer and node tests can drive everything.\n *\n * Deliberately JSX-free, mirroring `./settings.ts`.\n *\n * @module dsh-commandcode-provider/client/usage\n */\n\nimport type { CommandCodeAccountsReport } from '../usage-wire.ts'\nimport type { RemoteResult } from '@deepseek-ai/dsh-typert-protocol'\n\n/**\n * Merge the plugin's Remote endpoint into the harness's typed client Remote\n * surface (the same declaration pattern the harness's generated\n * typert.remote-client files use), so `ctx.remote.commandcode.report()` is\n * typed once the contribution is mounted.\n */\ndeclare module '@deepseek-ai/dsh-typert-protocol' {\n interface TypertRemoteMap {\n 'commandcode/report': () => Promise<RemoteResult<CommandCodeAccountsReport>>\n }\n interface TypertRemoteNamespaceMap {\n commandcode: {\n report: () => Promise<RemoteResult<CommandCodeAccountsReport>>\n }\n }\n}\n\n/** The narrow slice of the mounted Remote this controller calls. */\nexport interface UsageRemote {\n report(): Promise<\n | { ok: true; value: CommandCodeAccountsReport }\n | { ok: false; error: { message: string } }\n >\n}\n\n/** The card's fetch lifecycle. */\nexport type UsageStatus =\n /** Never fetched (no API key configured yet, or not requested). */\n | 'idle'\n /** A fetch is in flight; `report` retains the last good data if any. */\n | 'loading'\n /** The last fetch succeeded. */\n | 'ready'\n /** The last fetch failed (no key, unreachable host, old plugin). */\n | 'error'\n\n/** The card's full state face. */\nexport interface UsagePageState {\n status: UsageStatus\n /** The last successfully fetched report (retained across refetches). */\n report: CommandCodeAccountsReport | undefined\n /** The last failure's message (error status). */\n error: string | undefined\n /** Millis timestamp of the last successful fetch. */\n fetchedAt: number | undefined\n}\n\nconst IDLE: UsagePageState = { status: 'idle', report: undefined, error: undefined, fetchedAt: undefined }\n\n/**\n * Controller bridging the `commandcode/report` Remote onto the card. Public\n * API mirrors {@link CommandCodeSettingsController}: `state()` projections,\n * `subscribe`, and one `refresh()` action.\n */\nexport class CommandCodeUsageController {\n private readonly remote: UsageRemote\n private readonly listeners = new Set<() => void>()\n private current: UsagePageState = IDLE\n private generation = 0\n private inFlight = false\n private disposed = false\n\n constructor(remote: UsageRemote) {\n this.remote = remote\n }\n\n /** Release every subscription. Idempotent; in-flight results are dropped. */\n dispose(): void {\n this.disposed = true\n this.generation += 1\n this.listeners.clear()\n }\n\n /** Subscribe to state projections. @returns the disposer. */\n subscribe(listener: () => void): () => void {\n this.listeners.add(listener)\n return () => this.listeners.delete(listener)\n }\n\n /** The current card state face. */\n state(): UsagePageState {\n return this.current\n }\n\n /**\n * Fetch (or refetch) the report. Concurrent refreshes collapse onto one\n * request; a superseded fetch's late result is dropped, never published.\n */\n async refresh(): Promise<void> {\n if (this.disposed || this.inFlight) return\n const generation = ++this.generation\n this.inFlight = true\n this.current = { ...this.current, status: 'loading', error: undefined }\n this.publish()\n try {\n const response = await this.remote.report()\n if (this.disposed || generation !== this.generation) return\n if (response.ok) {\n this.current = { status: 'ready', report: response.value, error: undefined, fetchedAt: Date.now() }\n } else {\n this.current = { ...this.current, status: 'error', error: response.error.message }\n }\n } catch (error: unknown) {\n if (this.disposed || generation !== this.generation) return\n this.current = {\n ...this.current,\n status: 'error',\n error: error instanceof Error ? error.message : String(error),\n }\n } finally {\n if (generation === this.generation) this.inFlight = false\n }\n this.publish()\n }\n\n private publish(): void {\n if (this.disposed) return\n for (const listener of this.listeners) listener()\n }\n}\n\n// ---------------------------------------------------------------------------\n// Display formatting (shared by the component, covered by node tests)\n// ---------------------------------------------------------------------------\n\n/** Format a dollar amount compactly (2 decimals). */\nexport function formatMoney(value: number): string {\n return `$${value.toFixed(2)}`\n}\n\n/** Format a dollar amount precisely (4 decimals) for small totals. */\nexport function formatMoneyExact(value: number): string {\n return `$${value.toFixed(4)}`\n}\n\n/** Format a large token count compactly (1.9M style). */\nexport function formatTokensCompact(value: number): string {\n if (value >= 1e9) return `${(value / 1e9).toFixed(1)}B`\n if (value >= 1e6) return `${(value / 1e6).toFixed(1)}M`\n if (value >= 1e3) return `${(value / 1e3).toFixed(1)}K`\n return String(value)\n}\n\n/** One window's fill ratio in [0, 1]; 0 when uncapped. */\nexport function windowRatio(used: number, cap: number): number {\n if (cap <= 0) return 0\n return Math.max(0, Math.min(1, used / cap))\n}\n\n/** Format a millis timestamp as a local short date-time; empty when unset. */\nexport function formatResetAt(ms: number): string {\n if (ms <= 0) return ''\n return new Date(ms).toLocaleString()\n}\n","/**\n * Wire contract for the Command Code account-usage Remote\n * (`commandcode/report`).\n *\n * The settings page renders the same account/usage/credit facts the\n * `/commandcode` command prints, but the browser never holds the API key —\n * the report must be produced Host-side and cross the Connection RPC carrier.\n * The harness exposes plugin-defined Host methods through the Typert Gateway:\n * the Host half registers a strict invocation descriptor against a Cordis\n * service (`src/usage-remote.ts`), and the browser half mounts the matching\n * Remote contribution on `ctx.remote` (`src/client/index.ts`).\n *\n * This module is the single source both halves share: the result validator\n * (a hand-rolled {@link TypertSchema}, so neither half needs a schema library)\n * and the exact descriptor object, so the endpoint can never drift apart.\n * It is deliberately dependency-free — the client bundle inlines it, and only\n * `import type` edges leave it (erased at build).\n *\n * @module dsh-commandcode-provider/usage-wire\n */\n\nimport type { CommandCodeUsageReport } from './adapter.ts'\nimport type { InvocationDescriptor, TypertRemoteContribution, TypertSchema } from '@deepseek-ai/dsh-typert-protocol'\n\n/** One account's usage entry in the multi-account report. */\nexport interface CommandCodeAccountUsage {\n /** Stable slot id (`default`, `account-2`, …). */\n id: string\n /** Display label (user-provided or generated). */\n label: string\n /** Whether an API key resolved for this account. */\n configured: boolean\n /** Whether this account currently serves requests (first usable slot). */\n active: boolean\n /** Rotation mark: `''` (usable), `'rate-limit'`, or `'invalid-credential'`. */\n mark: string\n /** Known cooldown end in millis; 0 when unknown or not cooling down. */\n cooldownUntil: number\n /** The per-account report; `failures`-only when the fetch itself failed. */\n report: CommandCodeUsageReport\n}\n\n/** The settings page's account card data: one entry per configured account. */\nexport interface CommandCodeAccountsReport {\n accounts: CommandCodeAccountUsage[]\n}\n\n/** The npm package identity both contribution registrations claim. */\nexport const USAGE_REMOTE_PACKAGE = '@mars-sea/dsh-commandcode-provider'\n\n/** Canonical `<namespace>/<method>` endpoint of the usage report Remote. */\nexport const USAGE_REPORT_ENDPOINT = 'commandcode/report'\n\n/** Reject one boundary value with a field-naming error. */\nfunction reject(field: string): never {\n throw new TypeError(`commandcode/report result: invalid ${field}`)\n}\n\n/** Read one required finite number field (`field` is the dotted error label). */\nfunction numberField(source: Record<string, unknown>, key: string, field: string): number {\n const value = source[key]\n if (typeof value !== 'number' || !Number.isFinite(value)) reject(field)\n return value\n}\n\n/** Read one required string field (`field` is the dotted error label). */\nfunction stringField(source: Record<string, unknown>, key: string, field: string): string {\n const value = source[key]\n if (typeof value !== 'string') reject(field)\n return value\n}\n\n/** Read one required boolean field (`field` is the dotted error label). */\nfunction booleanField(source: Record<string, unknown>, key: string, field: string): boolean {\n const value = source[key]\n if (typeof value !== 'boolean') reject(field)\n return value\n}\n\n/** Narrow an unknown value to a plain record, or reject. */\nfunction record(value: unknown, field: string): Record<string, unknown> {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) reject(field)\n return value as Record<string, unknown>\n}\n\n/** Validate one window-limit block (`fiveHour` / `weekly`). */\nfunction windowLimit(value: unknown, field: string): { used: number; cap: number; exceeded: boolean; resetAt: number } {\n const source = record(value, field)\n return {\n used: numberField(source, 'used', `${field}.used`),\n cap: numberField(source, 'cap', `${field}.cap`),\n exceeded: booleanField(source, 'exceeded', `${field}.exceeded`),\n resetAt: numberField(source, 'resetAt', `${field}.resetAt`),\n }\n}\n\n/**\n * Parse one untrusted boundary value into a {@link CommandCodeUsageReport}.\n * Optional sections stay optional; every present field is shape-checked so a\n * malformed frame fails the boundary instead of rendering garbage.\n */\nfunction parseUsageReport(value: unknown): CommandCodeUsageReport {\n const source = record(value, 'report')\n const failures = source.failures\n if (!Array.isArray(failures) || failures.some((entry) => typeof entry !== 'string')) reject('failures')\n const report: CommandCodeUsageReport = { failures: failures as string[] }\n\n if (source.account !== undefined) {\n const account = record(source.account, 'account')\n report.account = {\n id: stringField(account, 'id', 'account.id'),\n name: stringField(account, 'name', 'account.name'),\n userName: stringField(account, 'userName', 'account.userName'),\n }\n }\n\n if (source.usage !== undefined) {\n const usage = record(source.usage, 'usage')\n report.usage = {\n totalCount: numberField(usage, 'totalCount', 'usage.totalCount'),\n totalCost: numberField(usage, 'totalCost', 'usage.totalCost'),\n successRate: numberField(usage, 'successRate', 'usage.successRate'),\n completedCount: numberField(usage, 'completedCount', 'usage.completedCount'),\n failedCount: numberField(usage, 'failedCount', 'usage.failedCount'),\n totalTokensIn: numberField(usage, 'totalTokensIn', 'usage.totalTokensIn'),\n totalTokensOut: numberField(usage, 'totalTokensOut', 'usage.totalTokensOut'),\n totalCredits: numberField(usage, 'totalCredits', 'usage.totalCredits'),\n periodBasis: stringField(usage, 'periodBasis', 'usage.periodBasis'),\n }\n }\n\n if (source.credits !== undefined) {\n const credits = record(source.credits, 'credits')\n report.credits = {\n monthlyCredits: numberField(credits, 'monthlyCredits', 'credits.monthlyCredits'),\n purchasedCredits: numberField(credits, 'purchasedCredits', 'credits.purchasedCredits'),\n freeCredits: numberField(credits, 'freeCredits', 'credits.freeCredits'),\n fiveHour: windowLimit(credits.fiveHour, 'credits.fiveHour'),\n weekly: windowLimit(credits.weekly, 'credits.weekly'),\n }\n }\n\n if (source.plan !== undefined) {\n const plan = record(source.plan, 'plan')\n const monthly = plan.monthlyCredits\n if (monthly !== null && (typeof monthly !== 'number' || !Number.isFinite(monthly))) reject('plan.monthlyCredits')\n report.plan = {\n planId: stringField(plan, 'planId', 'plan.planId'),\n name: stringField(plan, 'name', 'plan.name'),\n status: stringField(plan, 'status', 'plan.status'),\n monthlyCredits: monthly as number | null,\n currentPeriodEnd: numberField(plan, 'currentPeriodEnd', 'plan.currentPeriodEnd'),\n }\n }\n\n return report\n}\n\n/** Parse one untrusted boundary value into a {@link CommandCodeAccountUsage}. */\nfunction parseAccountUsage(value: unknown): CommandCodeAccountUsage {\n const source = record(value, 'account')\n return {\n id: stringField(source, 'id', 'account.id'),\n label: stringField(source, 'label', 'account.label'),\n configured: booleanField(source, 'configured', 'account.configured'),\n active: booleanField(source, 'active', 'account.active'),\n mark: stringField(source, 'mark', 'account.mark'),\n cooldownUntil: numberField(source, 'cooldownUntil', 'account.cooldownUntil'),\n report: parseUsageReport(source.report),\n }\n}\n\n/** Parse the wire result into a {@link CommandCodeAccountsReport}. */\nfunction parseAccountsReport(value: unknown): CommandCodeAccountsReport {\n const source = record(value, 'result')\n const accounts = source.accounts\n if (!Array.isArray(accounts)) reject('accounts')\n return { accounts: accounts.map(parseAccountUsage) }\n}\n\n/**\n * The strict result codec both halves attach to the descriptor. Hand-rolled:\n * the client bundle may not require a schema library, and `TypertSchema` is\n * deliberately minimal so one `parse` function satisfies it.\n */\nexport const usageReportSchema: TypertSchema<CommandCodeAccountsReport> = {\n parse: parseAccountsReport,\n}\n\n/**\n * The one invocation descriptor, shared verbatim by the Host registration and\n * the Client mount. `service` names the Cordis key the Gateway resolves the\n * receiver from; `namespace`/`method` name the wire endpoint.\n */\nexport const USAGE_REPORT_DESCRIPTOR: InvocationDescriptor = {\n id: `${USAGE_REMOTE_PACKAGE}#${USAGE_REPORT_ENDPOINT}`,\n service: 'commandcodeUsage',\n namespace: 'commandcode',\n method: 'report',\n invocation: { kind: 'direct' },\n parameters: [],\n result: {\n mode: 'strict',\n typeSymbol: `${USAGE_REMOTE_PACKAGE}#CommandCodeAccountsReport`,\n schema: usageReportSchema,\n },\n}\n\n/** The Host-face contribution registered on `ctx.typert`. */\nexport const USAGE_HOST_CONTRIBUTION = {\n package: USAGE_REMOTE_PACKAGE,\n face: 'host' as const,\n schemas: [],\n invocations: [USAGE_REPORT_DESCRIPTOR],\n}\n\n/** The Client-face contribution mounted on `ctx.remote`. */\nexport const USAGE_REMOTE_CONTRIBUTION: TypertRemoteContribution = {\n package: USAGE_REMOTE_PACKAGE,\n descriptors: [USAGE_REPORT_DESCRIPTOR],\n}\n","","/**\n * The plugin's own version, read from package.json at build time.\n *\n * The client bundle inlines the JSON import (rolldown resolves it during the\n * tsdown build; node tests read it through tsx), so the rendered value always\n * matches the published package version with no second constant to keep in\n * sync. Rendered as a muted footer line on the settings page so a user can\n * report the exact build they run.\n *\n * @module dsh-commandcode-provider/client/version\n */\n\nimport pkg from '../../package.json'\n\n/** The published package version (e.g. `'0.6.0'`). */\nexport const PLUGIN_VERSION: string = pkg.version\n","/**\n * React component for the \"Command Code\" settings page (browser half).\n *\n * Renders as a `settings.section` entry — a page at the same settings-nav\n * level as General / Models / Plugins. The shell supplies the nav row and\n * renders this body inside the content column. All copy comes from the\n * `settings.commandcode` locale namespace; all state comes from the\n * `CommandCodeSettingsController` injected by the slot registration.\n *\n * The layout mirrors the harness's settings pages: a max-width content\n * column, labelled fields with hints, a reset affordance, and a\n * save/discard footer. Styles are injected once by the client entry\n * (see src/client/index.ts) and class-prefixed `cc-` to stay local.\n */\n\nimport { useEffect, useState } from 'react'\nimport { Button } from '@deepseek-ai/dsh-client-ui-primitives'\nimport type { Translate } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { CommandCodeCredits } from '../adapter.ts'\nimport type { CommandCodeAccountUsage } from '../usage-wire.ts'\nimport type { SettingsCommandCodeKey } from './locales.ts'\nimport type { AccountItemState, SettingsPageState, StagedField } from './settings.ts'\nimport type { UsagePageState } from './usage.ts'\nimport { formatMoney, formatMoneyExact, formatResetAt, formatTokensCompact, windowRatio } from './usage.ts'\nimport { PLUGIN_VERSION } from './version.ts'\n\n/** Props composed by the slot registration: locale seat + injected face. */\nexport interface CommandCodeSettingsProps {\n t: Translate<SettingsCommandCodeKey>\n useCommandCodeSettings<T>(selector: (state: SettingsPageState) => T): T\n useCommandCodeUsage<T>(selector: (state: UsagePageState) => T): T\n edit(field: string, text: string): void\n resetField(field: string): void\n save(): void\n discard(): void\n refreshUsage(): void\n addAccount(): void\n removeAccount(id: string): void\n editAccountLabel(id: string, text: string): void\n editAccountKey(id: string, text: string): void\n}\n\n/** One labelled field row in the page body. */\nfunction Field({\n id,\n label,\n hint,\n state,\n disabled,\n numeric,\n placeholder,\n onEdit,\n onReset,\n t,\n}: {\n id: string\n label: string\n hint: string\n state: StagedField\n disabled: boolean\n numeric?: boolean\n placeholder?: string | undefined\n onEdit(text: string): void\n onReset(): void\n t: Translate<SettingsCommandCodeKey>\n}) {\n return (\n <div className=\"cc-field\">\n <div className=\"cc-fieldHead\">\n <label className=\"cc-label\" htmlFor={id}>{label}</label>\n <span className=\"cc-badges\">\n {state.overridden ? <span className=\"cc-badge\">{t('overridden')}</span> : null}\n <button type=\"button\" className=\"cc-reset\" disabled={disabled} onClick={onReset}>{t('reset')}</button>\n </span>\n </div>\n <input\n id={id}\n className={state.invalid ? 'cc-input cc-inputInvalid' : 'cc-input'}\n type=\"text\"\n inputMode={numeric ? 'numeric' : undefined}\n value={state.text}\n placeholder={placeholder}\n disabled={disabled}\n onChange={(event) => onEdit(event.target.value)}\n />\n <p className={state.invalid ? 'cc-invalid' : 'cc-hint'}>\n {state.invalid ? invalidCopy(state.invalidReason, t) : hint}\n </p>\n </div>\n )\n}\n\n/** The per-field error copy for a staged draft's failure reason. */\nfunction invalidCopy(reason: StagedField['invalidReason'], t: Translate<SettingsCommandCodeKey>): string {\n if (reason === 'tooSmall') return t('numberTooSmall')\n if (reason === 'tooLarge') return t('numberTooLarge')\n return t('invalidNumber')\n}\n\n/**\n * One boolean field row rendered as a toggle. The staged text is `'true'` /\n * `'false'` / `''` (unset → `defaultChecked`); toggling stages the string the\n * boolean field spec parses back into a real boolean on save.\n */\nfunction ToggleField({\n id,\n label,\n hint,\n state,\n disabled,\n defaultChecked,\n onEdit,\n onReset,\n t,\n}: {\n id: string\n label: string\n hint: string\n state: StagedField\n disabled: boolean\n defaultChecked: boolean\n onEdit(text: string): void\n onReset(): void\n t: Translate<SettingsCommandCodeKey>\n}) {\n const checked = state.text === '' ? defaultChecked : state.text === 'true'\n return (\n <div className=\"cc-field\">\n <div className=\"cc-fieldHead\">\n <label className=\"cc-label\" htmlFor={id}>{label}</label>\n <span className=\"cc-badges\">\n {state.overridden ? <span className=\"cc-badge\">{t('overridden')}</span> : null}\n <button type=\"button\" className=\"cc-reset\" disabled={disabled} onClick={onReset}>{t('reset')}</button>\n </span>\n </div>\n <label className=\"cc-toggleRow\">\n <input\n id={id}\n className=\"cc-toggle\"\n type=\"checkbox\"\n role=\"switch\"\n checked={checked}\n disabled={disabled}\n onChange={(event) => onEdit(event.target.checked ? 'true' : 'false')}\n />\n <span className=\"cc-hint\">{hint}</span>\n </label>\n </div>\n )\n}\n\n/**\n * The API-key control: write-only, reports configured state, never echoes the\n * key. The input is masked by default with a Show/Hide toggle so a pasted key\n * can be spot-checked without leaving the field.\n */\nfunction SecretKeyField({\n label,\n hint,\n state,\n disabled,\n configured,\n configuredLabel,\n unconfiguredLabel,\n showLabel,\n hideLabel,\n onEdit,\n}: {\n label: string\n hint: string\n state: StagedField\n disabled: boolean\n configured: boolean\n configuredLabel: string\n unconfiguredLabel: string\n showLabel: string\n hideLabel: string\n onEdit(text: string): void\n}) {\n const [visible, setVisible] = useState(false)\n return (\n <div className=\"cc-field\">\n <div className=\"cc-fieldHead\">\n <label className=\"cc-label\" htmlFor=\"cc-api-key\">{label}</label>\n <span className=\"cc-badges\">\n <span className={configured ? 'cc-badge' : 'cc-badgeMuted'}>\n {configured ? configuredLabel : unconfiguredLabel}\n </span>\n <button\n type=\"button\"\n className=\"cc-reset\"\n disabled={disabled}\n onClick={() => setVisible((value) => !value)}\n >\n {visible ? hideLabel : showLabel}\n </button>\n </span>\n </div>\n <input\n id=\"cc-api-key\"\n className=\"cc-input\"\n type={visible ? 'text' : 'password'}\n autoComplete=\"off\"\n spellCheck={false}\n value={state.text}\n disabled={disabled}\n onChange={(event) => onEdit(event.target.value)}\n />\n <p className=\"cc-hint\">{hint}</p>\n </div>\n )\n}\n\n/** One stat tile in the account card's summary grid. */\nfunction UsageStat({ label, value, sub }: { label: string; value: string; sub?: string | undefined }) {\n return (\n <div className=\"cc-usageStat\">\n <span className=\"cc-usageStatLabel\">{label}</span>\n <span className=\"cc-usageStatValue\">{value}</span>\n {sub !== undefined && sub !== '' ? <span className=\"cc-usageStatSub\">{sub}</span> : null}\n </div>\n )\n}\n\n/** One window-limit row: label, used/cap, a fill bar, and the reset time. */\nfunction UsageWindow({\n label,\n limit: { used, cap, exceeded, resetAt },\n t,\n}: {\n label: string\n limit: CommandCodeCredits['fiveHour']\n t: Translate<SettingsCommandCodeKey>\n}) {\n const ratio = windowRatio(used, cap)\n const reset = formatResetAt(resetAt)\n return (\n <div className=\"cc-usageWindow\">\n <div className=\"cc-usageWindowHead\">\n <span className=\"cc-usageWindowLabel\">{label}</span>\n {exceeded ? <span className=\"cc-usageExceeded\">{t('usageExceeded')}</span> : null}\n <span className=\"cc-usageWindowValue\">{cap > 0 ? `${formatMoney(used)} / ${formatMoney(cap)}` : formatMoney(used)}</span>\n </div>\n <div className=\"cc-usageBar\" role=\"progressbar\" aria-valuemin={0} aria-valuemax={100} aria-valuenow={Math.round(ratio * 100)}>\n <div className={exceeded ? 'cc-usageBarFill cc-usageBarFillWarn' : 'cc-usageBarFill'} style={{ width: `${ratio * 100}%` }} />\n </div>\n {reset !== '' ? <p className=\"cc-usageWindowReset\">{t('usageReset')} {reset}</p> : null}\n </div>\n )\n}\n\n/** One account's rotation state as a short badge next to its label. */\nfunction AccountMark({ entry, t }: { entry: CommandCodeAccountUsage; t: Translate<SettingsCommandCodeKey> }) {\n if (entry.active) return <span className=\"cc-usagePlan\">{t('usageActive')}</span>\n if (entry.mark === 'invalid-credential') return <span className=\"cc-usagePlanStatus\">{t('usageInvalidKey')}</span>\n if (entry.cooldownUntil > 0) {\n return <span className=\"cc-usagePlanStatus\">{t('usageCooldown')} {formatResetAt(entry.cooldownUntil)}</span>\n }\n if (entry.mark === 'rate-limit') return <span className=\"cc-usagePlanStatus\">{t('usageCooldown')}</span>\n return null\n}\n\n/**\n * One pool account's facts (identity, totals, credits, window limits)\n * rendered inside the account-usage card.\n */\nfunction AccountReport({ entry, t, onRemove }: {\n entry: CommandCodeAccountUsage\n t: Translate<SettingsCommandCodeKey>\n /** Present only for removable (non-default) accounts on a writable page. */\n onRemove?: (() => void) | undefined\n}) {\n const report = entry.report\n const account = report.account\n const accountName = account === undefined ? '' : account.userName || account.name\n const credits = report.credits\n const plan = report.plan\n const planName = plan?.name ?? ''\n const planStatus = plan !== undefined && plan.status !== '' && plan.status !== 'active' ? plan.status : ''\n\n return (\n <div className=\"cc-accountReport\">\n <div className=\"cc-usageHead\">\n <h4 className=\"cc-usageTitle\">{entry.label}</h4>\n <AccountMark entry={entry} t={t} />\n {accountName !== '' ? <span className=\"cc-usageAccount\">{accountName}</span> : null}\n {planName !== '' ? <span className=\"cc-usagePlan\">{planName}</span> : null}\n {planStatus !== '' ? <span className=\"cc-usagePlanStatus\">{planStatus}</span> : null}\n <span className=\"cc-usageMetaSpacer\" />\n {onRemove !== undefined ? (\n <button type=\"button\" className=\"cc-usageRefresh\" onClick={onRemove}>{t('accountRemove')}</button>\n ) : null}\n </div>\n\n {!entry.configured ? <p className=\"cc-usageHint\">{t('usageUnconfigured')}</p> : null}\n\n {report.usage !== undefined ? (\n <div className=\"cc-usageStats\">\n <UsageStat\n label={t('usageRequests')}\n value={String(report.usage.completedCount)}\n sub={`${t('usageFailed')} ${report.usage.failedCount}`}\n />\n <UsageStat label={t('usageSuccessRate')} value={`${report.usage.successRate}%`} />\n <UsageStat\n label={t('usageCost')}\n value={formatMoneyExact(report.usage.totalCost)}\n sub={`${formatMoney(report.usage.totalCredits)} credits`}\n />\n <UsageStat\n label={t('usageTokens')}\n value={formatTokensCompact(report.usage.totalTokensIn + report.usage.totalTokensOut)}\n sub={`${formatTokensCompact(report.usage.totalTokensIn)} ${t('usageTokensIn')} / ${formatTokensCompact(report.usage.totalTokensOut)} ${t('usageTokensOut')}`}\n />\n </div>\n ) : null}\n\n {credits !== undefined ? (\n <div className=\"cc-usageStats\">\n <UsageStat label={t('usageMonthly')} value={formatMoney(credits.monthlyCredits)} />\n <UsageStat label={t('usagePurchased')} value={formatMoney(credits.purchasedCredits)} />\n <UsageStat label={t('usageFree')} value={formatMoney(credits.freeCredits)} />\n </div>\n ) : null}\n\n {credits !== undefined ? (\n <div className=\"cc-usageWindows\">\n <UsageWindow label={t('usageFiveHour')} limit={credits.fiveHour} t={t} />\n <UsageWindow label={t('usageWeekly')} limit={credits.weekly} t={t} />\n </div>\n ) : null}\n\n {plan !== undefined && plan.currentPeriodEnd > 0 ? (\n <div className=\"cc-usageMeta\">\n <p className=\"cc-usageUpdated\">{t('usagePeriodEnd')} {new Date(plan.currentPeriodEnd).toLocaleDateString()}</p>\n <span className=\"cc-usageMetaSpacer\" />\n {report.failures.length > 0 ? <p className=\"cc-usagePartial\" title={report.failures.join('; ')}>{t('usagePartial')}</p> : null}\n </div>\n ) : report.failures.length > 0 ? (\n <div className=\"cc-usageMeta\">\n <span className=\"cc-usageMetaSpacer\" />\n <p className=\"cc-usagePartial\" title={report.failures.join('; ')}>{t('usagePartial')}</p>\n </div>\n ) : null}\n </div>\n )\n}\n\n/** The status dot on an account tab: cooling/invalid warn, everything else ok. */\nfunction AccountTabDot({ entry }: { entry: CommandCodeAccountUsage }) {\n const cls = entry.mark === 'invalid-credential'\n ? 'cc-tabDot cc-tabDotError'\n : entry.mark !== '' || entry.cooldownUntil > 0\n ? 'cc-tabDot cc-tabDotWarn'\n : 'cc-tabDot cc-tabDotOk'\n return <span className={cls} />\n}\n\n/**\n * The account-usage card: the `/commandcode` dashboard's facts rendered as\n * a native settings card. With several accounts the card is a carousel — a\n * tab strip (label + status dot) switches between accounts so the page stays\n * short; each account's report carries its own remove affordance (the\n * default account is not removable). Accounts staged for removal in the\n * management card are hidden here immediately. Data arrives through the\n * `commandcode/report` Remote; the API keys never leave the Host.\n */\nfunction UsageCard({ t, usage, apiKeyConfigured, removingIds, removableIds, canManage, onRefresh, onRemoveAccount }: {\n t: Translate<SettingsCommandCodeKey>\n usage: UsagePageState\n apiKeyConfigured: boolean\n /** Ids of accounts staged for removal (hidden from the carousel). */\n removingIds: string[]\n /**\n * Ids of accounts the settings document can actually remove (the stored\n * extra accounts' refs). Composition-only accounts (literal-key slots with\n * positional `account-N` ids) are NOT removable from the page — the\n * settings document cannot name them — so they get no remove button.\n */\n removableIds: string[]\n /** Whether the page accepts writes (the remove affordance follows it). */\n canManage: boolean\n onRefresh(): void\n onRemoveAccount(id: string): void\n}) {\n // First paint with a configured key fetches automatically; later fetches\n // are explicit (refresh button) or follow a landed save.\n useEffect(() => {\n if (apiKeyConfigured && usage.status === 'idle') onRefresh()\n }, [apiKeyConfigured, usage.status, onRefresh])\n\n const loading = usage.status === 'loading'\n const report = usage.report\n // Locally remembered removals: the usage controller keeps the old report\n // until the post-save refresh lands, and removedRefs clears at save-land —\n // without this the just-removed account would pop back in for one refresh\n // round-trip. Cleared when a fresh report arrives (fetchedAt changes).\n const [locallyRemoved, setLocallyRemoved] = useState<readonly string[]>([])\n useEffect(() => {\n setLocallyRemoved([])\n }, [usage.fetchedAt])\n const hidden = new Set([...removingIds, ...locallyRemoved])\n const seenIds = new Set<string>()\n const entries = (report?.accounts ?? []).filter((entry) => {\n if (hidden.has(entry.id)) return false\n // Hand-edited settings can name the same credential ref twice; dedupe so\n // the tab strip never carries duplicate keys/selections.\n if (seenIds.has(entry.id)) return false\n seenIds.add(entry.id)\n return true\n })\n const [selectedId, setSelectedId] = useState<string | undefined>(undefined)\n // The selected tab: the explicit choice while it still exists, else the\n // serving (active) account, else the first entry.\n const selected = entries.find((entry) => entry.id === selectedId)\n ?? entries.find((entry) => entry.active)\n ?? entries[0]\n const removeSelected = canManage && selected !== undefined && removableIds.includes(selected.id)\n ? () => {\n const id = selected.id\n setLocallyRemoved((prev) => [...prev, id])\n onRemoveAccount(id)\n }\n : undefined\n\n return (\n <div className=\"cc-usageCard\" aria-label={t('usageTitle')}>\n <div className=\"cc-usageHead\">\n <h3 className=\"cc-usageTitle\">{t('usageTitle')}</h3>\n <span className=\"cc-usageMetaSpacer\" />\n <button type=\"button\" className=\"cc-usageRefresh\" disabled={loading || !apiKeyConfigured} onClick={onRefresh}>\n {loading ? t('usageRefreshing') : t('usageRefresh')}\n </button>\n </div>\n\n {!apiKeyConfigured ? <p className=\"cc-usageHint\">{t('usageNoKey')}</p> : null}\n {apiKeyConfigured && report === undefined && loading ? <p className=\"cc-usageHint\">{t('usageLoading')}</p> : null}\n {usage.status === 'error' ? (\n <p className=\"cc-usageError\" role=\"status\">\n <span>{t('usageError')}{usage.error !== undefined && usage.error !== '' ? ` — ${usage.error}` : ''}</span>\n </p>\n ) : null}\n\n {entries.length > 1 ? (\n <div className=\"cc-tabs\" role=\"tablist\" aria-label={t('accountsTitle')}>\n {entries.map((entry) => (\n <button\n key={entry.id}\n type=\"button\"\n role=\"tab\"\n aria-selected={selected?.id === entry.id}\n className={selected?.id === entry.id ? 'cc-tab cc-tabActive' : 'cc-tab'}\n onClick={() => setSelectedId(entry.id)}\n >\n <AccountTabDot entry={entry} />\n {entry.label}\n </button>\n ))}\n </div>\n ) : null}\n\n {selected !== undefined ? (\n <AccountReport\n key={selected.id}\n entry={selected}\n t={t}\n onRemove={removeSelected}\n />\n ) : null}\n\n {report !== undefined && usage.fetchedAt !== undefined ? (\n <div className=\"cc-usageMeta\">\n <span className=\"cc-usageMetaSpacer\" />\n <p className=\"cc-usageUpdated\">{t('usageUpdated')} {new Date(usage.fetchedAt).toLocaleTimeString()}</p>\n </div>\n ) : null}\n </div>\n )\n}\n\n/**\n * One extra account row: label, key, configured badge. Saved accounts are\n * removed from the usage card above; a NOT-YET-SAVED addition never appears\n * there (the usage report is Host-side), so it keeps its own remove button —\n * otherwise the only way to undo a mistaken Add would be discarding every\n * other staged edit.\n */\nfunction AccountRow({ account, disabled, t, onLabel, onKey, onRemove }: {\n account: AccountItemState\n disabled: boolean\n t: Translate<SettingsCommandCodeKey>\n onLabel(text: string): void\n onKey(text: string): void\n onRemove(): void\n}) {\n const locked = !account.writable\n const [keyVisible, setKeyVisible] = useState(false)\n return (\n <div className=\"cc-field\">\n <div className=\"cc-fieldHead\">\n <label className=\"cc-label\" htmlFor={`cc-account-label-${account.id}`}>{t('accountLabel')}</label>\n <span className=\"cc-badges\">\n {account.added ? <span className=\"cc-badge\">{t('unsaved')}</span> : null}\n <span className={account.configured ? 'cc-badge' : 'cc-badgeMuted'}>\n {account.configured ? t('apiKeySet') : t('apiKeyUnset')}\n </span>\n <button\n type=\"button\"\n className=\"cc-reset\"\n disabled={disabled}\n onClick={() => setKeyVisible((value) => !value)}\n >\n {keyVisible ? t('hide') : t('show')}\n </button>\n {account.added ? (\n <button type=\"button\" className=\"cc-reset\" disabled={disabled} onClick={onRemove}>{t('accountRemove')}</button>\n ) : null}\n </span>\n </div>\n <input\n id={`cc-account-label-${account.id}`}\n className=\"cc-input\"\n type=\"text\"\n value={account.label}\n disabled={disabled}\n onChange={(event) => onLabel(event.target.value)}\n />\n <input\n id={`cc-account-key-${account.id}`}\n className=\"cc-input\"\n type={keyVisible ? 'text' : 'password'}\n autoComplete=\"off\"\n spellCheck={false}\n placeholder={t('accountKey')}\n value={account.keyText}\n disabled={disabled || locked}\n onChange={(event) => onKey(event.target.value)}\n />\n <p className=\"cc-hint\">{locked ? t('apiKeyLocked') : t('accountKeyHint')}</p>\n </div>\n )\n}\n\n/** The multi-account card: the active-account selector + extra accounts in rotation order + add button. */\nfunction AccountsCard({ t, state, disabled, onAdd, onRemove, onLabel, onKey, onActive, onActiveReset }: {\n t: Translate<SettingsCommandCodeKey>\n state: SettingsPageState\n disabled: boolean\n onAdd(): void\n onRemove(id: string): void\n onLabel(id: string, text: string): void\n onKey(id: string, text: string): void\n onActive(text: string): void\n onActiveReset(): void\n}) {\n const active = state.activeAccount\n return (\n <div className=\"cc-card\" aria-label={t('accountsTitle')}>\n <div className=\"cc-field\">\n <div className=\"cc-fieldHead\">\n <label className=\"cc-label\">{t('accountsTitle')}</label>\n <span className=\"cc-badges\">\n <button type=\"button\" className=\"cc-reset\" disabled={disabled} onClick={onAdd}>{t('accountAdd')}</button>\n </span>\n </div>\n <p className=\"cc-hint\">{t('accountsHint')}</p>\n </div>\n <div className=\"cc-field\">\n <div className=\"cc-fieldHead\">\n <label className=\"cc-label\" htmlFor=\"cc-active-account\">{t('activeAccount')}</label>\n <span className=\"cc-badges\">\n {active.overridden ? <span className=\"cc-badge\">{t('overridden')}</span> : null}\n <button type=\"button\" className=\"cc-reset\" disabled={disabled} onClick={onActiveReset}>{t('reset')}</button>\n </span>\n </div>\n <select\n id=\"cc-active-account\"\n className=\"cc-input\"\n value={active.text}\n disabled={disabled}\n onChange={(event) => onActive(event.target.value)}\n >\n <option value=\"\">{t('activeAccountAuto')}</option>\n <option value=\"default\">{t('accountDefault')}</option>\n {state.accounts.filter((account) => !account.added).map((account) => (\n <option key={account.id} value={account.ref}>{account.label}</option>\n ))}\n </select>\n <p className=\"cc-hint\">{t('activeAccountHint')}</p>\n </div>\n {state.accounts.map((account) => (\n <AccountRow\n key={account.id}\n account={account}\n disabled={disabled}\n t={t}\n onLabel={(text) => onLabel(account.id, text)}\n onKey={(text) => onKey(account.id, text)}\n onRemove={() => onRemove(account.id)}\n />\n ))}\n </div>\n )\n}\n\n/**\n * Show the \"Saved ✓\" affordance for a short window after each accepted save.\n * The controller only counts saves (`savedCount`); the flash timing lives\n * here so the state machine stays timer-free.\n */\nfunction useSavedFlash(tick: number): boolean {\n const [visible, setVisible] = useState(false)\n useEffect(() => {\n if (tick === 0) return\n setVisible(true)\n const timer = setTimeout(() => setVisible(false), 2500)\n return () => clearTimeout(timer)\n }, [tick])\n return visible\n}\n\n/** The settings page body: connection facts for the Command Code provider. */\nexport function CommandCodeSettingsPage(props: CommandCodeSettingsProps) {\n const { t } = props\n const state = props.useCommandCodeSettings((snapshot) => snapshot)\n const usage = props.useCommandCodeUsage((snapshot) => snapshot)\n const disabled = !state.writable\n const keyLocked = !state.apiKeyWritable\n const savedVisible = useSavedFlash(state.savedCount)\n return (\n <section className=\"cc-section\" aria-label={t('title')}>\n <h2 className=\"cc-title\">{t('title')}</h2>\n <p className=\"cc-intro\">{t('intro')}</p>\n {!state.writable ? <p className=\"cc-readOnly\" role=\"status\">{t('readOnly')}</p> : null}\n <UsageCard\n t={t}\n usage={usage}\n apiKeyConfigured={state.anyAccountConfigured}\n removingIds={state.accountsRemoving}\n removableIds={state.accounts.map((account) => account.id)}\n canManage={state.writable}\n onRefresh={props.refreshUsage}\n onRemoveAccount={props.removeAccount}\n />\n <AccountsCard\n t={t}\n state={state}\n disabled={disabled}\n onAdd={props.addAccount}\n onRemove={props.removeAccount}\n onLabel={props.editAccountLabel}\n onKey={props.editAccountKey}\n onActive={(text) => props.edit('activeAccount', text)}\n onActiveReset={() => props.resetField('activeAccount')}\n />\n <div className=\"cc-card\">\n <SecretKeyField\n label={t('apiKey')}\n hint={keyLocked ? t('apiKeyLocked') : t('apiKeyHint')}\n state={state.apiKey}\n disabled={disabled || keyLocked}\n configured={state.apiKeyConfigured}\n configuredLabel={t('apiKeySet')}\n unconfiguredLabel={t('apiKeyUnset')}\n showLabel={t('show')}\n hideLabel={t('hide')}\n onEdit={(text) => props.edit('apiKey', text)}\n />\n <Field\n id=\"cc-api-base\"\n label={t('apiBase')}\n hint={t('apiBaseHint')}\n state={state.apiBase}\n disabled={disabled}\n onEdit={(text) => props.edit('apiBase', text)}\n onReset={() => props.resetField('apiBase')}\n t={t}\n />\n <Field\n id=\"cc-working-dir\"\n label={t('workingDir')}\n hint={t('workingDirHint')}\n state={state.workingDir}\n disabled={disabled}\n placeholder={state.defaultWorkingDir}\n onEdit={(text) => props.edit('workingDir', text)}\n onReset={() => props.resetField('workingDir')}\n t={t}\n />\n <Field\n id=\"cc-request-timeout\"\n label={t('requestTimeoutMs')}\n hint={t('requestTimeoutMsHint')}\n state={state.requestTimeoutMs}\n disabled={disabled}\n numeric\n onEdit={(text) => props.edit('requestTimeoutMs', text)}\n onReset={() => props.resetField('requestTimeoutMs')}\n t={t}\n />\n <Field\n id=\"cc-stream-idle-timeout\"\n label={t('streamIdleTimeoutMs')}\n hint={t('streamIdleTimeoutMsHint')}\n state={state.streamIdleTimeoutMs}\n disabled={disabled}\n numeric\n onEdit={(text) => props.edit('streamIdleTimeoutMs', text)}\n onReset={() => props.resetField('streamIdleTimeoutMs')}\n t={t}\n />\n <ToggleField\n id=\"cc-filter-models-by-plan\"\n label={t('filterModelsByPlan')}\n hint={t('filterModelsByPlanHint')}\n state={state.filterModelsByPlan}\n disabled={disabled}\n defaultChecked\n onEdit={(text) => props.edit('filterModelsByPlan', text)}\n onReset={() => props.resetField('filterModelsByPlan')}\n t={t}\n />\n </div>\n <div className=\"cc-footer\">\n {state.failed ? <p className=\"cc-failed\" role=\"status\">{t('saveFailed')}</p> : null}\n {savedVisible ? <p className=\"cc-saved\" role=\"status\">{t('saved')}</p> : null}\n <Button variant=\"ghost\" size=\"sm\" disabled={!state.dirty || state.saving} onClick={props.discard}>\n {t('discard')}\n </Button>\n <Button\n variant=\"primary\"\n size=\"sm\"\n disabled={!state.dirty || state.invalid || state.saving}\n onClick={props.save}\n >\n {t(state.saving ? 'saving' : 'save')}\n </Button>\n </div>\n <p className=\"cc-version\">Command Code Provider v{PLUGIN_VERSION}</p>\n </section>\n )\n}\n","/**\n * Locale copy for the \"Command Code\" settings page, and the declaration that\n * merges the page's namespace into the framework's `LocaleNamespaceMap` so\n * `ctx.locale.register` / `ctx.slots.register(..., { locale })` are typed.\n *\n * zh is the source of truth for the key set (repo convention); en must carry\n * the exact same keys — a mismatch is a compile error at the register site.\n */\ndeclare module '@deepseek-ai/dsh-client-ui-slots' {\n interface LocaleNamespaceMap {\n /** Copy of the Command Code settings page. */\n 'settings.commandcode': SettingsCommandCodeKey\n }\n}\n\n/** Dictionary keys of the Command Code settings page. */\nexport type SettingsCommandCodeKey =\n | 'nav'\n | 'title'\n | 'intro'\n | 'apiKey'\n | 'apiKeyHint'\n | 'apiKeySet'\n | 'apiKeyUnset'\n | 'apiKeyLocked'\n | 'apiBase'\n | 'apiBaseHint'\n | 'workingDir'\n | 'workingDirHint'\n | 'requestTimeoutMs'\n | 'requestTimeoutMsHint'\n | 'streamIdleTimeoutMs'\n | 'streamIdleTimeoutMsHint'\n | 'filterModelsByPlan'\n | 'filterModelsByPlanHint'\n | 'accountsTitle'\n | 'accountsHint'\n | 'accountAdd'\n | 'accountRemove'\n | 'accountLabel'\n | 'accountKey'\n | 'accountKeyHint'\n | 'accountDefault'\n | 'activeAccount'\n | 'activeAccountAuto'\n | 'activeAccountHint'\n | 'overridden'\n | 'reset'\n | 'invalidNumber'\n | 'numberTooSmall'\n | 'numberTooLarge'\n | 'readOnly'\n | 'unsaved'\n | 'save'\n | 'saving'\n | 'saved'\n | 'saveFailed'\n | 'discard'\n | 'cancel'\n | 'show'\n | 'hide'\n | 'usageTitle'\n | 'usageRefresh'\n | 'usageRefreshing'\n | 'usageLoading'\n | 'usageNoKey'\n | 'usageError'\n | 'usageRequests'\n | 'usageFailed'\n | 'usageSuccessRate'\n | 'usageCost'\n | 'usageTokens'\n | 'usageTokensIn'\n | 'usageTokensOut'\n | 'usageMonthly'\n | 'usagePurchased'\n | 'usageFree'\n | 'usageFiveHour'\n | 'usageWeekly'\n | 'usageExceeded'\n | 'usageReset'\n | 'usagePartial'\n | 'usageUpdated'\n | 'usagePeriodEnd'\n | 'usageActive'\n | 'usageCooldown'\n | 'usageInvalidKey'\n | 'usageUnconfigured'\n\nexport const zh: Record<SettingsCommandCodeKey, string> = {\n nav: 'Command Code',\n title: 'Command Code',\n intro:\n '配置 Command Code Provider 连接。API 密钥仅保存在本机凭据服务中,不会回显;'\n + '其他字段写入用户设置,下次请求即生效。',\n apiKey: 'API 密钥',\n apiKeyHint: '在 commandcode.ai 控制台创建。留空保存不会覆盖已存储的密钥。',\n apiKeySet: '已配置',\n apiKeyUnset: '未配置',\n apiKeyLocked: '密钥由只读来源提供',\n apiBase: 'API 地址',\n apiBaseHint: '默认 https://api.commandcode.ai,一般无需修改。',\n workingDir: '工作目录',\n workingDirHint: '可选。留空时使用占位符显示的进程工作目录;仅在需要固定路径时填写。',\n requestTimeoutMs: '请求超时(毫秒)',\n requestTimeoutMsHint: '等待响应首个字节的超时;默认 60000。',\n streamIdleTimeoutMs: '流空闲超时(毫秒)',\n streamIdleTimeoutMsHint: '生成流停滞多久视为断连;默认 300000(长思考模型可静默数分钟,默认值刻意放宽)。',\n filterModelsByPlan: '隐藏套餐外模型',\n filterModelsByPlanHint: '开启后,模型选择器只列出当前套餐可用的模型;账户持有按需余额时会显示全部。',\n accountsTitle: '多账户轮换',\n accountsHint: '当前账户达到用量限额(429)或密钥失效(401)时,请求自动切换到下一个账户;全部耗尽时会提示最早的重置时间。',\n accountAdd: '添加账户',\n accountRemove: '移除',\n accountLabel: '账户备注名',\n accountKey: 'API 密钥',\n accountKeyHint: '该账户的 API 密钥。留空保存不会覆盖已存储的密钥。',\n accountDefault: '默认账户',\n activeAccount: '当前使用账户',\n activeAccountAuto: '自动(第一个可用账户)',\n activeAccountHint: '手动指定优先使用的账户,保存后下次请求即生效;所选账户耗尽时仍会自动切换到其他可用账户。',\n overridden: '已覆盖',\n reset: '重置',\n invalidNumber: '无效数字',\n numberTooSmall: '不能小于 1(毫秒)',\n numberTooLarge: '超出允许上限(2147483647 毫秒)',\n readOnly: '当前配置为只读。',\n unsaved: '未保存',\n save: '保存',\n saving: '保存中',\n saved: '已保存 ✓',\n saveFailed: '保存失败,请重试。',\n discard: '放弃',\n cancel: '取消',\n show: '显示',\n hide: '隐藏',\n usageTitle: '账户用量',\n usageRefresh: '刷新',\n usageRefreshing: '刷新中…',\n usageLoading: '正在获取账户用量…',\n usageNoKey: '配置 API 密钥后,这里会显示账户的用量与额度状态。',\n usageError: '用量获取失败',\n usageRequests: '请求',\n usageFailed: '失败',\n usageSuccessRate: '成功率',\n usageCost: '花费',\n usageTokens: 'Token',\n usageTokensIn: '入',\n usageTokensOut: '出',\n usageMonthly: '月额度',\n usagePurchased: '已购',\n usageFree: '赠送',\n usageFiveHour: '5 小时窗口',\n usageWeekly: '每周窗口',\n usageExceeded: '已超限',\n usageReset: '重置于',\n usagePartial: '部分端点数据不可用',\n usageUpdated: '更新于',\n usagePeriodEnd: '账期截止',\n usageActive: '当前使用',\n usageCooldown: '限额冷却中',\n usageInvalidKey: '密钥无效',\n usageUnconfigured: '该账户尚未配置 API 密钥。',\n}\n\nexport const en: Record<SettingsCommandCodeKey, string> = {\n nav: 'Command Code',\n title: 'Command Code',\n intro:\n 'Configure the Command Code Provider connection. The API key is stored only'\n + ' in the local credential service and never echoed; other fields are written'\n + ' to user settings and take effect on the next request.',\n apiKey: 'API key',\n apiKeyHint: 'Create one in the commandcode.ai console. Saving with this field'\n + ' blank keeps the stored key.',\n apiKeySet: 'Configured',\n apiKeyUnset: 'Not configured',\n apiKeyLocked: 'Key provided by a read-only source',\n apiBase: 'API base URL',\n apiBaseHint: 'Defaults to https://api.commandcode.ai; usually leave as-is.',\n workingDir: 'Working directory',\n workingDirHint: 'Optional. Leave blank to use the process cwd shown as the'\n + ' placeholder; fill in only to pin a specific path.',\n requestTimeoutMs: 'Request timeout (ms)',\n requestTimeoutMsHint: 'Time to wait for the first response byte; default 60000.',\n streamIdleTimeoutMs: 'Stream idle timeout (ms)',\n streamIdleTimeoutMsHint: 'How long a stalled stream is treated as dead; default 300000'\n + ' (deliberately generous — long-thinking models can stay silent for minutes).',\n filterModelsByPlan: 'Hide out-of-plan models',\n filterModelsByPlanHint: 'When on, the model picker lists only models your subscription'\n + ' includes; any on-demand credit balance shows the full catalog.',\n accountsTitle: 'Account rotation',\n accountsHint: 'When the active account hits its usage limit (429) or its key'\n + ' fails (401), requests switch to the next account; when every account is'\n + ' exhausted the error names the earliest window reset.',\n accountAdd: 'Add account',\n accountRemove: 'Remove',\n accountLabel: 'Account label',\n accountKey: 'API key',\n accountKeyHint: 'This account’s API key. Saving with the field blank keeps the stored key.',\n accountDefault: 'Default account',\n activeAccount: 'Active account',\n activeAccountAuto: 'Auto (first usable account)',\n activeAccountHint: 'Pin the preferred account; applies to the next request after saving.'\n + ' If the selected account is exhausted, requests still rotate to another usable account.',\n overridden: 'Overridden',\n reset: 'Reset',\n invalidNumber: 'Invalid number',\n numberTooSmall: 'Must be at least 1 (ms)',\n numberTooLarge: 'Above the allowed maximum (2147483647 ms)',\n readOnly: 'Settings are read-only.',\n unsaved: 'Unsaved',\n save: 'Save',\n saving: 'Saving',\n saved: 'Saved ✓',\n saveFailed: 'Save failed, please retry.',\n discard: 'Discard',\n cancel: 'Cancel',\n show: 'Show',\n hide: 'Hide',\n usageTitle: 'Account usage',\n usageRefresh: 'Refresh',\n usageRefreshing: 'Refreshing…',\n usageLoading: 'Fetching account usage…',\n usageNoKey: 'Configure an API key to see this account’s usage and credit state here.',\n usageError: 'Could not fetch usage',\n usageRequests: 'Requests',\n usageFailed: 'failed',\n usageSuccessRate: 'Success rate',\n usageCost: 'Spend',\n usageTokens: 'Tokens',\n usageTokensIn: 'in',\n usageTokensOut: 'out',\n usageMonthly: 'Monthly',\n usagePurchased: 'Purchased',\n usageFree: 'Free',\n usageFiveHour: '5-hour window',\n usageWeekly: 'Weekly window',\n usageExceeded: 'Exceeded',\n usageReset: 'Resets',\n usagePartial: 'Some endpoint data unavailable',\n usageUpdated: 'Updated',\n usagePeriodEnd: 'Period ends',\n usageActive: 'Active',\n usageCooldown: 'Cooling down',\n usageInvalidKey: 'Invalid key',\n usageUnconfigured: 'No API key configured for this account yet.',\n}\n","/**\n * Browser half of the dsh-commandcode-provider bundle.\n *\n * Two responsibilities:\n *\n * 1. A \"Command Code\" settings page (a `settings.section` entry at the same\n * nav level as General / Models / Plugins). The Models page renders an\n * unknown-adapter-family card for the `commandcode` provider and disables\n * its submit, so the API key cannot be configured there; this page is the\n * dedicated surface. It writes the API key through the credentials domain\n * (the `COMMANDCODE_API_KEY` reference the plugin resolves) and the\n * connection facts through the `llm-commandcode` settings namespace, so a\n * saved key or endpoint reaches the very next request.\n *\n * 2. The friendly-error wrapper for the harness's image-session gate — see\n * `./sessions.ts`. The wrapper is deliberately narrow: only the\n * `model-unavailable` code is rewritten, only when the message matches the\n * image-session gate, and only the message text changes.\n *\n * The wire types are spelled structurally in `./sessions.ts` (not imported\n * from `@deepseek-ai/dsh-host-apiproxy`) so this client bundle does not drag\n * an extra peer dependency into the package; the shapes are stable and the\n * client build inlines them anyway.\n */\n\nimport type { Context } from '@deepseek-ai/cordis'\nimport { createSnapshotStore } from '@deepseek-ai/dsh-client-runtime/client'\n// Type-only imports that pull in the client-service augmentations\n// (`slots`/`remote`/`locale` on Context) and the `settings.section` SlotMap\n// entry (`settingsScope` arrives through dsh-client-ui-settings).\nimport type {} from '@deepseek-ai/dsh-api-remotes/client'\nimport type {} from '@deepseek-ai/dsh-client-locale/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-settings/client'\nimport { installFriendlyImageError } from './sessions.ts'\nimport { CommandCodeSettingsController, COMMANDCODE_NS, type SettingsPageState } from './settings.ts'\nimport { CommandCodeUsageController, type UsagePageState, type UsageRemote } from './usage.ts'\nimport { USAGE_REMOTE_CONTRIBUTION } from '../usage-wire.ts'\nimport { CommandCodeSettingsPage } from './section.tsx'\nimport { zh, en } from './locales.ts'\n\nexport { isImageSessionRejection, withFriendlyImageError } from './sessions.ts'\nimport type { ConnectionLike } from './sessions.ts'\n\n/** CSS for the settings page, injected once (harness bundle convention). */\nconst PAGE_CSS = `\n.cc-section{max-width:720px;color:var(--dsw-alias-label-primary);flex-direction:column;gap:12px;display:flex}\n.cc-title{margin:0;font-size:18px;font-weight:600}\n.cc-intro{color:var(--dsw-alias-label-tertiary);margin:0;font-size:13px;line-height:1.5}\n.cc-readOnly{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px;line-height:1.5}\n.cc-card{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:12px;padding:4px 16px}\n.cc-field{flex-direction:column;gap:6px;padding:12px 0;display:flex}\n.cc-field+.cc-field{border-top:1px solid var(--dsw-alias-border-l2)}\n.cc-fieldHead{align-items:center;gap:8px;display:flex}\n.cc-label{min-width:0;color:var(--dsw-alias-label-primary);flex:1;font-size:13px;font-weight:500;line-height:1.5}\n.cc-badges{align-items:center;gap:8px;display:inline-flex}\n.cc-badge{white-space:nowrap;background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-secondary);border-radius:999px;padding:1px 8px;font-size:11px;font-weight:500;line-height:17px}\n.cc-badgeMuted{white-space:nowrap;color:var(--dsw-alias-label-tertiary);border-radius:999px;padding:1px 8px;font-size:11px;line-height:17px}\n.cc-reset{font:inherit;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;padding:0;font-size:12px;line-height:1.5}\n.cc-reset:hover:not(:disabled){color:var(--dsw-alias-label-primary)}\n.cc-reset:disabled{cursor:default;opacity:.5}\n.cc-input{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-1);height:34px;font:inherit;color:var(--dsw-alias-label-primary);border-radius:8px;padding:0 12px;font-size:13px;line-height:1.5}\n.cc-input:focus-visible{border-color:var(--dsw-alias-brand-primary);outline:none}\n.cc-input:disabled{color:var(--dsw-alias-label-tertiary);cursor:default}\n.cc-inputInvalid{border-color:var(--dsw-alias-label-error)}\n.cc-invalid{color:var(--dsw-alias-label-error);margin:0;font-size:12px;line-height:1.5}\n.cc-hint{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px;line-height:1.5}\n.cc-footer{justify-content:flex-end;align-items:center;gap:8px;display:flex}\n.cc-toggleRow{align-items:center;gap:8px;cursor:pointer;display:flex}\n.cc-toggleRow:has(.cc-toggle:disabled){cursor:default}\n.cc-toggle{appearance:none;flex-shrink:0;background:var(--dsw-alias-border-l2);border-radius:999px;width:30px;height:18px;margin:0;cursor:pointer;position:relative;transition:background .15s ease}\n.cc-toggle:checked{background:var(--dsw-alias-brand-primary)}\n.cc-toggle::after{content:'';background:#fff;border-radius:50%;width:14px;height:14px;position:absolute;top:2px;left:2px;transition:left .15s ease}\n.cc-toggle:checked::after{left:14px}\n.cc-toggle:disabled{cursor:default;opacity:.5}\n.cc-failed{min-width:0;color:var(--dsw-alias-label-error);flex:1;margin:0;font-size:12px;line-height:1.5}\n.cc-usageCard{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:12px;padding:14px 16px;flex-direction:column;gap:12px;display:flex}\n.cc-usageHead{align-items:center;gap:8px;display:flex}\n.cc-usageTitle{color:var(--dsw-alias-label-primary);flex:1;margin:0;font-size:13px;font-weight:600;line-height:1.5}\n.cc-usageAccount{max-width:40%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-secondary);border-radius:999px;padding:1px 8px;font-size:11px;font-weight:500;line-height:17px}\n.cc-usagePlan{white-space:nowrap;background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-brand-primary);border-radius:999px;padding:1px 8px;font-size:11px;font-weight:600;line-height:17px}\n.cc-usagePlanStatus{white-space:nowrap;color:var(--dsw-alias-label-error);border-radius:999px;padding:1px 8px;font-size:11px;font-weight:500;line-height:17px}\n.cc-usageRefresh{font:inherit;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;padding:0;font-size:12px;line-height:1.5}\n.cc-usageRefresh:hover:not(:disabled){color:var(--dsw-alias-label-primary)}\n.cc-usageRefresh:disabled{cursor:default;opacity:.5}\n.cc-usageHint{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px;line-height:1.5}\n.cc-usageError{align-items:center;gap:8px;color:var(--dsw-alias-label-error);margin:0;font-size:12px;line-height:1.5;display:flex}\n.cc-usageStats{grid-template-columns:repeat(auto-fit,minmax(120px,1fr));gap:8px;display:grid}\n.cc-usageStat{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-1);border-radius:8px;padding:8px 10px;flex-direction:column;gap:2px;display:flex}\n.cc-usageStatLabel{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:1.5}\n.cc-usageStatValue{color:var(--dsw-alias-label-primary);font-size:15px;font-weight:600;line-height:1.4}\n.cc-usageStatSub{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:1.5}\n.cc-usageWindows{flex-direction:column;gap:16px;display:flex}\n.cc-usageWindow{flex-direction:column;gap:6px;display:flex}\n.cc-usageWindowHead{align-items:baseline;gap:8px;display:flex}\n.cc-usageWindowLabel{color:var(--dsw-alias-label-secondary);flex:1;font-size:12px;font-weight:500;line-height:1.5}\n.cc-usageWindowValue{color:var(--dsw-alias-label-primary);font-size:12px;font-weight:500;line-height:1.5}\n.cc-usageExceeded{color:var(--dsw-alias-label-error);font-size:11px;font-weight:500;line-height:1.5}\n.cc-usageBar{overflow:hidden;background:var(--dsw-alias-bg-layer-1);border-radius:999px;height:6px}\n.cc-usageBarFill{background:var(--dsw-alias-brand-primary);border-radius:999px;height:100%;transition:width .3s ease}\n.cc-usageBarFillWarn{background:var(--dsw-alias-label-error)}\n.cc-usageWindowReset{color:var(--dsw-alias-label-tertiary);margin:0;font-size:11px;line-height:1.5}\n.cc-usageMeta{align-items:center;gap:8px;display:flex}\n.cc-accountReport{flex-direction:column;gap:12px;display:flex}\n.cc-tabs{flex-wrap:wrap;gap:6px;display:flex}\n.cc-tab{align-items:center;font:inherit;color:var(--dsw-alias-label-secondary);cursor:pointer;background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l2);border-radius:999px;padding:2px 10px;font-size:12px;line-height:18px;display:inline-flex;gap:6px}\n.cc-tab:hover:not(.cc-tabActive){color:var(--dsw-alias-label-primary)}\n.cc-tabActive{color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-brand-primary)}\n.cc-tabDotOk{background:var(--dsw-alias-brand-primary);border-radius:50%;width:6px;height:6px}\n.cc-tabDotWarn{background:#d97706;border-radius:50%;width:6px;height:6px}\n.cc-tabDotError{background:var(--dsw-alias-label-error);border-radius:50%;width:6px;height:6px}\n.cc-usageMetaSpacer{flex:1}\n.cc-usageUpdated{color:var(--dsw-alias-label-tertiary);margin:0;font-size:11px;line-height:1.5}\n.cc-usagePartial{color:var(--dsw-alias-label-error);margin:0;font-size:11px;line-height:1.5}\n.cc-version{margin:4px 0 0;text-align:center;color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:1.5}\n.cc-saved{color:var(--dsw-alias-state-success-primary,var(--dsw-alias-label-secondary));margin:0;font-size:12px;font-weight:500;line-height:1.5}\n`\n\n/** Inject the page stylesheet once (idempotent per tag). */\nfunction injectPageCss(): void {\n if (typeof document === 'undefined') return\n const id = '@mars-sea/dsh-commandcode-provider/CommandCodeSettingsPage.module.css'\n if (document.querySelector(`style[data-plugin-css=\"${id}\"]`) !== null) return\n const tag = document.createElement('style')\n tag.dataset.plugin = '@mars-sea/dsh-commandcode-provider'\n tag.dataset.pluginCss = id\n tag.textContent = PAGE_CSS\n document.head.appendChild(tag)\n}\n\n/**\n * Client plugin body. Gates on the services the settings page needs\n * (`slots`, `locale`, `connection`, `remote`, `settingsScope`) plus the\n * `connection` used by the friendly-error wrapper — the same inject list the\n * harness's own settings-surface plugins declare.\n */\nexport function apply(ctx: Context): void {\n injectPageCss()\n\n // Friendly image-gate error wrapper (unchanged behaviour).\n const connection = ctx.get('connection') as ConnectionLike | undefined\n if (connection !== undefined) {\n installFriendlyImageError(connection)\n }\n\n // The \"Command Code\" settings page: register the section once the\n // `settings.section` declaration is on the ledger (ui-settings-general\n // owns the shell; registration order relative to it is not constrained —\n // `slots.inject` waits for the declaration).\n ctx.effect(() => ctx.locale.register('settings.commandcode', { zh, en }), 'dsh-commandcode-provider: page copy')\n\n const api = ctx.get('connection').api\n const hostDescription = ctx.get('connection').hostDescription\n const scope = ctx.settingsScope.bind<Record<string, unknown>>({ namespace: COMMANDCODE_NS })\n const controller = new CommandCodeSettingsController(scope, { credentials: api.credentials }, hostDescription)\n ctx.effect(() => () => controller.dispose(), 'dsh-commandcode-provider: settings controller')\n const store = createSnapshotStore<SettingsPageState>(controller.state())\n controller.subscribe(() => store.set(controller.state()))\n\n // The account-usage card: mount the shared Remote contribution, then resolve\n // the `remote.commandcode` namespace through a scoped inject. Cordis only\n // serves services a fiber declares in `inject`, and the namespace service\n // exists only after the mount — a static inject would deadlock the plugin\n // (the mounter would wait for its own mount), so the inject is registered\n // dynamically once the mount lands. A Host half that predates the Remote\n // fails the call instead, and the card renders its error branch.\n let usageNamespace: (typeof ctx.remote)['commandcode'] | undefined\n let usageMountError: string | undefined\n ctx.effect(() => {\n let cancelled = false\n let unmount: (() => Promise<void>) | undefined\n void ctx.remote.$mount(USAGE_REMOTE_CONTRIBUTION).then((dispose) => {\n if (cancelled) {\n void dispose()\n return\n }\n unmount = dispose\n ctx.inject(['remote.commandcode'], (namespaceCtx) => {\n usageNamespace = namespaceCtx.remote.commandcode\n namespaceCtx.effect(() => () => {\n usageNamespace = undefined\n }, 'dsh-commandcode-provider: usage namespace')\n })\n }, (error: unknown) => {\n // A mount failure (e.g. a harness without the Remote mount) leaves the\n // namespace unset; keep the reason so the card can surface it.\n usageMountError = error instanceof Error ? error.message : String(error)\n })\n return () => {\n cancelled = true\n usageNamespace = undefined\n if (unmount !== undefined) void unmount()\n }\n }, 'dsh-commandcode-provider: usage remote')\n const usageRemote: UsageRemote = {\n report: async () => {\n const namespace = usageNamespace\n if (namespace === undefined) {\n return { ok: false, error: { message: usageMountError ?? 'commandcode/report remote is not mounted' } }\n }\n return namespace.report()\n },\n }\n const usageController = new CommandCodeUsageController(usageRemote)\n ctx.effect(() => () => usageController.dispose(), 'dsh-commandcode-provider: usage controller')\n const usageStore = createSnapshotStore<UsagePageState>(usageController.state())\n usageController.subscribe(() => usageStore.set(usageController.state()))\n\n const injected = () => ({\n hooks: { commandCodeSettings: store, commandCodeUsage: usageStore },\n edit: (field: string, text: string) => controller.edit(field, text),\n resetField: (field: string) => controller.resetField(field),\n // A landed save can change the key or endpoint the usage endpoints read,\n // so the account card refetches; a failed save keeps the old data.\n save: () => void controller.save().then(() => {\n const settled = controller.state()\n if (!settled.failed && settled.anyAccountConfigured) void usageController.refresh()\n }),\n discard: () => controller.discard(),\n refreshUsage: () => void usageController.refresh(),\n addAccount: () => controller.addAccount(),\n removeAccount: (id: string) => controller.removeAccount(id),\n editAccountLabel: (id: string, text: string) => controller.editAccountLabel(id, text),\n editAccountKey: (id: string, text: string) => controller.editAccountKey(id, text),\n })\n\n ctx.slots.inject('settings.section', () => ctx.slots.register({\n name: 'settings.section',\n id: 'commandcode',\n order: 12,\n label: () => ctx.locale.bind('settings.commandcode')('nav'),\n locale: 'settings.commandcode',\n inject: injected,\n }, CommandCodeSettingsPage))\n}\n\nexport const inject: readonly string[] = [\n 'slots',\n 'locale',\n 'connection',\n 'remote',\n 'settingsScope',\n]\n"],"mappings":"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"}