From 20143c02f08116b6a2c7f9e0000c55b4cc4d4c53 Mon Sep 17 00:00:00 2001
From: GT610
Date: Sun, 18 Oct 2026 19:51:37 +0800
Subject: [PATCH 1/6] perf(build): keep source maps out of the published bundle
The tarball carried lib/index.js.map and lib/client.js.map: 1.63 MiB raw,
32.9% of the unpacked payload. Nothing reads them: lib/client.js is a CJS
bundle the webview executes, and scripts/verify-engine-load.mjs audits
import/require statements rather than comments, so the `//# sourceMappingURL`
trailer is inert.
`files` now excludes them, and they are untracked as well. They are the one
tsdown output that does not rebuild byte-identically on this checkout --
lib/index.js, lib/client.js and lib/index.d.ts all reproduce exactly -- so
tracking them only gives the CI `git diff --exit-code -- lib/` guard a
platform-dependent failure. Local builds still emit them, so debugging keeps
its maps.
npm pack --dry-run: tarball 2,948,915 -> 2,479,266 B (-15.9%), unpacked
5,188,371 -> 3,480,662 B (-32.9%), 18 -> 16 files.
---
.gitignore | 6 +++++-
lib/client.js.map | 1 -
lib/index.js.map | 1 -
package.json | 1 +
4 files changed, 6 insertions(+), 3 deletions(-)
delete mode 100644 lib/client.js.map
delete mode 100644 lib/index.js.map
diff --git a/.gitignore b/.gitignore
index 560ca96..dd1b0ca 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,7 +5,11 @@ node_modules.bak/
.npm-cache/
# DSH STORE reviews the fixed Git Commit, so the built runtime files ship in
# git. `lib/` artifacts are committed explicitly with `git add -f`; the ignore
-# stays so map churn and stray local rebuilds do not show up as noise.
+# stays so stray local rebuilds do not show up as noise. Source maps are
+# deliberately outside both: nothing loads them, `files` keeps them out of the
+# tarball, and they are the one tsdown output that does not rebuild
+# byte-identically across machines, so tracking them only breaks the CI
+# `git diff --exit-code -- lib/` guard.
lib/
*.tgz
.DS_Store
diff --git a/lib/client.js.map b/lib/client.js.map
deleted file mode 100644
index a75c224..0000000
--- a/lib/client.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"client.js","names":["record","numberField","booleanField","IDLE","record","stringField","reject","pkg.version","(pkg as { repository?: unknown }).repository","useState","useMemo","Menu","Button","useSyncExternalStore","useCallback","useRef","HIDDEN_STYLE","useState","useRef","money","count","useState","useId","useState","Button","useRef"],"sources":["../src/client/snapshot-store.ts","../src/readable-error.ts","../src/client/settings-scope.ts","../src/timeout-limits.ts","../src/model-visibility.ts","../src/context-window.ts","../src/output-budget.ts","../src/client/settings-write.ts","../src/client/settings.ts","../src/display-format.ts","../src/client/usage.ts","../src/client/prices.ts","../src/client/login-page.ts","../src/client/login.ts","../src/wire-shared.ts","../src/usage-wire.ts","../src/login-wire.ts","../src/enrollment-wire.ts","../src/client/enrollment.ts","../src/client/locales.ts","../src/plan-tiers.ts","../src/client/model-select.ts","../package.json","../src/client/version.ts","../src/client/update.ts","../src/client/section.tsx","../src/client/login-row.tsx","../src/client/card.tsx","../src/client/analytics-copy.ts","../src/client/panel-copy.ts","../src/client/panel.ts","../src/analytics-wire.ts","../src/client/analytics-comparison.ts","../src/client/analytics-view.tsx","../src/client/panel-view.tsx","../src/cost-facts.ts","../src/client/session-cost.ts","../src/client/session-cost-display.ts","../src/client/session-cost-view.tsx","../src/client/page-styles.ts","../src/client/panel-styles.ts","../src/client/analytics.ts","../src/client/index.ts"],"sourcesContent":["/**\n * A tiny observable snapshot store — the `getSnapshot` / `subscribe` / `set`\n * triple React's `useSyncExternalStore` consumes through the harness slot kit\n * (the host builds each slot's `useFoo(selector)` hook from one of these).\n *\n * Vendored on purpose, and small enough to stay that way: the harness's\n * `@deepseek-ai/dsh-client-store` is a seeded platform module, but pulling it in\n * would add a fourth `require()` target (and a client-only peer) to the bundle\n * for the ~30 lines used here, and its `set()` carries engine semantics\n * (dev-mode deep freeze, forced replacement) these callers do not want.\n */\n\n/** Observable snapshot consumed by slot hooks. */\nexport interface SnapshotStore {\n getSnapshot(): T\n subscribe(listener: () => void): () => void\n set(value: T): void\n}\n\n/** Notify every subscriber without letting one faulty UI consumer suppress the rest. */\nfunction notifyListeners(listeners: ReadonlySet<() => void>): void {\n for (const listener of listeners) {\n try {\n listener()\n } catch (error: unknown) {\n console.error('[dsh-commandcode-provider] snapshot subscriber failed:', error)\n }\n }\n}\n\n/** Create one observable snapshot store. */\nexport function createSnapshotStore(initial: T): SnapshotStore {\n let snapshot = initial\n const listeners = new Set<() => void>()\n return {\n getSnapshot: () => snapshot,\n subscribe(listener: () => void) {\n listeners.add(listener)\n return () => {\n listeners.delete(listener)\n }\n },\n set(value: T) {\n if (Object.is(value, snapshot)) return\n snapshot = value\n notifyListeners(listeners)\n },\n }\n}\n","/**\n * Readable error text for the settings page AND the Host-side failure paths.\n *\n * @module dsh-commandcode-provider/readable-error\n */\n\n/**\n * Turn a caught value into readable text.\n *\n * `error instanceof Error ? error.message : String(error)` degrades to the\n * literal string `[object Object]` for a plain object with no `Error`\n * prototype — which is exactly what a Remote call across the webview/host\n * boundary can hand back: `dsh-typert-protocol` serializes a rejection for\n * the wire, and a structurally-cloned value loses its prototype chain even\n * when the host threw a real `Error` (issue #74). Reading a `message` string\n * off the plain object first recovers the original text in that case; only a\n * value with neither an `Error` prototype nor a usable `message` field falls\n * through to a JSON dump.\n *\n * Shared by both halves on purpose. The browser client needs it for rejections\n * that crossed the RPC boundary, and the Host needs it for values that reached\n * it from a transport, a JSON body, or a user-thrown non-Error — the same\n * degradation, one owner.\n */\nexport function readableErrorText(error: unknown): string {\n if (error instanceof Error) return error.message\n if (typeof error === 'string') return error\n if (error !== null && typeof error === 'object') {\n const message = (error as { message?: unknown }).message\n if (typeof message === 'string' && message !== '') return message\n try {\n return JSON.stringify(error)\n } catch {\n return Object.prototype.toString.call(error)\n }\n }\n return String(error)\n}\n","/**\n * Browser settings scope over the `remote.settings` Typert namespace.\n *\n * The harness's own `settingsScope` client wrapper was REMOVED by the 0.1.7\n * settings rewrite and has no replacement, so this module IS the client half:\n * it speaks the `describe()` / `mutate(namespace, ops, revision)` wire directly\n * and implements the `SettingsScope` face the settings-page controller\n * consumes. `view.writable` is the Host's own authorization fact — the client\n * never infers write permission from localhost, URL shape or origin.\n *\n * **Capture the namespace from an inject-scoped context, never read it off\n * `ctx.remote`.** React-free so `tests/settings-scope.test.ts` can drive the\n * lifecycle over a fake remote.\n *\n * @module dsh-commandcode-provider/client/settings-scope\n */\n\nimport type { SettingsScope, SettingsScopeSnapshot } from './settings.ts'\nimport { createSnapshotStore, type SnapshotStore } from './snapshot-store.ts'\nimport { readableErrorText } from '../readable-error.ts'\n\n/** Result envelope of one current Typert Remote call. */\ntype Envelope = { ok: true; value: T } | { ok: false; error?: { message?: string } | undefined }\n\n/** One path-addressed form edit — the `SettingsPathOp` wire shape. */\nexport interface SettingsPathOp {\n op: 'set' | 'unset'\n path: readonly string[]\n value?: unknown\n}\n\n/** 本地确认结果,不改宿主远端载体;恢复快照不能冒充本次写入成功。 */\nexport type SettingsMutationResult = 'accepted' | 'conflict' | 'failed' | 'cancelled'\n\n/** One entry's row inside a `settings.describe()` view — `SettingsNamespaceView`. */\ninterface SettingsNamespaceRow {\n ns?: unknown\n value?: unknown\n base?: unknown\n user?: unknown\n revision?: unknown\n}\n\n/** The `settings.describe()` view: the directory plus the Host's write posture. */\ninterface SettingsView {\n namespaces?: SettingsNamespaceRow[] | undefined\n writable?: boolean | undefined\n}\n\n/** The `remote.settings` namespace this scope calls. Structural: never imported. */\nexport interface SettingsRemoteNamespace {\n describe(): Promise>\n /** A write answers with the fresh ROW for its namespace, not the directory. */\n mutate(\n namespace: string,\n ops: readonly SettingsPathOp[],\n revision?: number,\n ): Promise>\n}\n\n/**\n * Reads the `remote.settings` namespace object, or `undefined` while it is not\n * mounted.\n *\n * This is a SEAM rather than a property on {@link SettingsScopeContext}\n * because the namespace has to be captured inside a context that declares it\n * (`ctx.inject(['remote.settings'], (settingsCtx) => …)`). Reading it off our\n * own `ctx.remote` throws `cannot get property \"remote.settings\" without\n * inject` inside this module's `try`/`catch` — silently, with no describe ever\n * sent and the scope stuck on its initial `writable: false` snapshot. Do not\n * \"simplify\" this seam away (AGENTS.md has the full incident).\n */\nexport type SettingsRemoteResolver = () => SettingsRemoteNamespace | undefined\n\n/**\n * The client `Context` slice this module consumes, typed structurally so the\n * browser bundle never imports a version-specific module value and node tests\n * can hand in a plain object. Only `remote` itself (a declared service) is read\n * here — never `remote.`, which requires its own inject.\n */\nexport interface SettingsScopeContext {\n remote: {\n $on?: ((event: string, listener: () => void) => (() => void) | undefined) | undefined\n }\n /** Connection lifecycle; older clients and tests may omit it. */\n on?: ((event: string, listener: () => void) => unknown) | undefined\n}\n\n/** Mirror snapshot: one in-flight-or-idle describe read and its held view. */\ninterface MirrorState {\n status: 'idle' | 'loading' | 'ready'\n view: SettingsView | null\n error: string | null\n}\n\n/**\n * Backoff before re-reading a directory whose FIRST read failed, in millis.\n *\n * Only a failure with NOTHING held retries. With no view the scope keeps its\n * initial `{ status: 'loading', writable: false }` snapshot and the settings\n * page renders fully disabled, while the forwarded invalidation signals need a\n * live Host to fire and the namespace only re-mounts on a reload. A failure\n * with a held view retries nothing — the page already shows the last good\n * document (`tests/settings-scope.test.ts` pins both).\n */\nexport const SETTINGS_DESCRIBE_RETRY_MS: readonly number[] = [1000, 2000, 4000]\n\n/** Timer seam for the bounded describe retry; tests drive it without waiting. */\nexport interface SettingsRetryTimer {\n set(callback: () => void, ms: number): unknown\n clear(handle: unknown): void\n}\n\n/** The production timer: a browser/node timeout, no polling. */\nconst REAL_SETTINGS_TIMER: SettingsRetryTimer = {\n set(callback, ms) {\n const handle = setTimeout(callback, ms)\n ;(handle as { unref?: () => void }).unref?.()\n return handle\n },\n clear(handle) { clearTimeout(handle as ReturnType) },\n}\n\n/** Shallow equality over the snapshot fields, so an unchanged derive never churns subscribers. */\nfunction sameSnapshot(a: SettingsScopeSnapshot, b: SettingsScopeSnapshot): boolean {\n return a.status === b.status\n && Object.is(a.value, b.value)\n && Object.is(a.base, b.base)\n && Object.is(a.user, b.user)\n && Object.is(a.revision, b.revision)\n && a.writable === b.writable\n && a.mode === b.mode\n}\n\n/** Accept a decoded row value only when it is the object a settings section is. */\nfunction decodeRow(value: unknown): Record | undefined {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) return undefined\n return value as Record\n}\n\n/**\n * One shared mirror of the Host `settings.describe()` view.\n *\n * The run loop is the harness's own: serialize behind `inFlight`, fold a\n * concurrent invalidation into exactly one rerun, and hold the previous view\n * across a failed read (status stays `ready` with an `error`, or returns to\n * `idle` when nothing was ever held).\n */\nclass SettingsDescribeMirror {\n private readonly store: SnapshotStore\n private inFlight: Promise | undefined\n private rerun = false\n private generation = 0\n /** Pending retry handle and how many of {@link SETTINGS_DESCRIBE_RETRY_MS} are spent. */\n private retryHandle: unknown\n private retries = 0\n private disposed = false\n\n constructor(\n private readonly resolveRemote: SettingsRemoteResolver,\n private readonly timer: SettingsRetryTimer = REAL_SETTINGS_TIMER,\n ) {\n this.store = createSnapshotStore({\n status: 'idle',\n view: null,\n error: null,\n })\n }\n\n getSnapshot(): MirrorState {\n return this.store.getSnapshot()\n }\n\n subscribe(listener: () => void): () => void {\n return this.store.subscribe(listener)\n }\n\n /** The cheap idempotent entry: kick a first read. */\n ensure(): void {\n void this.load()\n }\n\n /**\n * Refresh from the Host. A call during an in-flight read marks one rerun\n * after it settles instead of racing a second wire read.\n * @returns settlement after this call's freshness is reflected.\n */\n load(): Promise {\n if (this.disposed) return Promise.resolve()\n // A live read supersedes a scheduled retry: the retry exists only to\n // revive a mirror that nothing else would ever re-read.\n this.clearRetry()\n if (this.inFlight !== undefined) {\n this.rerun = true\n return this.inFlight\n }\n const run = Promise.resolve().then(() => this.run())\n this.inFlight = run\n return run\n }\n\n /**\n * Fold one write answer's namespace ROW into the held view without a wire\n * read, and invalidate any read still in flight: a read begun before the\n * write committed must not publish the pre-write document over it. With no\n * held document the answer is not published as a partial document — the\n * next read (or the failed-write recovery) picks it up.\n * @param row - The namespace view a settings write answered with.\n */\n acceptView(row: SettingsNamespaceRow): void {\n const before = this.store.getSnapshot()\n this.generation += 1\n if (this.inFlight !== undefined) this.rerun = true\n if (before.view === null) return\n const held = before.view\n const namespaces = held.namespaces?.some((candidate) => candidate.ns === row.ns)\n ? held.namespaces.map((candidate) => (candidate.ns === row.ns ? row : candidate))\n : [...(held.namespaces ?? []), row]\n this.store.set({ ...before, view: { ...held, namespaces } })\n }\n\n private async run(): Promise {\n try {\n for (;;) {\n const before = this.store.getSnapshot()\n if (before.status === 'idle') this.store.set({ ...before, status: 'loading' })\n this.rerun = false\n const generation = ++this.generation\n let outcome: { view: SettingsView } | { failure: string }\n try {\n const namespace = this.resolveRemote()\n if (namespace === undefined) throw new Error('the settings remote namespace is not mounted')\n const response = await namespace.describe()\n if (response.ok) {\n const value: unknown = response.value\n // The mirror holds a VIEW or nothing: an empty/malformed answer\n // must not be published as `ready` with an undefined view, or the\n // derive below would read through it. (Upstream guards the same way\n // by testing the held view for `undefined`.)\n outcome = typeof value === 'object' && value !== null\n ? { view: value as SettingsView }\n : { failure: 'settings describe answered no view' }\n } else {\n outcome = { failure: response.error?.message ?? 'settings describe failed' }\n }\n } catch (error: unknown) {\n outcome = { failure: readableErrorText(error) }\n }\n if (generation !== this.generation) continue\n if ('view' in outcome) {\n this.retries = 0\n this.store.set({ status: 'ready', view: outcome.view, error: null })\n } else {\n const held = this.store.getSnapshot()\n this.store.set({\n status: held.view === null ? 'idle' : 'ready',\n view: held.view,\n error: outcome.failure,\n })\n // Nothing held → nothing can heal this but a retry (see\n // SETTINGS_DESCRIBE_RETRY_MS); a held view needs none.\n if (held.view === null) this.scheduleRetry()\n }\n if (!this.rerun) break\n }\n } finally {\n this.inFlight = undefined\n }\n }\n\n /**\n * Schedule the next retry of a failed FIRST read ({@link SETTINGS_DESCRIBE_RETRY_MS}).\n * Bounded: once the ladder is spent the scope keeps its degraded snapshot,\n * exactly as before, until an invalidation or a namespace re-mount arrives.\n */\n private scheduleRetry(): void {\n if (this.disposed || this.retries >= SETTINGS_DESCRIBE_RETRY_MS.length) return\n const delay = SETTINGS_DESCRIBE_RETRY_MS[this.retries]!\n this.retries += 1\n this.retryHandle = this.timer.set(() => {\n this.retryHandle = undefined\n void this.load()\n }, delay)\n }\n\n /** Cancel a pending retry (a live read is starting, or the scope is going away). */\n private clearRetry(): void {\n if (this.retryHandle !== undefined) this.timer.clear(this.retryHandle)\n this.retryHandle = undefined\n }\n\n /** Stop the mirror: no further reads, and no retry may fire after disposal. */\n dispose(): void {\n this.disposed = true\n this.clearRetry()\n }\n}\n\n/**\n * One namespace's derived scope over the shared mirror, plus its serialized\n * Host writes — the face `CommandCodeSettingsController` consumes\n * (`getSnapshot` / `subscribe` / `set` / `unset`).\n */\nclass RemoteSettingsScope implements SettingsScope {\n private readonly resolveRemote: SettingsRemoteResolver\n private readonly store: SnapshotStore>\n private readonly mirror: SettingsDescribeMirror\n private readonly namespace: string\n private tail: Promise = Promise.resolve()\n private writeGeneration = 0\n private disposed = false\n private unsubscribe: (() => void) | undefined\n /** Revision answered by a superseded write still ahead of the mirror. */\n private pendingRevision: number | undefined\n\n constructor(\n resolveRemote: SettingsRemoteResolver,\n mirror: SettingsDescribeMirror,\n namespace: string,\n ) {\n this.resolveRemote = resolveRemote\n this.mirror = mirror\n this.namespace = namespace\n this.store = createSnapshotStore>({\n status: 'loading',\n value: undefined,\n base: undefined,\n user: undefined,\n revision: undefined,\n writable: false,\n mode: 'host',\n })\n this.unsubscribe = mirror.subscribe(() => { this.derive() })\n this.derive()\n }\n\n getSnapshot(): SettingsScopeSnapshot {\n return this.store.getSnapshot()\n }\n\n subscribe(listener: () => void): () => void {\n return this.store.subscribe(listener)\n }\n\n /** Queue one field write (the single-path `set` op form). */\n async set(field: string, value: unknown): Promise {\n await this.mutate([{ op: 'set', path: [field], value }])\n }\n\n /** Queue one field clear (the single-path `unset` op form). */\n async unset(field: string): Promise {\n await this.mutate([{ op: 'unset', path: [field] }])\n }\n\n /**\n * Queue one atomic namespace mutation behind the single-flight fence.\n * A rejected write (e.g. `SETTINGS_CONFLICT`) re-reads the Host so the\n * snapshot reports what actually landed; an accepted one folds its answer\n * in directly — unless a newer write already superseded it, in which case\n * that answer's revision becomes the next write's fence.\n */\n mutate(ops: readonly SettingsPathOp[], expectedRevision?: number): Promise {\n const ownedOps = structuredClone(ops)\n const generation = ++this.writeGeneration\n return this.enqueue(async () => {\n const revision = expectedRevision ?? this.pendingRevision ?? this.getSnapshot().revision\n const response = await this.mutateRemote(ownedOps, revision)\n if (!response.ok) {\n await this.recover(generation)\n return response.error?.message?.includes('SETTINGS_CONFLICT') ? 'conflict' : 'failed'\n }\n const row = response.value\n if (row?.ns !== this.namespace || decodeRow(row.value) === undefined || typeof row.revision !== 'number') {\n await this.recover(generation)\n return 'failed'\n }\n if (this.disposed) return 'accepted'\n if (generation === this.writeGeneration) {\n this.pendingRevision = undefined\n this.mirror.acceptView(row)\n } else {\n this.pendingRevision = typeof row.revision === 'number' ? row.revision : undefined\n }\n return 'accepted'\n })\n }\n\n private async mutateRemote(\n ops: readonly SettingsPathOp[],\n revision: number | undefined,\n ): Promise> {\n try {\n const namespace = this.resolveRemote()\n if (namespace === undefined) {\n return { ok: false, error: { message: 'the settings remote namespace is not mounted' } }\n }\n return await namespace.mutate(this.namespace, ops, revision)\n } catch (error: unknown) {\n return { ok: false, error: { message: readableErrorText(error) } }\n }\n }\n\n /** Reload Host state for the latest failed write; superseded failures leave recovery to it. */\n private async recover(generation: number): Promise {\n if (this.disposed || generation !== this.writeGeneration) return\n this.pendingRevision = undefined\n await this.mirror.load()\n }\n\n /** Derive this namespace's snapshot from the mirror's held view. */\n private derive(): void {\n if (this.disposed) return\n const mirrored = this.mirror.getSnapshot()\n // `undefined` as well as `null`: the held view is only ever the wire's\n // answer, and a malformed one never reaches the store (see `run`).\n if (mirrored.view === null || mirrored.view === undefined) return\n const writable = mirrored.view.writable === true\n const row = mirrored.view.namespaces?.find((candidate) => candidate.ns === this.namespace)\n if (row === undefined) {\n this.publish({ status: 'unavailable', writable })\n return\n }\n const decoded = decodeRow(row.value)\n if (decoded === undefined) return\n this.publish({\n status: 'ready',\n writable,\n value: decoded as T,\n base: row.base,\n user: row.user,\n revision: typeof row.revision === 'number' ? row.revision : undefined,\n })\n }\n\n /** Publish `next` over the current snapshot, skipping the write when nothing changed. */\n private publish(next: {\n status: SettingsScopeSnapshot['status']\n writable: boolean\n value?: T\n base?: unknown\n user?: unknown\n revision?: number | undefined\n }): void {\n const current = this.store.getSnapshot()\n const candidate: SettingsScopeSnapshot = {\n status: next.status,\n value: 'value' in next ? next.value : current.value,\n base: 'base' in next ? next.base : current.base,\n user: 'user' in next ? next.user : current.user,\n revision: 'revision' in next ? next.revision : current.revision,\n writable: next.writable,\n mode: current.mode,\n }\n if (sameSnapshot(candidate as SettingsScopeSnapshot, current as SettingsScopeSnapshot)) return\n this.store.set(candidate)\n }\n\n /** Queue operations one at a time; disposal makes the queue inert. */\n private enqueue(operation: () => Promise): Promise {\n if (this.disposed) return Promise.resolve('cancelled')\n const task = this.tail.then(async () => {\n if (this.disposed) return 'cancelled' as const\n return operation()\n })\n this.tail = task.then(() => {}, () => {})\n return task\n }\n\n /** Stop queued operations, stop deriving, and wait for the current wire call to settle. */\n async dispose(): Promise {\n this.disposed = true\n this.writeGeneration += 1\n this.unsubscribe?.()\n await this.tail\n }\n}\n\n/** The scope plus the handles the plugin entry wires into its fiber lifecycle. */\nexport interface ManagedSettingsScope extends SettingsScope {\n mutate(ops: readonly SettingsPathOp[], expectedRevision?: number): Promise\n /** Re-read the Host — used when the `remote.settings` namespace mounts after boot. */\n refresh(): void\n /** Stop deriving, drop the forwarded-event subscriptions, and settle in-flight work. */\n dispose(): Promise\n}\n\n/**\n * Build the plugin's settings scope for one namespace.\n *\n * Subscribes the two signals that can move the Host view — the forwarded\n * `settings/document-updated` invalidation and (when the client exposes it)\n * `connection/reset` — kicks the first describe read, and derives the namespace\n * row on every mirror change.\n *\n * `resolveRemote` must be the INJECT-CAPTURED namespace (see\n * {@link SettingsRemoteResolver}), and the caller that owns that inject calls\n * {@link ManagedSettingsScope.refresh} once the namespace lands — that is what\n * turns the first, namespace-less read into a served one. A profile that never\n * mounts the namespace leaves the page in its degraded (`unavailable`,\n * read-only) state instead of throwing.\n *\n * @param namespace - Settings namespace (profile entry id) this scope binds.\n */\nexport function createSettingsScope(\n context: SettingsScopeContext,\n namespace: string,\n resolveRemote: SettingsRemoteResolver,\n timer: SettingsRetryTimer = REAL_SETTINGS_TIMER,\n): ManagedSettingsScope {\n const mirror = new SettingsDescribeMirror(resolveRemote, timer)\n const scope = new RemoteSettingsScope(resolveRemote, mirror, namespace)\n const disposers: Array<() => void> = []\n if (typeof context.remote.$on === 'function') {\n const off = context.remote.$on('settings/document-updated', () => { mirror.ensure() })\n if (typeof off === 'function') disposers.push(off)\n }\n if (typeof context.on === 'function') {\n const off = context.on('connection/reset', () => { void mirror.load() })\n if (typeof off === 'function') disposers.push(off as () => void)\n }\n mirror.ensure()\n return {\n getSnapshot: () => scope.getSnapshot(),\n subscribe: (listener) => scope.subscribe(listener),\n set: (field, value) => scope.set(field, value),\n unset: (field) => scope.unset(field),\n mutate: (ops, revision) => scope.mutate(ops, revision),\n refresh: () => { void mirror.load() },\n dispose: async () => {\n for (const dispose of disposers.splice(0)) dispose()\n // Before the scope: a pending describe retry would otherwise re-read a\n // directory nobody is rendering any more.\n mirror.dispose()\n await scope.dispose()\n },\n }\n}\n","/** 两端共用可编辑超时范围,存储仍是整数毫秒;提示不能借用重试退避上限。 */\nexport const MIN_TIMEOUT_SECONDS = 0.001\nexport const MAX_TIMEOUT_SECONDS = 3600\n","/** 网页、终端与模型目录共用的选择规则;显式开关优先于白名单。 */\nexport function modelIsVisible(id: string, allowlist: readonly string[], overrides: unknown): boolean {\n const flag = overrides !== null && typeof overrides === 'object' && !Array.isArray(overrides)\n ? (overrides as Record)[id] : undefined\n return typeof flag === 'boolean' ? flag : allowlist.length === 0 || allowlist.includes(id)\n}\n\n/** 只接收布尔事实,手工配置中的其他值不能成为可见性开关。 */\nexport function readVisibility(raw: unknown): Record {\n if (raw === null || typeof raw !== 'object' || Array.isArray(raw)) return {}\n return Object.fromEntries(Object.entries(raw).filter(([id, value]) => id !== '' && typeof value === 'boolean'))\n}\n","/** 自定义上下文长度(issue #86):按模型覆盖优先于全局值,全局值优先于目录公布值。\n * 本模块保持纯函数(无 node 依赖),浏览器设置页与 Host 侧共用同一套边界与判定。 */\n\n/** 自定义上下文长度接受的下界(token);0 或负数不是窗口。 */\nexport const CONTEXT_WINDOW_MIN = 1\n/** 自定义上下文长度接受的上界(token);覆盖任何已知模型窗口仍留有余量。 */\nexport const CONTEXT_WINDOW_MAX = 10_000_000\n\n/** 源头可携带自定义上下文长度的配置面(Config 与连接选项结构相同)。 */\nexport interface ContextWindowOptions {\n /** 全局自定义值:覆盖目录公布值,对没有按模型覆盖的模型生效。 */\n contextWindow?: number | undefined\n /** 按模型覆盖,键为目录模型 id;优先于 {@link contextWindow}。 */\n contextWindowOverrides?: Readonly> | undefined\n}\n\n/**\n * 判定一个值能否作为自定义上下文长度:边界内的安全整数,符合宿主模型元数据约束。\n *\n * 程序化构造的连接可能绕过 schemastery 归一化,所以 `resolveAdapterOptions`\n * 也要重新判定——越界或非数值直接丢弃,回落到目录公布值,而不是让请求带着\n * 一个网关会拒绝的窗口上线。\n */\nexport function isValidContextWindow(value: unknown): value is number {\n return typeof value === 'number' && Number.isSafeInteger(value)\n && value >= CONTEXT_WINDOW_MIN && value <= CONTEXT_WINDOW_MAX\n}\n\n/**\n * 只接收合法条目的按模型覆盖表;空表、非对象与非法数值一律视为未设置。\n * 配置校验会拒绝非整数或越界值;本函数额外保护绕过配置校验的程序化调用,\n * 丢弃坏条目,不把非法窗口交给宿主。返回新对象;未设置时为 `undefined`。\n */\nexport function readContextWindowOverrides(raw: unknown): Readonly> | undefined {\n if (raw === null || typeof raw !== 'object' || Array.isArray(raw)) return undefined\n const entries = Object.entries(raw).filter(\n (entry): entry is [string, number] => entry[0] !== '' && isValidContextWindow(entry[1]),\n )\n return entries.length === 0 ? undefined : Object.fromEntries(entries)\n}\n\n/**\n * 一次模型解析的有效上下文长度:按模型覆盖 → 全局值 → 目录公布值。\n *\n * 适配器只在有目录条目时调用(未知模型保持既有的「无上下文宣告」形状),\n * 所以 `catalog` 是已知的正数;按模型覆盖与全局值在 `resolveAdapterOptions`\n * 已清洗,这里对程序化构造的连接再判一次,坏值静默回落到目录值。\n */\nexport function effectiveContextWindow(\n catalog: number,\n model: string,\n options: ContextWindowOptions,\n): number {\n const perModel = options.contextWindowOverrides?.[model]\n if (isValidContextWindow(perModel)) return perModel\n if (isValidContextWindow(options.contextWindow)) return options.contextWindow\n return catalog\n}\n","/**\n * Output-budget bounds shared by the Host, the browser settings page and the\n * adapter (issue #74).\n *\n * The module stays pure (no node imports) so the client bundle can inline it,\n * exactly like `context-window.ts`. The report behind issue #74 asked for a\n * knob that stops the adapter from writing `max_tokens` at all; that is the\n * `0` sentinel here rather than a separate `null` spelling, because the value\n * travels through one numeric settings field on both surfaces.\n */\n\n/**\n * The output budget this bundle asks for, and the ceiling it will never exceed.\n *\n * 131 072, chosen against a measured provider limit rather than a round guess.\n * Probing `/alpha/generate` directly on 2026-09-28: 64 000 → 200, 131 072 → 200,\n * 196 608 → 200, **200 000 → 200, 200 704 → 400**, 1 000 000 → 400. The server\n * therefore caps `max_tokens` at 200 000, and it does so identically for a\n * 262 144-window model (`stealth/pixel-canary`, retired by Command Code on\n * 2026-10-01 and named here only as the probe's subject) and a 1 000 000-window\n * one (`stealth/space-bunny-alpha`) — the cap is global, not per model. 131 072\n * keeps a 35 % margin under it while covering the real output ceiling of the\n * models that have one (Claude 64 K, Gemini 64 K, several at 128 K).\n *\n * The old 64 000 was never a provider requirement: it cost nothing in latency\n * (a 64 000 request answered headers in 1.28 s against 1.57 s for 131 072) but\n * it did cap what a model could ever say in one turn.\n *\n * No client-side clamp is applied on top of this: an earlier version pre-shrank\n * `max_tokens` from an estimate of the prompt already sent (`requestContextBudget()`,\n * issue #67), but that estimate over-corrected on ordinary long conversations —\n * exactly the \"output gets cut short as the conversation grows\" symptom issue #74\n * reported — while a live A/B probe (2026-09-30, `stealth/space-bunny-alpha`,\n * ~19.6% over its 1,000,000-token window with no client-side shrink) showed the\n * endpoint answers a genuine overflow with an unambiguous `400 … exceeds the\n * model's context window`, which `isContextOverflowDetail()` classifies as\n * `CONTEXT_WINDOW_EXCEEDED` independently of this constant.\n *\n * A user-set positive budget can only TIGHTEN this, never raise it — a figure\n * above the cap would be refused by the gateway anyway, so the settings field\n * refuses it at the input instead of spending a round trip to learn that.\n *\n * Lives here rather than in `adapter.ts` so the browser settings page can bound\n * its input by the same figure the Host enforces; `adapter.ts` re-exports it\n * under its historical name.\n */\nexport const MAX_OUTPUT_TOKEN_LIMIT = 131_072\n\n/**\n * The `maxOutputTokens` value that asks the adapter to send NO `max_tokens`\n * field at all, leaving the per-turn output size to the platform (issue #74).\n * Only the CLI and OpenAI transports can honour it: Anthropic's Messages\n * endpoint requires the field, so that route keeps sending its derived budget.\n *\n * This is also the field's lower bound, which is why no separate `MIN_` constant\n * exists: zero is not a small budget, it is the instruction.\n */\nexport const OMIT_OUTPUT_TOKENS = 0\n\n/**\n * Whether a value can serve as a user output budget: the omit sentinel, or a\n * whole token count inside the gateway's own ceiling.\n *\n * Programmatically built connections can bypass schemastery normalization, so\n * the resolve step re-judges every value here and drops an out-of-range one\n * back to \"unset\" instead of letting the request carry a budget the gateway\n * refuses.\n */\nexport function isValidMaxOutputTokens(value: unknown): value is number {\n return typeof value === 'number' && Number.isSafeInteger(value)\n && value >= OMIT_OUTPUT_TOKENS && value <= MAX_OUTPUT_TOKEN_LIMIT\n}\n\n/**\n * Apply a user output budget to a derived one.\n *\n * `undefined` means the user set nothing, so the derived ceiling stands\n * unchanged — the default path, and the one every existing profile takes.\n * {@link OMIT_OUTPUT_TOKENS} is a wire instruction rather than a number, so it\n * also leaves the derived budget alone; {@link omitOutputTokens} is what turns\n * it into an absent field.\n */\nexport function applyMaxOutputTokens(derived: number, configured: number | undefined): number {\n if (configured === undefined || configured === OMIT_OUTPUT_TOKENS) return derived\n return Math.min(derived, configured)\n}\n\n/**\n * Whether this attempt must send no `max_tokens` field at all.\n *\n * Two guards narrow this beyond the user's own setting, and both are\n * correctness requirements rather than conveniences:\n *\n * - The Messages route is excluded deliberately: the endpoint rejects a body\n * without the field (`Invalid input: expected number, received undefined at\n * max_tokens`), so omitting it there would not lengthen an answer, it would\n * make the whole Claude family unusable. The CLI and OpenAI transports accept\n * an absent field, which is where the setting does what it promises.\n * - An explicit per-call budget from the host is an instruction, not a default,\n * so it wins over the plugin-wide setting. `session-title` is the concrete\n * case: it asks for 64 tokens precisely because its output must stay bounded,\n * and dropping the field there would let a title generation run long instead\n * of making a long answer fit (issue #88's fix depends on that bound).\n */\nexport function omitOutputTokens(\n configured: number | undefined,\n protocol: string,\n hostRequestedTokens?: number,\n): boolean {\n if (configured !== OMIT_OUTPUT_TOKENS) return false\n if (protocol === 'messages') return false\n return hostRequestedTokens === undefined\n}\n","/** 设置写入过程:同一控制器的意图按顺序执行,配置确认与凭据确认分别保留。\n * 生产使用现有远端设置/凭据,测试替换这些依赖;不提供跨服务事务。 */\nimport { readVisibility } from '../model-visibility.ts'\nimport type { SettingsPageApi, SettingsScope, SettingsScopeSnapshot } from './settings.ts'\nimport type { SettingsMutationResult, SettingsPathOp } from './settings-scope.ts'\n\nexport const DEFAULT_API_KEY_REF = 'COMMANDCODE_API_KEY'\nexport interface StoredRule { models: string[]; account: string }\n\n/** 与宿主路由的第一条匹配规则一致,重复模型只归属于先出现的账号。 */\nexport function accountModelMap(rules: readonly StoredRule[]): Map {\n const claimed = new Set()\n const map = new Map()\n for (const rule of rules) {\n const list = map.get(rule.account) ?? []\n for (const model of rule.models) {\n if (claimed.has(model)) continue\n claimed.add(model)\n list.push(model)\n }\n map.set(rule.account, list)\n }\n return map\n}\n\nexport interface SettingsWriteResult {\n config: 'none' | 'confirmed' | 'conflict' | 'unconfirmed'\n credential: 'none' | 'not-issued' | 'confirmed' | 'unconfirmed'\n issue: 'target-changed' | 'closed' | 'cleanup-pending' | undefined\n refreshFailed: boolean\n /** 实际发出调用的原引用,仅用于核对;从不包含密钥内容。 */\n credentialRef: string | undefined\n}\n\nexport type SettingsWriteIntent =\n | { kind: 'save'; ops: readonly SettingsPathOp[]; visibleModels?: readonly string[]; contextWindowOverrides?: Record; key?: string }\n | { kind: 'rename'; ref: string; label: string }\n | { kind: 'remove' | 'cleanup'; ref: string }\n | { kind: 'key'; target: string; value?: string }\n | { kind: 'active'; id: string }\n | { kind: 'models'; target: string; models: readonly string[] }\n\ntype Snapshot = SettingsScopeSnapshot>\ntype CredentialInfo = { configured: boolean; writable: boolean }\ntype FieldBaseline = { value: unknown; base: unknown; user: unknown; overridden: boolean }\ninterface Command {\n intent: SettingsWriteIntent\n ops: readonly SettingsPathOp[]\n baseline: Map\n defaultRef: string | undefined\n}\ninterface QueuedWrite { command: Command; resolve(result: SettingsWriteResult): void }\n\nconst record = (value: unknown): Record => value !== null && typeof value === 'object' && !Array.isArray(value) ? value as Record : {}\nconst result = (): SettingsWriteResult => ({ config: 'none', credential: 'none', issue: undefined, refreshFailed: false, credentialRef: undefined })\nconst closedResult = (): SettingsWriteResult => ({ ...result(), issue: 'closed' })\nconst fieldBaseline = (snapshot: Snapshot, field: string): FieldBaseline => ({\n value: snapshot.value?.[field], base: record(snapshot.base)[field], user: record(snapshot.user)[field],\n overridden: Object.hasOwn(record(snapshot.user), field),\n})\n\n/** 不用显示文本比较配置;数组顺序与显式覆盖/继承也是写入事实。 */\nfunction sameValue(a: unknown, b: unknown): boolean {\n if (Object.is(a, b)) return true\n if (Array.isArray(a) || Array.isArray(b)) return Array.isArray(a) && Array.isArray(b) && a.length === b.length && a.every((value, i) => sameValue(value, b[i]))\n if (a === null || b === null || typeof a !== 'object' || typeof b !== 'object') return false\n const left = record(a), right = record(b)\n const keys = Object.keys(left)\n return keys.length === Object.keys(right).length && keys.every(key => Object.hasOwn(right, key) && sameValue(left[key], right[key]))\n}\n\nexport function writeCompleted(outcome: SettingsWriteResult): boolean {\n return outcome.issue === undefined && outcome.config !== 'conflict' && outcome.config !== 'unconfirmed'\n && outcome.credential !== 'not-issued' && outcome.credential !== 'unconfirmed'\n}\n\nexport class SettingsWriter {\n private readonly pending: QueuedWrite[] = []\n private running = false\n private closed = false\n private readonly facts = new Map()\n /** 每个引用独立的读写世代,防止旧描述覆盖随后确认的凭据修改。 */\n private readonly factVersions = new Map()\n private refreshGeneration = 0\n private refreshFailed = false\n\n constructor(\n private readonly scope: SettingsScope>,\n private readonly credentials: SettingsPageApi['credentials'],\n private readonly onFactsChanged: () => void,\n ) {}\n\n credential(ref: string): CredentialInfo | undefined { return this.facts.get(ref) }\n factsRefreshFailed(): boolean { return this.refreshFailed }\n\n /** 在入队时捕获意图与目标;执行者不能重新读取页面草稿。 */\n submit(intent: SettingsWriteIntent): Promise {\n if (this.closed) return Promise.resolve(closedResult())\n const owned = structuredClone(intent)\n const snapshot = this.scope.getSnapshot()\n const ops = owned.kind === 'save' ? [...owned.ops] : []\n if (owned.kind === 'save' && owned.visibleModels !== undefined) {\n const list = [...owned.visibleModels]\n const keys = new Set()\n for (const layer of [snapshot.base, snapshot.user, snapshot.value]) {\n for (const id of Object.keys(readVisibility(record(layer).modelVisibility))) keys.add(id)\n }\n ops.push({ op: 'set', path: ['visibleModels'], value: list },\n { op: 'set', path: ['modelVisibility'], value: Object.fromEntries([...keys].map(id => [id, list.length === 0 || list.includes(id)])) })\n }\n // 自定义上下文长度(issue #86):整表一次写入(含清空后的空表,写在\n // 用户层以遮蔽基础层,而不是 unset 让基础层重新露出)。\n if (owned.kind === 'save' && owned.contextWindowOverrides !== undefined) {\n ops.push({ op: 'set', path: ['contextWindowOverrides'], value: owned.contextWindowOverrides })\n }\n const baseline = new Map(ops.map(op => [op.path[0]!, structuredClone(fieldBaseline(snapshot, op.path[0]!))]))\n const defaultRef = (owned.kind === 'save' && owned.key !== undefined) || (owned.kind === 'key' && owned.target === 'default')\n ? this.defaultRef() : undefined\n return new Promise(resolve => {\n this.pending.push({ command: { intent: owned, ops, baseline, defaultRef }, resolve })\n if (!this.running) void this.drain()\n })\n }\n\n /** 销毁不等待远端;未发出的任务立即结束,已发调用只能自然收束。 */\n dispose(): void {\n this.closed = true\n for (const task of this.pending.splice(0)) task.resolve(closedResult())\n this.facts.clear()\n this.factVersions.clear()\n }\n\n private async drain(): Promise {\n this.running = true\n try {\n for (;;) {\n const task = this.pending.shift()\n if (task === undefined) break\n let outcome: SettingsWriteResult\n try { outcome = this.closed ? closedResult() : await this.execute(task.command) }\n catch { outcome = { ...result(), config: 'unconfirmed' } }\n task.resolve(outcome)\n }\n } finally { this.running = false }\n }\n\n private defaultRef(): string {\n const ref = this.scope.getSnapshot().value?.apiKeyEnv\n return typeof ref === 'string' && ref !== '' ? ref : DEFAULT_API_KEY_REF\n }\n private value(field: string): unknown { return this.scope.getSnapshot().value?.[field] }\n private accounts(): Record[] {\n const raw = this.value('accounts')\n return Array.isArray(raw) ? raw.filter(item => item !== null && typeof item === 'object' && !Array.isArray(item)) as Record[] : []\n }\n private rules(): StoredRule[] {\n const raw = this.value('modelAccountRules')\n if (!Array.isArray(raw)) return []\n return raw.flatMap(item => {\n const rule = record(item)\n const models = Array.isArray(rule.models) ? rule.models.filter((id): id is string => typeof id === 'string' && id !== '') : []\n return models.length ? [{ models, account: typeof rule.account === 'string' && rule.account !== '' ? rule.account : 'default' }] : []\n })\n }\n private cleanupRefs(): string[] {\n const raw = this.value('credentialCleanupRefs')\n return Array.isArray(raw) ? [...new Set(raw.filter((ref): ref is string => typeof ref === 'string' && ref !== ''))] : []\n }\n private bump(ref: string): number {\n const next = (this.factVersions.get(ref) ?? 0) + 1\n this.factVersions.set(ref, next)\n return next\n }\n\n /** 只刷新事实;此入口永远不重放凭据修改。缺少条目不能解释为不存在。 */\n async refreshCredentials(extra: readonly string[] = []): Promise {\n if (this.closed) return false\n const refs = [...new Set([this.defaultRef(), ...this.accounts().flatMap(account => typeof account.apiKeyEnv === 'string' ? [account.apiKeyEnv] : []), ...extra])]\n const generation = ++this.refreshGeneration\n const versions = new Map(refs.map(ref => [ref, this.bump(ref)]))\n let success = false\n try {\n const response = await this.credentials.describe(refs)\n if (this.closed) return false\n success = response.ok && refs.every(ref => typeof response.value?.[ref]?.configured === 'boolean')\n success = success && refs.every(ref => this.factVersions.get(ref) === versions.get(ref))\n if (success) for (const ref of refs) {\n if (this.factVersions.get(ref) !== versions.get(ref)) continue\n const view = response.value![ref]!\n this.facts.set(ref, { configured: view.configured, writable: view.writable ?? true })\n }\n } catch { /* 未读到新事实时保留最后已确认结果,不猜测不存在。 */ }\n if (!this.closed && generation === this.refreshGeneration) {\n this.refreshFailed = !success\n this.onFactsChanged()\n }\n return success\n }\n\n private async commit(ops: readonly SettingsPathOp[], baseline?: ReadonlyMap): Promise {\n if (this.closed) return 'cancelled'\n const snapshot = this.scope.getSnapshot()\n if (!snapshot.writable || this.scope.mutate === undefined) return 'failed'\n if (baseline && [...baseline].some(([field, before]) => !sameValue(before, fieldBaseline(snapshot, field)))) return 'conflict'\n try { return await this.scope.mutate(ops, snapshot.revision) }\n catch { return 'failed' }\n }\n\n private async configure(outcome: SettingsWriteResult, ops: readonly SettingsPathOp[], baseline?: ReadonlyMap): Promise {\n if (ops.length === 0) return true\n const confirmation = await this.commit(ops, baseline)\n outcome.config = confirmation === 'accepted' ? 'confirmed' : confirmation === 'conflict' ? 'conflict' : 'unconfirmed'\n if (confirmation === 'cancelled' || this.closed) outcome.issue = 'closed'\n return confirmation === 'accepted' && !this.closed\n }\n\n private async changeCredential(outcome: SettingsWriteResult, ref: string, value: string | undefined, defaultRef?: string): Promise {\n outcome.credential = 'not-issued'\n if (this.closed) { outcome.issue = 'closed'; return }\n if (defaultRef !== undefined && this.defaultRef() !== defaultRef) { outcome.issue = 'target-changed'; return }\n outcome.credentialRef = ref\n this.bump(ref)\n try {\n const response = value === undefined ? await this.credentials.unset(ref) : await this.credentials.set(ref, value)\n outcome.credential = response.ok ? 'confirmed' : 'unconfirmed'\n } catch { outcome.credential = 'unconfirmed' }\n if (this.closed) { outcome.issue = 'closed'; return }\n this.bump(ref)\n // 远端写入确认说明引用已修改;后续读回不提供密钥内容校验。\n if (outcome.credential === 'confirmed') {\n this.facts.set(ref, { configured: value !== undefined, writable: this.facts.get(ref)?.writable ?? true })\n this.onFactsChanged()\n }\n if (defaultRef !== undefined && this.defaultRef() !== defaultRef) outcome.issue = 'target-changed'\n outcome.refreshFailed = !(await this.refreshCredentials([ref]))\n if (defaultRef !== undefined && this.defaultRef() !== defaultRef) outcome.issue = 'target-changed'\n if (this.closed) outcome.issue = 'closed'\n }\n\n private async execute(command: Command): Promise {\n const outcome = result()\n const intent = command.intent\n if (!this.scope.getSnapshot().writable) return {\n ...outcome,\n config: intent.kind === 'key' || (intent.kind === 'save' && command.ops.length === 0) ? 'none' : 'unconfirmed',\n credential: intent.kind === 'key' || (intent.kind === 'save' && intent.key !== undefined) ? 'not-issued' : 'none',\n }\n if (intent.kind === 'save') {\n if (intent.key !== undefined) outcome.credential = 'not-issued'\n if (!(await this.configure(outcome, command.ops, command.baseline))) return outcome\n if (intent.key !== undefined) await this.changeCredential(outcome, command.defaultRef!, intent.key, command.defaultRef)\n } else if (intent.kind === 'key') {\n if (intent.value !== undefined && intent.value.trim() === '') return { ...outcome, credential: 'not-issued' }\n await this.changeCredential(outcome, command.defaultRef ?? intent.target, intent.value, command.defaultRef)\n } else if (intent.kind === 'rename') {\n if (intent.label === '') return { ...outcome, config: 'unconfirmed' }\n await this.configure(outcome, [{ op: 'set', path: ['accounts'], value: this.accounts().map(account => account.apiKeyEnv === intent.ref ? { ...account, label: intent.label } : { ...account }) }])\n } else if (intent.kind === 'active') {\n // 恢复自动轮换与恢复继承不同;基础层有固定账号时必须显式覆盖为空。\n const base = record(this.scope.getSnapshot().base).activeAccount\n const op: SettingsPathOp = intent.id !== '' || (typeof base === 'string' && base !== '')\n ? { op: 'set', path: ['activeAccount'], value: intent.id } : { op: 'unset', path: ['activeAccount'] }\n await this.configure(outcome, [op])\n } else if (intent.kind === 'models') {\n const chosen = [...new Set(intent.models.filter(id => id !== ''))]\n const taken = new Set(chosen)\n const map = accountModelMap(this.rules())\n for (const [account, models] of map) if (account !== intent.target) map.set(account, models.filter(id => !taken.has(id)))\n map.set(intent.target, chosen)\n const rules = [...map].flatMap(([account, models]) => models.length ? [{ account, models }] : [])\n await this.configure(outcome, [{ op: 'set', path: ['modelAccountRules'], value: rules }])\n } else {\n if (intent.kind === 'remove') {\n if (!this.accounts().some(account => account.apiKeyEnv === intent.ref) && !this.cleanupRefs().includes(intent.ref)) return { ...outcome, config: 'unconfirmed' }\n const snapshot = this.scope.getSnapshot()\n const ops: SettingsPathOp[] = [\n { op: 'set', path: ['accounts'], value: this.accounts().filter(account => account.apiKeyEnv !== intent.ref).map(account => ({ ...account })) },\n { op: 'set', path: ['modelAccountRules'], value: this.rules().filter(rule => rule.account !== intent.ref) },\n { op: 'set', path: ['credentialCleanupRefs'], value: [...new Set([...this.cleanupRefs(), intent.ref])] },\n ]\n if (this.value('activeAccount') === intent.ref) ops.push(record(snapshot.base).activeAccount === intent.ref\n ? { op: 'set', path: ['activeAccount'], value: '' } : { op: 'unset', path: ['activeAccount'] })\n if (!(await this.configure(outcome, ops))) return outcome\n }\n await this.cleanRemoved(outcome, intent.ref)\n }\n return outcome\n }\n\n private async cleanRemoved(outcome: SettingsWriteResult, ref: string): Promise {\n if (!this.cleanupRefs().includes(ref)) {\n if (outcome.config !== 'confirmed') outcome.config = 'unconfirmed'\n outcome.issue = 'cleanup-pending'\n return\n }\n if (this.closed) { outcome.issue = 'closed'; return }\n if (!(await this.refreshCredentials([ref]))) { outcome.credential = 'not-issued'; outcome.refreshFailed = true; return }\n if (this.closed) { outcome.issue = 'closed'; return }\n const inherited = record(this.scope.getSnapshot().base).accounts\n const referenced = ref === this.defaultRef() || this.accounts().some(account => account.apiKeyEnv === ref)\n || (Array.isArray(inherited) && inherited.some(account => record(account).apiKeyEnv === ref))\n || this.rules().some(rule => rule.account === ref) || this.value('activeAccount') === ref\n if (!referenced && this.facts.get(ref)?.configured === true) {\n await this.changeCredential(outcome, ref, undefined)\n if (!writeCompleted(outcome) || outcome.refreshFailed) {\n if (outcome.issue === undefined && outcome.credential === 'confirmed') outcome.issue = 'cleanup-pending'\n return\n }\n }\n if (this.closed) { outcome.issue = 'closed'; return }\n // 最后一步失败不能抹掉前面已经确认的账号移除/凭据清理事实。\n const cleanup = result()\n if (!(await this.configure(cleanup, [{ op: 'set', path: ['credentialCleanupRefs'], value: this.cleanupRefs().filter(entry => entry !== ref) }]))) {\n if (outcome.config === 'none') outcome.config = cleanup.config\n outcome.issue = cleanup.issue ?? 'cleanup-pending'\n } else if (outcome.config === 'none') outcome.config = cleanup.config\n }\n}\n","/** 设置页面控制器只负责输入校验、草稿版本与页面投影。\n * 保存及即时账号操作由同一个设置写入过程持有;设置与凭据分别确认。 */\n\nimport { MIN_TIMEOUT_SECONDS, MAX_TIMEOUT_SECONDS } from '../timeout-limits.ts'\nimport { modelIsVisible, readVisibility } from '../model-visibility.ts'\nimport { CONTEXT_WINDOW_MAX, CONTEXT_WINDOW_MIN, isValidContextWindow, readContextWindowOverrides } from '../context-window.ts'\nimport { MAX_OUTPUT_TOKEN_LIMIT, OMIT_OUTPUT_TOKENS, isValidMaxOutputTokens } from '../output-budget.ts'\nimport type { SettingsMutationResult, SettingsPathOp } from './settings-scope.ts'\nimport { SettingsWriter, DEFAULT_API_KEY_REF, accountModelMap, writeCompleted, type StoredRule, type SettingsWriteIntent, type SettingsWriteResult } from './settings-write.ts'\nexport { DEFAULT_API_KEY_REF, accountModelMap } from './settings-write.ts'\n\n/** The settings namespace the plugin registers (host half, src/index.ts). */\nexport const COMMANDCODE_NS = 'llm-commandcode'\n\n/** The settings-scope snapshot fields consumed by this controller. */\nexport interface SettingsScopeSnapshot {\n status: 'loading' | 'ready' | 'unavailable'\n value: T | undefined\n base: unknown\n user: unknown\n revision: number | undefined\n writable: boolean\n mode: 'host'\n}\n\n/** Current settings-scope service face used without importing a browser plugin value. */\nexport interface SettingsScope {\n getSnapshot(): SettingsScopeSnapshot\n subscribe(listener: () => void): () => void\n set(field: string, value: unknown): Promise\n unset(field: string): Promise\n /** 多字段共用一次宿主版本检查并返回确认;缺少此能力不能提交配置。 */\n mutate?(ops: readonly SettingsPathOp[], expectedRevision?: number): Promise\n}\n\n/** Result envelope returned by one current Typert Remote call. */\ninterface RemoteResult {\n ok: boolean\n value?: T\n error?: { message: string }\n}\n\n/** Credential facts returned without exposing the credential value. */\ninterface CredentialInfo {\n configured: boolean\n writable: boolean\n}\n\n/** The narrow slice of the wire face this controller needs. */\nexport interface SettingsPageApi {\n /** Credential methods exposed by the current Typert Remote namespace. */\n credentials: {\n describe(refs: string[]): Promise>>\n set(ref: string, value: string): Promise>\n unset(ref: string): Promise>\n }\n /**\n * The model catalog for the model editors (Host-side). Optional: a transport\n * without the Remote mount leaves the editors on the empty-catalog state.\n */\n models?(): Promise>\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 /** `format`, `tooSmall`/`tooLarge`; undefined when valid. */\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/**\n * One per-model context-length override row (issue #86): the model's id with\n * the staged token text its input shows. Blank text means \"no override once\n * saved\" (the row drops out); an unparseable draft blocks save.\n */\nexport interface ContextOverrideRow {\n /** Catalog model id; one override per model. */\n model: string\n /** Live draft text the input shows. */\n text: string\n /** Whether the staged draft fails to parse (blocks save). */\n invalid: boolean\n /** `format`, `tooSmall`/`tooLarge`; undefined when valid. */\n invalidReason: InvalidReason | undefined\n}\n\n/**\n * One extra account row. Account management commits immediately (no page\n * save), so a row carries only Host facts — never a staged draft.\n */\nexport interface AccountItemState {\n /** Stable id — the account's credential reference (also its slot id). */\n id: string\n ref: string\n /** Stored label (falls back to the reference). */\n label: string\n configured: boolean\n credentialKnown: boolean\n writable: boolean\n}\n\n/** The immediate account operations, named for the failure copy. */\nexport type AccountOperation = 'rename' | 'remove' | 'key' | 'active' | 'models'\n\n/** One selectable catalog model in the settings page's model editors. */\nexport interface CatalogModelOption {\n id: string\n name: string\n /**\n * Minimum plan-tier key (a Host `KNOWN_PLANS` value), or undefined for\n * models outside the snapshot / older Hosts. Drives the tier headings in\n * the editor dropdowns; absent tiers render unheaded.\n */\n tier?: string\n /**\n * Per-model MONTHLY allowance in USD, already resolved Host-side against the\n * account pool's highest plan (Go, GOAT and Pro publish one). Undefined for\n * plans without an allowance, for models the page has no row for, and for\n * older Hosts — the row then shows no allowance instead of a guess.\n */\n allowance?: number\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 /** 没有描述或写入确认时状态未知,不能显示为未配置。 */\n apiKeyKnown: 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 /**\n * The default API key draft (write-only; starts blank, never echoes the\n * stored key). Only the Models-page card stages it for its own save; the\n * settings page writes keys immediately through `setAccountKey()`.\n */\n apiKey: StagedField\n apiBase: StagedField\n requestTimeoutMs: StagedField\n streamIdleTimeoutMs: StagedField\n /**\n * transportMaxRetries draft: how many transport failures one request absorbs\n * before the failure surfaces (issue #39's second report — the retry policy's\n * 1000-attempt, 15-minute cadence turned a 10-second TCP connect timeout into\n * an ~8-minute stall). Unset means the Host default, so it stages like the\n * timeout fields above rather than as a toggle with an implicit default.\n */\n transportMaxRetries: StagedField\n /** Opt-in durable offload of images after this model has answered. */\n offloadSeenImagesForCache: StagedField\n /** filterModelsByPlan draft; `''` = \"inherit the default\" (on). */\n filterModelsByPlan: StagedField\n /** webSearch draft; `''` = \"inherit the default\" (on — this route serves dsh's web_search). */\n webSearch: StagedField\n /** showSidebarQuota draft; `''` = \"inherit the default\" (off — the card is opt-in). */\n showSidebarQuota: StagedField\n /** zdr draft; `''` = \"inherit the default\" (off — ZDR is opt-in). */\n zdr: StagedField\n /**\n * Whether the STORED document turns the sidebar quota card on\n * (`showSidebarQuota === true`). Deliberately NOT the staged draft above: the\n * page has an explicit Save, and a card that appeared from an unsaved draft\n * would outlive a discarded edit (staging lives as long as the client does)\n * until the next page load.\n */\n sidebarQuota: boolean\n /** The stored pinned account: a slot id; `''` = \"auto — first usable account\". */\n activeAccount: string\n /** Extra accounts (multi-account rotation), in rotation order. */\n accounts: AccountItemState[]\n /**\n * Each account's dedicated models, keyed by slot id, derived from the stored\n * `modelAccountRules` with the runtime's first-match-wins semantics, so a\n * model sits under exactly the one account that would serve it.\n */\n accountModels: Record\n /** Whether an immediate account operation is in flight. */\n accountBusy: boolean\n /** The last immediate account operation that failed (cleared by the next one). */\n accountFailed: AccountOperation | undefined\n /** 已移除账户的待清理凭据引用,来自持久化配置,刷新后仍能重试。 */\n pendingCredentialCleanup: string[]\n /** 宿主开通尚未完成的引用,不展示可操作的账号行。 */\n accountEnrollmentRefs: string[]\n /** Effective visible-model allowlist: staged draft or stored value. Empty = show all. */\n visibleModels: string[]\n /** 区分不受限制与终端显式隐藏全部;不能用空数组推断显示全部。 */\n visibleModelsAll: boolean\n /** Global custom context-length draft; `''` = follow the catalog (issue #86). */\n contextWindow: StagedField\n /** Single-turn output budget draft; `''` = the derived default, `0` = omit the field (issue #74). */\n maxOutputTokens: StagedField\n /** Per-model context-length rows: staged draft or stored values, one per model. */\n contextWindowOverrides: ContextOverrideRow[]\n /** The catalog the model editors offer (Host-side, empty until loaded). */\n catalogModels: CatalogModelOption[]\n /** Whether the catalog fetch failed (editors fall back to typing). */\n catalogFailed: boolean\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 /** Monotonic counter bumped once per accepted save (the component flashes on it). */\n savedCount: number\n /** 本次写入各阶段的确认事实,不用整体失败推断回滚。 */\n saveResult: SettingsWriteResult | undefined\n accountResult: SettingsWriteResult | undefined\n credentialRefreshFailed: boolean\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, like the Host schema's `z.number()`.\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 * The compact token-count shorthand (`32K`, `1M`) in BINARY units, the way\n * context windows are quoted: 32K → 32 768 (32 × 1024), 128K → 131 072,\n * 1M → 1 048 576 (1024 × 1024), so the common power-of-two windows land on\n * their exact values instead of 1000-based rounding. A leading sign is not part\n * of the grammar, so this path can only produce values ≥ 0.\n */\nconst COMPACT_TOKENS = /^(\\d+(?:\\.\\d+)?)\\s*([kKmM])$/\n\n/**\n * A whole-token count field with optional compact shorthand, shared by the\n * context-length and output-budget inputs (issues #86, #74).\n *\n * Plain text goes through the {@link numberField} parse plus the caller's\n * whole-token validator; shorthand converts to whole tokens first\n * (`Math.round` keeps fractional shorthand like `1.5K` on whole tokens) and is\n * then bounds-checked against the SAME `bounds`, so an overshoot names\n * `tooLarge` here instead of reaching the Host schema, which would reject it at\n * save time with only a generic failure. Empty clears in both paths.\n *\n * `isValid` is what tells the two apart: context lengths start at 1, while the\n * output budget's lower bound IS its omit sentinel (`0` means \"send no\n * `max_tokens`\"), so no single numeric range can serve both.\n */\nfunction tokenCountField(\n field: string,\n bounds: { min: number; max: number },\n isValid: (value: unknown) => boolean,\n): FieldSpec {\n const plain = numberField(field, bounds)\n return {\n field,\n format: plain.format,\n parse: (text) => {\n const compact = COMPACT_TOKENS.exec(text.trim())\n if (compact === null) {\n const parsed = plain.parse(text)\n // 时长字段允许小数,词元计数则必须是整数;不能直接沿用通用数字字段的放行结果。\n return parsed.kind === 'set' && !isValid(parsed.value)\n ? { kind: 'invalid', reason: 'format' }\n : parsed\n }\n const value = Math.round(Number(compact[1]) * (compact[2]!.toLowerCase() === 'k' ? 1024 : 1024 * 1024))\n if (value < bounds.min) return { kind: 'invalid', reason: 'tooSmall' }\n if (value > bounds.max) return { kind: 'invalid', reason: 'tooLarge' }\n // No whole-token re-check here: the grammar cannot produce a negative or a\n // fraction, and `bounds.max` already caps the value, so a validator that\n // only tests integrality-plus-range is settled by the two checks above.\n return { kind: 'set', value }\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 * The single-turn output budget (issue #74).\n *\n * The range INCLUDES `0`, and `0` is not a budget: it is the sentinel asking\n * the adapter to send no `max_tokens` field at all, leaving the per-turn output\n * size to the platform. The upper bound is the gateway's own cap\n * ({@link MAX_OUTPUT_TOKEN_LIMIT}) rather than an arbitrary one — a larger\n * figure would simply be refused, so the input is where that is worth saying. A\n * blank draft clears the setting back to the derived default, which is the\n * behaviour every existing profile has.\n */\nfunction maxOutputTokensField(field: string): FieldSpec {\n return tokenCountField(\n field,\n { min: OMIT_OUTPUT_TOKENS, max: MAX_OUTPUT_TOKEN_LIMIT },\n isValidMaxOutputTokens,\n )\n}\n\n/**\n * The second-based bounds the timeout fields are EDITED in.\n *\n * The stored unit stays milliseconds — that is the Host schema\n * (`z.number().min(1).max(MAX_TIMER_DELAY_MS)` in src/index.ts, dsh-timeout's\n * 2^31-1 timer ceiling), and switching it would break every existing profile —\n * so this is presentation only: the field formats ms ÷ 1000 on the way in and\n * multiplies by 1000 on the way out. 3600 rather than the Host's ceiling (~24.8\n * days), because a header wait longer than an hour is a hung process, not a\n * budget, and the input is the place to refuse it. A hand-written profile can\n * still carry a larger value; `secondsField` displays that true number rather\n * than silently clamping, it just cannot be re-typed here.\n */\nexport { MIN_TIMEOUT_SECONDS, MAX_TIMEOUT_SECONDS } from '../timeout-limits.ts'\n\n/**\n * 秒制输入保留毫秒精度,兼容已有 1500ms、1ms 等配置。\n *\n * Milliseconds are the wrong unit to show: the defaults are 300000 and the\n * ceiling is 2147483647, so the page asked users to do arithmetic to answer\n * \"how long is a reasonable wait\". `format` divides, `parse` multiplies, and\n * the stored value never leaves milliseconds.\n *\n * 最多三位小数;不接受更多位数后悄悄取整,避免页面与存储不一致。\n */\nfunction secondsField(field: string, bounds: { min: number; max: number }): FieldSpec {\n return {\n field,\n format: (value) => (typeof value === 'number' ? String(value / 1000) : ''),\n parse: (text) => {\n const trimmed = text.trim()\n if (trimmed === '') return { kind: 'clear' }\n const parsed = Number(trimmed)\n if (!Number.isFinite(parsed) || !/^-?(?:\\d+(?:\\.\\d{1,3})?|\\.\\d{1,3})$/.test(trimmed)) return { kind: 'invalid', reason: 'format' }\n if (parsed < bounds.min) return { kind: 'invalid', reason: 'tooSmall' }\n if (parsed > bounds.max) return { kind: 'invalid', reason: 'tooLarge' }\n return { kind: 'set', value: Math.round(parsed * 1000) }\n },\n }\n}\n\n/** The fields this page edits inside the `llm-commandcode` namespace. */\nconst SECTION_FIELDS: FieldSpec[] = [\n textField('apiBase'),\n secondsField('requestTimeoutMs', { min: MIN_TIMEOUT_SECONDS, max: MAX_TIMEOUT_SECONDS }),\n secondsField('streamIdleTimeoutMs', { min: MIN_TIMEOUT_SECONDS, max: MAX_TIMEOUT_SECONDS }),\n // A COUNT of retries, not a millisecond wait: it shares the Host schema's\n // 0..50 bounds (`MAX_TRANSPORT_MAX_RETRIES` in src/transport-retry.ts, applied\n // to `transportMaxRetries` in src/index.ts) rather than the timer ceiling\n // above, so a draft can never be saved in a shape the Host rejects. The Host\n // stays the final gate, and the client bundle cannot import that node-side\n // module — `tests/transport-retry.test.ts` pins the schema's bound against\n // the constant so this mirrored literal cannot drift unnoticed.\n numberField('transportMaxRetries', { min: 0, max: 50 }),\n // 自定义上下文长度(issue #86):直接复用 Host schema 的同一对边界常量\n // (context-window.ts 是纯模块,客户端可打包导入),不像 transportMaxRetries\n // 那样需要镜像字面量加测试钉住。输入侧额外接受 256K/1M 简写,落盘仍是数字。\n tokenCountField('contextWindow', { min: CONTEXT_WINDOW_MIN, max: CONTEXT_WINDOW_MAX }, isValidContextWindow),\n // 输出预算(issue #74):0 是「不发送 max_tokens」的省略哨兵,因此上界用\n // 网关自己的总上限,而不是套用上下文窗口的范围。\n maxOutputTokensField('maxOutputTokens'),\n booleanField('offloadSeenImagesForCache'),\n booleanField('filterModelsByPlan'),\n booleanField('webSearch'),\n booleanField('showSidebarQuota'),\n booleanField('zdr'),\n]\n\n/** Whether two model-id lists are equal as sets (order-insensitive). */\nfunction sameModels(a: readonly string[], b: readonly string[]): boolean {\n if (a.length !== b.length) return false\n const set = new Set(a)\n return b.every((id) => set.has(id))\n}\n\n/** 共享控制器跨普通切页保存草稿,插件销毁才关闭写入过程。 */\nexport class CommandCodeSettingsController {\n private readonly scope: SettingsScope>\n private readonly api: SettingsPageApi\n private readonly specs = new Map(SECTION_FIELDS.map((spec) => [spec.field, spec]))\n private readonly staged = new Map()\n private readonly listeners = new Set<() => void>()\n private readonly disposers: Array<() => void> = []\n private disposed = false\n private credentialRef = DEFAULT_API_KEY_REF\n private readonly writer: SettingsWriter\n private saveResult: SettingsWriteResult | undefined\n private accountResult: SettingsWriteResult | undefined\n /** Staged visible-model allowlist (undefined = no draft). */\n private visibleModelsDraft: string[] | undefined = undefined\n /** Staged per-model context-length overrides as raw text (undefined = no draft, issue #86). */\n private contextWindowOverridesDraft: Record | undefined = undefined\n private catalogModels: CatalogModelOption[] = []\n private catalogFailed = false\n private saving = false\n private failed = false\n private savedCount = 0\n private accountPending = 0\n private accountFailed: AccountOperation | undefined = undefined\n\n constructor(\n scope: SettingsScope>,\n api: SettingsPageApi,\n ) {\n this.scope = scope\n this.api = api\n this.writer = new SettingsWriter(scope, api.credentials, () => this.publish())\n this.disposers.push(scope.subscribe(() => {\n this.recomputeCredentialRef()\n void this.writer.refreshCredentials()\n this.publish()\n }))\n this.recomputeCredentialRef()\n void this.writer.refreshCredentials()\n this.refreshCatalog()\n }\n\n /** Release every subscription held on external sources. Idempotent. */\n dispose(): void {\n if (this.disposed) return\n this.disposed = true\n this.writer.dispose()\n this.staged.clear()\n this.visibleModelsDraft = undefined\n this.contextWindowOverridesDraft = undefined\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 the profile Config gets a page that\n * addresses the renamed ref instead of silently writing the default —\n * 与模型卡共享同一设置引用。\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 }\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.writer.credential(this.credentialRef)\n const accounts = this.effectiveAccounts()\n const active = this.sectionValue('activeAccount')\n return {\n available: snapshot.status === 'ready',\n writable: snapshot.writable,\n apiKeyConfigured: credential?.configured ?? false,\n apiKeyKnown: credential !== undefined,\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 requestTimeoutMs: this.field('requestTimeoutMs'),\n streamIdleTimeoutMs: this.field('streamIdleTimeoutMs'),\n transportMaxRetries: this.field('transportMaxRetries'),\n offloadSeenImagesForCache: this.field('offloadSeenImagesForCache'),\n filterModelsByPlan: this.field('filterModelsByPlan'),\n webSearch: this.field('webSearch'),\n showSidebarQuota: this.field('showSidebarQuota'),\n zdr: this.field('zdr'),\n sidebarQuota: this.sectionValue('showSidebarQuota') === true,\n activeAccount: typeof active === 'string' ? active : '',\n accounts,\n accountModels: Object.fromEntries(accountModelMap(this.storedRules())),\n accountBusy: this.accountPending > 0,\n accountFailed: this.accountFailed,\n pendingCredentialCleanup: this.cleanupRefs().filter((ref) => !this.enrollmentRefs(true).includes(ref)),\n accountEnrollmentRefs: this.enrollmentRefs(false),\n visibleModels: this.effectiveVisibleModels(),\n visibleModelsAll: this.visibleModelsDraft === undefined ? this.storedShowsAll() : this.visibleModelsDraft.length === 0,\n contextWindow: this.field('contextWindow'),\n maxOutputTokens: this.field('maxOutputTokens'),\n contextWindowOverrides: this.effectiveContextWindowOverrides(),\n catalogModels: this.catalogModels,\n catalogFailed: this.catalogFailed,\n dirty: plan.length > 0 || this.visibleModelsDirty() || this.contextWindowOverridesDirty(),\n invalid: plan.some((item) => item.change === undefined)\n || this.effectiveContextWindowOverrides().some((row) => row.invalid),\n saving: this.saving,\n failed: this.failed,\n savedCount: this.savedCount,\n saveResult: this.saveResult,\n accountResult: this.accountResult,\n credentialRefreshFailed: this.writer.factsRefreshFailed(),\n }\n }\n\n // --- Staged form ---\n\n private enrollmentRefs(includeNamed: boolean): string[] {\n const records = this.sectionValue('accountEnrollmentTasks')\n if (!Array.isArray(records)) return []\n return records.flatMap((item: unknown) => {\n if (typeof item !== 'object' || item === null) return []\n const record = item as Record\n return typeof record.ref === 'string' && (includeNamed || record.phase !== 'naming') ? [record.ref] : []\n })\n }\n\n /** Stage one field's draft text. */\n edit(field: string, text: string): void {\n if (field !== 'apiKey') this.spec(field)\n this.staged.set(field, { text, clear: false })\n this.failed = false\n this.saveResult = undefined\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.saveResult = undefined\n this.publish()\n }\n\n /** Discard every staged edit. */\n discard(): void {\n if (this.staged.size === 0 && this.visibleModelsDraft === undefined\n && this.contextWindowOverridesDraft === undefined && !this.failed) return\n this.staged.clear()\n this.visibleModelsDraft = undefined\n this.contextWindowOverridesDraft = undefined\n this.failed = false\n this.saveResult = undefined\n this.publish()\n }\n\n /**\n * Re-read the Host's credential facts without any staged edit. The browser\n * login stores a key Host-side behind the page's back; the plugin entry\n * calls this when a login lands so the configured/writable badges follow.\n */\n async refreshCredentials(): Promise {\n if (!(await this.writer.refreshCredentials()) || this.disposed) return\n if (this.saveResult) this.saveResult = { ...this.saveResult, refreshFailed: false }\n if (this.accountResult) this.accountResult = { ...this.accountResult, refreshFailed: false }\n this.publish()\n }\n\n /** 冻结点击时的草稿;只清理本次已确认且期间未被替换的对象。 */\n async save(): Promise {\n if (this.disposed || this.saving) return\n const submitted = new Map(this.staged)\n const submittedVisible = this.visibleModelsDraft\n const submittedContextOverrides = this.contextWindowOverridesDraft\n const plan = this.plan()\n const visibleDirty = this.visibleModelsDirty()\n const contextOverrides = this.parsedContextWindowOverrides()\n const contextOverridesDirty = this.contextWindowOverridesDirty()\n // 一个无法解析的按模型覆盖行与越界的普通字段一样整体阻止本次保存,\n // 而不是把其余字段写下去、留下这行草稿。\n if ((plan.length === 0 && !visibleDirty && !contextOverridesDirty)\n || plan.some(item => item.change === undefined) || contextOverrides.invalid) return\n const ops = plan.flatMap(item => typeof item.change === 'object' ? [item.change] : [])\n const key = plan.find(item => item.field === 'apiKey')?.change\n this.saving = true\n this.failed = false\n this.saveResult = undefined\n // 入队先于通知订阅者,避免通知回调发起的后续操作插队。\n const completion = this.writer.submit({ kind: 'save', ops,\n ...(visibleDirty ? { visibleModels: submittedVisible ?? [] } : {}),\n ...(contextOverridesDirty ? { contextWindowOverrides: contextOverrides.values } : {}),\n ...(typeof key === 'string' ? { key } : {}),\n })\n this.publish()\n const outcome = await completion\n if (this.disposed) return outcome\n this.saving = false\n this.saveResult = outcome\n this.failed = !writeCompleted(outcome)\n if (!this.failed) this.savedCount += 1\n for (const [field, draft] of submitted) {\n const confirmed = field === 'apiKey'\n ? outcome.credential === 'confirmed' && outcome.issue === undefined\n : outcome.config === 'confirmed' || writeCompleted(outcome)\n if (confirmed && this.staged.get(field) === draft) this.staged.delete(field)\n }\n if ((outcome.config === 'confirmed' || writeCompleted(outcome)) && this.visibleModelsDraft === submittedVisible) this.visibleModelsDraft = undefined\n if ((outcome.config === 'confirmed' || writeCompleted(outcome)) && this.contextWindowOverridesDraft === submittedContextOverrides) this.contextWindowOverridesDraft = undefined\n this.publish()\n return outcome\n }\n\n /** Stage the visible-model allowlist (multi-select). */\n editVisibleModels(models: string[]): void {\n this.visibleModelsDraft = [...models]\n this.failed = false\n this.saveResult = undefined\n this.publish()\n }\n\n /** Stage \"show all models\" (clears the allowlist). */\n clearVisibleModels(): void {\n this.visibleModelsDraft = []\n this.failed = false\n this.saveResult = undefined\n this.publish()\n }\n\n /**\n * Stage the whole per-model context-length map (issue #86): one entry per\n * row, the value the row's input shows verbatim (blank = drop the override\n * on save). The component rebuilds the map from its projected rows, so a\n * model reselect moves the value to its new key in the same edit.\n */\n editContextWindowOverrides(next: Record): void {\n this.contextWindowOverridesDraft = { ...next }\n this.failed = false\n this.saveResult = undefined\n this.publish()\n }\n\n /** The stored per-model overrides, already cleaned by the shared validity rule. */\n private storedContextWindowOverrides(): Record {\n return { ...readContextWindowOverrides(this.sectionValue('contextWindowOverrides')) }\n }\n\n /** Effective rows: the staged draft verbatim, or the stored values formatted. */\n private effectiveContextWindowOverrides(): ContextOverrideRow[] {\n const draft = this.contextWindowOverridesDraft\n const source: Record = draft !== undefined\n ? draft\n : Object.fromEntries(Object.entries(this.storedContextWindowOverrides()).map(([model, value]) => [model, String(value)]))\n return Object.entries(source)\n .filter(([model]) => model !== '')\n .map(([model, text]) => {\n const parsed = this.spec('contextWindow').parse(text)\n return {\n model,\n text,\n invalid: parsed.kind === 'invalid',\n invalidReason: parsed.kind === 'invalid' ? parsed.reason : undefined,\n }\n })\n }\n\n /**\n * The draft parsed for the write: blank rows and unparseable rows drop out\n * (an invalid row blocks save on its own), everything else is the value the\n * writer puts at `contextWindowOverrides`.\n */\n private parsedContextWindowOverrides(): { values: Record; invalid: boolean } {\n const values: Record = {}\n let invalid = false\n for (const row of this.effectiveContextWindowOverrides()) {\n if (row.invalid) {\n invalid = true\n continue\n }\n const parsed = this.spec('contextWindow').parse(row.text)\n if (parsed.kind === 'set' && typeof parsed.value === 'number') values[row.model] = parsed.value\n }\n return { values, invalid }\n }\n\n private contextWindowOverridesDirty(): boolean {\n if (this.contextWindowOverridesDraft === undefined) return false\n const values = this.parsedContextWindowOverrides().values\n const stored = this.storedContextWindowOverrides()\n const keys = new Set([...Object.keys(values), ...Object.keys(stored)])\n return [...keys].some((model) => values[model] !== stored[model])\n }\n\n // --- Immediate account management ---\n\n renameAccount(ref: string, label: string): Promise {\n return this.runAccountOp('rename', { kind: 'rename', ref, label: label.trim() })\n }\n\n /** 配置移除确认后才清理凭据,失败记录留在宿主清理队列。 */\n removeAccount(ref: string): Promise {\n return this.runAccountOp('remove', { kind: 'remove', ref })\n }\n\n retryCredentialCleanup(ref: string): Promise {\n return this.runAccountOp('remove', { kind: 'cleanup', ref })\n }\n\n private cleanupRefs(): string[] {\n const raw = this.sectionValue('credentialCleanupRefs')\n return Array.isArray(raw) ? [...new Set(raw.filter((ref): ref is string => typeof ref === 'string' && ref !== ''))] : []\n }\n\n setAccountKey(target: string, key: string): Promise {\n return this.runAccountOp('key', { kind: 'key', target, value: key.trim() })\n }\n\n clearAccountKey(target: string): Promise {\n return this.runAccountOp('key', { kind: 'key', target })\n }\n\n setActiveAccount(id: string): Promise {\n return this.runAccountOp('active', { kind: 'active', id })\n }\n\n setAccountModels(target: string, models: readonly string[]): Promise {\n return this.runAccountOp('models', { kind: 'models', target, models })\n }\n\n /** 即时入口与保存共享写入过程,只在这里维护页面忙碌投影。 */\n private async runAccountOp(op: AccountOperation, intent: SettingsWriteIntent): Promise {\n this.accountPending += 1\n this.accountFailed = undefined\n this.accountResult = undefined\n const completion = this.writer.submit(intent)\n this.publish()\n const outcome = await completion\n this.accountPending -= 1\n if (this.disposed) return false\n const ok = writeCompleted(outcome)\n this.accountResult = outcome\n this.accountFailed = ok ? undefined : op\n this.publish()\n return ok\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)[field]\n : undefined\n }\n\n private userLayer(): Record | undefined {\n const user = this.scope.getSnapshot().user\n return typeof user === 'object' && user !== null && !Array.isArray(user)\n ? (user as Record)\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 private plan(): Array<{ field: string; change: SettingsPathOp | string | undefined }> {\n const plan: Array<{ field: string; change: SettingsPathOp | string | undefined }> = []\n for (const [field, staged] of this.staged) {\n if (field === 'apiKey') {\n const value = staged.text.trim()\n if (value !== '') plan.push({ field, change: value })\n continue\n }\n const spec = this.spec(field)\n if (staged.clear) {\n if (this.stored(field)) plan.push({ field, change: { op: 'unset', path: [field] } })\n continue\n }\n if (staged.text === spec.format(this.sectionValue(field))) continue\n const parsed = spec.parse(staged.text)\n const change: SettingsPathOp | undefined = parsed.kind === 'invalid' ? undefined\n : parsed.kind === 'clear' ? { op: 'unset', path: [field] } : { op: 'set', path: [field], value: parsed.value }\n plan.push({ field, change })\n }\n return plan\n }\n\n /**\n * Fetch the model catalog through the Host Remote. Runs once at construction;\n * call again (e.g. from the client entry once the Remote mount lands) to\n * (re)try — a later success clears a prior failure flag, so the editors\n * recover without a page reload.\n */\n refreshCatalog(): void {\n const models = this.api.models\n if (models === undefined) {\n this.catalogFailed = true\n this.publish()\n return\n }\n void models().then((response) => {\n if (response.ok && Array.isArray(response.value?.models)) {\n // Defensive per-entry shaping: the Remote result is untrusted at the\n // boundary, and an older Host predates the tier field.\n const shaped: CatalogModelOption[] = []\n for (const model of response.value.models) {\n if (typeof model !== 'object' || model === null) continue\n const entry = model as unknown as Record\n if (typeof entry.id !== 'string' || typeof entry.name !== 'string') continue\n shaped.push({\n id: entry.id,\n name: entry.name,\n ...(typeof entry.tier === 'string' ? { tier: entry.tier } : {}),\n ...(typeof entry.allowance === 'number' && Number.isFinite(entry.allowance)\n ? { allowance: entry.allowance }\n : {}),\n })\n }\n this.catalogModels = shaped\n this.catalogFailed = false\n } else {\n this.catalogFailed = true\n }\n }, () => {\n this.catalogFailed = true\n }).then(() => this.publish())\n }\n\n // --- Stored accounts and rules ---\n\n /** The raw `accounts` array of the stored section, verbatim. */\n private rawStoredAccounts(): Array> {\n const raw = this.scope.getSnapshot().value?.accounts\n if (!Array.isArray(raw)) return []\n return raw.filter(\n (entry): entry is Record =>\n typeof entry === 'object' && entry !== null && !Array.isArray(entry),\n )\n }\n\n /**\n * The stored extra accounts this page can address: the rows carrying a\n * credential reference. Entries it cannot name (a composition entry with a\n * literal `apiKey`, or an unknown shape) are never dropped — every list\n * write starts from {@link rawStoredAccounts} and copies them verbatim,\n * because the settings layer replaces the whole array.\n */\n private storedExtras(): Array<{ label: string; ref: string }> {\n const out: Array<{ label: string; ref: string }> = []\n const seen = new Set()\n for (const record of this.rawStoredAccounts()) {\n const ref = record.apiKeyEnv\n if (typeof ref !== 'string' || ref === '' || seen.has(ref)) continue\n seen.add(ref)\n const label = record.label\n out.push({ label: typeof label === 'string' && label !== '' ? label : ref, ref })\n }\n return out\n }\n\n private effectiveAccounts(): AccountItemState[] {\n return this.storedExtras().map((extra) => ({\n id: extra.ref,\n ref: extra.ref,\n label: extra.label,\n configured: this.writer.credential(extra.ref)?.configured ?? false,\n credentialKnown: this.writer.credential(extra.ref) !== undefined,\n writable: this.writer.credential(extra.ref)?.writable ?? true,\n }))\n }\n\n /** The stored routing rules from the settings section (`modelAccountRules`). */\n private storedRules(): StoredRule[] {\n const raw = this.scope.getSnapshot().value?.modelAccountRules\n if (!Array.isArray(raw)) return []\n const out: StoredRule[] = []\n for (const entry of raw) {\n if (typeof entry !== 'object' || entry === null || Array.isArray(entry)) continue\n const record = entry as Record\n const models = Array.isArray(record.models)\n ? record.models.filter((m): m is string => typeof m === 'string' && m !== '')\n : []\n if (models.length === 0) continue\n out.push({\n models,\n account: typeof record.account === 'string' && record.account !== '' ? record.account : 'default',\n })\n }\n return out\n }\n\n /** 原始白名单;空列表延续现有的显示全部语义。 */\n private storedAllowlist(): string[] {\n const raw = this.scope.getSnapshot().value?.visibleModels\n if (!Array.isArray(raw)) return []\n return raw.filter((m): m is string => typeof m === 'string' && m !== '')\n }\n\n private storedShowsAll(): boolean {\n return this.storedAllowlist().length === 0\n && !Object.values(readVisibility(this.scope.getSnapshot().value?.modelVisibility)).includes(false)\n }\n\n /** 目录、白名单与显式显示的旧模型一起投影,目录失败不删除旧选择。 */\n private storedVisibleModels(): string[] {\n const list = this.storedAllowlist()\n const flags = readVisibility(this.scope.getSnapshot().value?.modelVisibility)\n const ids = [...new Set([...list, ...this.catalogModels.map((model) => model.id), ...Object.keys(flags)])]\n return ids.filter((id) => modelIsVisible(id, list, flags))\n }\n\n private effectiveVisibleModels(): string[] {\n if (this.visibleModelsDraft === undefined) return this.storedVisibleModels()\n return this.visibleModelsDraft.length === 0\n ? this.catalogModels.map((model) => model.id)\n : this.visibleModelsDraft\n }\n\n private visibleModelsDirty(): boolean {\n if (this.visibleModelsDraft === undefined) return false\n if (this.visibleModelsDraft.length === 0) return !this.storedShowsAll()\n return this.storedShowsAll() || !sameModels(this.visibleModelsDraft, this.storedVisibleModels())\n }\n\n private publish(): void {\n if (this.disposed) return\n for (const listener of this.listeners) listener()\n }\n}\n","/** Shared, dependency-free formatting for Host commands and browser surfaces. */\n\nexport function formatMoney(value: number): string {\n return `$${value.toFixed(2)}`\n}\n\nexport function formatMoneyExact(value: number): string {\n return `$${value.toFixed(4)}`\n}\n\n/**\n * 紧凑数字:K/M/B 三级,一切档位决策的唯一实现。\n *\n * 档位必须**回头判断**:先除以档位再四舍五入会算出 `999_999 → \"1000.0K\"`、\n * `999_999_999 → \"1000.0M\"` 这类既超长、又落在并不存在的档位上的结果,\n * 因此每个档位算完后若已经够到下一档,就改用下一档重算一次。\n *\n * @param value - 非负计数或词元数。\n * @param keepZeroDecimal - 整数值是否保留一位小数。词元显示沿用 `3.0B` 的旧样式;\n * 计数显示去掉多余的 `.0`,见 {@link formatCompactCount}。\n * @returns 紧凑文本;不足 1000 时原样返回该整数。\n */\nfunction compact(value: number, keepZeroDecimal: boolean): string {\n const rounded = (scaled: number): number => Math.round(scaled * 10) / 10\n const text = (scaled: number): string => {\n const fixed = rounded(scaled)\n return keepZeroDecimal ? fixed.toFixed(1) : String(fixed)\n }\n if (value >= 1e9) return `${text(value / 1e9)}B`\n if (value >= 1e6) return rounded(value / 1e6) >= 1000 ? `${text(value / 1e9)}B` : `${text(value / 1e6)}M`\n if (value >= 1e3) return rounded(value / 1e3) >= 1000 ? `${text(value / 1e6)}M` : `${text(value / 1e3)}K`\n return String(value)\n}\n\n/**\n * 紧凑计数:请求数、成功/失败数这类会被窄卡片截断的整数。\n * `1234` → `1.2K`、`12000` → `12K`、`1500000` → `1.5M`,整数不带多余的 `.0`。\n */\nexport function formatCompactCount(value: number): string {\n return compact(value, false)\n}\n\n/** 紧凑词元数:与 {@link formatCompactCount} 共用档位,但整数值保留一位小数(`3.0B`)。 */\nexport function formatTokensCompact(value: number): string {\n return compact(value, true)\n}\n\n/**\n * 精确值悬停提示:只在紧凑显示确实丢了信息时才返回文本。\n * 未换算时悬停弹出的文字与卡片上写的一模一样,没有意义,因此返回 `undefined` 让调用方\n * 整个省略 `title`,而不是挂一个内容重复的提示。\n *\n * @param parts - 标签与精确数值,按卡片上的显示顺序。\n * @returns 形如 `请求数 1234567 · 成功 1234567 · 失败 123` 的提示,或 `undefined`。\n */\nexport function compactCountTitle(parts: readonly (readonly [string, number])[]): string | undefined {\n return parts.some(([, value]) => formatCompactCount(value) !== String(value))\n ? parts.map(([label, value]) => `${label} ${value}`).join(' · ')\n : undefined\n}\n\n/** The input is already in percent units; callers add the percent sign. */\nexport function formatSuccessRate(value: number): string {\n return String(Number(value.toFixed(2)))\n}\n\n/** One window's fill ratio in [0, 1]; zero 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/** Local date-time, with the empty state chosen by the caller. */\nexport function formatResetAt(ms: number): string {\n return ms <= 0 ? '' : new Date(ms).toLocaleString()\n}\n\n/** 只有官方汇总与订阅共同确认同一起点,才展示完整账期;旧宿主和部分响应保持未知。 */\nexport function formatUsageBillingPeriod(usageStart: number | undefined, planStart: number | undefined, planEnd: number | undefined): string {\n if (usageStart === undefined || planStart !== usageStart || planEnd === undefined || usageStart <= 0 || planEnd <= usageStart) return ''\n const start = new Date(usageStart)\n const end = new Date(planEnd)\n if (!Number.isFinite(start.getTime()) || !Number.isFinite(end.getTime())) return ''\n return `${start.toLocaleDateString()} – ${end.toLocaleDateString()}`\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 * @module dsh-commandcode-provider/client/usage\n */\n\nimport type { CommandCodeAccountsReport, CommandCodeCatalog, CommandCodePriceTable } from '../usage-wire.ts'\nimport type { CommandCodeLoginStatus } from '../login-wire.ts'\nimport type { EnrollmentRemote } from './enrollment.ts'\nimport type { AnalyticsRemote } from './analytics.ts'\nimport type { AnalyticsQuery, AnalyticsReport } from '../analytics-wire.ts'\nimport type { RemoteResult } from '@deepseek-ai/dsh-typert-protocol'\nimport { readableErrorText } from '../readable-error.ts'\nexport { compactCountTitle, formatCompactCount, formatMoney, formatMoneyExact, formatTokensCompact, formatSuccessRate, windowRatio, formatResetAt } from '../display-format.ts'\n\n/**\n * Merge the plugin's Remote endpoints into the harness's typed client Remote\n * surface, so `ctx.remote.commandcode.*()` is typed once each contribution is\n * mounted. The `commandcode` namespace member is declared exactly once here\n * (interface merging forbids duplicate members) and therefore carries the usage\n * report, the model catalog, the price table AND the login endpoints.\n */\ndeclare module '@deepseek-ai/dsh-typert-protocol' {\n interface TypertRemoteMap {\n 'commandcode/report': () => Promise>\n 'commandcode/models': () => Promise>\n 'commandcode/prices': () => Promise>\n 'commandcode/analytics': (query: AnalyticsQuery) => Promise>\n }\n interface TypertRemoteNamespaceMap {\n commandcode: Partial & AnalyticsRemote & {\n report: () => Promise>\n models: () => Promise>\n /**\n * Optional because the Host half and this browser bundle can be a\n * cross-version pair: a Host older than the price table mounts no\n * `commandcode/prices` descriptor, so the member is genuinely absent at\n * runtime. The price controller reads a missing method as \"no table\"\n * (see `./prices.ts`) instead of throwing.\n */\n prices?: () => Promise>\n loginBegin: () => Promise>\n loginStatus: () => Promise>\n loginCancel: () => Promise>\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 models(): Promise<\n | { ok: true; value: CommandCodeCatalog }\n | { ok: false; error: { message: string } }\n >\n /**\n * Optional for the same cross-version reason as the namespace member above;\n * `CommandCodePricesController` reads the absence as a permanent \"no prices\"\n * state.\n */\n prices?(): Promise<\n | { ok: true; value: CommandCodePriceTable }\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 {\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: readableErrorText(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/** Host facts drive the usage card, including keys invisible to browser credentials. */\nexport function usageCardState(usage: UsagePageState) {\n const accounts = usage.report?.accounts ?? []\n return {\n loading: usage.status === 'loading',\n shouldRefresh: usage.status === 'idle',\n noKey: accounts.length > 0 && !accounts.some(account => account.configured),\n }\n}\n","/**\n * Browser controller for the model price table the composer's session-cost\n * figure depends on.\n *\n * The rates are vendored Host-side (`src/model-prices.ts`) and cross the\n * `commandcode/prices` Remote, so the browser never carries its own copy that\n * could drift from the snapshot, and a price update reaches an open page\n * without rebuilding the client bundle.\n *\n * @module dsh-commandcode-provider/client/prices\n */\n\nimport type { CommandCodePriceTable } from '../usage-wire.ts'\nimport { readableErrorText } from '../readable-error.ts'\n\n/** The narrow slice of the mounted Remote this controller calls. */\nexport interface PricesRemote {\n /**\n * Optional because the Host and the browser bundle can be a cross-version\n * pair: a Host half older than this feature serves no `commandcode/prices`\n * endpoint, and the controller must read that as \"no price table\" instead of\n * calling an undefined method.\n */\n prices?(): Promise<\n | { ok: true; value: CommandCodePriceTable }\n | { ok: false; error: { message: string; permanent?: boolean } }\n >\n}\n\n/** The price table's fetch lifecycle. */\nexport type PricesStatus =\n /** Never requested. */\n | 'idle'\n /** A fetch is in flight. */\n | 'loading'\n /** The table is loaded and cached for the page's lifetime. */\n | 'ready'\n /** The last fetch failed; `ensure()` may try again. */\n | 'error'\n\n/** The readout's price-table state face. */\nexport interface SessionCostPricesState {\n status: PricesStatus\n /** The cached table (only ever set once). */\n table: CommandCodePriceTable | undefined\n /** The last failure's message. */\n error: string | undefined\n}\n\nconst IDLE: SessionCostPricesState = { status: 'idle', table: undefined, error: undefined }\n\n/**\n * Timer seam for the bounded retry backoff, so a node test can drive the\n * schedule without waiting on it.\n */\nexport interface PriceRetryTimer {\n set(callback: () => void, ms: number): unknown\n clear(handle: unknown): void\n}\nconst RETRY_TIMER: PriceRetryTimer = {\n set(callback, ms) { const handle = setTimeout(callback, ms); handle.unref?.(); return handle },\n clear(handle) { clearTimeout(handle as ReturnType) },\n}\n\n/**\n * Cache over the `commandcode/prices` Remote, with a bounded transient-retry\n * budget (three retries at 1/2/4 s — bounded, not a poll). Public API mirrors\n * {@link CommandCodeUsageController}: `state()`, `subscribe` and `ensure()`;\n * `reload()` additionally drops the cache and restarts the budget when the\n * Host namespace rebinds. A MANUAL `ensure()` still fetches after the budget\n * is spent, and a PERMANENT failure — the Host serving no such endpoint — is\n * terminal for the binding until `reload()`.\n */\nexport class CommandCodePricesController {\n private readonly remote: PricesRemote\n private readonly listeners = new Set<() => void>()\n private current: SessionCostPricesState = IDLE\n private generation = 0\n private inFlight = false\n private disposed = false\n\n private retryHandle: unknown\n private attempts = 0\n private permanent = false\n private readonly timer: PriceRetryTimer\n\n constructor(remote: PricesRemote, timer: PriceRetryTimer = RETRY_TIMER) {\n this.timer = timer\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.clearRetry()\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 state face. */\n state(): SessionCostPricesState {\n return this.current\n }\n\n /**\n * Fetch the table unless it is already loaded, permanent, or in flight — and\n * unless a bounded retry already owns the next attempt. Only the client\n * entry calls this (on rebind and on a manual refresh), so a mounted readout\n * renders the current state instead of triggering a fetch of its own.\n */\n ensure(): void {\n if (this.disposed || this.permanent || this.inFlight || this.current.status === 'ready') return\n this.clearRetry()\n const call = this.remote.prices\n // An older Host half serves no price endpoint. That is a permanent\n // condition for this page, so it lands in the error state (the readout\n // stays hidden) rather than retrying on every mount.\n if (typeof call !== 'function') {\n this.permanent = true\n this.publish({ status: 'error', table: undefined, error: 'the Host serves no commandcode/prices endpoint' })\n return\n }\n const generation = this.generation\n this.inFlight = true\n this.attempts += 1\n this.publish({ status: 'loading', table: this.current.table, error: undefined })\n let request: ReturnType>\n try { request = call.call(this.remote) } catch (error) { request = Promise.reject(error) }\n void request.then((result) => {\n if (this.disposed || generation !== this.generation) return\n this.inFlight = false\n if (result.ok) {\n this.publish({ status: 'ready', table: result.value, error: undefined })\n return\n }\n this.permanent = result.error.permanent === true\n this.publish({ status: 'error', table: undefined, error: result.error.message })\n this.scheduleRetry()\n }, (error: unknown) => {\n if (this.disposed || generation !== this.generation) return\n this.inFlight = false\n this.publish({\n status: 'error',\n table: undefined,\n error: readableErrorText(error),\n })\n this.scheduleRetry()\n })\n }\n\n /** Rebinding a Host invalidates cached prices and restarts the bounded retry budget. */\n reload(): void {\n if (this.disposed) return\n this.generation += 1\n this.inFlight = false\n this.clearRetry()\n this.permanent = false\n this.attempts = 0\n this.current = IDLE\n this.ensure()\n }\n\n private clearRetry(): void {\n if (this.retryHandle !== undefined) this.timer.clear(this.retryHandle)\n this.retryHandle = undefined\n }\n\n private scheduleRetry(): void {\n if (this.disposed || this.permanent || this.attempts >= 4) return\n this.retryHandle = this.timer.set(() => { this.retryHandle = undefined; this.ensure() }, 1000 * 2 ** (this.attempts - 1))\n }\n\n private publish(next: SessionCostPricesState): void {\n this.current = next\n for (const listener of this.listeners) listener()\n }\n}\n","/** 收到宿主授权地址后才打开页面;浏览器拦截不应中断登录,界面始终保留手动链接。 */\nexport function openLoginPage(authUrl: string): void {\n if (typeof window === 'undefined') return\n try {\n // 授权页不持有设置页引用,也不接收设置页来源地址。\n // 使用 noopener 时成功打开也可能返回 null,因此不据此判断弹窗是否被拦截。\n window.open(authUrl, '_blank', 'noopener,noreferrer')\n } catch { /* 自动打开失败时仍可通过手动链接完成授权。 */ }\n}\n","/**\n * Browser controller for the settings page's login panel: `begin` asks the\n * Host to bind the callback server and returns the Studio URL, the controller\n * polls `loginStatus` while the attempt is live, and `cancel` tears it down.\n * The key itself never crosses to the browser — the Host validates and stores\n * it through the credentials seam.\n *\n * Transport-level failures (no mounted Remote, an older Host without the login\n * endpoints) land in the dedicated `unavailable` phase so the page can point\n * back at manual paste. Deliberately JSX-free, mirroring `./settings.ts` and\n * `./usage.ts`.\n *\n * @module dsh-commandcode-provider/client/login\n */\n\nimport type { RemoteResult } from '@deepseek-ai/dsh-typert-protocol'\nimport { readableErrorText } from '../readable-error.ts'\nimport { openLoginPage } from './login-page.ts'\nimport type { CommandCodeLoginFailureReason, CommandCodeLoginStatus } from '../login-wire.ts'\nimport type { Translate } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { SettingsCommandCodeKey } from './locales.ts'\n\n/** The endpoint-level Remote surface this controller calls. */\ndeclare module '@deepseek-ai/dsh-typert-protocol' {\n interface TypertRemoteMap {\n 'commandcode/loginBegin': (targetRef?: string) => Promise>\n 'commandcode/loginStatus': () => Promise>\n 'commandcode/loginCancel': () => Promise>\n }\n}\n\n/** The narrow slice of the mounted Remote this controller calls. */\nexport interface LoginRemote {\n loginBegin(targetRef?: string): Promise\n loginStatus(): Promise\n loginCancel(): Promise\n}\n\n/** One Remote call's outcome as the controller sees it. */\nexport type LoginCallResult =\n | { ok: true; value: CommandCodeLoginStatus }\n | { ok: false; error: { message: string } }\n\n/** The panel's full state face. */\nexport interface LoginPageState {\n /**\n * `idle` — nothing started; `starting` — begin() in flight; `waiting` —\n * the Studio URL is live and polling; `success`/`failed` — terminal;\n * `unavailable` — the Remote itself could not be reached (old Host, mount\n * failure), manual paste is the way.\n */\n phase: 'idle' | 'starting' | 'waiting' | 'success' | 'failed' | 'unavailable'\n /** The saved extra account receiving this attempt, or undefined for default. */\n targetRef?: string\n /** The Studio authorization URL while `waiting`. */\n authUrl: string | undefined\n /** The account display name on `success`. */\n userName: string | undefined\n /** The key's Studio label on `success`. */\n keyName: string | undefined\n /** The stable failure reason when `failed`. */\n reason: CommandCodeLoginFailureReason | undefined\n /** Secondary failure detail when `failed`/`unavailable`. */\n message: string | undefined\n}\n\n/** Keep one account's login status out of every other account's row. */\nexport function loginStateForTarget(\n state: LoginPageState,\n targetRef: string | undefined,\n): { visible: LoginPageState; busyElsewhere: boolean } {\n if (state.targetRef === targetRef) return { visible: state, busyElsewhere: false }\n return {\n visible: { ...state, phase: 'idle', authUrl: undefined },\n busyElsewhere: state.phase === 'starting' || state.phase === 'waiting',\n }\n}\n\n/** How often a live attempt is polled. */\nconst POLL_INTERVAL_MS = 1_000\n\n/**\n * The login panel's fetch/poll lifecycle. One poll loop at a time; a fresh\n * `begin()` supersedes any previous loop via a generation token.\n */\nexport class CommandCodeLoginController {\n private readonly remote: () => LoginRemote | undefined\n private readonly listeners = new Set<() => void>()\n private readonly pollMs: number\n /** Monotonic token; only the latest loop may publish polling results. */\n private generation = 0\n private disposed = false\n\n private phase: LoginPageState['phase'] = 'idle'\n private targetRef: string | undefined\n private authUrl: string | undefined\n private userName: string | undefined\n private keyName: string | undefined\n private reason: CommandCodeLoginFailureReason | undefined\n private message: string | undefined\n private openedPage = false\n\n constructor(remote: () => LoginRemote | undefined, pollMs = POLL_INTERVAL_MS, private readonly openPage = openLoginPage) {\n this.remote = remote\n this.pollMs = pollMs\n }\n\n /** Subscribe to state projections. */\n subscribe(listener: () => void): () => void {\n this.listeners.add(listener)\n return () => this.listeners.delete(listener)\n }\n\n state(): LoginPageState {\n return {\n phase: this.phase,\n ...(this.targetRef === undefined ? {} : { targetRef: this.targetRef }),\n authUrl: this.authUrl,\n userName: this.userName,\n keyName: this.keyName,\n reason: this.reason,\n message: this.message,\n }\n }\n\n /** Start (or rejoin) a login attempt and begin polling its status. */\n async begin(targetRef?: string): Promise {\n if (this.disposed || this.phase === 'starting' || this.phase === 'waiting') return\n const generation = ++this.generation\n this.openedPage = false\n this.targetRef = targetRef\n this.set({ phase: 'starting', authUrl: undefined, userName: undefined, keyName: undefined, reason: undefined, message: undefined })\n const remote = this.remote()\n if (remote === undefined) {\n this.set({ phase: 'unavailable', authUrl: undefined, userName: undefined, keyName: undefined, reason: undefined, message: 'login remote is not mounted' })\n return\n }\n let result: LoginCallResult\n try {\n result = await remote.loginBegin(targetRef)\n } catch (error: unknown) {\n // A transport throw (gateway hiccup) reads the same as a rejected call.\n result = { ok: false, error: { message: readableErrorText(error) } }\n }\n if (this.superseded(generation)) return\n if (!result.ok) {\n this.set({ phase: 'unavailable', authUrl: undefined, userName: undefined, keyName: undefined, reason: undefined, message: result.error.message })\n return\n }\n this.apply(result.value)\n if (this.currentPhase === 'waiting') void this.poll(generation)\n }\n\n /** Cancel a waiting attempt. */\n async cancel(): Promise {\n if (this.disposed || (this.phase !== 'starting' && this.phase !== 'waiting')) return\n const generation = ++this.generation\n const remote = this.remote()\n if (remote === undefined) return\n let result: LoginCallResult\n try {\n result = await remote.loginCancel()\n } catch {\n // The Host may be gone; reflect the local cancel regardless.\n this.set({ phase: 'failed', authUrl: undefined, userName: undefined, keyName: undefined, reason: 'cancelled', message: undefined })\n return\n }\n if (this.superseded(generation)) return\n if (result.ok) this.apply(result.value)\n else this.set({ phase: 'failed', authUrl: undefined, userName: undefined, keyName: undefined, reason: 'cancelled', message: undefined })\n }\n\n /** Stop polling and release listeners. Idempotent. */\n dispose(): void {\n if (this.disposed) return\n this.disposed = true\n this.generation += 1\n this.listeners.clear()\n }\n\n /** Poll until the attempt leaves `waiting` or a newer loop supersedes us. */\n private async poll(generation: number): Promise {\n // `currentPhase` is a getter, read (not the field) so control-flow\n // narrowing across `await` cannot claim the phase is frozen.\n while (!this.disposed && !this.superseded(generation) && this.currentPhase === 'waiting') {\n await sleep(this.pollMs)\n if (this.disposed || this.superseded(generation) || this.currentPhase !== 'waiting') return\n const remote = this.remote()\n if (remote === undefined) {\n this.set({ phase: 'unavailable', authUrl: undefined, userName: undefined, keyName: undefined, reason: undefined, message: 'login remote is not mounted' })\n return\n }\n let result: LoginCallResult\n try {\n result = await remote.loginStatus()\n } catch {\n continue // one missed poll is not an outage; the next tick retries\n }\n if (this.superseded(generation) || this.currentPhase !== 'waiting') return\n if (result.ok) this.apply(result.value)\n }\n }\n\n private get currentPhase(): LoginPageState['phase'] {\n return this.phase\n }\n\n /** Project one Host status onto the panel face. */\n private apply(status: CommandCodeLoginStatus): void {\n const base = { authUrl: undefined, userName: undefined, keyName: undefined, reason: undefined, message: undefined }\n if (status.state === 'waiting') {\n // 在宿主返回地址后打开,每次尝试仅执行一次,状态轮询不重复开页。\n if (status.authUrl && !this.openedPage) {\n this.openedPage = true\n this.openPage(status.authUrl)\n }\n this.set({ ...base, phase: 'waiting', authUrl: status.authUrl })\n return\n }\n if (status.state === 'success') {\n this.set({ ...base, phase: 'success', userName: status.userName, keyName: status.keyName })\n return\n }\n if (status.state === 'failed') {\n this.set({ ...base, phase: 'failed', reason: status.reason, message: status.message })\n return\n }\n // `idle` mid-poll means the Host restarted; the attempt is gone.\n this.set({ ...base, phase: 'failed', reason: 'cancelled', message: 'the login attempt is no longer active' })\n }\n\n /** Replace the whole state face and notify. Explicit over partial patches. */\n private set(state: LoginPageState): void {\n this.phase = state.phase\n this.authUrl = state.authUrl\n this.userName = state.userName\n this.keyName = state.keyName\n this.reason = state.reason\n this.message = state.message\n this.publish()\n }\n\n private superseded(generation: number): boolean {\n return this.disposed || generation !== this.generation\n }\n\n private publish(): void {\n if (this.disposed) return\n for (const listener of [...this.listeners]) listener()\n }\n}\n\nfunction sleep(ms: number): Promise {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n\n// Hint copy for the login panel / card row, JSX-free so node tests drive it.\n\n/**\n * The per-reason copy for a failed attempt. Shared by the settings page's login\n * panel and the Models-page card's login row — the same reason can surface from\n * either.\n */\nexport function loginFailureCopy(\n reason: CommandCodeLoginFailureReason | undefined,\n t: Translate,\n): string {\n if (reason === 'denied') return t('loginDenied')\n if (reason === 'timeout') return t('loginTimeout')\n if (reason === 'invalid-key') return t('loginInvalidKey')\n if (reason === 'network') return t('loginNetwork')\n if (reason === 'unavailable') return t('loginStoreFailed')\n if (reason === 'cancelled') return t('loginCancelled')\n return t('loginFailedGeneric')\n}\n\n/** One login panel row's computed hint: text, class stem, and optional title. */\nexport interface LoginHint {\n text: string\n className: string\n /** Tooltip shown when the row carries secondary failure detail. */\n title: string | undefined\n}\n\n/**\n * The hint text + class for one login panel state, shared by the settings\n * page's login panel and the Models-page card's login row so both surfaces\n * can never drift apart. Pure: no timers, no state.\n */\nexport function loginHint(\n state: LoginPageState,\n t: Translate,\n): LoginHint {\n if (state.phase === 'starting' || state.phase === 'waiting') {\n return {\n text: t(state.phase === 'starting' ? 'loginStarting' : 'loginWaiting'),\n className: 'cc-hint',\n title: undefined,\n }\n }\n if (state.phase === 'success') {\n const keyName = state.keyName !== undefined && state.keyName !== '' ? ` · ${state.keyName}` : ''\n return {\n text: `${t('loginSuccess')} ${state.userName ?? ''}${keyName}`.trim(),\n className: 'cc-loginDone',\n title: undefined,\n }\n }\n if (state.phase === 'failed') {\n return {\n text: loginFailureCopy(state.reason, t),\n className: 'cc-loginError',\n title: state.message,\n }\n }\n if (state.phase === 'unavailable') {\n return {\n text: `${t('loginUnavailable')} ${state.message ?? ''}`.trim(),\n className: 'cc-loginError',\n title: undefined,\n }\n }\n return { text: t('loginHintIdle'), className: 'cc-hint', title: undefined }\n}\n","/**\n * Shared boundary-validation and Remote-descriptor plumbing for the plugin's\n * hand-rolled Typert wire contracts (`commandcode/report`, `commandcode/models`,\n * `commandcode/prices`, `commandcode/login*`).\n *\n * Every Remote this plugin serves crosses the Typert Gateway with a strict\n * result schema: the Host half registers a descriptor against a Cordis service\n * (`src/usage-remote.ts`) and the browser half mounts the matching contribution\n * on `ctx.remote` (`src/client/index.ts`). This module is dependency-free so\n * the client bundle can inline it, and it holds the schema helpers and\n * descriptor boilerplate the wire files used to duplicate.\n *\n * @module dsh-commandcode-provider/wire-shared\n */\nimport type { InvocationDescriptor, TypertSchema } from '@deepseek-ai/dsh-typert-protocol'\n\n/** The npm package identity every contribution and descriptor claims. */\nexport const REMOTE_PACKAGE = '@mars-sea/dsh-commandcode-provider'\n\n/** The Cordis service key the Gateway resolves every Command Code Remote from. */\nexport const REMOTE_SERVICE = 'commandcodeUsage'\n\n/** The wire namespace all Command Code endpoints share. */\nexport const REMOTE_NAMESPACE = 'commandcode'\n\n/** The read/validate helpers one boundary codec needs. */\nexport interface BoundaryValidator {\n /** Reject one boundary value with a field-naming error. */\n reject(field: string): never\n /** Narrow an unknown value to a plain record, or reject. */\n record(value: unknown, field: string): Record\n /** Read one required string field (`field` is the dotted error label). */\n stringField(source: Record, key: string, field: string): string\n /** Read one required finite number field (`field` is the dotted error label). */\n numberField(source: Record, key: string, field: string): number\n /** Read one required boolean field (`field` is the dotted error label). */\n booleanField(source: Record, key: string, field: string): boolean\n}\n\n/**\n * Build the validator helpers one endpoint uses. `prefix` names the endpoint\n * in the rejection message (e.g. `commandcode/report result:`), so each wire\n * file keeps its own diagnostic phrasing while sharing the helper bodies.\n *\n * The helpers return the reject call directly in the failure branch: since\n * `reject` is typed `never`, the ternary's union collapses to the success type\n * without relying on TypeScript's control-flow analysis of a never-returning\n * call (which only recognizes function declarations, not the destructured\n * arrow `reject` callers receive from this factory). Callers that need the\n * narrowing in an `if` must therefore assign inside the positive branch.\n */\nexport function makeBoundaryValidator(prefix: string): BoundaryValidator {\n const reject = (field: string): never => {\n throw new TypeError(`${prefix} invalid ${field}`)\n }\n const record = (value: unknown, field: string): Record =>\n typeof value === 'object' && value !== null && !Array.isArray(value)\n ? value as Record\n : reject(field)\n const stringField = (source: Record, key: string, field: string): string =>\n typeof source[key] === 'string' ? source[key] as string : reject(field)\n const numberField = (source: Record, key: string, field: string): number =>\n typeof source[key] === 'number' && Number.isFinite(source[key] as number)\n ? source[key] as number\n : reject(field)\n const booleanField = (source: Record, key: string, field: string): boolean =>\n typeof source[key] === 'boolean' ? source[key] as boolean : reject(field)\n return { reject, record, stringField, numberField, booleanField }\n}\n\n/**\n * One strict result codec: `mode: 'strict'` carries the LAZY schema factory\n * (`create()`) the registry requires and the Gateway validates with\n * (`codec.create().parse`). There is NO `schema` member — issue #49.\n */\ninterface StrictCodec
}\n control={\n \n }\n />\n {/* Only a real fetch failure explains the disabled add button; the\n catalog still loading does not (it may yet land). */}\n {state.catalogFailed ?
{t('contextOverrideNoCatalog')}
: null}\n {rows.length > 0 ? (\n // Column heads for the row trio below; the third cell is the remove\n // button's width, so the value label stays optically over its input.\n
\n \n \n {/* The plugin's own caret instead of the platform arrow: the\n native one renders in whatever style the OS chooses, which is\n exactly the inconsistency this card should not carry. */}\n \n \n setText(row.model, event.target.value)}\n />\n \n {row.invalid ?
{invalidCopy(row.invalidReason, t, 'context')}
: null}\n
\n ))}\n >\n )\n}\n\n/**\n * Privacy & security: the opt-in that changes where data goes. ZDR restricts\n * which upstream serves a request, so it starts off.\n */\nfunction PrivacyCard({ state, disabled, t, onEdit, onReset }: FormCardProps) {\n return (\n \n onEdit('zdr', text)}\n onReset={() => onReset('zdr')}\n t={t}\n />\n \n )\n}\n\n/** Integrations & display: surfaces outside chat that reuse this provider. */\nfunction IntegrationsCard({ state, disabled, t, onEdit, onReset }: FormCardProps) {\n return (\n \n onEdit('webSearch', text)}\n onReset={() => onReset('webSearch')}\n t={t}\n />\n {/* Opt-in, and off by default: the sidebar quota card is a display\n surface, so an unset document shows nothing on the left. */}\n onEdit('showSidebarQuota', text)}\n onReset={() => onReset('showSidebarQuota')}\n t={t}\n />\n \n )\n}\n\n/**\n * The collapsed \"Advanced\" card: the API base and the network limits. Folds\n * through the same `CollapsibleGroup` the Models & context group uses, so the\n * two disclosures stay identical; while collapsed, a badge names the customized\n * count and an invalid number (which blocks save) is surfaced on the header.\n */\nfunction AdvancedSection({ state, disabled, t, onEdit, onReset }: FormCardProps) {\n const overridden = ADVANCED_FIELDS.filter((field) => state[field].overridden).length\n const invalid = advancedGroupInvalid(state)\n return (\n (\n <>\n {overridden > 0 ? (\n \n {overridden === 1 ? t('advancedOverriddenOne') : t('advancedOverriddenMany', { count: overridden })}\n \n ) : null}\n {!expanded && invalid ? (\n {t('advancedInvalid')}\n ) : null}\n >\n )}\n footer={invalid ?
{t('advancedInvalid')}
: null}\n >\n
{t('advancedSettingsHint')}
\n onEdit('apiBase', text)}\n onReset={() => onReset('apiBase')}\n t={t}\n />\n onEdit('requestTimeoutMs', text)}\n onReset={() => onReset('requestTimeoutMs')}\n t={t}\n />\n onEdit('streamIdleTimeoutMs', text)}\n onReset={() => onReset('streamIdleTimeoutMs')}\n t={t}\n />\n onEdit('transportMaxRetries', text)}\n onReset={() => onReset('transportMaxRetries')}\n t={t}\n />\n onEdit('offloadSeenImagesForCache', text)}\n onReset={() => onReset('offloadSeenImagesForCache')}\n t={t}\n />\n \n )\n}\n\n/** One row of the unified account list: a stored account merged with its usage entry. */\ninterface AccountRowModel {\n /** Slot id: `default` or the extra account's credential reference. */\n id: string\n label: string\n /** Credential reference for extra accounts; undefined for the default slot. */\n ref: string | undefined\n isDefault: boolean\n /** Whether this page can manage the row (false for literal-only composition entries). */\n managed: boolean\n /** Whether a key resolves for this account (stored credential or a Host-side source). */\n configured: boolean\n /** Whether a stored credential exists this page could delete. */\n storedKey: boolean\n credentialKnown: boolean\n keyWritable: boolean\n usage: CommandCodeAccountUsage | undefined\n}\n\n/**\n * Merge the controller's accounts with the usage report. The default slot is\n * always first; report entries this page cannot manage (literal keys from the\n * composition config) still render, read-only, so the list names every\n * account the pool rotates through.\n */\nfunction accountRows(state: SettingsPageState, usage: UsagePageState, t: Translate): AccountRowModel[] {\n const report = new Map((usage.report?.accounts ?? []).map((entry) => [entry.id, entry]))\n const defaultUsage = report.get('default')\n const rows: AccountRowModel[] = [{\n id: 'default',\n label: t('accountDefault'),\n ref: undefined,\n isDefault: true,\n managed: true,\n configured: state.apiKeyConfigured || defaultUsage?.configured === true,\n storedKey: state.apiKeyConfigured,\n credentialKnown: state.apiKeyKnown || typeof defaultUsage?.configured === 'boolean',\n keyWritable: state.apiKeyWritable,\n usage: defaultUsage,\n }]\n for (const account of state.accounts) {\n const entry = report.get(account.id)\n rows.push({\n id: account.id,\n label: account.label,\n ref: account.ref,\n isDefault: false,\n managed: true,\n configured: account.configured || entry?.configured === true,\n storedKey: account.configured,\n credentialKnown: account.credentialKnown || typeof entry?.configured === 'boolean',\n keyWritable: account.writable,\n usage: entry,\n })\n }\n const known = new Set(rows.map((row) => row.id))\n for (const entry of usage.report?.accounts ?? []) {\n if (known.has(entry.id)) continue\n known.add(entry.id)\n rows.push({\n id: entry.id,\n label: entry.label,\n ref: undefined,\n isDefault: false,\n managed: false,\n configured: entry.configured,\n storedKey: false,\n credentialKnown: true,\n keyWritable: false,\n usage: entry,\n })\n }\n return rows\n}\n\n/**\n * The row's status dot. Read top-down, so a problem always outranks \"serving\":\n * red for a key the Host rejected, amber while a rate limit is cooling down,\n * green for the account that is actually serving requests. A standby (or not\n * yet configured) account draws NOTHING — `cc-tabDotBlank` is an unfilled,\n * borderless dot that only holds the column so the account names stay aligned\n * with the rows that do have a verdict. Green therefore means \"in use\", not\n * \"healthy\": a wall of green dots would say nothing.\n */\nfunction statusDotClass(row: AccountRowModel): string {\n const entry = row.usage\n if (entry?.mark === 'invalid-credential') return 'cc-tabDot cc-tabDotError'\n if (entry !== undefined && (entry.mark !== '' || entry.cooldownUntil > 0)) return 'cc-tabDot cc-tabDotWarn'\n if (row.configured && entry?.active === true) return 'cc-tabDot cc-tabDotOk'\n return 'cc-tabDot cc-tabDotBlank'\n}\n\n/**\n * The same verdict as a sentence, for the dot's tooltip. Undefined on a blank\n * dot: there is no verdict to read out, and a hover hotspot on an invisible\n * 8px mark would only invite the question it cannot usefully answer.\n */\nfunction statusDotTitle(row: AccountRowModel, t: Translate): string | undefined {\n const entry = row.usage\n if (entry?.mark === 'invalid-credential') return t('usageInvalidKey')\n if (entry !== undefined && (entry.mark !== '' || entry.cooldownUntil > 0)) return t('usageCooldown')\n if (!row.credentialKnown) return t('writeStateUnknown')\n if (!row.configured) return t('apiKeyUnset')\n return entry?.active === true ? t('usageActive') : undefined\n}\n\n/** One compact quota meter for a row's summary line. */\nfunction MiniMeter({ label, limit }: { label: string; limit: NonNullable }) {\n const ratio = windowRatio(limit.used, limit.cap)\n const percent = limit.cap > 0 ? `${Math.round(ratio * 100)}%` : formatMoney(limit.used)\n return (\n 0 ? `${formatMoney(limit.used)} / ${formatMoney(limit.cap)}` : undefined}>\n {label}\n \n \n \n {percent}\n \n )\n}\n\n/**\n * The monthly credit balance for a row's summary line: the billing endpoint's\n * `monthlyCredits` is what is LEFT, shown as the amount alone.\n */\nfunction MonthlyBalance({ label, remaining }: { label: string; remaining: number }) {\n return (\n \n {label}\n {formatMoney(Math.max(0, remaining))}\n \n )\n}\n\n/** A single-input inline form (paste key, rename) with confirm/cancel. */\nfunction InlineInput({ id, label, secret, initial, placeholder, confirmLabel, disabled, t, onSubmit, onCancel }: {\n id: string\n label: string\n secret?: boolean\n initial?: string\n placeholder?: string\n confirmLabel: string\n disabled: boolean\n t: Translate\n onSubmit(value: string): void\n onCancel(): void\n}) {\n const [value, setValue] = useState(initial ?? '')\n const [visible, setVisible] = useState(false)\n const ready = value.trim() !== ''\n return (\n \n )\n}\n\n/** A destructive confirmation bar shown in place of a menu action. */\nfunction ConfirmBar({ text, confirmLabel, disabled, t, onConfirm, onCancel }: {\n text: string\n confirmLabel: string\n disabled: boolean\n t: Translate\n onConfirm(): void\n onCancel(): void\n}) {\n return (\n
\n {adding ? (\n \n ) : (\n \n )}\n \n )\n}\n\n/**\n * Show the save bar's \"saved\" confirmation 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 // The count lives in the shared controller and outlives this component, so\n // a remount (switching settings pages, reopening settings) sees a non-zero\n // count it did not witness. Only a save landing while mounted may flash.\n const seen = useRef(tick)\n useEffect(() => {\n if (tick === seen.current) return\n seen.current = tick\n setVisible(true)\n const timer = setTimeout(() => setVisible(false), 2500)\n return () => clearTimeout(timer)\n }, [tick])\n return visible\n}\n\n/**\n * The update hint: one throttled npm-registry check per page open (the\n * throttle and all failure handling live in ./update.ts). Resolves to the\n * newest published version when it is newer than this build, else undefined —\n * every failure mode degrades to no hint at all.\n */\nfunction usePluginUpdate(): string | undefined {\n const [available, setAvailable] = useState(undefined)\n useEffect(() => {\n let cancelled = false\n void checkForUpdate({\n currentVersion: PLUGIN_VERSION,\n now: Date.now(),\n store: localStorageUpdateStore(),\n }).then((version) => {\n if (!cancelled) setAvailable(version)\n // A rejected checkForUpdate would be a bug (it catches internally);\n // swallow it regardless — the footer must never break the page.\n }, () => {})\n return () => {\n cancelled = true\n }\n }, [])\n return available\n}\n\ntype SaveBarTone = 'pending' | 'error' | 'success'\n\ninterface SaveBarView {\n visible: boolean\n tone: SaveBarTone\n message: string\n /** Whether Discard/Save apply (hidden while only the saved confirmation shows). */\n actions: boolean\n}\n\n/**\n * What the save bar says. It exists only while there is something to act on\n * or to confirm: pending edits, a save in flight, a failure, or the brief\n * confirmation after a save landed. Account operations never reach it, they\n * commit on their own.\n */\nfunction saveBarView(state: SettingsPageState, savedVisible: boolean, t: Translate): SaveBarView {\n const notice = settingsWriteNotice(state.saveResult, t)\n if (notice) return { visible: true, tone: state.failed ? 'error' : 'pending', message: notice, actions: state.dirty || state.failed }\n if (state.failed) return { visible: true, tone: 'error', message: t('saveFailed'), actions: state.dirty || state.failed }\n if (state.dirty || state.saving) {\n return state.invalid\n ? { visible: true, tone: 'error', message: t('saveInvalid'), actions: true }\n : { visible: true, tone: 'pending', message: t('unsavedChanges'), actions: true }\n }\n if (savedVisible) return { visible: true, tone: 'success', message: t('saved'), actions: false }\n return { visible: false, tone: 'success', message: '', actions: false }\n}\n\n/** The save bar's leading status mark: a soft dot while pending, a glyph once there is an outcome. */\nfunction SaveBarIcon({ tone }: { tone: SaveBarTone }) {\n if (tone === 'pending') return \n return (\n \n \n \n )\n}\n\n/**\n * The floating save bar: pinned to the bottom of the settings scrollport and\n * slid out of view when there is nothing to save. It stays mounted so it can\n * animate out, and keeps showing its last message while it does (the state\n * that hid it has no message of its own).\n */\nfunction SaveBar({ view, state, t, onDiscard, onSave }: {\n view: SaveBarView\n state: SettingsPageState\n t: Translate\n onDiscard(): void\n onSave(): void\n}) {\n const last = useRef(view)\n if (view.visible) last.current = view\n const shown = view.visible ? view : last.current\n return (\n
\n
\n \n
{shown.message}
\n {shown.actions ? (\n
\n {/* Own buttons rather than the primitives: they are sized to sit\n concentrically inside the bar (see .cc-saveBar). */}\n \n \n
\n \n \n )\n}\n","/**\n * The shared login row: one field row that starts the Host-side browser login,\n * links to the Studio authorization page while the attempt is live, and reports\n * the outcome. Rendered by BOTH the settings page (`section.tsx`) and the\n * Models-page provider card (`card.tsx`) so the two surfaces share one\n * component and one hint state machine — whose copy/class logic lives in the\n * JSX-free `./login.ts` (`loginHint`/`loginFailureCopy`) so node tests can drive\n * every phase. This file only renders it.\n *\n * @module dsh-commandcode-provider/client/login-row\n */\n\nimport type { Translate } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { SettingsCommandCodeKey } from './locales.ts'\nimport { loginHint, loginStateForTarget } from './login.ts'\nimport type { LoginPageState } from './login.ts'\n\n/** One login row's props (same face both surfaces supply). */\nexport interface LoginRowProps {\n state: LoginPageState\n /** Only the matching attempt appears in this row; omitted means default. */\n targetRef?: string\n disabled: boolean\n disabledHint?: string | undefined\n t: Translate\n onBegin(): void\n onCancel(): void\n}\n\nexport function LoginRow({ state, targetRef, disabled, disabledHint, t, onBegin, onCancel }: LoginRowProps) {\n const { visible: visibleState, busyElsewhere } = loginStateForTarget(state, targetRef)\n const busy = visibleState.phase === 'starting' || visibleState.phase === 'waiting'\n const hint = loginHint(visibleState, t)\n return (\n
\n )\n}\n","/**\n * The Command Code configuration panel inside the harness Models settings page,\n * rendered through the `settings.models.provider-card` keyed slot with\n * `entryKey = 'llm-commandcode'` (the plugin's settings namespace, the key the\n * Models page dispatches for every Command Code provider row).\n *\n * The official Models page opens one editor per provider row through its own\n * 编辑 button, and for a namespace it curates no layout for (`llm-commandcode`)\n * that editor is a bare shell: a config hint over a permanently disabled apply.\n * This panel takes its place — it watches the slot outlet's siblings and, while\n * the official editor is open, hides the useless shell and shows the real\n * controls in its slot (credential/route badges, API-key field, sign-in,\n * discard/save). Closed, it renders nothing and the row looks exactly like any\n * other provider row.\n *\n * The slot's owner props (`configured`, `keyConfigured`) mirror what the Models\n * page already knows; the authoritative credential facts still come from this\n * plugin's `CommandCodeSettingsController` — shared with the dedicated settings\n * page, so the two surfaces can never disagree about whether a key is stored.\n * A controller-less render (panel mounted before the section registered its\n * inject face — the composition runs one apply) degrades to the stateless\n * registration notice. Styles ride the page stylesheet the client entry injects\n * once; the card adds no CSS of its own.\n */\n\nimport { useEffect, useRef, useState } from 'react'\nimport type { Translate } from '@deepseek-ai/dsh-client-ui-slots'\nimport { settingsWriteNotice, type SettingsCommandCodeKey } from './locales.ts'\nimport type { SettingsPageState, StagedField } from './settings.ts'\nimport type { LoginPageState } from './login.ts'\nimport { LoginRow } from './login-row.tsx'\n\n/**\n * The Models-page extension slots, merged into the SlotMap with the exact\n * declarations ui-settings-models ships. The merge must stay structurally\n * identical to upstream's (kind/scope/owner), or a dsh carrying its own\n * declaration would fail the duplicate-merge check at compile time.\n */\ndeclare module '@deepseek-ai/dsh-client-ui-slots' {\n interface SlotMap {\n /** One provider card's adapter extension area, keyed by the row's settingsNs. */\n 'settings.models.provider-card': { kind: 'keyed'; scope: 'root'; owner: ProviderCardExtrasOwnerProps }\n /** Ordered extension area after the provider rows and the add controls. */\n 'settings.models.footer': { kind: 'list'; scope: 'root'; owner: ModelsFooterOwnerProps }\n }\n}\n\n/** The provider directory row as the Models page dispatches it. */\nexport interface ProviderDirectoryRow {\n /** The provider route id (`commandcode` for this plugin). */\n readonly provider: string\n readonly displayName: string\n /** The settings namespace the row configures (the slot's dispatch key). */\n readonly settingsNs: string\n readonly settingsPath: readonly string[]\n /** Whether the provider route is live. */\n readonly active: boolean\n /** Whether the adapter declares the route as shipped. */\n readonly declared?: boolean\n}\n\n/** Owner share of one provider-card extension occurrence (upstream's shape). */\nexport interface ProviderCardExtrasOwnerProps {\n /** The card's directory row. */\n readonly provider: ProviderDirectoryRow\n /** Whether any layer configures this provider (its profile resolves). */\n readonly configured: boolean\n /** The row's referenced api-key credential, confirmed configured by the page's join. */\n readonly keyConfigured: boolean\n}\n\n/** Owner share of the footer area (the section supplies nothing). */\nexport interface ModelsFooterOwnerProps {\n /** Marker field: footer owner props are intentionally empty. */\n children?: never\n}\n\n/** Owner props the Models page supplies at its dispatch sites. */\nexport type ProviderCardOwnerProps = ProviderCardExtrasOwnerProps\n\n/**\n * The slot whose outlet anchors this panel inside the Models row — the\n * renderer's own `data-slot` attribute value, stable across builds (unlike\n * CSS-module class hashes).\n */\nexport const CARD_SLOT_KEY = 'settings.models.provider-card'\n\n/** The DOM facts the sibling lookup reads (satisfied by real Elements). */\nexport interface SlotWrapperSiblings {\n previousElementSibling: { className: string } | null\n nextElementSibling: { className: string } | null\n}\n\n/**\n * Find the official editor card among the slot outlet's siblings, or null\n * while it is closed. The Models page renders the editor as an immediate\n * sibling of the outlet wrapper — after it in a provider row (the target of\n * the row's 编辑 toggle), before it in the first-run setup and add-provider\n * cards, where it is always open. The editor is the only such sibling whose\n * CSS module class carries the `editor` stem (`_editor`); the row header\n * and the add card's provider select never do, so the lookup needs no hash\n * knowledge.\n */\nexport function adjacentEditorCard(wrapper: SlotWrapperSiblings | null): { className: string } | null {\n if (wrapper === null) return null\n for (const sibling of [wrapper.previousElementSibling, wrapper.nextElementSibling]) {\n if (sibling !== null && typeof sibling.className === 'string' && sibling.className.includes('editor')) {\n return sibling\n }\n }\n return null\n}\n\n/** The closed-panel style: the outlet stays mounted as the detection anchor. */\nconst HIDDEN_STYLE = { display: 'none' } as const\n\n/** Injected face the card's slot registration supplies. */\nexport interface CommandCodeCardProps {\n t: Translate\n useCommandCodeSettings(selector: (state: SettingsPageState) => T): T\n useCommandCodeLogin(selector: (state: LoginPageState) => T): T\n edit(field: string, text: string): void\n save(): void\n discard(): void\n refreshCredentials(): void\n beginLogin(): void\n cancelLogin(): void\n}\n\n/** The card's two postures. */\ntype CardMode =\n | { kind: 'registration' }\n | { kind: 'live'; ready: boolean; controllerConfigured: boolean; writable: boolean; apiKeyWritable: boolean }\n\n/**\n * Decide the card's posture from one settings snapshot. Pure: the component\n * subscribes once and passes the snapshot in, so hook order never depends\n * on the registration→live transition. (The owner facts stay on the\n * component — only the snapshot decides the posture.)\n */\nexport function cardMode(\n snapshot: SettingsPageState | undefined,\n): CardMode {\n if (snapshot === undefined) return { kind: 'registration' }\n return {\n kind: 'live',\n ready: snapshot.available,\n controllerConfigured: snapshot.apiKeyConfigured,\n writable: snapshot.writable,\n apiKeyWritable: snapshot.apiKeyWritable,\n }\n}\n\n/** Credential-state badge: the solid pill when set, the muted outline when not. */\nfunction StatusBadge({ ok, okLabel, pendingLabel }: {\n ok: boolean\n okLabel: string\n pendingLabel: string\n}) {\n return {ok ? okLabel : pendingLabel}\n}\n\n/** The key paste field, with the show/hide toggle over it. */\nfunction CardKeyField({ state, disabled, t, onEdit }: {\n state: StagedField\n disabled: boolean\n t: Translate\n onEdit(text: string): void\n}) {\n const [visible, setVisible] = useState(false)\n return (\n
\n
\n {t('apiKey')}\n \n \n \n
\n onEdit(event.target.value)}\n />\n
{t('apiKeyHint')}
\n
\n )\n}\n\n/**\n * The slot component body. Dispatched on every Command Code provider card of\n * the Models page (saved row, first-run setup posture, add-provider draft).\n *\n * Closed (the official 编辑 toggle off) it renders nothing: the row head the\n * Models page owns already names the provider and shows the credential dot, so\n * a page full of providers stays compact. Open, it hides that editor shell and\n * shows the real controls — badges, API-key field, sign-in, discard/save.\n */\nexport function CommandCodeProviderCard(props: CommandCodeCardProps & ProviderCardOwnerProps) {\n const { t } = props\n // Single subscription: the whole snapshot drives posture + body together.\n const state = props.useCommandCodeSettings !== undefined\n ? props.useCommandCodeSettings((snapshot) => snapshot)\n : undefined\n const mode = cardMode(state)\n const login = props.useCommandCodeLogin !== undefined\n ? props.useCommandCodeLogin((snapshot) => snapshot)\n : undefined\n const dirty = state?.dirty ?? false\n const saving = state?.saving ?? false\n const invalid = state?.invalid ?? false\n const notice = settingsWriteNotice(state?.saveResult, t) || (state?.failed ? t('saveFailed') : '')\n const savingBlocked = !dirty || invalid\n const configured = mode.kind === 'live' && mode.ready ? mode.controllerConfigured : props.keyConfigured\n const disabled = mode.kind === 'live' && (!mode.writable || (state !== undefined && !mode.apiKeyWritable))\n const showBody = mode.kind === 'live' && mode.ready && state !== undefined\n // The official editor's open state lives in the Models page's own component\n // state and never reaches this slot's props; the outlet wrapper is the stable\n // neighbor, so watch ITS siblings for the editor's mount/unmount. The outlet\n // stays mounted either way — it is the observation anchor — so the closed\n // panel hides its own root instead of unmounting.\n const rootRef = useRef(null)\n const [editorOpen, setEditorOpen] = useState(false)\n useEffect(() => {\n const root = rootRef.current\n if (root === null || typeof MutationObserver === 'undefined') return\n const wrapper = root.closest(`[data-slot=\"${CARD_SLOT_KEY}\"]`) ?? root.parentElement\n if (wrapper === null) return\n const row = wrapper.parentElement\n if (row === null) return\n let hiddenEditor: HTMLElement | null = null\n const sync = () => {\n const editor = adjacentEditorCard(wrapper) as HTMLElement | null\n setEditorOpen(editor !== null)\n if (editor !== null) {\n // React pins no inline style on the editor shell, so this survives the\n // shell's own re-renders; a shell that unmounts and remounts is\n // re-hidden by the next observation.\n editor.style.display = 'none'\n hiddenEditor = editor\n }\n }\n sync()\n const observer = new MutationObserver(sync)\n observer.observe(row, { childList: true })\n return () => {\n observer.disconnect()\n // If the shell outlives the panel (plugin reload), give it back: it is\n // the honest fallback face again.\n if (hiddenEditor !== null) hiddenEditor.style.display = ''\n }\n }, [])\n return (\n
\n )\n}\n","/** 模型分析沿用宿主语言;每个数值有独立标签,缺失样本与试算前提必须可见。 */\nexport const ANALYTICS_COPY_ZH = {\n analyticsNav: '模型分析', quotaNav: '账号额度',\n analysisRecent: '最近会话', analysisRange: '指定时间', analysisLimit: '会话数量', analysisFrom: '开始日期', analysisTo: '结束日期', analysisApply: '读取统计',\n analysisLoading: '正在读取历史记录…', analysisUnavailable: '宿主未提供历史查询服务,无法统计关闭后的会话。', analysisEmpty: '所选范围内没有 Command Code 请求记录。',\n analysisInvalid: '请输入 1–100 个会话,或不超过 366 天的有效日期范围。', analysisScope: '统计范围', analysisScanned: '已读取会话', analysisMatched: '含请求会话', analysisUnreadable: '读取失败', analysisSkipped: '已跳过',\n analysisPartial: '结果不完整:历史超过读取上限,或部分记录不可读。金额只覆盖已读取且可计价的请求。', analysisCatalog: '模型目录暂不可用,历史统计仍可查看。',\n analysisUnpriced: '部分请求缺少用量或价格,金额与词元仅为已知小计。展开明细可查看样本覆盖。',\n analysisOverview: '用量总览', analysisSections: '分析内容', analysisHistory: '历史用量', analysisSimulation: '价格试算', analysisByModel: '模型用量比较', analysisModelHint: '比例条表示占已知成本小计的份额;展开查看明细。',\n analysisIntro: '查看历史用量,比较模型成本与响应表现。', analysisModel: '模型', analysisCostShare: '已知成本 / 占比', analysisNoShare: '无占比', analysisShareHint: '占全部已知成本小计',\n analysisSimulationHeading: '相同工作量价格试算', analysisSimulationHint: '差额以所选历史全部请求的当前价估算为基准;负数表示成本更低,仅比较完整覆盖的相同工作量。', analysisSimulationCost: '试算成本', analysisCoverage: '计价覆盖', analysisUsd: '美元', analysisTokenUnit: '词元',\n analysisScenarioMonthly: '折算 30 天', analysisDifference: '较历史基准', analysisBaseline: '历史成本基准', analysisZeroBaseline: '基准为零,不计算比例',\n analysisNeedRange: '请选择日期范围', analysisShortRange: '观察范围不足一天', analysisIncomplete: '历史读取不完整', analysisNoRequests: '没有请求记录',\n analysisScenarioExcluded: '存在超上下文请求', analysisScenarioUnpriced: '存在未知用量或价格', analysisBaselineUnpriced: '历史基准未全部计价',\n analysisCost: '已知成本 · 美元', analysisRequests: '模型请求', analysisSessionCount: '会话数', analysisResponse: '平均响应', analysisFirstToken: '平均首词元', analysisSpeed: '输出速度', analysisSeconds: '秒', analysisSpeedUnit: '词元/秒',\n analysisPriced: '计价请求', analysisTimed: '响应样本', analysisFirstTokenSamples: '首词元样本', analysisDecodeSamples: '解码样本', analysisUsageSamples: '用量样本', analysisAverage: '每会话均摊', analysisMissing: '无数据',\n analysisDetails: '查看汇总明细', analysisTokens: '词元与缓存', analysisInput: '未缓存输入', analysisOutput: '输出', analysisCacheRead: '缓存读取', analysisCacheWrite: '缓存写入',\n analysisOutcome: '请求状态', analysisCompleted: '完成', analysisFailed: '失败', analysisRetries: '宿主重试', analysisCancelled: '取消', analysisUnknown: '未知状态', analysisSamples: '统计样本', analysisSessionCost: '会话与成本',\n analysisMonthly: '按该时间段折算 30 天', analysisMonthlyHint: '仅完整、全部计价且跨度至少一天的日期范围提供折算。',\n analysisRules: '统计口径与试算说明', analysisShortBasis: '按当前价格估算,非历史账单。缺失用量与耗时不会补零。',\n analysisBasis: '按当前价格快照重算;不是历史账单,不含订阅费和充值,词元用量不等于账号积分。仅有请求数量、没有任务边界;不计算任务质量或智能评分。旧记录缺失的用量和耗时不会补零。',\n analysisAssumption: '沿用原请求的词元与时段,对比不同模型的价格。换模型后的生成长度、缓存命中、重试和质量可能变化;不会调用模型或自动推荐。',\n analysisContext: '上下文词元', analysisCapabilities: '模型能力', analysisInputType: '输入类型', analysisEfforts: '推理力度', analysisExcluded: '超出上下文', analysisUnknownPrice: '未知用量或价格', analysisSearch: '筛选试算模型', analysisSearchPlaceholder: '输入模型名称或标识', analysisNoMatches: '没有匹配的模型,请调整筛选条件。',\n analysisImages: '支持图片', analysisTextOnly: '仅文本', analysisNoEfforts: '未提供推理力度',\n analysisCoverageHint: '耗时从步骤或重试开始计至模型结算;包含前置处理,不含后续工具执行。首词元包含推理与工具参数。速度按有解码计时的输出词元总量计算。试算未校验图片及工具兼容性,也不代表账号已获授权。',\n effortNone: '关闭 (none)', effortLow: '低 (low)', effortMedium: '中 (medium)', effortHigh: '高 (high)', effortXhigh: '极高 (xhigh)', effortMax: '最高 (max)',\n} as const\nexport type AnalyticsKey = keyof typeof ANALYTICS_COPY_ZH\n/** 按项目约定,错误、缺失与读取状态在各语言环境中统一为中文。 */\nexport const ANALYTICS_COPY_EN: Record = {\n analyticsNav: 'Model analysis', quotaNav: 'Account quota',\n analysisRecent: 'Recent sessions', analysisRange: 'Date range', analysisLimit: 'Session count', analysisFrom: 'Start date', analysisTo: 'End date', analysisApply: 'Read statistics',\n analysisLoading: ANALYTICS_COPY_ZH.analysisLoading, analysisUnavailable: ANALYTICS_COPY_ZH.analysisUnavailable, analysisEmpty: ANALYTICS_COPY_ZH.analysisEmpty,\n analysisInvalid: ANALYTICS_COPY_ZH.analysisInvalid, analysisScope: 'Scope', analysisScanned: 'Sessions read', analysisMatched: 'Sessions with requests', analysisUnreadable: 'Read failures', analysisSkipped: 'Skipped',\n analysisPartial: ANALYTICS_COPY_ZH.analysisPartial, analysisCatalog: ANALYTICS_COPY_ZH.analysisCatalog,\n analysisUnpriced: ANALYTICS_COPY_ZH.analysisUnpriced,\n analysisOverview: 'Usage overview', analysisSections: 'Analysis sections', analysisHistory: 'Recorded usage', analysisSimulation: 'Price simulation', analysisByModel: 'Model usage comparison', analysisModelHint: 'Bars show each share of the known cost subtotal; expand for details.',\n analysisIntro: 'Review recorded usage and compare model cost and response times.', analysisModel: 'Model', analysisCostShare: 'Known cost / share', analysisNoShare: ANALYTICS_COPY_ZH.analysisNoShare, analysisShareHint: 'Share of the known cost subtotal',\n analysisSimulationHeading: 'Price simulation for the same workload', analysisSimulationHint: 'Differences use all selected recorded requests repriced at current rates as the baseline. Negative means lower cost; only complete coverage is compared.', analysisSimulationCost: 'Simulated cost', analysisCoverage: 'Priced coverage', analysisUsd: 'USD', analysisTokenUnit: 'tokens',\n analysisScenarioMonthly: '30-day estimate', analysisDifference: 'vs. recorded baseline', analysisBaseline: 'Recorded cost baseline', analysisZeroBaseline: ANALYTICS_COPY_ZH.analysisZeroBaseline,\n analysisNeedRange: ANALYTICS_COPY_ZH.analysisNeedRange, analysisShortRange: ANALYTICS_COPY_ZH.analysisShortRange, analysisIncomplete: ANALYTICS_COPY_ZH.analysisIncomplete, analysisNoRequests: ANALYTICS_COPY_ZH.analysisNoRequests,\n analysisScenarioExcluded: ANALYTICS_COPY_ZH.analysisScenarioExcluded, analysisScenarioUnpriced: ANALYTICS_COPY_ZH.analysisScenarioUnpriced, analysisBaselineUnpriced: ANALYTICS_COPY_ZH.analysisBaselineUnpriced,\n analysisCost: 'Known cost · USD', analysisRequests: 'Model requests', analysisSessionCount: 'Sessions', analysisResponse: 'Mean response', analysisFirstToken: 'Mean first token', analysisSpeed: 'Output speed', analysisSeconds: 's', analysisSpeedUnit: 'tokens/s',\n analysisPriced: 'Priced requests', analysisTimed: 'Response samples', analysisFirstTokenSamples: 'First-token samples', analysisDecodeSamples: 'Decode samples', analysisUsageSamples: 'Usage samples', analysisAverage: 'Per session', analysisMissing: ANALYTICS_COPY_ZH.analysisMissing,\n analysisDetails: 'View aggregate details', analysisTokens: 'Tokens and cache', analysisInput: 'Uncached input', analysisOutput: 'Output', analysisCacheRead: 'Cache read', analysisCacheWrite: 'Cache write',\n analysisOutcome: 'Request outcomes', analysisCompleted: 'Completed', analysisFailed: 'Failed', analysisRetries: 'Host retries', analysisCancelled: 'Cancelled', analysisUnknown: 'Unknown outcome', analysisSamples: 'Samples', analysisSessionCost: 'Sessions and cost',\n analysisMonthly: '30-day extrapolation from this range', analysisMonthlyHint: 'Requires a complete, fully priced date range spanning at least one day.',\n analysisRules: 'Statistics and simulation notes', analysisShortBasis: 'Estimated at current prices, not an invoice. Missing usage and timing stay unknown.',\n analysisBasis: 'Repriced with the current snapshot; not an invoice. Excludes subscriptions and top-ups. Tokens are not account credits. Requests have no task boundaries; no task quality or intelligence scores. Missing usage and timing stay unknown.',\n analysisAssumption: 'Compares model prices using original tokens and request times. Output length, cache hits, retries and quality may change with another model. Makes no model calls or automatic recommendations.',\n analysisContext: 'Context tokens', analysisCapabilities: 'Model capabilities', analysisInputType: 'Input type', analysisEfforts: 'Reasoning efforts', analysisExcluded: 'Over context limit', analysisUnknownPrice: 'Unknown usage or price', analysisSearch: 'Filter simulation models', analysisSearchPlaceholder: 'Model name or ID', analysisNoMatches: ANALYTICS_COPY_ZH.analysisNoMatches,\n analysisImages: 'Images supported', analysisTextOnly: 'Text only', analysisNoEfforts: 'No reasoning efforts listed',\n analysisCoverageHint: 'Response time runs from step/retry start to model settlement, includes preparation and excludes subsequent tools. First token includes reasoning and tool arguments. Speed uses output tokens with decode timing. Simulation does not validate image/tool compatibility or prove account entitlement.',\n effortNone: 'None', effortLow: 'Low', effortMedium: 'Medium', effortHigh: 'High', effortXhigh: 'Extra high', effortMax: 'Max',\n}\n","/**\n * Bilingual copy for the Command Code **plans & quota panel** (the sidebar\n * footer card and the center-column dashboard it opens).\n *\n * The panel follows the harness's active language: `PANEL_LOCALE_NS` is a\n * registered locale namespace (`ctx.locale.register`), both panel slot\n * registrations declare it, and the renderer hands the component a `t` seat\n * whose identity changes on a language switch (so a memoized panel re-renders).\n * {@link buildPanelView} takes that translator as an input and builds every\n * string through it, so the projection stays React-free and testable and no\n * component carries copy of its own. The settings page keeps its own\n * `settings.commandcode` namespace (see `./locales.ts`); the two never mix.\n *\n * @module dsh-commandcode-provider/client/panel-copy\n */\n\nimport { ANALYTICS_COPY_ZH, ANALYTICS_COPY_EN, type AnalyticsKey } from './analytics-copy.ts'\n\ndeclare module '@deepseek-ai/dsh-client-ui-slots' {\n interface LocaleNamespaceMap {\n /** Copy of the plans & quota panel (footer card + dashboard). */\n 'panel.commandcode': PanelKey\n }\n}\n\n/**\n * The plans & quota panel key set. `zh` is the source of truth for the key set\n * (repo convention); en must carry the exact same keys — a mismatch is a\n * compile error at the register site.\n */\nexport type PanelKey =\n | AnalyticsKey\n /** Footer card title and panel heading. */\n | 'nav'\n /** Panel sub-heading under the title. */\n | 'subtitle'\n /** Refresh button / in-flight label. */\n | 'refresh'\n | 'refreshing'\n /** Dashboard exit: the button's accessible name and its tooltip. */\n | 'close'\n | 'closeHint'\n /** First-paint fetch. */\n | 'loading'\n /** No credential at all: how to get one. */\n | 'noKey'\n | 'noKeyHint'\n /** Report section headings. */\n | 'plan'\n | 'credits'\n | 'limits'\n | 'usage'\n /** Monthly credit state and its tiles. */\n | 'monthly'\n | 'monthlyLimit'\n | 'monthlyUsed'\n | 'remaining'\n | 'purchased'\n | 'free'\n /** Usage-window rows (long labels in the dashboard, short in the footer). */\n | 'fiveHour'\n | 'weekly'\n | 'fiveHourShort'\n | 'weeklyShort'\n | 'windowUnlimited'\n | 'exceeded'\n | 'exhausted'\n | 'resets'\n /** Usage tiles. */\n | 'requests'\n | 'failed'\n | 'completed'\n | 'usageBillingPeriod'\n | 'usagePeriodUnknown'\n | 'successRate'\n | 'spend'\n | 'tokens'\n | 'tokensIn'\n | 'tokensOut'\n /** Meta line. */\n | 'periodEnds'\n | 'updated'\n | 'partial'\n /** Rotation state on an account. */\n | 'active'\n | 'coolingDown'\n | 'invalidKey'\n /** Footer-card plan fallbacks. */\n | 'unconfigured'\n | 'unavailable'\n /** Whole-report failures (mirrors the settings card's blocked taxonomy). */\n | 'errorInvalidKey'\n | 'errorInvalidKeyHint'\n | 'errorServiceUnavailable'\n | 'errorServiceUnavailableHint'\n | 'errorNetwork'\n | 'errorNetworkHint'\n | 'errorInvalidResponse'\n | 'errorInvalidResponseHint'\n /** A fetch that failed for any other reason. */\n | 'errorGeneric'\n\n/** The locale namespace both panel slots bind their `t` seat to. */\nexport const PANEL_LOCALE_NS = 'panel.commandcode'\n\n/** A panel translator: one key in, one localized string out. */\nexport type PanelTranslator = (key: PanelKey) => string\n\n/** The panel's Simplified Chinese string table (the key-set source of truth). */\nexport const PANEL_COPY_ZH: Record = {\n ...ANALYTICS_COPY_ZH,\n nav: 'Command Code',\n subtitle: '套餐、额度与配额窗口',\n refresh: '刷新',\n refreshing: '刷新中…',\n close: '关闭',\n closeHint: '返回会话',\n loading: '正在获取账户用量…',\n noKey: '尚未配置 API 密钥',\n noKeyHint: '在 设置 → Command Code 中粘贴密钥或登录后,点击刷新。',\n plan: '套餐',\n credits: '额度',\n limits: '配额窗口',\n usage: '用量',\n completed: '成功',\n usageBillingPeriod: '官方账期用量',\n usagePeriodUnknown: '官方用量汇总,统计周期未确认',\n monthly: '月额度',\n monthlyLimit: '月额度上限',\n monthlyUsed: '本月已用',\n remaining: '剩余',\n purchased: '已购',\n free: '赠送',\n fiveHour: '5 小时窗口',\n weekly: '每周窗口',\n fiveHourShort: '5 小时',\n weeklyShort: '每周',\n windowUnlimited: '不限',\n exceeded: '已超限',\n exhausted: '已用尽',\n resets: '重置于',\n requests: '请求',\n failed: '失败',\n successRate: '成功率',\n spend: '花费',\n tokens: 'Token',\n tokensIn: '入',\n tokensOut: '出',\n periodEnds: '账期截止',\n updated: '更新于',\n partial: '部分端点数据不可用',\n active: '当前使用',\n coolingDown: '限额冷却中',\n invalidKey: '密钥无效',\n unconfigured: '未配置',\n unavailable: '无数据',\n errorInvalidKey: 'API 密钥无效或已过期',\n errorInvalidKeyHint: '服务端拒绝了全部请求(401)。请检查该账户的密钥,或到 commandcode.ai 控制台重新生成。',\n errorServiceUnavailable: 'Command Code 服务暂时不可用',\n errorServiceUnavailableHint: '服务端返回错误(5xx),请稍后点击刷新重试。',\n errorNetwork: '无法连接 Command Code 服务',\n errorNetworkHint: '所有请求都没有到达服务端。请检查网络连接或 API 地址设置。',\n errorInvalidResponse: 'Command Code 响应无法读取',\n errorInvalidResponseHint: '已收到响应,但正文读取或解析失败。下方详情可区分读取超时、中断与格式异常;可先点击刷新重试。',\n errorGeneric: '用量获取失败',\n}\n\n/** The panel's English string table (must mirror {@link PANEL_COPY_ZH}). */\nexport const PANEL_COPY_EN: Record = {\n ...ANALYTICS_COPY_EN,\n nav: 'Command Code',\n subtitle: 'Plans, credits and quota windows',\n refresh: 'Refresh',\n refreshing: 'Refreshing…',\n close: 'Close',\n closeHint: 'Back to the conversation',\n loading: 'Loading account usage…',\n noKey: 'No API key configured',\n noKeyHint: 'Paste a key — or sign in — under Settings → Command Code, then refresh.',\n plan: 'Plan',\n credits: 'Credits',\n limits: 'Quota windows',\n usage: 'Usage',\n completed: 'completed',\n usageBillingPeriod: 'Official billing-period usage',\n usagePeriodUnknown: 'Official usage summary; the billing period is unconfirmed',\n monthly: 'Monthly',\n monthlyLimit: 'Monthly limit',\n monthlyUsed: 'Monthly used',\n remaining: 'Remaining',\n purchased: 'Purchased',\n free: 'Free',\n fiveHour: '5-hour window',\n weekly: 'Weekly window',\n fiveHourShort: '5-hour',\n weeklyShort: 'Weekly',\n windowUnlimited: 'unlimited',\n exceeded: 'Exceeded',\n exhausted: 'Used up',\n resets: 'Resets',\n requests: 'Requests',\n failed: 'failed',\n successRate: 'Success rate',\n spend: 'Spend',\n tokens: 'Tokens',\n tokensIn: 'in',\n tokensOut: 'out',\n periodEnds: 'Period ends',\n updated: 'Updated',\n partial: 'Some endpoint data unavailable',\n active: 'Active',\n coolingDown: 'Cooling down',\n invalidKey: 'Invalid key',\n unconfigured: 'Not configured',\n unavailable: 'No data',\n errorInvalidKey: 'API key invalid or expired',\n errorInvalidKeyHint: 'The server rejected every request (401). Check the key for this account, or generate a new one in the commandcode.ai console.',\n errorServiceUnavailable: 'The Command Code service is temporarily unavailable',\n errorServiceUnavailableHint: 'The server returned errors (5xx). Try Refresh again in a moment.',\n errorNetwork: 'Could not reach the Command Code service',\n errorNetworkHint: 'No request reached the server. Check your network connection or the API base setting.',\n errorInvalidResponse: 'Could not read the Command Code response',\n errorInvalidResponseHint: 'Responses arrived, but reading or parsing their bodies failed. Details below distinguish timeouts, interrupted reads, and invalid formats. Try Refresh again.',\n errorGeneric: 'Could not fetch account usage',\n}\n\n/** Every panel key, in the English table's declaration order. */\nexport const PANEL_KEYS: readonly PanelKey[] = Object.keys(PANEL_COPY_EN) as PanelKey[]\n\n/**\n * The English translator. Used as the fallback when no locale seat is\n * available (a defensive path: every supported engine supplies one) and as the\n * default in tests that only assert the projection's figures.\n */\nexport function panelTextEN(key: PanelKey): string {\n return PANEL_COPY_EN[key] ?? key\n}\n","/**\n * View model for the Command Code plans & quota panel (the sidebar footer card\n * and the dashboard it opens).\n *\n * JSX-free and React-free, mirroring `./settings.ts` / `./usage.ts`: it turns\n * the shared usage snapshot into one presentation tree both components render,\n * and owns the one shared side effect (the throttled auto refresh below). Node\n * tests drive everything here without a DOM.\n *\n * Every displayed string is decided here, as a `PanelKey` plus a `text` record\n * resolved through the injected translator, so the components carry no copy of\n * their own and the panel follows the harness's active language\n * (`./panel-copy.ts` owns both dictionaries and the `panel.commandcode` locale\n * namespace; the slots hand the translator in).\n *\n * @module dsh-commandcode-provider/client/panel\n */\n\nimport type { CommandCodeUsageReport } from '../adapter.ts'\nimport type { CommandCodeAccountUsage } from '../usage-wire.ts'\nimport type { UsagePageState } from './usage.ts'\nimport { compactCountTitle, formatCompactCount, formatMoney, formatMoneyExact, formatSuccessRate, formatTokensCompact, formatResetAt, formatUsageBillingPeriod } from '../display-format.ts'\nimport { PANEL_KEYS, panelTextEN } from './panel-copy.ts'\nimport type { PanelKey, PanelTranslator } from './panel-copy.ts'\n\n/** One quota window (5-hour or weekly) in display form. */\nexport interface PanelWindowView {\n /** Row-label key into the view's `text` record. */\n label: PanelKey\n /** `used / cap`, or just `used` when the window is uncapped. */\n value: string\n /** The window reports a cap, so `percent` is meaningful. */\n capped: boolean\n /** Percentage actually consumed (may exceed 100 when over the cap). */\n percent: number\n /** Fill width for the bar, clamped to [0, 100]. */\n barPercent: number\n /** Window is over its cap. */\n exceeded: boolean\n /** Local reset time, empty when the endpoint reported none. */\n resetsAt: string\n}\n\n/**\n * Monthly credit state. Consumption is derived the way the official CLI derives\n * it (`getCreditDepletionPct`): the plan's credit total is the LIMIT and the\n * billing endpoint's `credits.monthlyCredits` is the REMAINING balance, so\n * consumption is `limit - remaining`. Purchased and free credits are separate\n * balances that extend what an account can spend, so they are their own tiles.\n */\nexport interface PanelMonthlyView {\n /**\n * A ratio is meaningful — the plan published a credit total AND the billing\n * endpoint published the balance left of it. When false the view draws no bar:\n * a percentage needs both halves, and inventing either is how a failed billing\n * call becomes a confident \"100% used\".\n */\n known: boolean\n /** Plan credit total for the period (the limit); a dash when unreported. */\n limit: string\n /** Consumed this period (`limit - remaining`); a dash until both are known. */\n used: string\n /** Credits still available; a dash when the balance was not reported. */\n remaining: string\n /** Purchased top-up balance. */\n purchased: string\n /** Promotional balance. */\n free: string\n /** Consumption as a percentage of the limit; 0 when there is no ratio. */\n percent: number\n /** Fill width for the bar, clamped to [0, 100]. */\n barPercent: number\n /** The plan's credits are used up. */\n exhausted: boolean\n /** Billing period end, local date; empty when unreported. */\n periodEnds: string\n}\n\n/** One compact bar in the sidebar footer card. */\nexport interface PanelFooterBar {\n /** Row label key (short forms: `Monthly`, `5-hour`, `Weekly`). */\n label: PanelKey\n /** Printed right-hand percentage, e.g. `32%`; empty when there is no ratio. */\n percent: string\n /** Fill width, clamped to [0, 100]. */\n barPercent: number\n /** Render in the warning colour. */\n warn: boolean\n /**\n * This window's own spend against its limit, e.g. `$1.32 / $6.00`. RENDERED,\n * not just a tooltip: the card exists to show these figures, and the\n * magnitudes are small dollar amounts.\n */\n detail: string\n}\n\n/** One usage tile. */\nexport interface PanelStatView {\n label: PanelKey\n value: string\n /** Secondary line, empty when there is none. */\n sub: string\n /** 精确值悬停提示;只在紧凑显示确实丢掉信息时才有,否则省略。 */\n title?: string | undefined\n}\n\n/** One pool account's report, ready to render. */\nexport interface PanelAccountView {\n id: string\n label: string\n /** The account's display name (user name, else account name); empty when unreported. */\n owner: string\n /** Subscription display name; empty when unreported. */\n planName: string\n /** Subscription status when it is not a plain `active`; empty otherwise. */\n planStatus: string\n /** Rotation/credential state ('invalidKey' / 'coolingDown'); undefined when plain. */\n mark: PanelKey | undefined\n /** Known cooldown end, appended to the cooling-down badge; empty otherwise. */\n cooldownUntil: string\n /** No credential resolved for this slot. */\n unconfigured: boolean\n /** Billing period end, empty when unreported. */\n periodEnds: string\n /** Whether the account currently serves requests. */\n active: boolean\n /** Monthly credit state; undefined when neither endpoint reported it. */\n monthly: PanelMonthlyView | undefined\n windows: PanelWindowView[]\n stats: PanelStatView[]\n /** 官方统计周期;与订阅未对齐时显示未知,不能用账期截止日单独推断。 */\n usagePeriod: string\n}\n\n/** What actually went wrong, once — for the alert box. */\nexport interface PanelFailureView {\n title: PanelKey\n /** The actionable line under the title. */\n hint: PanelKey\n /** The underlying transport message, shown small; empty when there is none. */\n detail: string\n}\n\n/** The whole panel, in render order. */\nexport interface PanelView {\n /** Every localized string this view references, by key. */\n text: Partial>\n /** Footer-card plan text (`Go`, `Pro`, …), or a state word. */\n planName: string\n /** Footer-card rotation/credential state line; empty when nothing to say. */\n status: string\n /**\n * The compact bars the sidebar footer card stacks: the two quota windows an\n * account actually runs into, 5-hour first then weekly. The monthly bar\n * belongs to the DASHBOARD alone — it moves once a billing period, whereas\n * these two are what stop a session — and a window with no cap is left out\n * (no ratio to draw).\n */\n footerBars: PanelFooterBar[]\n /**\n * This period's spend in dollars; empty when the usage endpoint reported\n * nothing. NOT drawn as its own row — the card's visible figures are the two\n * windows' own spend (see {@link PanelFooterBar.detail}) — so it rides the\n * tooltip and the accessible name instead.\n */\n cost: string\n /**\n * The footer card's accessible name and tooltip: `Command Code · Pro ·\n * 5-hour $0.04 / $3.00 (1%) · Weekly $1.32 / $6.00 (22%) · Spend $1.32`.\n * Always starts with the visible title, so the accessible name contains the\n * visible label.\n */\n footTitle: string\n /** Every account, in rotation order (empty when there is nothing to show). */\n accounts: PanelAccountView[]\n /** Id of the account the panel opens on (the serving one), if any. */\n selectedId: string | undefined\n /** That account's view, for the footer card; undefined with no accounts. */\n selected: PanelAccountView | undefined\n /** A fetch is in flight and no data has landed for this paint. */\n loading: boolean\n /** No credential is configured at all. */\n noKey: boolean\n /** Report-level failure box; undefined when the report is usable. */\n failure: PanelFailureView | undefined\n /** A fetch failed while data is still on screen. */\n staleError: string | undefined\n /** Endpoint-level partial failure note; undefined when every endpoint answered. */\n partial: PanelKey | undefined\n /** Freshness line, empty when nothing has been fetched. */\n updatedAt: string\n}\n\n/** Inputs {@link buildPanelView} needs beyond the usage snapshot. */\nexport interface PanelViewInput {\n usage: UsagePageState\n /** Whether any account holds a credential (the settings controller's fact). */\n apiKeyConfigured: boolean\n /**\n * Locale translator for every label the view composes. The panel slots bind\n * their `t` seat to the `panel.commandcode` namespace and pass it here; an\n * omitted one falls back to English (the tests' default, and the defensive\n * path when no locale face is installed).\n */\n t?: PanelTranslator\n}\n\n/** A quota window's state as the wire carries it. */\ninterface WindowInput {\n used: number\n cap: number\n exceeded: boolean\n resetAt: number\n}\n\n/** `$1.23`, and `$0.0123` only when the amount is too small for cents to show it. */\nfunction money(value: number): string {\n if (value === 0) return formatMoney(0)\n return Math.abs(value) < 0.01 ? formatMoneyExact(value) : formatMoney(value)\n}\n\n/**\n * What a figure shows when the endpoint that carries it did not report one. A\n * dash, never a zero: the panel exists to state what the account has spent, so\n * \"we were not told\" has to look different from \"nothing\".\n */\nconst UNREPORTED = '—'\n\n/** Local reset time; empty when the endpoint reported none. */\nfunction resetText(ms: number): string {\n return formatResetAt(ms)\n}\n\n/** Local short date; empty when unset. */\nfunction dateText(ms: number): string {\n if (ms <= 0) return ''\n return new Date(ms).toLocaleDateString()\n}\n\n/** Local time-of-day; empty when unset. */\nfunction timeText(ms: number): string {\n if (ms <= 0) return ''\n return new Date(ms).toLocaleTimeString()\n}\n\n/**\n * Consumption as a percentage, NOT clamped at 100 — an over-quota window\n * reports its real overshoot (150%), which is what the printed figure should\n * say. Bar widths clamp separately via {@link barPercent}.\n */\nfunction rawPercent(used: number, cap: number): number {\n if (cap <= 0) return 0\n return Math.round((used / cap) * 100)\n}\n\n/** A percentage usable as a CSS width, clamped into [0, 100]. */\nfunction barPercent(percent: number): number {\n return Math.min(100, Math.max(0, percent))\n}\n\n/** Build one quota-window view. */\nfunction windowView(label: PanelKey, limit: WindowInput): PanelWindowView {\n const percent = rawPercent(limit.used, limit.cap)\n const capped = limit.cap > 0\n return {\n label,\n // Spend only: an uncapped window has no denominator, so its row pairs this\n // figure with the \"unlimited\" label instead of a `used / cap` it lacks.\n value: capped ? `${money(limit.used)} / ${money(limit.cap)}` : money(limit.used),\n capped,\n percent,\n barPercent: barPercent(percent),\n exceeded: limit.exceeded,\n resetsAt: resetText(limit.resetAt),\n }\n}\n\n/**\n * Build the monthly credit view from the two endpoints that carry it.\n *\n * The limit is the PLAN's credit total, not the billing endpoint's\n * `monthlyCredits` (that field is a remaining balance — see\n * {@link PanelMonthlyView}), so a plan that publishes no total still shows its\n * balances, just without a ratio.\n *\n * The trap this guards: a MISSING balance is not a consumed one. The billing\n * endpoint is one of four the report fetches in parallel, so it fails on its\n * own while the plan still arrives, and reading the absent balance as 0 turns\n * that partial failure into `limit - 0 = limit` — a confident \"100% used\" for\n * an account that may have spent nothing. The official CLI draws no meter unless\n * the credits payload is present at all (`hasCreditsInfo`); every derived figure\n * here stays a placeholder until the balance reported.\n */\nfunction monthlyView(report: CommandCodeUsageReport): PanelMonthlyView | undefined {\n const credits = report.credits\n const plan = report.plan\n if (credits === undefined && plan === undefined) return undefined\n\n const limitValue = plan?.monthlyCredits ?? null\n // Only an EXPLICIT `false` means the balance was omitted. An unset flag comes\n // from a Host half older than the field, which always sent a real number.\n const remainingReported = credits !== undefined && credits.monthlyReported !== false\n const remaining = remainingReported ? Math.max(0, credits.monthlyCredits) : 0\n // A ratio needs BOTH halves: the plan's total and the balance left of it.\n const known = limitValue !== null && limitValue > 0 && remainingReported\n const used = known ? Math.max(0, limitValue - remaining) : 0\n const percent = known ? rawPercent(used, limitValue) : 0\n\n return {\n known,\n limit: limitValue !== null ? money(limitValue) : UNREPORTED,\n used: known ? money(used) : UNREPORTED,\n remaining: remainingReported ? money(remaining) : UNREPORTED,\n purchased: credits !== undefined && credits.purchasedReported !== false ? money(Math.max(0, credits.purchasedCredits)) : UNREPORTED,\n free: credits !== undefined && credits.freeReported !== false ? money(Math.max(0, credits.freeCredits)) : UNREPORTED,\n percent,\n barPercent: barPercent(percent),\n exhausted: known && remaining <= 0,\n periodEnds: dateText(plan?.currentPeriodEnd ?? 0),\n }\n}\n\n/** Build one account's view. */\nfunction accountView(entry: CommandCodeAccountUsage, t: PanelTranslator): PanelAccountView {\n const { report } = entry\n const account = report.account\n const plan = report.plan\n const credits = report.credits\n const usage = report.usage\n const usageRange = formatUsageBillingPeriod(usage?.periodStart, plan?.currentPeriodStart, plan?.currentPeriodEnd)\n\n const stats: PanelStatView[] = []\n if (usage !== undefined) {\n stats.push({\n label: 'requests',\n // 与设置页同一套紧凑规则:这里是同一份用量的另一个展示面,\n // 两边必须给出同一个数字的同一个写法。\n value: formatCompactCount(usage.totalCount),\n sub: `${formatCompactCount(usage.completedCount)} ${t('completed')} / ${formatCompactCount(usage.failedCount)} ${t('failed')}`,\n title: compactCountTitle([\n [t('requests'), usage.totalCount],\n [t('completed'), usage.completedCount],\n [t('failed'), usage.failedCount],\n ] as const),\n })\n stats.push({ label: 'successRate', value: `${formatSuccessRate(usage.successRate)}%`, sub: '' })\n stats.push({\n label: 'spend',\n value: formatMoneyExact(usage.totalCost),\n sub: `${formatMoney(usage.totalCredits)} credits`,\n })\n stats.push({\n label: 'tokens',\n value: formatTokensCompact(usage.totalTokensIn + usage.totalTokensOut),\n sub: `${formatTokensCompact(usage.totalTokensIn)} ${t('tokensIn')} / ${formatTokensCompact(usage.totalTokensOut)} ${t('tokensOut')}`,\n })\n }\n\n const windows: PanelWindowView[] = []\n // One row per window the endpoint actually REPORTED: an unlimited plan\n // reports none, and drawing two zero-cap rows would invent a limit it does not\n // have. A window reporting `cap === 0` is uncapped spend and does get a row.\n if (credits?.fiveHour !== undefined) windows.push(windowView('fiveHour', credits.fiveHour))\n if (credits?.weekly !== undefined) windows.push(windowView('weekly', credits.weekly))\n\n // Rotation/credential state: the serving account first, then the two marks\n // the pool can carry, then a cooldown whose end time is known.\n let mark: PanelKey | undefined\n if (entry.active) mark = 'active'\n else if (entry.mark === 'invalid-credential') mark = 'invalidKey'\n else if (entry.cooldownUntil > 0 || entry.mark === 'rate-limit') mark = 'coolingDown'\n\n return {\n id: entry.id,\n label: entry.label,\n owner: account === undefined ? '' : account.userName || account.name,\n planName: plan?.name ?? '',\n planStatus: plan !== undefined && plan.status !== '' && plan.status !== 'active' ? plan.status : '',\n mark,\n cooldownUntil: entry.cooldownUntil > 0 ? resetText(entry.cooldownUntil) : '',\n unconfigured: !entry.configured,\n periodEnds: dateText(plan?.currentPeriodEnd ?? 0),\n active: entry.active,\n monthly: monthlyView(report),\n windows,\n stats,\n usagePeriod: usage === undefined ? '' : usageRange\n ? `${t('usageBillingPeriod')} ${usageRange}`\n : t('usagePeriodUnknown'),\n }\n}\n\n/** The report-level failure box, or undefined when the report is usable. */\nfunction failureView(state: UsagePageState): PanelFailureView | undefined {\n const blockedEntry = state.report?.accounts.find((entry) => entry.report.blocked !== undefined)\n const blocked = blockedEntry?.report.blocked\n // Preserve each endpoint's status or transport error beside the summary.\n const detail = (blockedEntry?.report.failures ?? []).join(' · ')\n if (blocked === 'invalid-key') {\n return { title: 'errorInvalidKey', hint: 'errorInvalidKeyHint', detail }\n }\n if (blocked === 'service-unavailable') {\n return { title: 'errorServiceUnavailable', hint: 'errorServiceUnavailableHint', detail }\n }\n if (blocked === 'network') {\n return { title: 'errorNetwork', hint: 'errorNetworkHint', detail }\n }\n if (blocked === 'invalid-response') {\n return { title: 'errorInvalidResponse', hint: 'errorInvalidResponseHint', detail }\n }\n // A transport-level failure (unmounted Remote, offline browser) arrives as\n // the controller's own error rather than as a blocked report.\n if (state.status === 'error' && state.report === undefined) {\n return { title: 'errorGeneric', hint: 'errorGeneric', detail: state.error ?? '' }\n }\n return undefined\n}\n\n/**\n * Every panel string, resolved once per projection through the translator. One\n * object with all keys (rather than per-field lookups in the components) keeps\n * the copy table and the render sites in lockstep: a key cannot be read from\n * `text` unless {@link PANEL_KEYS} declares it.\n */\nfunction panelStrings(t: PanelTranslator): Record {\n const out = {} as Record\n for (const key of PANEL_KEYS) out[key] = t(key)\n return out\n}\n\n/**\n * Project the shared usage snapshot into the panel's render tree.\n *\n * Deduplication matches the settings card: hand-edited settings can name one\n * credential twice.\n */\nexport function buildPanelView(input: PanelViewInput): PanelView {\n const { usage } = input\n const t = input.t ?? panelTextEN\n const seen = new Set()\n const entries = (usage.report?.accounts ?? []).filter((entry) => {\n if (seen.has(entry.id)) return false\n seen.add(entry.id)\n return true\n })\n const accounts = entries.map((entry) => accountView(entry, t))\n const selectedEntry = entries.find((entry) => entry.active) ?? entries[0]\n const selectedView = accounts.find((view) => view.id === selectedEntry?.id)\n\n // The footer card stacks BOTH quota windows — the two limits an account\n // actually runs into — 5-hour first (the tighter and nearer one), then\n // weekly. `barPercent` clamps the fill; the printed percentage keeps the true\n // consumption, so an over-cap window still reads 150%.\n const footerBars: PanelFooterBar[] = []\n const windowBars: Array<[PanelKey, WindowInput | undefined]> = [\n ['fiveHourShort', selectedEntry?.report.credits?.fiveHour],\n ['weeklyShort', selectedEntry?.report.credits?.weekly],\n ]\n for (const [label, window] of windowBars) {\n if (window === undefined || window.cap <= 0) continue\n const percent = rawPercent(window.used, window.cap)\n footerBars.push({\n label,\n percent: `${percent}%`,\n barPercent: barPercent(percent),\n warn: window.exceeded,\n detail: `${money(window.used)} / ${money(window.cap)}`,\n })\n }\n\n // The card's one non-ratio figure: what this period has cost in dollars.\n const totalCost = selectedEntry?.report.usage?.totalCost\n const cost = totalCost === undefined ? '' : money(totalCost)\n\n let status = ''\n if (entries.length > 0 && !entries.some(entry => entry.configured)) status = t('unconfigured')\n else if (selectedView?.mark !== undefined && selectedView.mark !== 'active') status = t(selectedView.mark)\n else if (selectedEntry === undefined) status = t('unavailable')\n\n const planName = selectedView !== undefined && selectedView.planName !== '' ? selectedView.planName : t('nav')\n // `planName` falls back to the panel name, so it is only a second part when it\n // actually names a plan — otherwise the title would read `Command Code ·\n // Command Code`.\n const titleParts = planName === t('nav') ? [planName] : [t('nav'), planName]\n for (const bar of footerBars) {\n const figures = bar.detail === '' ? '' : ` ${bar.detail}`\n titleParts.push(`${t(bar.label)}${figures} (${bar.percent})`)\n }\n if (cost !== '') titleParts.push(`${t('spend')} ${cost}`)\n\n return {\n text: panelStrings(t),\n planName,\n status,\n footerBars,\n cost,\n footTitle: titleParts.join(' · '),\n accounts,\n selectedId: selectedEntry?.id,\n selected: selectedView,\n loading: usage.status === 'loading' && usage.report === undefined,\n noKey: entries.length > 0 && !entries.some(entry => entry.configured),\n failure: failureView(usage),\n staleError: usage.status === 'error' && usage.report !== undefined ? usage.error ?? '' : undefined,\n partial: (usage.report?.accounts.some((entry) => entry.report.failures.length > 0 && entry.report.blocked === undefined) ?? false)\n ? 'partial'\n : undefined,\n updatedAt: timeText(usage.fetchedAt ?? 0),\n }\n}\n\n// --- Auto refresh (one shared loop, started by whichever surface mounts first)\n\n/**\n * How often the panel re-reads the report while a surface is mounted. The quota\n * windows move slowly and one report costs four upstream calls, so this is a\n * background freshness tick, not a live meter.\n */\nexport const PANEL_AUTO_REFRESH_MS = 120_000\n\n/** The narrow face of `CommandCodeUsageController` this module drives. */\nexport interface RefreshSource {\n state(): UsagePageState\n refresh(): Promise\n}\n\n/** Timer seam: injectable so tests never wait on real time. */\nexport interface AutoRefreshTimer {\n set(callback: () => void, ms: number): unknown\n clear(handle: unknown): void\n}\n\n/** The default timer (the client bundle runs in a browser; node tests inject one). */\nconst REAL_TIMER: AutoRefreshTimer = {\n set: (callback, ms) => setTimeout(callback, ms),\n clear: (handle) => clearTimeout(handle as ReturnType),\n}\n\n/** Live mount count of {@link startPanelAutoRefresh}. */\nlet references = 0\n/** Owner ticket of the running loop, if any. */\nlet activeTicket: number | undefined\n/** Ticket handed to the next starter. */\nlet ticketSeq = 0\n/** Pending timer handle of the running loop. */\nlet handle: unknown\n\n/**\n * Start the shared auto refresh. One fetch when the surface appears (the sidebar\n * row is the point of the panel — it must be current, not wait for a click), then\n * a tick every {@link PANEL_AUTO_REFRESH_MS} while a surface stays mounted.\n *\n * Reference-counted: the sidebar entry and the dashboard can be mounted at once,\n * so only the first start fetches and only the last stop halts the loop. Every\n * tick goes through `usage.refresh()`, which collapses a concurrent fetch onto\n * the in-flight one. Returns the disposer that drops this surface's reference.\n *\n * @param usage - the shared usage controller.\n * @param isConfigured - whether a credential exists right now (re-read per tick).\n * @param timer - timer seam for tests.\n */\nexport function startPanelAutoRefresh(\n usage: RefreshSource,\n isConfigured: () => boolean,\n timer: AutoRefreshTimer = REAL_TIMER,\n): () => void {\n references += 1\n const ticket = ++ticketSeq\n const tick = (): void => {\n if (activeTicket !== ticket) return\n if (isConfigured()) void usage.refresh()\n handle = timer.set(tick, PANEL_AUTO_REFRESH_MS)\n }\n\n if (activeTicket === undefined) {\n activeTicket = ticket\n handle = timer.set(tick, PANEL_AUTO_REFRESH_MS)\n // First paint: refresh immediately so the row is never blank on arrival.\n if (isConfigured()) void usage.refresh()\n }\n\n let stopped = false\n return () => {\n if (stopped) return\n stopped = true\n references -= 1\n // Still mounted elsewhere: drop this reference only. The check is the\n // REFCOUNT, not this surface's ticket — the surface that started the loop\n // is not necessarily the last to unmount.\n if (references > 0) return\n activeTicket = undefined\n if (handle !== undefined) {\n timer.clear(handle)\n handle = undefined\n }\n }\n}\n\n/**\n * Drop every live reference and halt the loop without a timer.\n *\n * Exported for tests only: the loop's state is module-level on purpose (two\n * surfaces, one upstream poll). Production code releases through the disposer\n * {@link startPanelAutoRefresh} returns.\n */\nexport function resetPanelAutoRefresh(): void {\n references = 0\n activeTicket = undefined\n handle = undefined\n}\n","/** 模型分析的只读契约;只传数字和模型能力,不传会话正文、标题、路径或密钥。 */\nimport type { InvocationDescriptor, TypertRemoteContribution } from '@deepseek-ai/dsh-typert-protocol'\nimport { makeBoundaryValidator, makeRemoteDescriptor, makeStrictCodec, REMOTE_PACKAGE } from './wire-shared.ts'\nimport type { CostTokens } from './cost-facts.ts'\n\nexport type AnalyticsQuery = { mode: 'recent'; limit: number } | { mode: 'range'; from: number; to: number }\nexport interface AnalyticsMetrics {\n sessions: number; requests: number; completed: number; failed: number; cancelled: number; unknown: number; retries: number\n usageSamples: number; pricedRequests: number; cost: number; tokens: CostTokens\n latencySamples: number; latencyMs: number; ttftSamples: number; ttftMs: number; decodeSamples: number; decodeMs: number; decodeTokens: number\n}\nexport interface AnalyticsModel extends AnalyticsMetrics { id: string }\nexport interface AnalyticsScenario {\n id: string; name: string; contextWindow: number | null; images: boolean; efforts: string[]\n cost: number; pricedRequests: number; excludedRequests: number; unknownRequests: number\n}\nexport interface AnalyticsReport {\n generatedAt: number; pricingKey: number; query: AnalyticsQuery\n status: 'ready' | 'unavailable'\n scannedSessions: number; matchedSessions: number; unreadableSessions: number; skippedSessions: number; truncated: boolean; catalogUnavailable: boolean\n totals: AnalyticsMetrics; models: AnalyticsModel[]; scenarios: AnalyticsScenario[]\n monthlyEstimate: number | null\n}\nconst g = makeBoundaryValidator('commandcode/analytics')\nconst nonnegative = (s: Record, k: string): number => {\n const n = g.numberField(s, k, k)\n return n >= 0 ? n : g.reject(k)\n}\nconst count = (s: Record, k: string): number => {\n const n = nonnegative(s, k)\n return Number.isSafeInteger(n) ? n : g.reject(k)\n}\nexport function parseAnalyticsQuery(value: unknown): AnalyticsQuery {\n const s = g.record(value, 'query')\n if (s.mode === 'recent') {\n const limit = count(s, 'limit')\n if (limit < 1 || limit > 100) return g.reject('limit')\n return { mode: 'recent', limit }\n }\n if (s.mode !== 'range') return g.reject('mode')\n const from = count(s, 'from'), to = count(s, 'to')\n if (to <= from || to - from > 366 * 86400000 || to > 8640000000000000) return g.reject('range')\n return { mode: 'range', from, to }\n}\nconst counts = ['sessions', 'requests', 'completed', 'failed', 'cancelled', 'unknown', 'retries', 'usageSamples', 'pricedRequests', 'latencySamples', 'ttftSamples', 'decodeSamples'] as const\nconst quantities = ['cost', 'latencyMs', 'ttftMs', 'decodeMs', 'decodeTokens'] as const\nconst tokenKeys = ['uncachedInputTokens', 'outputTokens', 'cacheReadTokens', 'cacheWriteTokens'] as const\nfunction metrics(value: unknown): AnalyticsMetrics {\n const s = g.record(value, 'metrics'), result = {} as AnalyticsMetrics\n for (const k of counts) result[k] = count(s, k)\n for (const k of quantities) result[k] = nonnegative(s, k)\n const tokens = g.record(s.tokens, 'tokens')\n result.tokens = Object.fromEntries(tokenKeys.map(k => [k, nonnegative(tokens, k)])) as unknown as CostTokens\n if (result.completed + result.failed + result.cancelled + result.unknown !== result.requests\n || result.pricedRequests > result.usageSamples || result.usageSamples > result.requests\n || result.retries > result.requests || result.ttftSamples > result.requests || result.latencySamples > result.requests || result.decodeSamples > result.requests) return g.reject('coverage')\n return result\n}\nconst nullable = (s: Record, k: string): number | null => s[k] === null ? null : nonnegative(s, k)\nexport function parseAnalyticsReport(value: unknown): AnalyticsReport {\n const s = g.record(value, 'report')\n if (s.status !== 'ready' && s.status !== 'unavailable') return g.reject('status')\n if (!Array.isArray(s.models) || !Array.isArray(s.scenarios) || s.models.length > 1000 || s.scenarios.length > 1000) return g.reject('models')\n return {\n generatedAt: count(s, 'generatedAt'), pricingKey: count(s, 'pricingKey'), query: parseAnalyticsQuery(s.query), status: s.status,\n scannedSessions: count(s, 'scannedSessions'), matchedSessions: count(s, 'matchedSessions'), unreadableSessions: count(s, 'unreadableSessions'), skippedSessions: count(s, 'skippedSessions'),\n truncated: g.booleanField(s, 'truncated', 'truncated'), catalogUnavailable: g.booleanField(s, 'catalogUnavailable', 'catalogUnavailable'),\n totals: metrics(s.totals), monthlyEstimate: nullable(s, 'monthlyEstimate'),\n models: s.models.map(value => { const m = g.record(value, 'model'); return { ...metrics(m), id: g.stringField(m, 'id', 'id') } }),\n scenarios: s.scenarios.map(value => {\n const m = g.record(value, 'scenario')\n if (!Array.isArray(m.efforts) || !m.efforts.every(v => typeof v === 'string')) return g.reject('efforts')\n return { id: g.stringField(m, 'id', 'id'), name: g.stringField(m, 'name', 'name'), contextWindow: nullable(m, 'contextWindow'), images: g.booleanField(m, 'images', 'images'), efforts: m.efforts as string[], cost: nonnegative(m, 'cost'), pricedRequests: count(m, 'pricedRequests'), excludedRequests: count(m, 'excludedRequests'), unknownRequests: count(m, 'unknownRequests') }\n }),\n }\n}\nexport const ANALYTICS_DESCRIPTOR: InvocationDescriptor = {\n ...makeRemoteDescriptor('commandcode/analytics', 'analytics', `${REMOTE_PACKAGE}#AnalyticsReport`, { parse: parseAnalyticsReport }),\n parameters: [{ name: 'query', wire: 'query', source: 'json' as const, codec: makeStrictCodec(`${REMOTE_PACKAGE}#AnalyticsQuery`, { parse: parseAnalyticsQuery }) }],\n}\nexport const ANALYTICS_REMOTE_CONTRIBUTION: TypertRemoteContribution = { package: REMOTE_PACKAGE, descriptors: [ANALYTICS_DESCRIPTOR] }\n","/** 只从同一份报告派生比较结果;不读取历史、不改价格,也不随浏览器当前时间重新折算。 */\nimport type { AnalyticsReport, AnalyticsScenario } from '../analytics-wire.ts'\n\nexport type EstimateUnavailable = 'unavailable' | 'empty' | 'partial' | 'excluded' | 'coverage' | 'baseline' | 'recent' | 'short-range'\ntype Estimate = { value: number; reason?: never } | { value: null; reason: EstimateUnavailable }\nexport interface ScenarioComparison {\n monthly: Estimate\n difference: Estimate\n /** 正数表示比历史基准贵;基准为零时仍可比较金额,但不能计算比例。 */\n differencePercent: number | null\n}\n\nfunction coverageReason(report: AnalyticsReport, scenario: AnalyticsScenario): EstimateUnavailable | undefined {\n if (report.status !== 'ready') return 'unavailable'\n if (report.truncated || report.unreadableSessions > 0 || report.skippedSessions > 0) return 'partial'\n if (report.totals.requests === 0) return 'empty'\n if (scenario.excludedRequests > 0) return 'excluded'\n // 请求全部覆盖才保证比较的是同一批工作量;相同的部分覆盖数量不能证明样本相同。\n if (scenario.unknownRequests > 0 || scenario.pricedRequests !== report.totals.requests) return 'coverage'\n return undefined\n}\n\nexport function compareScenario(report: AnalyticsReport, scenario: AnalyticsScenario): ScenarioComparison {\n const reason = coverageReason(report, scenario)\n let monthly: Estimate\n if (reason) monthly = { value: null, reason }\n else if (report.query.mode !== 'range') monthly = { value: null, reason: 'recent' }\n else {\n // 未来的截止日不稀释用量;使用宿主生成报告的时间,与历史总览的观察窗口一致。\n const elapsed = Math.min(report.query.to, report.generatedAt) - report.query.from\n monthly = elapsed >= 86400000\n ? { value: scenario.cost * (30 * 86400000 / elapsed) }\n : { value: null, reason: 'short-range' }\n }\n const comparisonReason = reason ?? (report.totals.pricedRequests !== report.totals.requests ? 'baseline' : undefined)\n const difference: Estimate = comparisonReason\n ? { value: null, reason: comparisonReason }\n : { value: scenario.cost - report.totals.cost }\n return {\n monthly, difference,\n differencePercent: difference.value !== null && report.totals.cost > 0\n ? difference.value / report.totals.cost * 100 : null,\n }\n}\n","/** 只展示数字快照;筛选提交后才查询,页签、展开与模型筛选不触发历史读取。 */\nimport { useEffect, useId, useState } from 'react'\nimport type { KeyboardEvent, ReactNode } from 'react'\nimport type { AnalyticsMetrics, AnalyticsQuery, AnalyticsReport, AnalyticsScenario } from '../analytics-wire.ts'\nimport { parseAnalyticsQuery } from '../analytics-wire.ts'\nimport type { AnalyticsState } from './analytics.ts'\nimport type { AnalyticsKey } from './analytics-copy.ts'\nimport { compareScenario, type EstimateUnavailable } from './analytics-comparison.ts'\n\nexport interface AnalyticsViewProps {\n useCommandCodeAnalytics(selector: (state: AnalyticsState) => T): T\n refreshAnalytics(query?: AnalyticsQuery): void\n text(key: AnalyticsKey): string\n}\ntype Text = AnalyticsViewProps['text']\nfunction localDate(time: number): string {\n const d = new Date(time)\n return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`\n}\n/** 日期按用户本地日历展开为半开区间;截止日包括当日全部时间,夏令时不固定加 24 小时。 */\nexport function dateRange(from: string, to: string): AnalyticsQuery {\n const start = new Date(`${from}T00:00:00`), end = new Date(`${to}T00:00:00`)\n if (localDate(start.getTime()) !== from || localDate(end.getTime()) !== to) throw new TypeError('无效日期')\n end.setDate(end.getDate() + 1)\n return parseAnalyticsQuery({ mode: 'range', from: start.getTime(), to: end.getTime() })\n}\nconst money = (n: number) => `$${n.toFixed(4)}`\nconst digits = (n: number) => n.toLocaleString()\nconst meanSeconds = (ms: number, samples: number, text: Text) => samples ? `${(ms / samples / 1000).toFixed(2)} ${text('analysisSeconds')}` : text('analysisMissing')\nconst speed = (m: AnalyticsMetrics, text: Text) => m.decodeSamples && m.decodeMs ? `${(m.decodeTokens * 1000 / m.decodeMs).toFixed(1)} ${text('analysisSpeedUnit')}` : text('analysisMissing')\nfunction effortName(effort: string, text: Text): string {\n const keys: Record = { none: 'effortNone', low: 'effortLow', medium: 'effortMedium', high: 'effortHigh', xhigh: 'effortXhigh', max: 'effortMax' }\n return keys[effort] ? text(keys[effort]!) : effort\n}\nfunction Chevron() {\n return \n}\nfunction AnalysisIcon({ kind }: { kind: 'info' | 'search' }) {\n return \n}\nfunction Metric({ label, value, sub, children }: { label: string; value: string; sub?: string; children?: ReactNode }) {\n return {label}{value}{sub ? {sub} : null}{children}\n}\n/** 只比较已知成本;没有计价样本或已知小计为零时,不制造百分比。 */\nexport function knownCostShare(m: Pick, totalCost: number): number | null {\n return m.pricedRequests > 0 && totalCost > 0 ? m.cost / totalCost * 100 : null\n}\nfunction CostShare({ m, totalCost, text }: { m: AnalyticsMetrics; totalCost: number; text: Text }) {\n const share = knownCostShare(m, totalCost)\n if (share === null) return {text('analysisNoShare')}\n const percentage = `${share.toFixed(1)}%`\n return {percentage}\n}\nfunction DetailGroup({ title, values, text }: { title: AnalyticsKey; values: Array<[AnalyticsKey, string]>; text: Text }) {\n return
{text(title)}
{values.map(([key, value]) =>
{text(key)}
{value}
)}
\n}\n/** 样本为零时词元仍为未知;汇总和单模型复用相同口径,展开只改变展示。 */\nfunction MetricsDetails({ m, text }: { m: AnalyticsMetrics; text: Text }) {\n const tokens = m.tokens, tokenValue = (n: number) => m.usageSamples ? digits(n) : text('analysisMissing')\n return
\n > : null}\n \n}\n","/**\n * React components for the Command Code plans & quota panel: the sidebar footer\n * card and the dashboard it opens in the center column.\n *\n * Both render one {@link PanelView} projected by `./panel.ts` — no fact is\n * derived here. Strings arrive already localized in `view.text`: the slots\n * declare the `panel.commandcode` locale namespace, so the renderer hands this\n * component a `t` seat that is passed into `buildPanelView`, and a language\n * switch mints a new `t` identity, which re-renders both surfaces.\n *\n * The footer card is the panel's home — the shell renders it in the foot area\n * directly above the Settings seat, and unlike a `sidebar.panellist` row (whose\n * chrome and label the SHELL owns) this entry owns its whole surface and\n * therefore calls `open()` itself. Styles ride the stylesheet\n * `./panel-styles.ts` returns; classes are `ccp-` prefixed.\n *\n * @module dsh-commandcode-provider/client/panel-view\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 { SnapshotStore } from './snapshot-store.ts'\nimport type { UsagePageState } from './usage.ts'\nimport type { SettingsPageState } from './settings.ts'\nimport { buildPanelView } from './panel.ts'\nimport type { PanelAccountView, PanelView, PanelWindowView } from './panel.ts'\nimport { panelTextEN } from './panel-copy.ts'\nimport type { PanelKey } from './panel-copy.ts'\n// SlotMap merge for `main` / `sidebar.footer.action` (load-bearing: the slots\n// this file's components register into are typed only by that augmentation).\nimport './panel-slots.ts'\nimport { AnalyticsView } from './analytics-view.tsx'\nimport type { AnalyticsState } from './analytics.ts'\nimport type { AnalyticsQuery } from '../analytics-wire.ts'\n\n/**\n * Owner share of the sidebar-foot action hole: the shell renders the foot area\n * and hands each action only the column fold state. There is no button chrome\n * and no `label` seat — the entry is the whole surface.\n */\nexport interface SidebarFooterActionOwnerProps {\n /** Whether the sidebar renders wide content (false = 56px rail). */\n wide: boolean\n}\n\n/**\n * The injected face both panel slots carry. Bound by the client entry so the\n * components stay unaware of the settings controller, the login controller, the\n * layout service and the module-level auto-refresh loop.\n *\n * NOTE the split from {@link PanelComponentProps}: this is what the\n * registration's `inject` factory RETURNS, and the renderer does not hand it to\n * the component verbatim — `bindInjectSources` destructures the `hooks`\n * compartment OUT and re-exposes each member as a `use` prop\n * (`commandCodeUsage` → `useCommandCodeUsage`). A component that reads\n * `props.hooks.*` finds `undefined` at runtime and crashes on render, which the\n * slot renderer contains by ABDICATING the entry, so the surface vanishes with\n * no visible error.\n */\nexport interface PanelInjected {\n hooks: {\n commandCodeUsage: SnapshotStore\n commandCodeSettings: SnapshotStore\n commandCodeAnalytics?: SnapshotStore\n commandCodePanelMode?: SnapshotStore<'quota' | 'analysis'>\n }\n /** Fetch the report now (the dashboard's Refresh action). */\n refresh(): void\n /**\n * Leave the dashboard and show the Conversation again\n * (`ctx.layout.selectPanel(null)`; the current Session is untouched).\n */\n close(): void\n /** Start the shared background poll for this mount; returns its disposer. */\n startAutoRefresh(): () => void\n /** Select this panel in the center column (`ctx.layout.selectPanel`). */\n open(): void\n refreshAnalytics?(query?: AnalyticsQuery): void\n selectPanelMode?(mode: 'quota' | 'analysis'): void\n}\n\n/**\n * The props a panel component actually receives: the bound `useX` seats (what\n * {@link PanelInjected}'s `hooks` compartment becomes), the pass-through\n * actions, and no raw `hooks` key.\n *\n * `buildPanelView` is cheap (one pass over the account list) and recomputing it\n * per notification is what keeps a store update from ever rendering a stale\n * quota, so the selector is deliberately the whole snapshot.\n */\nexport interface PanelComponentProps {\n useCommandCodeAnalytics?(selector: (state: AnalyticsState) => T): T\n useCommandCodePanelMode?(selector: (state: 'quota' | 'analysis') => T): T\n refreshAnalytics?(query?: AnalyticsQuery): void\n selectPanelMode?(mode: 'quota' | 'analysis'): void\n useCommandCodeUsage(selector: (state: UsagePageState) => T): T\n useCommandCodeSettings(selector: (state: SettingsPageState) => T): T\n /**\n * Locale seat for the `panel.commandcode` namespace, bound by the\n * registration's own `locale` declaration. Optional so a missing locale face\n * degrades to English instead of crashing the surface.\n */\n t?: Translate\n refresh(): void\n close(): void\n startAutoRefresh(): () => void\n open(): void\n}\n\n/** Props of the sidebar footer card: the panel face plus the shell's fold state. */\nexport interface CommandCodeFooterEntryProps extends PanelComponentProps, SidebarFooterActionOwnerProps {}\n\n/** The panel's view, recomputed from both seats on every notification. */\nfunction usePanelView(props: PanelComponentProps): PanelView {\n const usage = props.useCommandCodeUsage((state) => state)\n const settings = props.useCommandCodeSettings((state) => state)\n return buildPanelView({\n usage,\n apiKeyConfigured: settings.anyAccountConfigured,\n t: props.t ?? panelTextEN,\n })\n}\n\n/**\n * The quota ring. One glyph serves the rail button, the footer card's top row\n * and the dashboard header: a faint track plus an arc whose sweep is the\n * consumption, drawn from 12 o'clock. Circumference 2πr = 45.55 at r = 7.25.\n */\nfunction Ring({ percent, warn, size }: { percent: number; warn: boolean; size: number }) {\n const clamped = Math.min(100, Math.max(0, percent))\n const circumference = 45.55\n // Rounded to three decimals: the raw product lands on floats like\n // 34.162499999999994, which is a needless DOM diff churn.\n const dashoffset = Math.round(circumference * (1 - clamped / 100) * 1000) / 1000\n return (\n \n \n \n )\n}\n\n/** One labelled bar. `compact` drops the reset line; the footer draws its own. */\nfunction QuotaBar({ label, value, percent, barPercent, warn, resetsAt, resetsLabel }: {\n label: string\n value: string\n percent: string\n barPercent: number\n warn: string\n resetsAt: string\n resetsLabel: string\n}) {\n const clamped = Math.min(100, Math.max(0, barPercent))\n return (\n
\n {/* The plan is already in the card's header badge; what is missing\n here is the RATIO, so the row names the plan the report carries\n and falls back to a placeholder only when the report is silent. */}\n {text('plan')}\n {account.planName !== '' ? account.planName : text('unavailable')}\n
\n )}\n\n {/* A balance the billing endpoint DID report, so a card without a ratio\n still states something true. */}\n {monthly !== undefined && monthly.remaining !== '—' ? (\n
\n \n {mode === 'quota' && view.updatedAt !== '' ? {text('updated')} {view.updatedAt} : null}\n \n {/* The dashboard REPLACES the conversation in the center column and\n this panel is the only surface that selects it, so without an exit\n the user cannot get back to the session at all (issue #41): the\n sidebar card only re-selects this same panel. The glyph is the\n button's whole content, so the name and tooltip carry the words. */}\n \n \n\n \n {mode === 'analysis' ? props.useCommandCodeAnalytics && props.refreshAnalytics ? :
\n )\n}\n\n/**\n * The sidebar footer card, registered into `sidebar.footer.action` — the list\n * the shell renders in the foot area directly ABOVE the Settings seat, so the\n * panel reads as a bottom-pinned sibling of Settings rather than a global panel\n * icon at the top of the column.\n *\n * The shell wraps nothing here, so this component owns the surface: the button,\n * its chrome and its accessible name. Expanded, it draws the title row and one\n * block per quota window (5-hour, then weekly) — the window's own spend and\n * limit, its percentage and its bar — and nothing else, because those two\n * windows are the figures an account runs into, so the period total stays in the\n * tooltip. In the 56px rail it collapses to a 36px icon button carrying the ring,\n * matching the shell's own rail geometry; `wide` comes from the shell.\n *\n * Rendering is gated on the settings page's `showSidebarQuota` toggle, which\n * defaults OFF: a fresh install shows no quota surface in the sidebar and runs\n * no background poll. The gate reads the STORED document (the settings\n * controller's `sidebarQuota` fact), so an unsaved draft cannot show the card\n * while a landed save flips it live. The entry stays REGISTERED — this is a\n * render decision, so nothing churns the slot ledger.\n */\nexport function CommandCodeFooterEntry(props: CommandCodeFooterEntryProps) {\n // While hidden this component renders NOTHING — no expanded card, no rail\n // icon — and starts no background usage poll; the dashboard cell stays\n // registered but has no trigger, which is exactly what \"hide the quota\n // display\" means.\n const visible = props.useCommandCodeSettings((snapshot) => snapshot.sidebarQuota)\n const view = usePanelView(props)\n\n const startAutoRefresh = props.startAutoRefresh\n useEffect(() => {\n if (!visible) return undefined\n return startAutoRefresh()\n }, [visible, startAutoRefresh])\n\n if (!visible) return null\n\n const text = (key: PanelKey): string => view.text[key] ?? key\n // The ring tracks the tightest window — the 5-hour one whenever it is capped,\n // which is the limit an account runs into first, and `footerBars` is ordered\n // that way, so the leading bar is the headline.\n const headline = view.footerBars[0]\n // The tooltip doubles as the accessible name; it always begins with the\n // visible title, so the label the user reads is contained in the name.\n const title = view.footTitle\n\n if (!props.wide) {\n return (\n \n )\n }\n\n return (\n \n )\n}\n","/** Shared, JSON-only billing facts. No Host or browser runtime imports. */\nimport type { CommandCodeModelPrice, CommandCodeModelRates, CommandCodePriceTable } from './usage-wire.ts'\n\nexport interface CostTokens {\n uncachedInputTokens: number\n outputTokens: number\n cacheReadTokens: number\n cacheWriteTokens: number\n}\n\n/** Requests with identical model/rates are folded into one group. */\nexport interface CostUsageGroup {\n provider: string\n model: string\n at: number | null\n contextTokens: number\n tokens: CostTokens\n}\n\nexport interface SessionCostFacts {\n pricingKey: number\n groups: CostUsageGroup[]\n /**\n * Token buckets contributed by summarization calls, already folded into\n * `groups` but deliberately NOT part of the harness's own `tokenUsage`\n * projection.\n *\n * Compaction issues its own `ctx.llm.stream()` call, so its cost is real\n * spend, but it produces no `assistant/message` or `assistant/attempt` event\n * — the only two the harness meter folds (see `token-meter/src/usage-projection.ts`).\n * The summary therefore lands in this projection alone, and the composer\n * readout subtracts this field before asserting that both projections\n * describe the same durable cut. Without the split the equality check fails\n * and the whole readout disappears whenever a session compacts.\n *\n * Always present: `parseState` backfills it to zero for state written before\n * this field existed.\n */\n summaryTokens: CostTokens\n}\n\nexport const zeroCostTokens = (): CostTokens => ({ uncachedInputTokens: 0, outputTokens: 0, cacheReadTokens: 0, cacheWriteTokens: 0 })\nexport const COST_TOKEN_KEYS = ['uncachedInputTokens', 'outputTokens', 'cacheReadTokens', 'cacheWriteTokens'] as const\n\nexport function peakHour(at: number, windows: ReadonlyArray): boolean {\n const time = new Date(at)\n return time.getUTCDay() !== 0 && time.getUTCDay() !== 6\n && windows.some(([start, end]) => time.getUTCHours() >= start && time.getUTCHours() < end)\n}\n\n/**\n * All prompt billing buckets determine a request's band, never cumulative\n * session input.\n *\n * A tiered model returns the matching band and does NOT then apply `peak`: the\n * page publishes those two dimensions independently and no row carries both\n * today, so the combination becoming real is visible before it reaches a user.\n * This ordering is a latent choice, not a verified upstream rule.\n */\nexport function requestRates(price: CommandCodeModelPrice, at: number | null, contextTokens: number, table: CommandCodePriceTable): CommandCodeModelRates {\n // ORDER IS LOAD-BEARING: the generator refuses non-ascending bounds or a\n // bounded last band and the wire parser rejects the same shapes, so a\n // conforming table cannot present bands out of order.\n const tier = price.contextTiers?.find(tier => tier.maxContext === undefined || contextTokens <= tier.maxContext)\n if (tier !== undefined) return tier\n return price.peak !== undefined && at !== null && peakHour(at, table.peakHours) ? price.peak : price\n}\n\n/** Cache version and wire guard: changing bands/rates must refold historical groups. */\nexport function pricingKey(table: CommandCodePriceTable): number {\n const rates = (r: CommandCodeModelRates) => [r.inputCost, r.outputCost, r.cacheReadCost, r.cacheWriteCost ?? null]\n const canonical = JSON.stringify(['commandCodeCost-v1', table.peakHours, table.models.map(p => [p.id, p.slug, p.free === true, rates(p), p.peak ? rates(p.peak) : null, p.contextTiers?.map(t => [t.maxContext ?? null, rates(t)]) ?? null])])\n let hash = 2166136261\n for (const c of canonical) hash = Math.imul(hash ^ c.charCodeAt(0), 16777619) >>> 0\n return hash\n}\n\n/** Only safe to merge requests whose billing classification is identical. */\nexport function costGroupKey(group: CostUsageGroup, table: CommandCodePriceTable): string {\n // The table is mutable, so an identity-keyed index can keep stale model\n // mappings after its rows are changed in place. The projection already\n // indexes its usage groups once per settlement; scan the small price table\n // here so every call observes the current rows.\n const price = table.models.find(p => p.id === group.model || p.slug === group.model)\n return JSON.stringify([group.provider, group.model, price === undefined ? null : requestRates(price, group.at, group.contextTokens, table), group.at === null])\n}\n","/**\n * Session-cost view model for the composer readout.\n *\n * JSX-free and React-free, mirroring `./panel.ts`: it turns the session's token\n * accounting plus the Host's price table into one presentation value AND the\n * exact text the two surfaces of the harness's token-usage UI receive — the\n * amount appended to the shipped pill, and the rows appended to the shipped\n * usage dialog. Node tests therefore drive the whole calculation, and every\n * user-visible string, without a DOM.\n *\n * It prices the session's DURABLE cumulative buckets, which is what the\n * composer's own \"N tokens\" pill reads too (`tokenUsage`), so the two surfaces\n * can never disagree about how much was used. Dollars are computed here because\n * Command Code publishes per-token rates and bills against dollar-denominated\n * windows; the account's own reported `totalCost` is a billing PERIOD figure,\n * not this session's.\n *\n * Three rules are load-bearing: only Command Code usage is priced (a session\n * served by another provider must render nothing, never a Command Code\n * estimate); a missing rate is never invented (the pricing page publishes a\n * cache-WRITE rate for only some models, so unpriced cache-write tokens are\n * surfaced as such rather than charged at a guessed multiple of the input rate);\n * and unpriceable means invisible — a confident `$0.00` would be a lie, and\n * this module never returns one.\n *\n * @module dsh-commandcode-provider/client/session-cost\n */\n\nimport { COST_TOKEN_KEYS, pricingKey, requestRates, peakHour, zeroCostTokens, type SessionCostFacts } from '../cost-facts.ts'\nimport type { CommandCodeModelPrice, CommandCodeModelRates, CommandCodePriceTable } from '../usage-wire.ts'\nimport { formatMoney, formatMoneyExact, formatTokensCompact } from '../display-format.ts'\n\n/** Tokens per published rate unit — the pricing page quotes USD per million. */\nconst TOKENS_PER_RATE_UNIT = 1_000_000\n\n/** The provider route whose usage this surface prices. */\nconst COMMANDCODE_PROVIDER = 'commandcode'\n\n/**\n * The English copy for this surface.\n *\n * A plain constant, NOT the `settings.commandcode` locale namespace: like the\n * plans & quota panel, the readout stays English on a Chinese harness. Do not\n * route it through `ctx.locale`.\n */\nexport const SESSION_COST_COPY = {\n /** Shown instead of an amount when the model costs nothing on every plan. */\n free: 'Free',\n /**\n * The separator the readout prefixes itself with, so the cost reads as the\n * last item of the token-usage pill's text run rather than a control beside\n * it. Rendered with the same colour and margins the shipped pill uses\n * between its own items.\n */\n separator: '·',\n panelTitle: 'Session cost',\n /** Marks an estimate from published rates rather than an invoice. */\n approximate: '≈',\n unpricedCacheWrite: 'cache write tokens have no published rate',\n /** Tooltip line naming the rate half in force. */\n peakRates: 'peak rates',\n offPeakRates: 'off-peak rates',\n /** Tooltip line explaining the approximate marker. */\n approximateNote: 'estimate from published rates, not the provider invoice',\n /** Row/tooltip label for uncached prompt tokens. */\n uncachedInput: 'uncached input',\n /** Row/tooltip label for completion tokens. */\n output: 'output',\n /** Row/tooltip label for cache-served input tokens. */\n cacheRead: 'cache read',\n /** Row/tooltip label for cache-written input tokens. */\n cacheWrite: 'cache write',\n} as const\n\n/**\n * The session's cumulative token buckets, as the `tokenUsage` projection\n * carries them. Declared structurally: this bundle does not depend on the\n * session-controller package, and a bucket the provider never reported is\n * absent rather than zero.\n */\nexport interface SessionUsageBuckets {\n readonly uncachedInputTokens?: number\n readonly outputTokens?: number\n readonly cacheReadTokens?: number\n readonly cacheWriteTokens?: number\n}\n\n/** One entry of the `modelSelection` projection. */\nexport interface SessionModelSelection {\n readonly provider: string\n readonly model: string\n}\n\n/**\n * The `modelSelection` projection: the selection the latest request consumed,\n * and the one the next request will use (falling back to the former).\n */\nexport interface SessionModelSelectionProjection {\n readonly lastUsed: SessionModelSelection | null\n readonly next: SessionModelSelection | null\n}\n\n/** Everything the view needs, already read off the seats by the component. */\nexport interface SessionCostInput {\n /** Durable billing groups; absent on older Hosts means no trustworthy estimate. */\n facts?: SessionCostFacts | undefined\n /** The durable cumulative token buckets, or undefined before any request. */\n usage: SessionUsageBuckets | undefined\n /** The session's model selection fold, or undefined on an older Host. */\n selection: SessionModelSelectionProjection | undefined\n /** The Host's price table, or undefined until it lands. */\n table: CommandCodePriceTable | undefined\n /** Legacy caller field; historical request timestamps alone determine rates. */\n now: number\n}\n\n/** One bucket's line in the usage dialog. */\nexport interface SessionCostBucketRow {\n /** Stable key. */\n key: 'uncachedInput' | 'cacheRead' | 'cacheWrite' | 'output'\n /** Row label. */\n label: string\n /** Tokens charged in this bucket; a bucket that charged nothing withholds its\n * row rather than printing a meaningless zero. */\n tokens: number\n /** What this bucket cost, or undefined when the table has no rate for it. */\n costText: string | undefined\n}\n\n/** The composer readout's presentation value. */\nexport interface SessionCostView {\n /** Priced total in dollars. */\n total: number\n /** Visible amount text, e.g. `$0.0123` (or the free word, when free). */\n value: string\n /** Full tooltip/accessible text, including the bucket breakdown. */\n title: string\n /** Per-bucket lines for the usage dialog, in reading order. */\n rows: SessionCostBucketRow[]\n /** Caveat lines for the pill's tooltip (rate half, approximation, unpriced). */\n notes: string[]\n /** The model costs nothing on every plan right now. */\n free: boolean\n /** The model's `peak` rates are in force. */\n peak: boolean\n /** Cache-write tokens the table has no rate for (never guessed, so the\n * total is a floor rather than an estimate). */\n unpricedCacheWriteTokens: number\n /** Published-rate totals are estimates rather than provider invoices. */\n approximate: boolean\n}\n\n/** A finite, non-negative count — anything else reads as absent. */\nfunction count(value: number | undefined): number {\n return typeof value === 'number' && Number.isFinite(value) && value > 0 ? value : 0\n}\n\n/**\n * Index a price table for lookup. Rows are keyed by catalog id and by pricing\n * slug, both exact and lowercased, because a session reports a catalog id while\n * a row no catalog model claims is served under the page's slug.\n */\nfunction indexTable(table: CommandCodePriceTable): Map {\n const index = new Map()\n for (const price of table.models) {\n for (const key of [price.id, price.slug]) {\n if (typeof key !== 'string' || key === '') continue\n if (!index.has(key)) index.set(key, price)\n const lower = key.toLowerCase()\n if (!index.has(lower)) index.set(lower, price)\n }\n }\n return index\n}\n\n/**\n * The dollar cost of each bucket, plus the total and the unpriced remainder.\n *\n * Every bucket is charged at its own published rate; the cache-write bucket\n * contributes only when the model publishes a rate for it, otherwise its tokens\n * come back as {@link SessionCostView.unpricedCacheWriteTokens} and its own cost\n * stays undefined so the panel can say so instead of printing a zero.\n */\ninterface SessionCostBreakdown {\n uncachedInput: number\n cacheRead: number\n cacheWrite: number | undefined\n output: number\n total: number\n unpricedCacheWriteTokens: number\n}\n\nfunction costOf(\n usage: SessionUsageBuckets,\n rates: CommandCodeModelRates,\n free: boolean,\n): SessionCostBreakdown {\n if (free) {\n return { uncachedInput: 0, cacheRead: 0, cacheWrite: 0, output: 0, total: 0, unpricedCacheWriteTokens: 0 }\n }\n const perUnit = (tokens: number, rate: number): number => (tokens * rate) / TOKENS_PER_RATE_UNIT\n const uncachedInput = perUnit(count(usage.uncachedInputTokens), rates.inputCost)\n const output = perUnit(count(usage.outputTokens), rates.outputCost)\n const cacheRead = perUnit(count(usage.cacheReadTokens), rates.cacheReadCost)\n const cacheWriteTokens = count(usage.cacheWriteTokens)\n const cacheWrite = rates.cacheWriteCost === undefined\n ? undefined\n : perUnit(cacheWriteTokens, rates.cacheWriteCost)\n return {\n uncachedInput,\n cacheRead,\n cacheWrite,\n output,\n total: uncachedInput + output + cacheRead + (cacheWrite ?? 0),\n unpricedCacheWriteTokens: rates.cacheWriteCost === undefined ? cacheWriteTokens : 0,\n }\n}\n\n/**\n * Amount text for a session cost.\n *\n * The panel's `money()` convention (2 decimals, 4 below a cent) is right for\n * billing windows, but a live session total starts far below a cent, where\n * `toFixed(4)` would print a flat `$0.0000` — broken rather than small. So a\n * total under $0.0001 is stated as a bound instead.\n */\nexport function sessionCostAmount(total: number): string {\n if (!Number.isFinite(total) || total <= 0) return formatMoney(0)\n if (total < 0.0001) return `<$0.0001`\n return total < 0.01 ? formatMoneyExact(total) : formatMoney(total)\n}\n\n/** One `label value` clause of the tooltip. */\nfunction clause(label: string, tokens: number): string | undefined {\n return tokens > 0 ? `${label} ${formatTokensCompact(tokens)}` : undefined\n}\n\n/**\n * Build the composer readout, or undefined when there is nothing honest to show.\n *\n * Undefined is the correct answer for a session with no usage yet, a session\n * another provider served, a model the price table does not know, and a table\n * that has not landed — the pill simply is not there.\n */\nexport function buildSessionCostView(input: SessionCostInput): SessionCostView | undefined {\n const { usage, table, facts } = input\n if (!usage || !table || !facts || facts.pricingKey !== pricingKey(table)) return undefined\n const totals = zeroCostTokens()\n const index = indexTable(table)\n const breakdown: SessionCostBreakdown = { uncachedInput: 0, cacheRead: 0, cacheWrite: 0, output: 0, total: 0, unpricedCacheWriteTokens: 0 }\n let free = true\n let peak = false\n let partial = false\n let priced = false\n const notes: string[] = []\n for (const group of facts.groups) {\n for (const key of COST_TOKEN_KEYS) totals[key] += group.tokens[key]\n if (group.provider !== COMMANDCODE_PROVIDER) { partial = true; continue }\n const price = index.get(group.model)\n if (!price) { partial = true; continue }\n const isFree = price.free === true\n free &&= isFree\n if (price.peak && group.at === null) {\n partial = true\n notes.push('request time unavailable; off-peak lower bound')\n }\n const rates = requestRates(price, group.at, group.contextTokens, table)\n const part = costOf(group.tokens, rates, isFree)\n priced ||= isFree || part.total > 0\n for (const key of ['uncachedInput', 'cacheRead', 'output', 'total', 'unpricedCacheWriteTokens'] as const) breakdown[key] += part[key]\n breakdown.cacheWrite = (breakdown.cacheWrite ?? 0) + (part.cacheWrite ?? 0)\n if (price.peak) {\n const isPeak = group.at !== null && peakHour(group.at, table.peakHours)\n peak ||= isPeak\n notes.push(isPeak ? SESSION_COST_COPY.peakRates : SESSION_COST_COPY.offPeakRates)\n }\n }\n // Both projections must describe the same durable cut. Never decorate token\n // rows from a newer/older fold, and never price an old Host's cumulative usage.\n //\n // Compaction summaries are the one legitimate difference: the compactor calls\n // `ctx.llm.stream()` itself, so the spend is real and this projection folds it,\n // but it emits none of the `assistant/*` events the harness meter counts.\n // Subtract exactly that contribution and keep the strict equality, so a stale\n // or newer fold on either side is still refused.\n const summary = facts.summaryTokens ?? zeroCostTokens()\n if (COST_TOKEN_KEYS.some(key => totals[key] - summary[key] !== count(usage[key])) || !priced) return undefined\n const { total, unpricedCacheWriteTokens } = breakdown\n partial ||= unpricedCacheWriteTokens > 0\n free &&= !partial\n if (partial) notes.push('Command Code priced subtotal only; unpriced or other-provider usage excluded')\n notes.push(SESSION_COST_COPY.approximateNote)\n const uncachedInput = totals.uncachedInputTokens\n const output = totals.outputTokens\n const cacheRead = totals.cacheReadTokens\n const cacheWrite = totals.cacheWriteTokens\n // No billed token of any kind means there is nothing to report yet: a `$0.00`\n // pill on a session that has not made a request would be noise, not\n // information, and on a free model it would be redundant.\n if (uncachedInput === 0 && output === 0 && cacheRead === 0 && cacheWrite === 0) return undefined\n\n // Free priced groups do not establish zero spending for unpriced groups:\n // keep the pure-Free label and real sub-cent amounts, but never a zero\n // subtotal.\n if (!free && total <= 0) return undefined\n\n const value = free\n ? SESSION_COST_COPY.free\n : `${partial ? '≥' : SESSION_COST_COPY.approximate}${sessionCostAmount(total)}`\n const money = (amount: number | undefined): string | undefined =>\n amount === undefined ? undefined : sessionCostAmount(amount)\n // Reading order mirrors the prompt's own order: what was charged at the input\n // rate, then the two cache buckets, then what the model produced.\n const rows: SessionCostBucketRow[] = [\n { key: 'uncachedInput', label: SESSION_COST_COPY.uncachedInput, tokens: uncachedInput, costText: money(breakdown.uncachedInput) },\n { key: 'cacheRead', label: SESSION_COST_COPY.cacheRead, tokens: cacheRead, costText: money(breakdown.cacheRead) },\n { key: 'cacheWrite', label: SESSION_COST_COPY.cacheWrite, tokens: cacheWrite, costText: unpricedCacheWriteTokens === cacheWrite && cacheWrite > 0 ? undefined : money(breakdown.cacheWrite) },\n { key: 'output', label: SESSION_COST_COPY.output, tokens: output, costText: money(breakdown.output) },\n ]\n if (unpricedCacheWriteTokens > 0) notes.push(SESSION_COST_COPY.unpricedCacheWrite)\n // Empty clauses are dropped BEFORE joining: `clause()` returns undefined for\n // a bucket with no tokens, and joining the raw list would leave a `· ·` gap\n // per absent bucket — a tooltip that reads as a rendering bug.\n const title = ([\n `${SESSION_COST_COPY.panelTitle} ${free ? SESSION_COST_COPY.free : sessionCostAmount(total)}`,\n clause(SESSION_COST_COPY.uncachedInput, uncachedInput),\n clause(SESSION_COST_COPY.output, output),\n clause(SESSION_COST_COPY.cacheRead, cacheRead),\n clause(SESSION_COST_COPY.cacheWrite, cacheWrite),\n ...notes,\n ] as Array).filter((part): part is string => part !== undefined).join(' · ')\n\n return {\n total,\n value,\n title,\n rows,\n notes: [...new Set(notes)],\n free,\n peak,\n unpricedCacheWriteTokens,\n approximate: !free,\n }\n}\n\n/**\n * The two nodes the text appended to the harness's token-usage pill is made of.\n *\n * The separator is a node of its own because it carries the shipped pill's\n * SEPARATOR colour rather than its label colour; the pill is a flex row whose\n * `gap` already spaces the appended item, so the separator is what makes the\n * result read as one continuous run (`1.2M tokens · Cache hit 87% · $0.0123`).\n */\nexport interface SessionCostPillRun {\n /** The shipped pill's own separator glyph. */\n separator: string\n /** The amount, `≈` marker and free word included. */\n value: string\n}\n\n/** Split the appended run into the two nodes the display creates. */\nexport function sessionCostPillRun(view: SessionCostView): SessionCostPillRun {\n return { separator: SESSION_COST_COPY.separator, value: view.value }\n}\n\n/**\n * How the harness's own usage dialog is decorated: one entry per row the\n * shipped component renders, IN ITS OWN ORDER.\n *\n * The price goes on the right of the row it belongs to (`3,206,544 tok $0.07`)\n * rather than in a block of our own rows beneath them, so the dialog keeps the\n * harness's layout and gains nothing to read past.\n *\n * Two rows are special. `cacheHit` carries a percentage, not a count, so it is\n * never priced. `cacheWrite` may be HIDDEN, and only then: the pricing page\n * publishes a cache-write rate for a minority of models, so its cell read\n * `unpriced` far more often than a number — but its tokens still count toward\n * the total the pill shows.\n */\nexport type SessionCostShippedRow = 'cacheHit' | 'uncachedInput' | 'cacheRead' | 'cacheWrite' | 'output'\n\n/** One shipped dialog row and what to do with it. */\nexport interface SessionCostRowDecoration {\n /** Which shipped row this is. */\n row: SessionCostShippedRow\n /**\n * The exact token count that row must be showing, or undefined for a row that\n * carries no count. The display layer verifies it before decorating anything:\n * the shipped labels are the `chat` locale's own strings (never English), so\n * rows are matched POSITIONALLY and this is what proves the position is right.\n */\n tokens: number | undefined\n /** The price to append to the row's value, or undefined to leave it alone. */\n amount: string | undefined\n /** Whether the row is dropped from the dialog entirely. */\n hidden: boolean\n}\n\n/**\n * Decorate the harness's usage dialog, row by row.\n *\n * The row sequence mirrors the shipped component's conditions exactly — the\n * cache-hit row exists while there is billed prompt input, the cache-write row\n * while those tokens are non-zero — because the display layer matches what it\n * finds positionally. A shape it cannot confirm is a shape it does not touch.\n *\n * A free model decorates nothing: every row's cost is zero by definition, the\n * pill already says `Free`, and a column of `$0.00` would be noise. A bucket\n * whose rate the page does not publish is likewise left unfilled rather than\n * filled with an invented number.\n */\nexport function sessionCostRowDecorations(view: SessionCostView): SessionCostRowDecoration[] {\n const bucket = (key: SessionCostBucketRow['key']): number =>\n view.rows.find((row) => row.key === key)?.tokens ?? 0\n const price = (key: SessionCostBucketRow['key']): string | undefined => {\n if (view.free) return undefined\n return view.rows.find((row) => row.key === key)?.costText\n }\n const uncachedInput = bucket('uncachedInput')\n const cacheRead = bucket('cacheRead')\n const cacheWrite = bucket('cacheWrite')\n const output = bucket('output')\n const plan: SessionCostRowDecoration[] = []\n if (uncachedInput + cacheRead + cacheWrite > 0) {\n plan.push({ row: 'cacheHit', tokens: undefined, amount: undefined, hidden: false })\n }\n plan.push({ row: 'uncachedInput', tokens: uncachedInput, amount: price('uncachedInput'), hidden: false })\n plan.push({ row: 'cacheRead', tokens: cacheRead, amount: price('cacheRead'), hidden: false })\n if (cacheWrite !== 0) {\n // Hidden only when the page publishes NO cache-write rate: those tokens are\n // genuinely unpriced, the note says so, and the row would otherwise show a\n // blank cell. When the rate IS known its price is part of the total, so the\n // row must stay — hiding it leaves the visible rows unable to explain the\n // figure above them.\n const amount = price('cacheWrite')\n plan.push({ row: 'cacheWrite', tokens: cacheWrite, amount, hidden: amount === undefined })\n }\n plan.push({ row: 'output', tokens: output, amount: price('output'), hidden: false })\n return plan\n}\n","/**\n * The DOM half of the composer's session-cost figure (browser only).\n *\n * The cost is not a surface of its own any more: it is injected INTO the two\n * surfaces the harness already draws under the composer — the token-usage pill\n * and the usage dialog that pill opens. This module owns that injection;\n * `./session-cost.ts` owns every number and string, and `./session-cost-view.tsx`\n * the two seats the figures come from.\n *\n * Why inject rather than take the pill's cell over (registering a `stats` entry\n * REPLACES the shipped readout, it does not extend it): that row is one component\n * owning its tokens / cache-hit / duration figures through the `chat` locale\n * namespace, and its cache-hit percentage obeys an exact-integer rule this plugin\n * must not re-derive. Owning it would mean reproducing all of it in English, and\n * every upstream change would stop reaching users.\n *\n * Four properties make the injection safe:\n *\n * 1. **The dialog's rows are styled by ELEMENT.** `dsh-client-ui-chat`'s\n * `stat-dialog` module styles its `dl` as a two-column grid and then\n * `.details dt` / `.details dd` — not by class, so a price node appended\n * INSIDE a shipped value cell inherits that cell's tabular numerals and right\n * alignment, and this plugin ships no CSS at all.\n * 2. **The dialog's rows are matched by POSITION and confirmed by value.** Their\n * labels are the `chat` locale's own strings, so no label is ever read: the\n * shape is predicted from the session's buckets and each value cell must then\n * carry exactly the token count predicted for it. A dialog that does not\n * confirm is left alone.\n * 3. **The pill keeps the cost visible when space runs out.** The button is an\n * inline flex row with `gap` and its label carries `min-width:0` plus ellipsis;\n * our appended span keeps the default `min-width:auto`, so the LABEL is what\n * truncates, and the cost inherits the button's typography and tint.\n * 4. **React owns those value cells' text, so a price is re-attached, never\n * assumed.** The shipped component renders each count as a single string, and\n * React rewrites such a cell through `textContent` when the count changes —\n * dropping every child with it, our price included. Every sync therefore\n * re-checks that the node is still where it was put; the cost of that is a\n * read, and the alternative is a price that silently disappears mid-session.\n *\n * A `MutationObserver` on `document.body` with `childList` (deliberately NOT\n * `subtree`, so streaming text never wakes it) is the only way to learn that the\n * portaled dialog has opened or closed. That observer is also what decorates a\n * newly opened dialog from the last view this module was handed.\n *\n * @module dsh-commandcode-provider/client/session-cost-display\n */\n\nimport type { SessionCostPillRun, SessionCostRowDecoration, SessionCostShippedRow, SessionCostView } from './session-cost.ts'\nimport {\n SESSION_COST_COPY,\n sessionCostPillRun,\n sessionCostRowDecorations,\n} from './session-cost.ts'\n\n/**\n * The shipped composer stats row (dsh-client-ui-chat `StatsPills`).\n *\n * A PREFERENCE, not a requirement: the attribute has been dropped TWICE\n * upstream — in 0.1.6-alpha.2, and again in 0.2.1-alpha.1, where the single\n * `StatsPills` component became two independent dock entries (`activity` and\n * `usage`) and each pill lost the shared row wrapper this selector named. A\n * lookup that insisted on it would silently stop finding the row. When it is\n * absent the search falls back to the dock OUTLET — deliberately the outlet\n * and never the outlet's parent, because the parent is the composer footer,\n * which holds the `ContextMeter` as well, and that meter's trigger is itself a\n * `button[aria-haspopup=\"dialog\"]` rendered AFTER the dock. A parent-scoped\n * \"last trigger wins\" would append the cost to the context ring instead.\n *\n * The fallback is still correct on 0.2.1-alpha.1: the dock registers `activity`\n * at order 0 and `usage` at order 1, both keep `aria-haspopup=\"dialog\"` on their\n * trigger button, and `data-session-stats-usage` remains unique to the token\n * dialog — so \"last trigger wins\" still selects the usage pill.\n */\nconst STATS_ROOT = '[data-composer-stats]'\n\n/**\n * The shipped token-usage dialog's `
`. Unique WITHIN one `StatsPills`\n * render (the per-message turn-usage panel has its own dialog with different\n * markup), but not across the document once two composers are live — see\n * {@link resolveDialog}.\n */\nconst USAGE_DIALOG = '[data-session-stats-usage]'\n\n/**\n * The usage dialog's trigger. Both pills announce a dialog, but the token one is\n * rendered LAST — and when no step carries timing the time pill is not a button\n * at all, so \"last\" still selects the token pill in both cases.\n */\nconst DIALOG_TRIGGER = 'button[aria-haspopup=\"dialog\"]'\n\n/**\n * Stable id for the hidden node the appended cost is described by. The pill's own\n * `aria-label` is recomputed by the harness on every render and cannot be\n * extended, so a description is how the cost reaches assistive technology.\n */\nconst A11Y_ID = 'dsh-commandcode-session-cost'\n\n/** How many consecutive misses before the missing anchor is worth a console line. */\nconst MISSES_BEFORE_WARNING = 3\n\n/**\n * How the display learns that the shipped usage dialog opened or closed.\n *\n * `target` is `document.body`, and the returned function detaches. The default\n * is a `MutationObserver`; the seam exists so tests can announce the dialog\n * without a global observer (the repository's usual injected-seam shape).\n */\nexport type SessionCostObserverFactory = (target: Node, listener: () => void) => (() => void) | undefined\n\n/**\n * The default observer: `childList` on `body`, and deliberately NOT `subtree`, so\n * streaming text inside the page never wakes it while the panel the harness\n * portals straight onto `body` does.\n */\nconst observeBodyChildren: SessionCostObserverFactory = (target, listener) => {\n if (typeof MutationObserver === 'undefined') return undefined\n const observer = new MutationObserver(listener)\n observer.observe(target, { childList: true })\n return () => observer.disconnect()\n}\n\n/** What the display layer reads: the injected document and where to look in it. */\nexport interface SessionCostDisplayOptions {\n /** The document to inject into (injected so node tests can drive a double). */\n doc: Document\n /**\n * The composer that owns this entry — our own dock OUTLET, so a session-scoped\n * composer looks in its OWN card rather than at whichever `[data-composer-stats]`\n * happens to come first in the document.\n */\n scope: () => ParentNode | null\n /** Observer seam; defaults to a `childList` `MutationObserver` on `body`. */\n observe?: SessionCostObserverFactory\n}\n\n/**\n * Owns the nodes injected into the shipped token-usage UI.\n *\n * One instance per mounted entry. `sync()` is cheap and idempotent: it re-reads\n * both targets on every call, which is what lets it self-heal when React\n * remounts the row or replaces the dialog, and it rewrites a node only when its\n * text actually changed.\n */\nexport class SessionCostDisplay {\n private readonly doc: Document\n private readonly scope: () => ParentNode | null\n private readonly observe: SessionCostObserverFactory\n private view: SessionCostView | undefined = undefined\n /** Detaches the observer installed by `start()`. */\n private detach: (() => void) | undefined = undefined\n /** The button we appended into, while it is still connected. */\n private pillHost: Element | undefined = undefined\n /** Our appended root, and the two nodes whose text changes. */\n private pillRoot: HTMLElement | undefined = undefined\n private pillValue: HTMLElement | undefined = undefined\n private pillA11y: HTMLElement | undefined = undefined\n /** Whether WE set `aria-describedby` on the button (so only we take it back). */\n private described = false\n /** The dialog we decorated, the price nodes we own, and the cells we hid. */\n private dialogHost: Element | undefined = undefined\n private dialogPrices = new Map()\n private dialogHidden = new Set()\n private pillMisses = 0\n\n constructor(options: SessionCostDisplayOptions) {\n this.doc = options.doc\n this.scope = options.scope\n this.observe = options.observe ?? observeBodyChildren\n }\n\n /** Begin watching for the shipped usage dialog opening and closing. */\n start(): void {\n if (this.detach !== undefined) return\n const body = this.doc.body\n if (body === null || body === undefined) return\n this.detach = this.observe(body, () => this.apply())\n }\n\n /**\n * Hand the display the current figure.\n *\n * Undefined — nothing priceable about this session — removes everything this\n * module injected, leaving both shipped surfaces exactly as they ship.\n */\n sync(view: SessionCostView | undefined): void {\n this.view = view\n this.apply()\n }\n\n /** Remove every injected node and stop observing. Safe to call twice. */\n dispose(): void {\n this.detach?.()\n this.detach = undefined\n this.removePill()\n this.clearDialog()\n this.view = undefined\n }\n\n /** Re-apply the last known view to whatever both targets are right now. */\n private apply(): void {\n this.applyPill()\n this.applyDialog()\n }\n\n // --- The pill: the cost as the last item of the shipped token pill's run\n\n private applyPill(): void {\n const view = this.view\n if (view === undefined) {\n this.removePill()\n return\n }\n if (this.pillHost?.isConnected !== true) {\n const button = this.resolvePillButton()\n if (button === null) {\n this.pillMisses += 1\n if (this.pillMisses === MISSES_BEFORE_WARNING) {\n console.warn(\n '[dsh-commandcode-provider] no shipped token pill in this composer\\'s dock outlet to append the session cost to; the figure stays in the usage dialog only',\n )\n }\n return\n }\n this.pillMisses = 0\n this.removePill()\n this.buildPill(button, sessionCostPillRun(view))\n }\n if (this.pillValue !== undefined) {\n const amount = sessionCostPillRun(view).value\n if (this.pillValue.textContent !== amount) this.pillValue.textContent = amount\n }\n if (this.pillRoot !== undefined) {\n if (this.pillRoot.title !== view.title) this.pillRoot.title = view.title\n const approximate = view.approximate ? 'true' : null\n if (this.pillRoot.getAttribute('data-approximate') !== approximate) {\n if (approximate === null) this.pillRoot.removeAttribute('data-approximate')\n else this.pillRoot.setAttribute('data-approximate', approximate)\n }\n }\n if (this.pillA11y !== undefined) {\n const described = `${SESSION_COST_COPY.panelTitle} ${view.value}`\n if (this.pillA11y.textContent !== described) this.pillA11y.textContent = described\n }\n }\n\n /**\n * The shipped token pill, scoped to this entry's own composer.\n *\n * The scope is the dock OUTLET (`display: contents`, one per slot), which holds\n * exactly that slot's entries — the shipped `stats` cell and ours, in their\n * registration order. {@link STATS_ROOT} narrows that to the stats row where\n * the markup marks it; where it does not, the outlet is already the narrowest\n * correct container, because the composer footer's `ContextMeter` sits BESIDE\n * the outlet rather than inside it. A missing scope is \"no pill\", never a\n * document-wide search: the outlet is what makes this lookup per-composer, and\n * two composers can be live at once.\n */\n private resolvePillButton(): Element | null {\n const scope = this.scope()\n if (scope === null) return null\n const root = scope.querySelector(STATS_ROOT) ?? scope\n const triggers = root.querySelectorAll(DIALOG_TRIGGER)\n return triggers.length === 0 ? null : (triggers[triggers.length - 1] ?? null)\n }\n\n /**\n * Create and append the cost run. The button's child list is static\n * (`[svg, label]`), so appending once is enough for it to stay last.\n */\n private buildPill(button: Element, run: SessionCostPillRun): void {\n const doc = this.doc\n const root = doc.createElement('span')\n root.setAttribute('data-composer-session-cost', '')\n // The separator is its own node so it can carry the shipped pill's separator\n // colour. Its LEFT spacing comes from the button's flex gap; the right margin\n // reproduces the shipped separator's `margin:0 6px` rhythm, so the run reads\n // at one consistent rhythm.\n const separator = doc.createElement('span')\n separator.textContent = run.separator\n separator.setAttribute('aria-hidden', 'true')\n separator.style.color = 'var(--dsw-alias-separator-primary)'\n separator.style.margin = '0 6px 0 0'\n const value = doc.createElement('span')\n value.textContent = run.value\n value.style.fontWeight = '500'\n // Referenced by the button's `aria-describedby`: a hidden node named by id is\n // still read out, which is how the cost survives the aria-label override.\n const a11y = doc.createElement('span')\n a11y.id = A11Y_ID\n a11y.style.display = 'none'\n root.appendChild(separator)\n root.appendChild(value)\n root.appendChild(a11y)\n button.appendChild(root)\n // Only ever claim the attribute when the button has none of its own: a\n // shipped `aria-describedby` is the harness's, and overwriting it would\n // delete a description we cannot restore.\n if (!button.hasAttribute('aria-describedby')) {\n button.setAttribute('aria-describedby', A11Y_ID)\n this.described = true\n }\n this.pillHost = button\n this.pillRoot = root\n this.pillValue = value\n this.pillA11y = a11y\n }\n\n private removePill(): void {\n if (this.pillRoot !== undefined && this.pillRoot.parentNode !== null) {\n this.pillRoot.parentNode.removeChild(this.pillRoot)\n }\n if (this.described) {\n this.pillHost?.removeAttribute('aria-describedby')\n this.described = false\n }\n this.pillHost = undefined\n this.pillRoot = undefined\n this.pillValue = undefined\n this.pillA11y = undefined\n }\n\n // --- The dialog: a price on the right of each row the harness already draws\n\n private applyDialog(): void {\n const view = this.view\n const host = view === undefined ? null : this.resolveDialog()\n if (host === null || view === undefined) {\n this.clearDialog()\n return\n }\n this.pruneDialog(host)\n const plan = sessionCostRowDecorations(view)\n const pairs = dialogPairs(host)\n if (!dialogShapeMatches(pairs, plan, this.dialogPrices)) {\n // Not the shape this session's buckets predict — a different build, or a\n // projection carrying values the counts cannot explain. Leave it as the\n // harness drew it rather than pricing the wrong row.\n this.clearDialog()\n return\n }\n const hidden = new Set()\n for (const [index, row] of plan.entries()) {\n const pair = pairs[index]\n if (pair === undefined) continue\n const span = this.dialogPrices.get(pair.dd)\n if (row.hidden) {\n // Both cells go, or the grid leaves an empty label behind. An inline\n // `display` survives the harness's own re-renders (React pins no style\n // on these nodes) and is given back on disposal.\n if (pair.dt.style.display !== 'none') pair.dt.style.display = 'none'\n if (pair.dd.style.display !== 'none') pair.dd.style.display = 'none'\n hidden.add(pair.dt)\n hidden.add(pair.dd)\n this.removeDialogPrice(pair.dd, span)\n continue\n }\n if (pair.dt.style.display === 'none') pair.dt.style.display = ''\n if (pair.dd.style.display === 'none') pair.dd.style.display = ''\n if (row.amount === undefined) {\n this.removeDialogPrice(pair.dd, span)\n continue\n }\n const price = span ?? this.createDialogPrice(pair.dd, row.row)\n // React owns this cell's text and rewrites it through `textContent` when\n // the count changes, dropping every child with it — so the price is\n // re-attached on a miss rather than assumed to still be there.\n if (price.parentNode !== pair.dd) pair.dd.appendChild(price)\n if (price.textContent !== row.amount) price.textContent = row.amount\n }\n // Cells hidden by an earlier shape (a cache-write row React then rewrote) go\n // back to the harness.\n for (const cell of [...this.dialogHidden]) {\n if (hidden.has(cell)) continue\n if (cell.style.display === 'none') cell.style.display = ''\n this.dialogHidden.delete(cell)\n }\n for (const cell of hidden) this.dialogHidden.add(cell)\n this.dialogHost = host\n }\n\n /** Forget the cells and prices a re-rendered dialog took with it. */\n private pruneDialog(host: Element): void {\n for (const [dd, price] of [...this.dialogPrices]) {\n if (dd.parentNode === host) continue\n if (price.parentNode !== null) price.parentNode.removeChild(price)\n this.dialogPrices.delete(dd)\n }\n for (const cell of [...this.dialogHidden]) {\n if (cell.parentNode === host) continue\n // The dialog was re-rendered and this cell went with the old tree. Give\n // the style back BEFORE dropping the reference: a detached node can be\n // recycled by the next render (React reuses DOM nodes across a remount of\n // the same shape), and a surviving `display: none` would hide a row of a\n // dialog we are no longer decorating, with nothing left tracking it.\n if (cell.style.display === 'none') cell.style.display = ''\n this.dialogHidden.delete(cell)\n }\n }\n\n /** The price node for one shipped value cell, appended as its last child. */\n private createDialogPrice(dd: HTMLElement, row: SessionCostShippedRow): HTMLElement {\n const price = this.doc.createElement('span')\n price.setAttribute('data-session-cost-price', row)\n // The cell is right-aligned over tabular numerals, so a fixed-width\n // inline-block lines the prices up as a column of their own.\n price.style.marginLeft = '6px'\n price.style.display = 'inline-block'\n price.style.minWidth = '56px'\n price.style.textAlign = 'right'\n price.style.fontWeight = '500'\n dd.appendChild(price)\n this.dialogPrices.set(dd, price)\n return price\n }\n\n private removeDialogPrice(dd: HTMLElement, price: HTMLElement | undefined): void {\n if (price === undefined) return\n if (price.parentNode !== null) price.parentNode.removeChild(price)\n this.dialogPrices.delete(dd)\n }\n\n /**\n * The shipped usage dialog, or null while it is closed (or ambiguous).\n *\n * The dialog is portaled onto `body`, so unlike the pill it cannot be scoped\n * from this entry, and the attribute is unique per DIALOG rather than per\n * document. While one composer was guaranteed a document-level lookup was\n * exact; 0.1.6-alpha.2 ended that guarantee by mounting an embedded\n * Conversation in the sidebar, so a second composer — its own session, dock and\n * dialog — can be live and open at the same time.\n *\n * There is no DOM link from a dialog back to its trigger (the portaled panel\n * carries no id and no `aria-controls`), so document order says nothing about\n * ownership. The shape confirmation in {@link dialogShapeMatches} would usually\n * reject the stranger, but it compares against THIS entry's counts, so a\n * coincidentally matching dialog would be priced with another session's\n * figures. Ambiguity is therefore answered by declining to decorate at all:\n * a dialog we cannot prove is ours is left alone.\n */\n private resolveDialog(): Element | null {\n if (this.dialogHost?.isConnected === true) return this.dialogHost\n // The dialog we injected into is gone: our nodes went with it, so only the\n // bookkeeping is left to drop.\n this.clearDialog()\n const dialogs = this.doc.querySelectorAll(USAGE_DIALOG)\n return dialogs.length === 1 ? (dialogs[0] ?? null) : null\n }\n\n /** Give the dialog back: every price removed, every hidden row restored. */\n private clearDialog(): void {\n for (const price of this.dialogPrices.values()) {\n if (price.parentNode !== null) price.parentNode.removeChild(price)\n }\n this.dialogPrices.clear()\n for (const cell of this.dialogHidden) {\n if (cell.style.display === 'none') cell.style.display = ''\n }\n this.dialogHidden.clear()\n this.dialogHost = undefined\n }\n}\n\n/** The shipped dialog's `dt`/`dd` pairs, in document order. */\nfunction dialogPairs(host: Element): Array<{ dt: HTMLElement; dd: HTMLElement }> {\n const pairs: Array<{ dt: HTMLElement; dd: HTMLElement }> = []\n let label: HTMLElement | null = null\n for (const node of Array.from(host.childNodes)) {\n const tag = tagNameOf(node)\n if (tag === 'DT') label = node as HTMLElement\n else if (tag === 'DD' && label !== null) {\n pairs.push({ dt: label, dd: node as HTMLElement })\n label = null\n }\n }\n return pairs\n}\n\n/** `tagName` upper-cased, or an empty string for a non-element node. */\nfunction tagNameOf(node: Node): string {\n const tag = (node as Element).tagName\n return typeof tag === 'string' ? tag.toUpperCase() : ''\n}\n\n/**\n * Whether the dialog really holds the rows this session's buckets predict.\n *\n * The shipped labels belong to the `chat` locale and differ per language, so rows\n * are matched by POSITION, and this is what makes that safe: the row count must\n * agree, the cache-hit row must be the percentage it is, and every other value\n * must carry exactly the token count of the bucket predicted for it. A mismatch\n * means the dialog is not what this view describes, and nothing is decorated.\n */\nfunction dialogShapeMatches(\n pairs: ReadonlyArray<{ dt: HTMLElement; dd: HTMLElement }>,\n plan: readonly SessionCostRowDecoration[],\n prices: ReadonlyMap,\n): boolean {\n if (pairs.length !== plan.length) return false\n return plan.every((row, index) => {\n const pair = pairs[index]\n if (pair === undefined) return false\n const text = hostValueText(pair.dd, prices.get(pair.dd))\n if (row.tokens === undefined) return text.includes('%')\n return digitsOf(text) === String(row.tokens)\n })\n}\n\n/**\n * A value cell's own text, without the price this module appended to it — the\n * digits of `3,206,544 tok` are the host's, the digits of `$0.07` are ours.\n */\nfunction hostValueText(dd: HTMLElement, price: HTMLElement | undefined): string {\n let text = ''\n for (const node of Array.from(dd.childNodes)) {\n if (node === price) continue\n text += node.textContent ?? ''\n }\n return text\n}\n\n/** Every digit of a display string, so locale grouping cannot break the match. */\nfunction digitsOf(text: string): string {\n return text.replace(/\\D/g, '')\n}\n","/**\n * The composer's live session-cost figure (browser half).\n *\n * This component renders NO surface of its own: the cost lives inside the\n * harness's own token-usage UI, the amount as the last item of the shipped\n * pill's text run (`1.2M tokens · Cache hit 87% · $0.0123`) and the breakdown as\n * extra rows in the usage dialog that pill opens. `./session-cost-display.ts`\n * owns that injection and `./session-cost.ts` every number and string; this file\n * owns the two seats the figures come from and the injection's lifetime.\n *\n * It is registered in `conversation.composer.dock` because that registration is\n * what delivers the seats: `useProjection` is a standard prop the composer hands\n * every dock occupant, and registering under the shipped `stats` cell's id would\n * REPLACE the harness's readout instead of extending it.\n *\n * The rendered node is a hidden marker — `display:none`, so it adds neither a box\n * nor a flex gap. It locates THIS composer from the entry (`closest()` on the\n * dock's outlet anchor), so a session-scoped composer reads its own card rather\n * than whichever row comes first, and it renders only while there is something\n * to show.\n *\n * Two seats are read, from two different owners: `useProjection` comes from the\n * composer (a standard prop, not part of this registration) and\n * `useCommandCodePrices` from our own `inject` face. Reading `props.hooks.*`\n * instead finds `undefined` at runtime and crashes the render, which the slot\n * renderer contains by ABDICATING the entry — a surface that vanishes with no\n * visible error. Both effects are `useEffect`, never `useLayoutEffect`: there is\n * nothing on screen to align with, and a layout effect would warn from the\n * server render the tests use.\n *\n * @module dsh-commandcode-provider/client/session-cost-view\n */\n\nimport type { SessionCostFacts } from '../cost-facts.ts'\nimport { useEffect, useRef } from 'react'\nimport type { SnapshotStore } from './snapshot-store.ts'\nimport type { SessionCostPricesState } from './prices.ts'\nimport { SessionCostDisplay } from './session-cost-display.ts'\nimport {\n buildSessionCostView,\n type SessionModelSelectionProjection,\n type SessionUsageBuckets,\n} from './session-cost.ts'\n\n/**\n * The dock outlet this entry renders inside, i.e. what it scopes itself from.\n *\n * The OUTLET, not its parent. The outlet is one `display:contents` div holding\n * exactly this slot's entries (the shipped `stats` cell and ours), so it is the\n * narrowest container that is still per-composer. Its parent is NOT: from\n * 0.1.6-alpha.2 the composer stacks the dock inside a footer that also holds the\n * `ContextMeter`, whose trigger is another `button[aria-haspopup=\"dialog\"]`\n * rendered after the dock — scoping to the parent would let the cost land on the\n * context ring.\n */\nconst DOCK_ANCHOR = '[data-slot=\"conversation.composer.dock\"]'\n\n/** Module-level constant so the marker's `style` prop never diffs. */\nconst HIDDEN_STYLE = { display: 'none' } as const\n\n/**\n * The injected face this registration carries. Bound by the client entry so the\n * component stays unaware of the Remote, the controller, and its caching.\n *\n * NOTE the split from {@link SessionCostComponentProps}: the renderer\n * destructures this face's `hooks` compartment and re-exposes each member as a\n * `use` prop (`commandCodePrices` → `useCommandCodePrices`); it does not\n * hand the component this object verbatim.\n */\nexport interface SessionCostInjected {\n hooks: {\n commandCodePrices: SnapshotStore\n }\n}\n\n/**\n * The projection keys this readout reads, declared structurally because the\n * plugin bundle does not depend on the session-controller package (whose\n * `UseProjection` this mirrors).\n */\ninterface ProjectionSeats {\n commandCodeCost: SessionCostFacts\n tokenUsage: SessionUsageBuckets\n modelSelection: SessionModelSelectionProjection\n}\n\n/** The projection reader the composer supplies to every dock occupant. */\nexport interface UseProjectionLike {\n (key: K): ProjectionSeats[K] | undefined\n (\n key: K,\n selector: (value: ProjectionSeats[K] | undefined) => S,\n eq?: (a: S, b: S) => boolean,\n ): S\n}\n\n/** The props this component actually receives. */\nexport interface SessionCostComponentProps {\n useCommandCodePrices(selector: (state: SessionCostPricesState) => T): T\n useProjection: UseProjectionLike\n}\n\n/** Log a missing seat once per page, so a silent no-op stays diagnosable. */\nlet warnedMissingSeat = false\n\n/**\n * The composer's session-cost entry. Guards the two seats before rendering the\n * mount: a dsh that does not supply the projection seat to dock occupants gets\n * an absent cost and one console line, never a render crash — which the renderer\n * would answer by abdicating the entry with no visible trace.\n */\nexport function CommandCodeSessionCost(props: SessionCostComponentProps) {\n if (typeof props.useProjection !== 'function' || typeof props.useCommandCodePrices !== 'function') {\n if (!warnedMissingSeat) {\n warnedMissingSeat = true\n console.error(\n '[dsh-commandcode-provider] the composer does not supply the projection/hook seats the session-cost readout needs; the readout stays hidden',\n )\n }\n return null\n }\n return \n}\n\n/** The mount: one injection lifetime, one hidden marker. Every hook lives here. */\nfunction SessionCostEntry(props: SessionCostComponentProps) {\n const markerRef = useRef(null)\n const displayRef = useRef(null)\n const prices = props.useCommandCodePrices((state) => state)\n const usage = props.useProjection('tokenUsage')\n const selection = props.useProjection('modelSelection')\n const facts = props.useProjection('commandCodeCost')\n const view = buildSessionCostView({ usage, selection, facts, table: prices.table, now: Date.now() })\n\n useEffect(() => {\n // No DOM outside a browser: the server render used by the tests, and a\n // node-hosted assembly, must both stay no-ops.\n if (typeof document === 'undefined') return\n const display = new SessionCostDisplay({\n doc: document,\n scope: () => markerRef.current?.closest(DOCK_ANCHOR) ?? null,\n })\n displayRef.current = display\n display.start()\n return () => {\n displayRef.current = null\n display.dispose()\n }\n }, [])\n\n // Every render: the projection is a fresh fold, so there is nothing cheaper to\n // compare than the plan the display derives from it — and the display rewrites\n // a node only when that node's own text actually moved.\n useEffect(() => {\n displayRef.current?.sync(view)\n })\n\n if (view === undefined) return null\n return \n}\n","/**\n * Stylesheet for the Command Code settings page — and the Models-page provider\n * card, which shares its `cc-` classes.\n *\n * Returned as a string, not injected here, so importing this module has no DOM\n * side effect: `./index.ts` installs it once under {@link PAGE_CSS_ID}. It is a\n * module of its own rather than a literal in the entry so `tests/styles.test.ts`\n * can audit every rule without importing the React tree (which pulls\n * `*.module.css` through the primitives package and needs a loader registered\n * first). The rules are GLOBAL CSS, so containment is a contract (issue #48):\n * every selector is qualified by one of our own `cc-` classes. Colours are\n * harness theme aliases with neutral fallbacks, and the `cc-` prefix keeps\n * these clear of the panel's `ccp-` set.\n *\n * @module dsh-commandcode-provider/client/page-styles\n */\n\n/**\n * Stylesheet id — the `data-plugin-css` value that makes injection idempotent.\n *\n * The prefix must match this package's real name and the panel stylesheet's\n * (`PANEL_CSS_ID`); the two ids must also stay DISTINCT, since they key two\n * separate style tags and a shared id would make the second injection a no-op.\n */\nexport const PAGE_CSS_ID = '@mars-sea/dsh-commandcode-provider/CommandCodeSettingsPage.module.css'\n\n/**\n * The settings-page stylesheet.\n *\n * The metrics are the harness's own settings pages', read out of the 0.1.7\n * bundles so the page sits beside General and Models without looking foreign:\n * a row is 12px of padding, its title 14/22 label-primary and its description\n * 12/18 label-tertiary, the control on the right. The hairline rhythm is\n * section-level: a 0.5px border-l2 rule separates the GROUPS (see\n * `cc-groupDivided`), never the rows inside one, so a group's rows read as one\n * list. Selectors and buttons are\n * capsules (36px / 28px compact), inputs are\n * 32px with an 8px radius and a 0.5px border-l4 edge, a card is a 0.5px\n * border-l4 outline with a 16px radius, and a nested panel is a\n * bg-module-platform fill with a 12px radius. Errors use state-error-primary.\n */\nexport const PAGE_CSS = `\n.cc-section{max-width:720px;color:var(--dsw-alias-label-primary);flex-direction:column;display:flex}\n.cc-title{margin:0;color:var(--dsw-alias-label-primary);font-size:16px;font-weight:500;line-height:24px}\n.cc-intro{margin:4px 0 0;color:var(--dsw-alias-label-tertiary);font-size:14px;line-height:22px}\n.cc-readOnly{margin:8px 0 0;color:var(--dsw-alias-state-warn-label,var(--dsw-alias-label-tertiary));font-size:12px;line-height:18px}\n.cc-spacer{flex:1}\n.cc-group{flex-direction:column;display:flex;margin-top:28px}\n.cc-groupDivided{margin-top:24px;padding-top:20px;border-top:.5px solid var(--dsw-alias-border-l2)}\n.cc-groupHead{align-items:center;gap:8px;display:flex;min-height:28px;padding-bottom:4px}\n.cc-groupTitle{margin:0;color:var(--dsw-alias-label-primary);font-size:14px;font-weight:500;line-height:22px}\n.cc-groupDesc{margin:0 0 12px;color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px}\n.cc-rows>.cc-groupDesc{margin:0;padding:4px 0 0}\n.cc-disclosure{width:100%;padding:0 0 4px;border:0;background:0 0;font:inherit;text-align:left;cursor:pointer;border-radius:6px}\n.cc-disclosure:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:2px}\n.cc-rows{flex-direction:column;display:flex}\n.cc-row{align-items:center;gap:8px;display:flex;padding:12px 0}\n.cc-rowFlush{padding:0}\n.cc-rowText{flex-direction:column;flex:1;gap:4px;min-width:0;padding-right:32px;display:flex}\n.cc-rowTitleLine{align-items:center;gap:8px;display:flex;min-width:0}\n.cc-rowTitle{min-width:0;color:var(--dsw-alias-label-primary);font-size:14px;font-weight:400;line-height:22px}\n.cc-rowDesc{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px}\n.cc-rowDesc p{margin:0}\n.cc-rowDesc p+p{margin-top:4px}\n.cc-rowError{margin:0;color:var(--dsw-alias-state-error-primary);font-size:12px;line-height:18px}\n.cc-rowControl{flex:none;align-items:center;justify-content:flex-end;gap:8px;display:inline-flex;max-width:60%}\n.cc-rowInput{width:200px}\n.cc-rowInputWide{width:280px}\n.cc-linkButton{box-sizing:border-box;flex:none;align-items:center;display:inline-flex;height:28px;padding:0 10px;border:0;border-radius:14px;background:0 0;color:var(--dsw-alias-label-tertiary);font:inherit;font-size:12px;line-height:18px;white-space:nowrap;cursor:pointer}\n.cc-linkButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-secondary)}\n.cc-linkButton:disabled{cursor:default;opacity:.4}\n.cc-linkButton:focus-visible{outline:none;box-shadow:0 0 0 2px var(--dsw-alias-border-l3)}\n.cc-badges{align-items:center;gap:8px;display:inline-flex}\n.cc-badge,.cc-badgeMuted{flex:none;align-items:center;display:inline-flex;white-space:nowrap;border-radius:999px;corner-shape:round;padding:1px 8px;font-size:12px;font-weight:500;line-height:17px}\n.cc-badge{background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-secondary)}\n.cc-badgeMuted{border:.5px solid var(--dsw-alias-border-l4);color:var(--dsw-alias-label-tertiary)}\n.cc-badgeWarn{background:var(--dsw-alias-state-warn-tertiary,var(--dsw-alias-bg-module-platform));color:var(--dsw-alias-state-warn-label,var(--dsw-alias-label-secondary))}\n.cc-field{flex-direction:column;gap:6px;padding:12px 0;display:flex}\n.cc-field+.cc-field{border-top:.5px 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-reset{font:inherit;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;padding:0;font-size:12px;line-height:18px}\n.cc-reset:hover:not(:disabled){color:var(--dsw-alias-label-primary)}\n.cc-reset:disabled{cursor:default;opacity:.4}\n.cc-input{box-sizing:border-box;height:32px;min-width:0;padding:0 10px;border:.5px solid var(--dsw-alias-border-l4);border-radius:8px;background:var(--dsw-alias-bg-layer-1);font:inherit;color:var(--dsw-alias-label-primary);font-size:14px;line-height:22px}\n.cc-input::placeholder{color:var(--dsw-alias-label-dimmed)}\n.cc-input:focus-visible{border-color:var(--dsw-alias-brand-primary);outline:none}\n.cc-input:disabled{opacity:.6;cursor:default}\n.cc-inputInvalid{border-color:var(--dsw-alias-state-error-primary)}\n.cc-hint{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px;line-height:18px}\n.cc-modelSelectAnchor{flex-direction:column;align-items:stretch;gap:6px;display:inline-flex;min-width:160px}\n.cc-selector{box-sizing:border-box;align-items:center;gap:12px;display:inline-flex;height:36px;padding:0 14px;border:0;border-radius:18px;background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-primary);font:inherit;font-size:14px;line-height:22px;text-align:left;cursor:pointer}\n.cc-selector:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}\n.cc-selector:disabled{cursor:default;opacity:.4}\n.cc-selector:focus-visible{outline:none;box-shadow:0 0 0 2px var(--dsw-alias-border-l3)}\n.cc-selectorText{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.cc-selectorCaret{flex-shrink:0;border-right:1.5px solid var(--dsw-alias-label-tertiary);border-bottom:1.5px solid var(--dsw-alias-label-tertiary);width:6px;height:6px;margin-bottom:3px;transform:rotate(45deg)}\n/* The search box sits inside the Menu anchor, so typing in it never trips\n * the Menu's outside-click close. */\n.cc-modelSearch{width:100%}\n.cc-modelSearch::-webkit-search-cancel-button{cursor:pointer}\n.cc-checkRow{align-items:center;gap:8px;display:inline-flex;min-width:0}\n.cc-checkRow:hover{cursor:pointer}\n/* A hand-drawn box, not the platform's accent-color checkbox: the native\n * control's colours come from color-scheme, which the theme sets once at BOOT\n * and never re-applies in-session, so a native box can paint light-chrome white\n * on a dark page. The mark rides a brand-primary fill, so it takes the brand\n * foreground (the only pairing that survives dark mode's near-white brand), and\n * the outline is a border-l3 hairline because border-l2 leaves an unchecked box\n * invisible against the menu surface. */\n.cc-check{box-sizing:border-box;appearance:none;flex-shrink:0;width:16px;height:16px;margin:0;border:1px solid var(--dsw-alias-border-l3);border-radius:4px;background:0 0;position:relative}\n.cc-check:checked{background:var(--dsw-alias-brand-primary);border-color:var(--dsw-alias-brand-primary)}\n.cc-check:checked::after{content:'';position:absolute;top:3px;left:5px;width:3px;height:7px;border:solid var(--dsw-alias-label-primary-foreground,#fff);border-width:0 1.5px 1.5px 0;transform:rotate(45deg)}\n.cc-checkName{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n/* Modelled on the platform's own Switch primitive (ui-primitives\n * Switch.module.css): a 36x20 capsule padding its track by 2px and sliding a\n * 16px thumb across the 32px content box. Three things are load-bearing.\n * (1) corner-shape:round on BOTH track and thumb — the theme sets a global\n * superellipse corner shape, which squares a capsule's ends off around a round\n * thumb. (2) No literal colours: brand-primary INVERTS between the modes, so a\n * hardcoded white thumb vanishes on the checked track in dark mode; the brand\n * foreground is what the platform paints on that fill. (3) border-l3 as the\n * off track — border-l2 leaves it indistinguishable from the page. */\n.cc-toggle{box-sizing:border-box;appearance:none;flex-shrink:0;width:36px;height:20px;margin:0;padding:2px;border:0;border-radius:10px;corner-shape:round;background:var(--dsw-alias-border-l3);cursor:pointer;position:relative}\n.cc-toggle:checked{background:var(--dsw-alias-brand-primary)}\n.cc-toggle::after{content:'';display:block;width:16px;height:16px;border-radius:50%;corner-shape:round;background:var(--dsw-alias-label-primary-foreground);transition:transform .12s ease}\n.cc-toggle:checked::after{transform:translateX(16px)}\n.cc-toggle:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:2px}\n.cc-toggle:disabled{cursor:default;opacity:.5}\n.cc-chevron{flex-shrink:0;border-right:1.5px solid var(--dsw-alias-label-tertiary);border-bottom:1.5px solid var(--dsw-alias-label-tertiary);width:7px;height:7px;margin-right:6px;margin-bottom:3px;transform:rotate(45deg);transition:transform .15s ease}\n.cc-chevronUp{transform:rotate(-135deg);margin-bottom:-3px}\n.cc-accountMode{align-items:center;gap:4px;display:flex;margin:-4px 0 12px;color:var(--dsw-alias-label-secondary);font-size:12px;line-height:18px}\n.cc-accountList{flex-direction:column;gap:8px;display:flex}\n.cc-accountList+.cc-addButton,.cc-accountList+.cc-addPanel{margin-top:8px}\n.cc-accountItem{flex-direction:column;gap:10px;display:flex;padding:12px 14px;border:.5px solid var(--dsw-alias-border-l4);border-radius:16px}\n.cc-accountItemActive{border-color:var(--dsw-static-neutral-bluish-400,var(--dsw-alias-border-l3))}\n.cc-accountHead{align-items:center;gap:4px;display:flex;min-height:28px}\n.cc-accountToggle{align-items:center;gap:8px;display:flex;flex:1;min-width:0;padding:0;background:0 0;border:0;color:inherit;cursor:pointer;font:inherit;text-align:left}\n.cc-accountToggle:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:2px;border-radius:4px}\n.cc-accountName{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--dsw-alias-label-primary);font-size:14px;font-weight:500;line-height:22px}\n.cc-iconButton{flex-shrink:0;align-items:center;justify-content:center;display:inline-flex;width:28px;height:28px;padding:0;background:0 0;border:0;border-radius:6px;color:var(--dsw-alias-label-tertiary);cursor:pointer}\n.cc-iconButton:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}\n.cc-iconButton:focus-visible{outline:none;box-shadow:0 0 0 2px var(--dsw-alias-border-l3)}\n/* Per-model context-length override rows (issue #86): the error wraps onto\n its own line beneath the select/input/remove trio. The three cells form a\n fixed column contract — flexible model, 112px value, 28px remove — and the\n cc-contextHead labels repeat the first two (plus the remove cell's width\n as a spacer) so they sit exactly over their columns. */\n.cc-contextItem{align-items:center;gap:8px;display:flex;flex-wrap:wrap;padding:8px 0}\n.cc-contextHead{align-items:center;gap:8px;display:flex;flex-wrap:wrap;padding:4px 0 0;color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px}\n.cc-contextHeadModel{flex:1;min-width:200px}\n.cc-contextHeadValue{flex:none;width:112px}\n.cc-contextHeadGap{flex:none;width:28px}\n.cc-contextSelect{position:relative;display:block;flex:1;min-width:200px}\n/* appearance:none swaps the platform arrow for the cc-contextCaret, shaped\n like cc-selectorCaret so every dropdown in the plugin opens with the same\n hand-drawn chevron. */\n.cc-contextModel{box-sizing:border-box;appearance:none;-webkit-appearance:none;width:100%;padding-inline-end:26px;text-overflow:ellipsis;cursor:pointer}\n.cc-contextCaret{position:absolute;inset-inline-end:12px;top:50%;width:6px;height:6px;border-right:1.5px solid var(--dsw-alias-label-tertiary);border-bottom:1.5px solid var(--dsw-alias-label-tertiary);transform:translateY(-50%) rotate(45deg);pointer-events:none}\n.cc-contextSelect:has(.cc-contextModel:disabled) .cc-contextCaret{opacity:.6}\n.cc-contextValue{flex:none;width:112px}\n.cc-contextError{flex-basis:100%}\n/* Three dots from one element: the dot plus two box-shadow copies. */\n.cc-kebab{width:3px;height:3px;border-radius:50%;corner-shape:round;background:currentColor;box-shadow:0 -5px 0 currentColor,0 5px 0 currentColor}\n.cc-tabDot{flex-shrink:0;width:8px;height:8px;border-radius:50%;corner-shape:round}\n.cc-tabDotOk{background:var(--dsw-alias-state-success-primary)}\n.cc-tabDotBlank{background:0 0;border:0}\n.cc-tabDotWarn{background:var(--dsw-alias-state-warn-primary,#d97706)}\n.cc-tabDotError{background:var(--dsw-alias-state-error-primary)}\n.cc-accountMeters{flex-wrap:wrap;gap:6px 20px;display:flex;padding-left:16px}\n.cc-miniMeter{align-items:center;gap:8px;display:inline-flex;font-size:12px;line-height:18px}\n.cc-miniMeterLabel{color:var(--dsw-alias-label-tertiary)}\n.cc-miniMeterTrack{overflow:hidden;background:var(--dsw-alias-bg-module-platform);border-radius:999px;width:64px;height:4px}\n.cc-miniMeterFill{display:block;background:var(--dsw-alias-brand-primary);border-radius:999px;height:100%}\n.cc-miniMeterValue{color:var(--dsw-alias-label-secondary);font-variant-numeric:tabular-nums}\n.cc-accountSetup,.cc-loginStatus{flex-direction:column;gap:8px;display:flex;padding-left:16px}\n.cc-loginStatus{flex-direction:row;flex-wrap:wrap;align-items:center;gap:4px 12px}\n.cc-loginStatus>p{margin:0;font-size:12px;line-height:18px}\n.cc-accountDetails{container-type:inline-size;border-top:.5px solid var(--dsw-alias-border-l2);flex-direction:column;gap:14px;display:flex;padding-top:12px}\n.cc-inlineForm,.cc-confirmBar{flex-direction:column;gap:8px;display:flex}\n.cc-inlineActions{align-items:center;gap:8px;display:flex}\n.cc-confirmBar{border:.5px solid var(--dsw-alias-state-error-primary);border-radius:12px;padding:12px 14px}\n.cc-confirmText{color:var(--dsw-alias-label-primary);margin:0;font-size:14px;line-height:22px}\n.cc-dangerButton{color:var(--dsw-alias-state-error-primary);border-color:var(--dsw-alias-state-error-primary)}\n.cc-dangerButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover-danger)}\n.cc-addButton{box-sizing:border-box;align-items:center;justify-content:center;gap:6px;display:flex;width:100%;height:44px;border:1px dashed var(--dsw-alias-border-l3);border-radius:16px;background:0 0;color:var(--dsw-alias-label-primary);font:inherit;font-size:14px;line-height:22px;cursor:pointer}\n.cc-addButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}\n.cc-addButton:disabled{cursor:default;opacity:.4}\n.cc-addButton:focus-visible{outline:none;box-shadow:0 0 0 2px var(--dsw-alias-border-l3)}\n.cc-addGlyph{position:relative;width:12px;height:12px}\n.cc-addGlyph::before,.cc-addGlyph::after{content:'';position:absolute;background:currentColor;border-radius:1px}\n.cc-addGlyph::before{left:0;right:0;top:5.25px;height:1.5px}\n.cc-addGlyph::after{top:0;bottom:0;left:5.25px;width:1.5px}\n.cc-addPanel{flex-direction:column;gap:12px;display:flex;padding:14px 16px;border-radius:12px;background:var(--dsw-alias-bg-module-platform)}\n.cc-panelTitle{color:var(--dsw-alias-label-primary);font-size:14px;font-weight:500;line-height:22px}\n.cc-accountReport{flex-direction:column;gap:14px;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:14px;font-weight:500;line-height:22px}\n.cc-usageAccount{max-width:40%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px}\n.cc-usagePlan{flex:none;white-space:nowrap;border:.5px solid var(--dsw-alias-border-l3);color:var(--dsw-alias-label-secondary);border-radius:999px;corner-shape:round;padding:0 7px;font-size:12px;font-weight:500;line-height:17px}\n.cc-usagePlanStatus{flex:none;margin:0;white-space:nowrap;color:var(--dsw-alias-state-error-primary);font-size:12px;line-height:18px}\n.cc-usageHint{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px;line-height:18px}\n/* Two fixed grids, not one auto-fit track: auto-fit wrapped the four activity\n * tiles 3 + 1 at the details' width. The activity row folds to 2 × 2 in a\n * narrow details panel. */\n.cc-usageStats{grid-template-columns:repeat(auto-fit,minmax(120px,1fr));gap:8px;display:grid}\n.cc-usageStatsActivity{grid-template-columns:repeat(4,minmax(0,1fr))}\n.cc-usageStatsBalance{grid-template-columns:repeat(3,minmax(0,1fr))}\n@container (max-width:460px){.cc-usageStatsActivity{grid-template-columns:repeat(2,minmax(0,1fr))}}\n.cc-usageStat{min-width:0;flex-direction:column;gap:2px;display:flex;padding:10px 12px;border-radius:12px;background:var(--dsw-alias-bg-module-platform)}\n.cc-usageStatLabel{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px}\n.cc-usageStatValue{color:var(--dsw-alias-label-primary);font-size:16px;font-weight:500;line-height:24px;font-variant-numeric:tabular-nums}\n.cc-usageStatSub{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.cc-usageWindows{flex-direction:column;gap:14px;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;line-height:18px}\n.cc-usageWindowValue{color:var(--dsw-alias-label-primary);font-size:12px;line-height:18px;font-variant-numeric:tabular-nums}\n.cc-usageExceeded{color:var(--dsw-alias-state-error-primary);font-size:12px;line-height:18px}\n.cc-usageBar{overflow:hidden;background:var(--dsw-alias-bg-module-platform);border-radius:999px;height:4px}\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-state-error-primary)}\n.cc-usageWindowReset{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px;line-height:18px}\n.cc-usageMeta{align-items:center;gap:8px;display:flex}\n.cc-usageMetaSpacer{flex:1}\n.cc-usageUpdated{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px;line-height:18px}\n.cc-usagePartial{color:var(--dsw-alias-state-error-primary);margin:0;font-size:12px;line-height:18px}\n.cc-usageBlocked{border:.5px solid var(--dsw-alias-state-error-primary);border-radius:12px;padding:12px 14px;display:flex;flex-direction:column;gap:4px}\n.cc-usageBlockedTitle{color:var(--dsw-alias-state-error-primary);margin:0;font-size:14px;font-weight:500;line-height:22px}\n.cc-usageBlockedHint{color:var(--dsw-alias-label-secondary);margin:0;font-size:12px;line-height:18px}\n.cc-usageBlockedDetail{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px;line-height:18px;word-break:break-word}\n.cc-version{margin:32px 0 0;text-align:center;color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px}\n.cc-versionLink{color:var(--dsw-alias-state-warn-label,var(--dsw-alias-label-secondary));text-decoration:none}\n.cc-versionLink:hover{color:var(--dsw-alias-label-primary);text-decoration:underline;text-underline-position:under}\n.cc-providerCard{flex-direction:column;display:flex}\n.cc-footer{justify-content:flex-end;align-items:center;gap:8px;display:flex}\n.cc-failed{display:inline-block;max-width:260px;min-width:0;color:var(--dsw-alias-state-error-primary);margin:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:12px;line-height:18px}\n.cc-loginLink{color:var(--dsw-alias-link,var(--dsw-alias-brand-primary));text-decoration:none;font-size:12px;line-height:18px}\n.cc-loginLink:hover{text-decoration:underline;text-underline-position:under}\n.cc-loginDone{color:var(--dsw-alias-state-success-primary,var(--dsw-alias-label-secondary))}\n.cc-loginError{color:var(--dsw-alias-state-error-primary)}\n/* The floating save bar: a centered capsule pinned to the bottom of the\n * settings scrollport. The dock is a zero-height sticky strip at the end of the\n * page, so the bar overlays the scrolling content instead of taking a row of\n * its own; while shown, the section reserves room at its end so the last line\n * can scroll clear. Hidden, it sinks and fades, and visibility (switched after\n * the transition) takes its buttons out of the tab order. Its surface is an\n * elevated layer (bg-layer-1 over the settings panel's layer-2) with the\n * platform's prominent elevation and no stroke, and its corners are concentric\n * (a 44px capsule around 36px buttons inset by 4px) so the gap around each\n * button is even. */\n.cc-sectionWithBar{padding-bottom:80px}\n.cc-saveBarDock{position:sticky;bottom:0;z-index:2;height:0;pointer-events:none}\n.cc-saveBar{--cc-saveBar-tone:var(--dsw-alias-state-warn-primary,#d97706);position:absolute;left:50%;bottom:20px;box-sizing:border-box;width:max-content;max-width:calc(100% - 24px);align-items:center;gap:10px;display:flex;height:44px;padding:4px 4px 4px 16px;border:0;border-radius:22px;corner-shape:round;background:var(--dsw-alias-bg-layer-1);box-shadow:var(--dsw-elevation-prominent,0 12px 32px -8px rgba(0,0,0,.24),0 2px 8px rgba(0,0,0,.08));opacity:0;visibility:hidden;transform:translate(-50%,12px);transition:opacity .16s ease,transform .16s ease,visibility 0s linear .16s}\n.cc-saveBarShown{opacity:1;visibility:visible;transform:translate(-50%,0);pointer-events:auto;transition:opacity .2s ease,transform .24s cubic-bezier(.2,.9,.3,1.1),visibility 0s}\n.cc-saveBar-error{--cc-saveBar-tone:var(--dsw-alias-state-error-primary)}\n.cc-saveBar-success{--cc-saveBar-tone:var(--dsw-alias-state-success-primary,#16a34a);padding-right:18px}\n.cc-saveBarIcon{flex-shrink:0;align-items:center;justify-content:center;display:inline-flex;width:16px;height:16px;color:var(--cc-saveBar-tone)}\n.cc-saveBarPulse{width:8px;height:8px;border-radius:50%;corner-shape:round;background:var(--cc-saveBar-tone)}\n.cc-saveBarText{min-width:0;margin:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--dsw-alias-label-primary);font-size:14px;line-height:22px}\n.cc-saveBar-error .cc-saveBarText{color:var(--dsw-alias-state-error-primary)}\n.cc-saveBarActions{flex-shrink:0;align-items:center;gap:4px;display:flex;margin-left:8px}\n.cc-saveBarButton{box-sizing:border-box;height:36px;padding:0 16px;border:0;border-radius:18px;corner-shape:round;font:inherit;font-size:14px;line-height:22px;white-space:nowrap;cursor:pointer}\n.cc-saveBarButton:focus-visible{outline:none;box-shadow:0 0 0 2px var(--dsw-alias-border-l3)}\n.cc-saveBarButton:disabled{cursor:default;opacity:.4}\n.cc-saveBarGhost{background:0 0;color:var(--dsw-alias-label-primary)}\n.cc-saveBarGhost:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}\n.cc-saveBarPrimary{background:var(--dsw-alias-button-primary-fill,var(--dsw-alias-brand-primary));color:var(--dsw-alias-label-primary-foreground,#fff)}\n.cc-saveBarPrimary:hover:not(:disabled){background:var(--dsw-alias-button-primary-hover,var(--dsw-alias-button-primary-fill,var(--dsw-alias-brand-primary)))}\n@media (prefers-reduced-motion:reduce){.cc-chevron,.cc-toggle::after,.cc-usageBarFill,.cc-saveBar,.cc-saveBarShown{transition:none}}\n`\n","/**\n * Stylesheet for the Command Code plans & quota panel (the sidebar footer card\n * and the dashboard it opens).\n *\n * Returned as a string, not injected here, so importing this module has no DOM\n * side effect: `./index.ts` installs it once under {@link PANEL_CSS_ID} and\n * removes it when the fiber unwinds.\n *\n * These rules are GLOBAL CSS, so containment is a contract (issue #48): every\n * selector is qualified by one of our own `ccp-` classes except the sidebar\n * anchor below, which carries its justification in place. `tests/styles.test.ts`\n * audits both stylesheets against the real foreign class stems. Colours are\n * harness theme aliases with neutral fallbacks; the `ccp-` prefix keeps these\n * clear of the settings page's `cc-` set.\n *\n * @module dsh-commandcode-provider/client/panel-styles\n */\n\n/**\n * Stylesheet id — the `data-plugin-css` value that makes injection idempotent.\n *\n * The prefix must match this package's real name and the settings-page sheet's\n * (`PAGE_CSS_ID`); the two ids must also stay DISTINCT, since they key two\n * separate style tags and a shared id would make the second injection a no-op.\n */\nexport const PANEL_CSS_ID = '@mars-sea/dsh-commandcode-provider/CommandCodePanel.module.css'\n\n/** The panel stylesheet. */\nexport const PANEL_CSS = `\n/* ------------------------------------------------- sidebar footer card */\n/* The shell renders this list ABOVE the Settings seat, so the card is the\n sidebar's bottom-most content, and supplies no chrome: the entry IS the\n button. Deliberately quiet — a surface beside Settings should read as part of\n the column — with one hover step and a hairline border.\n\n The shell's container is a flex ROW whose occupants each declare a full-width\n line and shrink-proof flex, so as a row it would overflow the column: this\n card cannot shrink and the neighbouring chip would absorb the overflow and\n collapse to nothing. The first rule is that fix, and THE ANCHOR IS\n LOAD-BEARING (issue #48): \"footerActions\" is not a stem this shell owns alone\n — dsh-client-ui-user-questions renders the ask-user-question dialog's button\n row as Mbwy4a_footerActions, and the unanchored rule stacked THAT row's\n side-by-side buttons on every page. \"footArea\" is declared by\n dsh-client-ui-sidebar alone (audited across every client bundle of the\n 0.1.6-alpha.1 engine, and against our own cc-/ccp- names, which collide with\n no engine class). The DESCENDANT combinator survives a wrapper element\n appearing between the two, so a restructured shell degrades to its own row\n rather than losing the fix. tests/styles.test.ts pins both halves. */\n[class*=\"_footArea\"] [class*=\"_footerActions\"]{flex-direction:column}\n.ccp-foot{box-sizing:border-box;flex:0 0 auto;width:100%;min-width:0;font:inherit;color:var(--dsw-alias-label-secondary);text-align:left;cursor:pointer;background:0 0;border:1px solid transparent;border-radius:10px;flex-direction:column;gap:6px;margin:0 0 4px;padding:8px;display:flex}\n.ccp-foot:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-interactive-bg-hover);border-color:var(--dsw-alias-border-l2)}\n.ccp-foot:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:1px}\n.ccp-footTop{align-items:center;gap:8px;min-width:0;display:flex}\n.ccp-footName{white-space:nowrap;text-overflow:ellipsis;color:var(--dsw-alias-label-primary);min-width:0;overflow:hidden;font-size:13px;font-weight:500;line-height:20px}\n/* One block per quota window: a head line carrying the window's own spend and\n limit, then the FULL-WIDTH bar under it. Stacking the two lets the card show\n the dollar figures — the reason this surface exists — without squeezing the\n bar into what is left beside them. Mirrors the dashboard's window block. */\n.ccp-footRow{flex-direction:column;gap:4px;min-width:0;display:flex}\n.ccp-footHead{align-items:baseline;gap:8px;min-width:0;display:flex}\n.ccp-footLabel{flex:1;color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:16px}\n.ccp-footAmount{flex:none;color:var(--dsw-alias-label-secondary);font-size:12px;line-height:16px;font-variant-numeric:tabular-nums;white-space:nowrap}\n/* The card's markup must stay PHRASING content — it renders inside the shell's\n own button — so these bars are spans, which makes display:block load-bearing:\n an inline box ignores width outright, so the fill would collapse to 0x0 and\n the bar would show no usage. */\n.ccp-footBar{display:block;background:var(--dsw-alias-bg-layer-2);border-radius:999px;height:5px;overflow:hidden}\n.ccp-footFill{display:block;background:var(--dsw-alias-brand-primary);border-radius:999px;height:100%;transition:width .3s ease}\n.ccp-footFillWarn{background:var(--dsw-alias-state-error-primary)}\n.ccp-footPct{flex:none;width:34px;color:var(--dsw-alias-label-secondary);text-align:right;font-size:12px;line-height:16px;font-variant-numeric:tabular-nums}\n\n/* The 56px rail: one icon button on the shell's own 36px rail cell, so the\n collapsed column keeps a single 18px glyph like its siblings. */\n.ccp-railButton{box-sizing:border-box;width:36px;height:36px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:1px solid transparent;border-radius:8px;flex:none;justify-content:center;align-items:center;margin:0 0 4px;padding:0;display:inline-flex}\n.ccp-railButton:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-interactive-bg-hover)}\n.ccp-railButton:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:1px}\n\n/* The ring glyph, sized entirely by its own width/height attribute, so the\n footer row, the rail button and the dashboard can each ask for their own. */\n.ccp-glyph{flex:none;justify-content:center;align-items:center;display:inline-flex;color:var(--dsw-alias-brand-primary)}\n\n/* ------------------------------------------------------------ dashboard */\n.ccp-main{background:var(--dsw-alias-bg-layer-1);width:100%;height:100%;overflow:auto;display:block}\n.ccp-mainInner{max-width:760px;margin:0 auto;padding:24px 20px 40px;flex-direction:column;gap:14px;display:flex;color:var(--dsw-alias-label-primary)}\n.ccp-header{align-items:center;gap:10px;display:flex;flex-wrap:wrap}\n.ccp-headerText{flex-direction:column;gap:2px;display:flex;min-width:0}\n.ccp-title{margin:0;font-size:18px;font-weight:600;line-height:1.4}\n.ccp-subtitle{margin:0;color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:1.5}\n.ccp-spacer{flex:1}\n.ccp-meta{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:1.5;font-variant-numeric:tabular-nums}\n/* 关闭图标沿用原语义与按钮尺寸,线性 SVG 随宿主文字颜色变化。 */\n.ccp-close{min-width:28px;justify-content:center;padding-left:0;padding-right:0}\n.ccp-hint{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px;line-height:1.5}\n\n.ccp-notice{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:12px;padding:12px 14px;flex-direction:column;gap:4px;display:flex}\n.ccp-noticeError{border-color:var(--dsw-alias-state-error-primary)}\n.ccp-noticeTitle{margin:0;font-size:13px;font-weight:600;line-height:1.5}\n.ccp-noticeError .ccp-noticeTitle{color:var(--dsw-alias-state-error-primary)}\n.ccp-noticeHint{margin:0;color:var(--dsw-alias-label-secondary);font-size:12px;line-height:1.55}\n.ccp-noticeDetail{margin:0;color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:1.5;word-break:break-word}\n\n.ccp-card{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:14px;padding:16px 18px;flex-direction:column;gap:16px;display:flex}\n.ccp-cardHead{align-items:center;gap:10px;display:flex;flex-wrap:wrap}\n.ccp-avatar{flex:none;width:28px;height:28px;color:var(--dsw-alias-brand-primary);background:var(--dsw-alias-bg-module-platform);border-radius:50%;justify-content:center;align-items:center;font-size:12px;font-weight:600;line-height:1;display:inline-flex}\n.ccp-cardIdentity{flex-direction:column;gap:1px;min-width:0;display:flex}\n.ccp-cardTitle{font-size:13px;font-weight:600;line-height:1.4}\n.ccp-cardOwner{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:1.4;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:220px}\n.ccp-block{flex-direction:column;gap:8px;display:flex}\n.ccp-blockTitle{margin:0;color:var(--dsw-alias-label-tertiary);font-size:12px;font-weight:600;line-height:1.5;text-transform:uppercase;letter-spacing:.04em}\n.ccp-planRow{align-items:center;gap:8px;display:flex;flex-wrap:wrap}\n.ccp-fieldLabel{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:1.5}\n.ccp-planName{color:var(--dsw-alias-label-primary);font-size:13px;font-weight:600;line-height:1.5}\n\n/* The monthly credits and the usage totals share one grid. */\n.ccp-tiles{display:grid;grid-template-columns:repeat(auto-fit,minmax(120px,1fr));gap:8px}\n.ccp-tile{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;min-width:0}\n.ccp-tileLabel{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:1.5}\n.ccp-tileValue{color:var(--dsw-alias-label-primary);font-size:15px;font-weight:600;line-height:1.4;font-variant-numeric:tabular-nums}\n.ccp-tileSub{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:1.5;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n\n/* Quota bars: the monthly bar and the two windows. */\n.ccp-windows{flex-direction:column;gap:14px;display:flex}\n.ccp-window{flex-direction:column;gap:6px;display:flex}\n.ccp-windowHead{align-items:baseline;gap:8px;display:flex}\n.ccp-windowLabel{color:var(--dsw-alias-label-secondary);font-size:12px;font-weight:500;line-height:1.5}\n.ccp-windowValue{color:var(--dsw-alias-label-secondary);font-size:12px;line-height:1.5;font-variant-numeric:tabular-nums;white-space:nowrap}\n.ccp-windowPct{color:var(--dsw-alias-label-primary);min-width:38px;text-align:right;font-size:12px;font-weight:600;line-height:1.5;font-variant-numeric:tabular-nums}\n.ccp-warnTag{white-space:nowrap;background:var(--dsw-alias-state-warn-tertiary,var(--dsw-alias-bg-module-platform));color:var(--dsw-alias-state-warn-primary,var(--dsw-alias-label-secondary));border-radius:999px;padding:0 8px;font-size:12px;font-weight:600;line-height:17px}\n.ccp-bar{overflow:hidden;background:var(--dsw-alias-bg-layer-1);border-radius:999px;height:8px}\n.ccp-barFill{background:var(--dsw-alias-brand-primary);border-radius:999px;height:100%;transition:width .3s ease}\n.ccp-barFillWarn{background:var(--dsw-alias-state-error-primary)}\n.ccp-windowReset{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px;line-height:1.5}\n\n.ccp-badge{white-space:nowrap;background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-brand-primary);border-radius:999px;padding:1px 8px;font-size:12px;font-weight:600;line-height:17px}\n.ccp-badgeError{background:transparent;color:var(--dsw-alias-state-error-primary)}\n.ccp-badgeWarn{background:var(--dsw-alias-state-warn-tertiary,var(--dsw-alias-bg-module-platform));color:var(--dsw-alias-state-warn-primary,var(--dsw-alias-label-secondary))}\n.ccp-badgeMuted{white-space:nowrap;background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-secondary);border-radius:999px;padding:1px 8px;font-size:12px;font-weight:500;line-height:17px;max-width:220px;overflow:hidden;text-overflow:ellipsis}\n\n/* Account switch: plain buttons, like the settings page's usage carousel. */\n.ccp-tabs{flex-wrap:wrap;gap:6px;display:flex}\n.ccp-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.ccp-tab:hover:not(.ccp-tabActive){color:var(--dsw-alias-label-primary)}\n.ccp-tabActive{color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-brand-primary)}\n\n@media (prefers-reduced-motion:reduce){.ccp-footFill,.ccp-barFill{transition:none}}\n/* 分析页继承设置页和宿主控件的语义变量;独立选择器不影响账号额度页面。 */\n.ccp-mainInnerAnalysis{max-width:1040px;box-sizing:border-box}\n/* 宿主侧栏会缩窄中心面板,按实际可用宽度切换列数,而不是仅看浏览器宽度。 */\n.ccp-analysis{font-size:14px;line-height:22px;min-width:0;color:var(--dsw-alias-label-primary);container-type:inline-size;container-name:ccp-analysis}\n.ccp-analysisFilters{display:flex;gap:12px;align-items:flex-end;flex-wrap:wrap;margin:8px 0 20px}\n.ccp-analysisField{display:flex;flex-direction:column;gap:6px;font-size:12px;line-height:18px;color:var(--dsw-alias-label-tertiary);min-width:0}\n.ccp-analysisFilters .ccp-analysisField{flex:0 1 158px}\n.ccp-analysisFilters .ccp-analysisScopeField{flex-basis:184px}\n.ccp-analysisFilters .ccp-analysisDateField{flex-basis:166px}\n/* 对齐原生选择器、日期输入与按钮的边框盒;保留独立箭头留白和点击区域。 */\n.ccp-analysisInput{box-sizing:border-box;width:100%;min-width:0;height:36px;padding:0 11px;font:inherit;font-size:14px;line-height:22px;color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-1);border:.5px solid var(--dsw-alias-border-l4);border-radius:8px}\n.ccp-analysisSelectShell{position:relative;display:block;width:100%;min-width:0}\n.ccp-analysisSelect{appearance:none;-webkit-appearance:none;padding-inline-end:40px;text-overflow:ellipsis;cursor:pointer;border:0;border-radius:18px;background:var(--dsw-alias-bg-module-platform)}\n.ccp-analysisSelectShell > .ccp-analysisChevron{position:absolute;inset-inline-end:12px;top:50%;transform:translateY(-50%) rotate(90deg);pointer-events:none}\n.ccp-analysisSelect:disabled + .ccp-analysisChevron{opacity:.6}\n.ccp-analysisInput::placeholder{color:var(--dsw-alias-label-tertiary)}\n.ccp-analysisApply{box-sizing:border-box;flex:none;height:36px;font:inherit;font-size:14px;line-height:22px;white-space:nowrap;padding:0 20px;border:0;border-radius:var(--dsw-radius-md,18px);background:var(--dsw-alias-button-primary-fill);color:var(--dsw-alias-label-primary-foreground);cursor:pointer;margin-left:2px}\n.ccp-analysisApply:hover:not(:disabled){background:var(--dsw-alias-button-primary-hover)}\n.ccp-analysisApply:disabled{opacity:.4;cursor:wait}\n.ccp-analysisInput:disabled{opacity:.6}\n.ccp-analysisInput:focus-visible,.ccp-analysisApply:focus-visible,.ccp-analysisTab:focus-visible,.ccp-analysisPanel:focus-visible,.ccp-analysisModelSummary:focus-visible,.ccp-analysisScenarioSummary:focus-visible,.ccp-analysisDisclosure:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:3px}\n/* 模型列表会裁切圆角,内收焦点框以保持第一行和最后一行也清晰可见。 */\n.ccp-analysisModelSummary:focus-visible,.ccp-analysisScenarioSummary:focus-visible{outline-offset:-3px;border-radius:6px}\n.ccp-analysisScope{display:flex;justify-content:space-between;gap:8px 18px;flex-wrap:wrap;color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px;margin-bottom:12px}\n.ccp-analysisScope > span:first-child{color:var(--dsw-alias-label-primary);font-weight:500}\n.ccp-analysisOverview{display:grid;grid-template-columns:1.45fr repeat(3,1fr);gap:20px;padding:16px 18px;background:var(--dsw-alias-bg-layer-3);border:.5px solid var(--dsw-alias-border-l4);border-radius:16px;font-variant-numeric:tabular-nums}\n.ccp-analysisMetric{display:flex;flex-direction:column;gap:3px;min-width:0}\n.ccp-analysisLabel{font-size:12px;line-height:18px;color:var(--dsw-alias-label-tertiary);font-weight:400}\n.ccp-analysisValue{font-size:14px;line-height:22px;font-weight:500;overflow-wrap:anywhere}\n.ccp-analysisSub{display:block;color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px;font-weight:400;overflow-wrap:anywhere}\n.ccp-analysisOverview .ccp-analysisMetric{gap:5px}\n.ccp-analysisOverview .ccp-analysisValue{font-size:20px;line-height:28px;font-weight:500}\n.ccp-analysisNote{font-size:12px;line-height:18px;color:var(--dsw-alias-label-tertiary);margin:9px 0 0}\n.ccp-analysisMessage{margin:12px 0 0;padding:12px 14px;border:.5px solid var(--dsw-alias-border-l4);border-radius:12px;background:var(--dsw-alias-bg-layer-3);font-size:14px;line-height:22px}\n.ccp-analysisWarning{display:flex;align-items:flex-start;gap:8px}\n.ccp-analysisIcon{flex:none}\n.ccp-analysisWarning > .ccp-analysisIcon{color:var(--dsw-alias-state-warn-label,var(--dsw-alias-label-secondary));margin-top:3px}\n.ccp-analysisWarning p{margin:0}\n.ccp-analysisWarning p + p{margin-top:5px}\n.ccp-analysisError{color:var(--dsw-alias-state-error-primary)}\n/* 沿用宿主分段控件的轨道、浮层与胶囊尺寸,保留原有页签键盘语义。 */\n.ccp-analysisTabs{box-sizing:border-box;display:inline-grid;grid-auto-flow:column;grid-auto-columns:1fr;gap:2px;padding:4px;border:0;border-radius:var(--dsw-radius-md,18px);background:var(--dsw-alias-interactive-bg-hover);margin:22px 0 0;max-width:100%}\n.ccp-analysisTab{height:28px;padding:0 16px;border:0;border-radius:var(--dsw-radius-sm,14px);background:transparent;font:inherit;font-size:13px;line-height:20px;font-weight:500;color:var(--dsw-alias-label-secondary);white-space:nowrap;cursor:pointer}\n.ccp-analysisTab:hover,.ccp-analysisTab[aria-selected=\"true\"]{color:var(--dsw-alias-label-primary)}\n.ccp-analysisTab[aria-selected=\"true\"]{background:var(--dsw-alias-bg-layer-1);box-shadow:var(--dsw-elevation-soft)}\n.ccp-analysisTabCount{display:inline-flex;justify-content:center;min-width:16px;padding:0 4px;margin-left:6px;border-radius:999px;background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-secondary);font-size:12px;line-height:18px}\n.ccp-analysisPanel{padding-top:20px;min-width:0}\n.ccp-analysisPanel[hidden]{display:none}\n.ccp-analysisSectionHead{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;margin-bottom:12px}\n.ccp-analysisHeading{font-size:14px;line-height:22px;font-weight:500;margin:0}\n.ccp-analysisSectionHead .ccp-analysisNote{margin:0;max-width:56ch}\n.ccp-analysisModels{border:.5px solid var(--dsw-alias-border-l4);border-radius:16px;overflow:hidden}\n.ccp-analysisModelRow + .ccp-analysisModelRow{border-top:.5px solid var(--dsw-alias-border-l2)}\n.ccp-analysisTableHead,.ccp-analysisModelSummary,.ccp-analysisScenarioSummary{position:relative;display:grid;grid-template-columns:minmax(190px,2.1fr) minmax(150px,1.45fr) minmax(90px,.9fr) minmax(90px,.9fr) minmax(100px,1fr) 16px;gap:18px;align-items:center;padding:16px 18px;font-variant-numeric:tabular-nums}\n.ccp-analysisTableHead{padding-top:11px;padding-bottom:11px;background:var(--dsw-alias-interactive-bg-hover);border-bottom:.5px solid var(--dsw-alias-border-l2);font-size:12px;line-height:18px;color:var(--dsw-alias-label-tertiary)}\n.ccp-analysisTableHead > span:not(:first-child){text-align:right}\n.ccp-analysisScenarioHead,.ccp-analysisScenarioSummary{grid-template-columns:minmax(190px,2fr) minmax(118px,1.1fr) minmax(155px,1.35fr) minmax(142px,1.15fr) 16px}\n.ccp-analysisModelSummary,.ccp-analysisScenarioSummary{cursor:pointer;list-style:none;min-height:60px}\n.ccp-analysisModelSummary::-webkit-details-marker,.ccp-analysisScenarioSummary::-webkit-details-marker,.ccp-analysisDisclosure::-webkit-details-marker{display:none}\n.ccp-analysisModelSummary:hover,.ccp-analysisScenarioSummary:hover{background:var(--dsw-alias-interactive-bg-hover)}\n.ccp-analysisIdentity{display:flex;flex-direction:column;gap:2px;min-width:0}\n.ccp-analysisModelName{font-size:14px;line-height:22px;font-weight:500;overflow-wrap:anywhere}\n.ccp-analysisModelCount{margin-top:3px}\n.ccp-analysisModelSummary > .ccp-analysisMetric,.ccp-analysisScenarioSummary > .ccp-analysisMetric{align-items:flex-end}\n/* 宽表使用集中表头,但保留每个指标的无障碍标签;窄面板恢复可见标签。 */\n.ccp-analysisModelSummary .ccp-analysisMetricLabel,.ccp-analysisScenarioSummary .ccp-analysisMetricLabel,.ccp-analysisSearchLabel{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n.ccp-analysisShare{display:flex;align-items:center;gap:8px;width:100%;max-width:148px;margin-top:3px}\n.ccp-analysisShareTrack{display:block;flex:1;height:4px;overflow:hidden;background:var(--dsw-alias-bg-module-platform);border-radius:999px}\n.ccp-analysisShareFill{display:block;height:100%;background:var(--dsw-alias-label-secondary);border-radius:999px}\n.ccp-analysisShareValue{font-size:12px;line-height:18px;min-width:40px;text-align:right;color:var(--dsw-alias-label-tertiary)}\n.ccp-analysisChevron{flex:none;color:var(--dsw-alias-label-tertiary)}\n.ccp-analysisModelRow[open] > .ccp-analysisModelSummary > .ccp-analysisChevron,.ccp-analysisModelRow[open] > .ccp-analysisScenarioSummary > .ccp-analysisChevron,.ccp-analysisAggregate[open] > .ccp-analysisDisclosure > .ccp-analysisChevron,.ccp-analysisRules[open] > .ccp-analysisDisclosure > .ccp-analysisChevron{transform:rotate(90deg)}\n.ccp-analysisDetails{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:22px;padding:16px 18px;background:var(--dsw-alias-bg-module-platform);border-top:.5px solid var(--dsw-alias-border-l2)}\n.ccp-analysisDetailTitle{font-size:12px;line-height:18px;font-weight:600;margin:0 0 11px}\n.ccp-analysisFacts{margin:0;display:flex;flex-direction:column;gap:8px}\n.ccp-analysisFact{display:flex;align-items:baseline;justify-content:space-between;gap:10px;min-width:0}\n.ccp-analysisFactValue{font-size:14px;line-height:22px;margin:0;text-align:right;font-variant-numeric:tabular-nums;overflow-wrap:anywhere;min-width:0}\n.ccp-analysisFact .ccp-analysisLabel{flex-shrink:0}\n.ccp-analysisFooter{display:flex;justify-content:space-between;gap:12px;align-items:flex-start;flex-wrap:wrap;margin-top:14px}\n.ccp-analysisAggregate{flex:1;min-width:210px}\n.ccp-analysisAggregate > .ccp-analysisDetails{border:.5px solid var(--dsw-alias-border-l4);border-radius:8px;margin-top:6px}\n.ccp-analysisDisclosure{display:flex;gap:7px;align-items:center;cursor:pointer;list-style:none;font-size:12px;line-height:18px;color:var(--dsw-alias-label-tertiary);padding:7px 0}\n.ccp-analysisDisclosure > .ccp-analysisChevron{width:14px;height:14px}\n.ccp-analysisMonthly{flex:none;max-width:340px;display:flex;justify-content:flex-end;flex-wrap:wrap;gap:2px 8px;align-items:baseline;text-align:right;font-size:12px;line-height:18px;color:var(--dsw-alias-label-tertiary);padding-top:5px}\n.ccp-analysisMonthlyValue{font-size:14px;line-height:22px;font-weight:500;color:var(--dsw-alias-label-primary);font-variant-numeric:tabular-nums}\n.ccp-analysisMonthly .ccp-analysisNote{width:100%;margin:0}\n.ccp-analysisAssumption{font-size:14px;line-height:22px;color:var(--dsw-alias-label-tertiary);margin:0 0 18px;max-width:76ch}\n.ccp-analysisBaseline{margin:0 0 16px}\n.ccp-analysisSearch{flex:0 1 270px}\n.ccp-analysisSearchShell{position:relative;display:block}\n.ccp-analysisSearchShell > .ccp-analysisIcon{position:absolute;top:10px;left:11px;color:var(--dsw-alias-label-tertiary);pointer-events:none}\n.ccp-analysisSearch .ccp-analysisInput{padding-left:35px}\n.ccp-analysisScenarioDetails{grid-template-columns:minmax(0,1fr) minmax(0,2fr)}\n.ccp-analysisScenarioDetails .ccp-analysisFactValue{max-width:70%}\n.ccp-analysisEmpty{font-size:14px;line-height:22px;color:var(--dsw-alias-label-tertiary);text-align:center;padding:34px 18px;margin:0;border:1px dashed var(--dsw-alias-border-l4);border-radius:8px}\n.ccp-analysisRules{margin-top:22px;border-top:.5px solid var(--dsw-alias-border-l2);padding-top:8px}\n.ccp-analysisRulesBody{display:grid;grid-template-columns:1fr 1fr;gap:24px;color:var(--dsw-alias-label-tertiary);font-size:14px;line-height:22px;margin-top:9px}\n.ccp-analysisRulesBody p{margin:0 0 10px}\n@container ccp-analysis (max-width:920px){\n.ccp-analysisTableHead{display:none}\n.ccp-analysisModelSummary{grid-template-columns:repeat(4,minmax(0,1fr)) 16px;gap:12px 18px}\n.ccp-analysisScenarioSummary{grid-template-columns:repeat(3,minmax(0,1fr)) 16px;gap:12px 18px}\n.ccp-analysisModelSummary > .ccp-analysisIdentity,.ccp-analysisScenarioSummary > .ccp-analysisIdentity{grid-column:1/-2}\n.ccp-analysisModelSummary > .ccp-analysisChevron{grid-column:5;grid-row:1;justify-self:end}\n.ccp-analysisScenarioSummary > .ccp-analysisChevron{grid-column:4;grid-row:1;justify-self:end}\n.ccp-analysisModelSummary > .ccp-analysisMetric,.ccp-analysisScenarioSummary > .ccp-analysisMetric{align-items:flex-start}\n.ccp-analysisModelSummary .ccp-analysisMetricLabel,.ccp-analysisScenarioSummary .ccp-analysisMetricLabel{position:static;width:auto;height:auto;padding:0;margin:0;overflow:visible;clip:auto;white-space:normal}\n.ccp-analysisDetails{grid-template-columns:repeat(2,minmax(0,1fr))}\n}\n@container ccp-analysis (max-width:588px){\n.ccp-analysisFilters{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px}\n.ccp-analysisFilters[data-mode=\"range\"] .ccp-analysisScopeField{grid-column:1/-1}\n.ccp-analysisApply{grid-column:1/-1;margin:0;width:100%}\n.ccp-analysisOverview{grid-template-columns:repeat(2,minmax(0,1fr));gap:20px 18px;padding:16px}\n.ccp-analysisModelSummary,.ccp-analysisScenarioSummary{grid-template-columns:repeat(2,minmax(0,1fr));gap:15px 18px;padding:16px}\n.ccp-analysisModelSummary > .ccp-analysisIdentity,.ccp-analysisScenarioSummary > .ccp-analysisIdentity{grid-column:1/-1;padding-right:24px}\n.ccp-analysisModelSummary > .ccp-analysisChevron,.ccp-analysisScenarioSummary > .ccp-analysisChevron{position:absolute;top:18px;right:16px;grid-column:auto;grid-row:auto}\n.ccp-analysisDetails,.ccp-analysisScenarioDetails{gap:20px;grid-template-columns:1fr;padding:16px}\n.ccp-analysisAggregate{width:100%;min-width:0}\n.ccp-analysisMonthly{width:100%;max-width:none;justify-content:flex-start;text-align:left;padding-top:0}\n.ccp-analysisSectionHead{align-items:flex-start}\n.ccp-analysisSectionHead .ccp-analysisSearch{flex-basis:100%;width:100%;order:2}\n.ccp-analysisRulesBody{grid-template-columns:1fr;gap:12px}\n/* 英文页签带数量时允许换行,避免轨道或文字撑出宿主的窄面板。 */\n.ccp-analysisTabs{margin-top:18px;grid-auto-columns:minmax(0,1fr)}\n.ccp-analysisTab{height:auto;min-height:28px;padding:4px 8px;white-space:normal}\n}\n@media (max-width:640px){.ccp-mainInnerAnalysis{padding:20px 16px 32px}}\n`\n","/** 手动读取历史,旧宿主可降级;查询切换和卸载后不接受过期结果。 */\nimport { parseAnalyticsQuery, parseAnalyticsReport, type AnalyticsQuery, type AnalyticsReport } from '../analytics-wire.ts'\nimport type { RemoteResult } from '@deepseek-ai/dsh-typert-protocol'\nexport interface AnalyticsRemote { analytics?(query: AnalyticsQuery): Promise> }\nexport interface AnalyticsState { status: 'idle' | 'loading' | 'ready' | 'error'; report?: AnalyticsReport; error?: string }\nexport class AnalyticsController {\n private current: AnalyticsState = { status: 'idle' }\n private listeners = new Set<() => void>()\n private generation = 0\n private disposed = false\n private query: AnalyticsQuery = { mode: 'recent', limit: 20 }\n constructor(private remote: AnalyticsRemote) {}\n state() { return this.current }\n subscribe(listener: () => void) { this.listeners.add(listener); return () => { this.listeners.delete(listener) } }\n dispose() { this.disposed = true; this.generation++; this.listeners.clear() }\n reload() { this.generation++; this.set({ status: 'idle' }) }\n refresh(query = this.query) {\n if (this.disposed) return\n const requested = parseAnalyticsQuery(query)\n this.query = requested\n const generation = ++this.generation\n this.set({ status: 'loading' })\n const call = this.remote.analytics\n if (!call) { this.set({ status: 'error', error: '宿主不支持模型分析,请更新插件' }); return }\n void Promise.resolve().then(() => call(requested)).then(result => {\n if (this.disposed || generation !== this.generation) return\n if (!result.ok) { this.set({ status: 'error', error: result.error.message === '宿主不支持模型分析,请更新插件' ? result.error.message : '模型分析读取失败,请稍后刷新或检查宿主日志' }); return }\n this.set({ status: 'ready', report: parseAnalyticsReport(result.value) })\n }).catch(() => {\n if (!this.disposed && generation === this.generation) this.set({ status: 'error', error: '模型分析读取失败,请稍后刷新或检查宿主日志' })\n })\n }\n private set(state: AnalyticsState) { this.current = state; for (const listener of this.listeners) listener() }\n}\n","/**\n * Browser half of the dsh-commandcode-provider bundle: the \"Command Code\"\n * settings page (`settings.section`, id `commandcode`), the Models-page\n * provider card (`settings.models.provider-card`, key `llm-commandcode`, see\n * `./card.tsx`), the quota/model-analysis panel's `main` cell + gated\n * `sidebar.footer.action` card, and the composer\n * `conversation.composer.dock` cost entry.\n *\n * The API key is written through the credentials domain (the\n * `COMMANDCODE_API_KEY` reference the plugin resolves via\n * `ctx.remote.credentials`), never as a settings value, and every other fact\n * through the `llm-commandcode` namespace — so a saved key or endpoint reaches\n * the very next request and the key literal cannot land in a settings document.\n */\n\nimport type { Context } from '@deepseek-ai/cordis'\nimport { createSnapshotStore } from './snapshot-store.ts'\nimport { readableErrorText } from '../readable-error.ts'\n// Type-only: the client-service augmentations (`slots`/`remote`/`locale` on\n// Context) and the `settings.section` SlotMap entry.\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-renderer/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-settings/client'\nimport { createSettingsScope, type SettingsRemoteNamespace, type SettingsScopeContext } from './settings-scope.ts'\nimport { CommandCodeSettingsController, COMMANDCODE_NS, type SettingsPageState } from './settings.ts'\nimport type { SettingsPageApi } from './settings.ts'\nimport { CommandCodeUsageController, type UsagePageState, type UsageRemote } from './usage.ts'\nimport { CommandCodePricesController, type SessionCostPricesState } from './prices.ts'\nimport { CommandCodeLoginController, type LoginPageState, type LoginRemote } from './login.ts'\nimport { USAGE_REMOTE_CONTRIBUTION, MODELS_REMOTE_CONTRIBUTION, PRICES_REMOTE_CONTRIBUTION } from '../usage-wire.ts'\nimport { LOGIN_REMOTE_CONTRIBUTION } from '../login-wire.ts'\nimport { ENROLLMENT_REMOTE_CONTRIBUTION } from '../enrollment-wire.ts'\nimport { AccountEnrollmentController, type EnrollmentRemote } from './enrollment.ts'\nimport type { TypertRemoteContribution } from '@deepseek-ai/dsh-typert-protocol'\nimport { CommandCodeSettingsPage } from './section.tsx'\nimport { CommandCodeProviderCard } from './card.tsx'\nimport { CommandCodePanel, CommandCodeFooterEntry } from './panel-view.tsx'\nimport type { PanelInjected } from './panel-view.tsx'\nimport { CommandCodeSessionCost } from './session-cost-view.tsx'\nimport type { SessionCostInjected } from './session-cost-view.tsx'\nimport { startPanelAutoRefresh } from './panel.ts'\nimport { PAGE_CSS, PAGE_CSS_ID } from './page-styles.ts'\nimport { PANEL_CSS, PANEL_CSS_ID } from './panel-styles.ts'\n// Type-only: pulls in the SlotMap merge for the composer dock\n// (`./session-cost-slots.ts`). The sidebar-foot / center-column merge rides the\n// `./panel-view.tsx` value import above, which imports `./panel-slots.ts`.\nimport type {} from './session-cost-slots.ts'\nimport { zh, en } from './locales.ts'\nimport { PANEL_COPY_EN, PANEL_COPY_ZH, PANEL_LOCALE_NS } from './panel-copy.ts'\nimport { ANALYTICS_REMOTE_CONTRIBUTION } from '../analytics-wire.ts'\nimport { AnalyticsController } from './analytics.ts'\nimport type { AnalyticsQuery } from '../analytics-wire.ts'\n\n\n\n/** Install one stylesheet by id and return a disposer for its owning effect. */\nfunction injectCss(id: string, css: string): () => void {\n if (typeof document === 'undefined') return () => {}\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 = css\n document.head.appendChild(tag)\n return () => tag.remove()\n}\n\n/**\n * Plans & quota panel id. It is the layout's `MainPanelId`: one string shared\n * by the `sidebar.footer.action` card and the `main` slot cell, so the card\n * selects this panel and nothing else. `dsh-client-ui-layout` is not a\n * dependency of this bundle, so its brand is applied at the call site instead\n * of importing the package.\n */\nconst PANEL_ID = 'commandcode-panel'\n\n/**\n * The composer figure's entry id in `conversation.composer.dock`. Its own id,\n * never the shipped `stats` cell's: reusing that id would REPLACE the tokens /\n * cache-hit / throughput readout rather than inject into it, and that readout\n * is the harness's to format.\n */\nconst SESSION_COST_ID = 'commandcode-session-cost'\n\n/**\n * The one shot of the `layout` service this plugin needs, declared\n * structurally: importing the package would make the browser resolve a client\n * module this bundle never calls. Read through the reflective\n * `ctx.get('layout')`, never a bare `ctx.layout` property — `layout` is not in\n * the exported inject list, and cordis throws `cannot get property … without\n * inject` for an undeclared service. (The footer card's own gate below IS a\n * static `ctx.inject(['layout'])`, but it is scoped to that one registration.)\n */\ninterface LayoutSelectionSeam {\n /** `null` shows the Conversation again; a string selects that registered `main` key. */\n selectPanel(id: string | null): void\n}\n\n/**\n * Client plugin body. Gates on `slots`, `locale` and `remote` — never on\n * `settingsScope`, whose wrapper service the 0.1.7 settings rewrite removed\n * (the scope below speaks the `remote.settings` wire directly), because\n * gating on a service 0.1.7 does not provide would park EVERY surface below\n * into silence. `settingsScope` must never reappear in the exported inject\n * list at the bottom of this file.\n */\nexport function apply(ctx: Context): void {\n injectCss(PAGE_CSS_ID, PAGE_CSS)\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; `slots.inject` waits for the declaration, so registration\n // order relative to it does not matter).\n ctx.effect(() => ctx.locale.register('settings.commandcode', { zh, en }), 'dsh-commandcode-provider: page copy')\n\n // The panel's copy is a namespace of its own: the panel is not part of the\n // settings page, but it follows the SAME active language — declaring\n // `PANEL_LOCALE_NS` on both panel registrations is what binds their `t` seat.\n ctx.effect(\n () => ctx.locale.register(PANEL_LOCALE_NS, { zh: PANEL_COPY_ZH, en: PANEL_COPY_EN }),\n 'dsh-commandcode-provider: panel copy',\n )\n\n // Credentials reach the browser as a Typert Remote namespace. This inject is\n // the activation gate for every surface below, so a profile whose Host\n // serves no credentials namespace simply never mounts the page.\n ctx.inject(['remote.credentials'], (remoteCtx) => {\n const credentials = (remoteCtx.remote as unknown as {\n credentials: SettingsPageApi['credentials']\n }).credentials\n applyClientSurfaces(remoteCtx, { credentials })\n })\n}\n\n/** Mount the one shared UI implementation. */\nfunction applyClientSurfaces(\n ctx: Context,\n api: SettingsPageApi,\n): void {\n // This plugin's own binding of the `llm-commandcode` namespace over\n // `remote.settings` (see `./settings-scope.ts`).\n //\n // The namespace object is captured from an INJECT-SCOPED context, never read\n // off `ctx.remote`: `remote.settings` is a Cordis service NESTED under\n // `remote`, and cordis answers a read through a context that does not declare\n // it with `Error: cannot get property \"remote.settings\" without inject` —\n // which lands inside the scope's own `try`/`catch`, so nothing is logged and\n // the page renders read-only with every control disabled (the 0.1.7\n // settings-page report, CHANGELOG 0.11.9; the full incident is in\n // AGENTS.md). The resolver hands the scope the very object the inject\n // resolved, and `refresh()` re-reads once it lands; a profile whose Host\n // serves no settings namespace simply never resolves it, where the page\n // keeps rendering its degraded state instead of crashing.\n let settingsNamespace: SettingsRemoteNamespace | undefined\n const scope = createSettingsScope>(\n ctx as unknown as SettingsScopeContext,\n COMMANDCODE_NS,\n () => settingsNamespace,\n )\n ctx.effect(() => () => { void scope.dispose() }, 'dsh-commandcode-provider: settings scope')\n ctx.inject(['remote.settings'], (settingsCtx) => {\n settingsNamespace = (settingsCtx.remote as unknown as {\n settings: SettingsRemoteNamespace\n }).settings\n // The first read raced this inject and answered \"not mounted\"; re-read now\n // that the namespace is here (and again whenever it re-mounts).\n scope.refresh()\n settingsCtx.effect(() => () => {\n settingsNamespace = undefined\n }, 'dsh-commandcode-provider: settings namespace')\n })\n // The model catalog for the settings page's model editors is served by the\n // `commandcode/models` Remote mounted below, which happens after this\n // controller is constructed — so it reads the catalog through this mutable\n // seam. Unset until the mount lands; the controller degrades to the\n // empty-catalog state meanwhile.\n let modelsRemote: NonNullable | undefined\n const controller = new CommandCodeSettingsController(\n scope,\n { ...api, models: () => modelsRemote?.() ?? Promise.resolve({ ok: false, error: { message: 'commandcode/models remote is not mounted' } }) },\n )\n ctx.effect(() => () => controller.dispose(), 'dsh-commandcode-provider: settings controller')\n const store = createSnapshotStore(controller.state())\n controller.subscribe(() => store.set(controller.state()))\n ctx.effect(\n () => {\n const remote = ctx.remote as unknown as {\n $on(\n event: 'credentials/reference-updated' | 'credentials/record-updated',\n listener: (ref: string) => void,\n ): () => void\n }\n const unregisterReference = remote.$on('credentials/reference-updated', () => {\n controller.refreshCredentials()\n })\n const unregisterRecord = remote.$on('credentials/record-updated', () => {\n controller.refreshCredentials()\n })\n return () => {\n unregisterReference()\n unregisterRecord()\n }\n },\n 'dsh-commandcode-provider: credential invalidations',\n )\n\n // One mount carries every endpoint this plugin serves (report, catalog, price\n // table, login), keeping the Client's bookkeeping 1:1 with the Host's single\n // registry registration. Cordis only serves services a fiber declares in\n // `inject`, and the namespace service exists only after the mount — so the\n // `remote.commandcode` inject is registered DYNAMICALLY once the mount\n // lands; a static one would deadlock the plugin, the mounter waiting for its\n // own mount. A Host half that predates the Remote fails the calls instead,\n // and the surfaces render their error branches.\n let usageNamespace: (typeof ctx.remote)['commandcode'] | undefined\n let usageMountError: string | undefined\n // `pricesController` and `refreshUsage` are declared here and assigned below,\n // because the mount effect's inject callback calls them while cordis runs it\n // synchronously — before their own `const` would be initialized. A read in\n // that temporal dead zone THROWS, which `?.` would not save.\n let pricesController: CommandCodePricesController | undefined\n let refreshUsage: (() => void) | undefined\n let analyticsController: AnalyticsController | undefined\n const contribution: TypertRemoteContribution = {\n package: USAGE_REMOTE_CONTRIBUTION.package,\n descriptors: [\n ...USAGE_REMOTE_CONTRIBUTION.descriptors,\n ...MODELS_REMOTE_CONTRIBUTION.descriptors,\n ...PRICES_REMOTE_CONTRIBUTION.descriptors,\n ...ANALYTICS_REMOTE_CONTRIBUTION.descriptors,\n ...LOGIN_REMOTE_CONTRIBUTION.descriptors,\n ...ENROLLMENT_REMOTE_CONTRIBUTION.descriptors,\n ],\n }\n ctx.effect(() => {\n let cancelled = false\n let unmount: (() => Promise) | undefined\n void ctx.remote.$mount(contribution).then((dispose: () => Promise) => {\n if (cancelled) {\n void dispose()\n return\n }\n unmount = dispose\n ctx.inject(['remote.commandcode'], (namespaceCtx) => {\n usageNamespace = namespaceCtx.remote.commandcode\n // The catalog Remote is live now; (re)fetch it for the model editors,\n // and the price table the composer's cost readout needs — `ensure()` is\n // idempotent, so asking earlier could only fail (the namespace did not\n // exist yet).\n controller.refreshCatalog()\n pricesController?.reload()\n analyticsController?.reload()\n // ...and the usage report. A surface can (and on a boot with the quota\n // card on, always does) ask for it BEFORE this mount lands: the answer\n // then is the synthetic \"remote is not mounted\" failure, which the\n // controller stores as `status: 'error'` — and its `shouldRefresh` only\n // fires from `idle`, so nothing would ever retry it (`usage.ts`). The\n // namespace is live here, so re-read now and replace that stale answer.\n refreshUsage?.()\n namespaceCtx.effect(() => () => {\n usageNamespace = undefined\n analyticsController?.reload()\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 = readableErrorText(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 models: async () => {\n const namespace = usageNamespace\n if (namespace === undefined) {\n return { ok: false, error: { message: usageMountError ?? 'commandcode/models remote is not mounted' } }\n }\n return namespace.models()\n },\n prices: async () => {\n const namespace = usageNamespace\n if (namespace === undefined) {\n return { ok: false, error: { message: usageMountError ?? 'commandcode/prices remote is not mounted' } }\n }\n const call = namespace.prices\n // A Host half older than the price table mounts no such descriptor, so\n // the namespace member is genuinely missing. Report it as a permanent\n // failure the readout understands rather than throwing.\n if (typeof call !== 'function') {\n return { ok: false, error: { message: 'the Host serves no commandcode/prices endpoint', permanent: true } }\n }\n return call.call(namespace)\n },\n }\n modelsRemote = () => usageRemote.models()\n const usageController = new CommandCodeUsageController(usageRemote)\n refreshUsage = () => void usageController.refresh()\n ctx.effect(() => () => usageController.dispose(), 'dsh-commandcode-provider: usage controller')\n const usageStore = createSnapshotStore(usageController.state())\n usageController.subscribe(() => usageStore.set(usageController.state()))\n\n // The composer's session-cost readout prices from a static table, so its\n // controller is a one-shot cache rather than a poll.\n pricesController = new CommandCodePricesController(usageRemote)\n ctx.effect(() => () => pricesController?.dispose(), 'dsh-commandcode-provider: price table')\n const pricesStore = createSnapshotStore(pricesController.state())\n pricesController.subscribe(() => pricesStore.set(pricesController.state()))\n\n analyticsController = new AnalyticsController({ analytics: async query => {\n const namespace = usageNamespace\n if (typeof namespace?.analytics !== 'function') return { ok: false, error: { message: '宿主不支持模型分析,请更新插件' } }\n return namespace.analytics(query)\n } })\n const analyticsStore = createSnapshotStore(analyticsController.state())\n analyticsController.subscribe(() => analyticsStore.set(analyticsController!.state()))\n ctx.effect(() => () => analyticsController?.dispose(), 'commandcode analytics controller')\n const panelMode = createSnapshotStore<'quota' | 'analysis'>('quota')\n const openAnalytics = () => {\n panelMode.set('analysis')\n const layout = ctx.get('layout') as LayoutSelectionSeam | undefined\n layout?.selectPanel(PANEL_ID)\n }\n\n // The login panel: same namespace, three endpoints. The key NEVER crosses to\n // the browser — the Host validates and stores it through the credentials\n // seam, and a landed login re-reads the credential badges + usage card.\n const loginRemote: LoginRemote = {\n loginBegin: async (targetRef?: string) => {\n if (usageNamespace === undefined) {\n return { ok: false, error: { message: usageMountError ?? 'commandcode remote is not mounted' } }\n }\n return usageNamespace.loginBegin(targetRef)\n },\n loginStatus: async () => {\n if (usageNamespace === undefined) {\n return { ok: false, error: { message: usageMountError ?? 'commandcode remote is not mounted' } }\n }\n return usageNamespace.loginStatus()\n },\n loginCancel: async () => {\n if (usageNamespace === undefined) {\n return { ok: false, error: { message: usageMountError ?? 'commandcode remote is not mounted' } }\n }\n return usageNamespace.loginCancel()\n },\n }\n const loginController = new CommandCodeLoginController(() => loginRemote)\n ctx.effect(() => () => loginController.dispose(), 'dsh-commandcode-provider: login controller')\n const loginStore = createSnapshotStore(loginController.state())\n let lastLoginPhase = loginController.state().phase\n loginController.subscribe(() => {\n const phase = loginController.state().phase\n // A landed login stored the key Host-side behind the page's back, so the\n // badges must follow and the account card can finally fetch.\n if (phase === 'success' && lastLoginPhase !== 'success') {\n controller.refreshCredentials()\n void usageController.refresh()\n }\n lastLoginPhase = phase\n loginStore.set(loginController.state())\n })\n\n const refreshUsageOn = (ok: boolean): boolean => {\n const outcome = controller.state().accountResult\n if (ok || outcome?.config === 'confirmed' || outcome?.credential === 'confirmed') void usageController.refresh()\n return ok\n }\n const injected = () => ({\n createEnrollment: () => new AccountEnrollmentController(() => {\n if (!usageNamespace?.enrollmentBegin) throw new Error('宿主不支持账号开通,请更新插件')\n return usageNamespace as EnrollmentRemote\n }, () => { scope.refresh(); controller.refreshCredentials(); void usageController.refresh() }),\n hooks: { commandCodeSettings: store, commandCodeUsage: usageStore, commandCodeLogin: loginStore },\n edit: (field: string, text: string) => controller.edit(field, text),\n resetField: (field: string) => controller.resetField(field),\n // 部分完成也可能改变凭据或连接配置,用本次确认结果刷新用量。\n save: () => void controller.save().then(outcome => {\n if (outcome?.config === 'confirmed' || outcome?.credential === 'confirmed') void usageController.refresh()\n }),\n discard: () => controller.discard(),\n refreshCredentials: () => void controller.refreshCredentials(),\n refreshUsage: () => void usageController.refresh(),\n ...(typeof (ctx.get('layout') as LayoutSelectionSeam | undefined)?.selectPanel === 'function' ? { openAnalytics } : {}),\n beginLogin: (targetRef?: string) => void loginController.begin(targetRef),\n cancelLogin: () => void loginController.cancel(),\n // Account operations commit immediately. The ones that change which keys\n // exist refetch the usage report so the account rows follow.\n renameAccount: (ref: string, label: string) => controller.renameAccount(ref, label),\n removeAccount: (ref: string) => controller.removeAccount(ref).then((ok) => {\n // 配置可能已移除、凭据清理仍失败;用量页也应立即跟随新的账户列表。\n if (ok || !controller.state().accounts.some((account) => account.ref === ref)) void usageController.refresh()\n return ok\n }),\n retryCredentialCleanup: (ref: string) => controller.retryCredentialCleanup(ref).then(refreshUsageOn),\n setAccountKey: (target: string, key: string) => controller.setAccountKey(target, key).then(refreshUsageOn),\n clearAccountKey: (target: string) => controller.clearAccountKey(target).then(refreshUsageOn),\n setActiveAccount: (id: string) => controller.setActiveAccount(id).then(refreshUsageOn),\n setAccountModels: (target: string, ids: string[]) => controller.setAccountModels(target, ids),\n editVisibleModels: (ids: string[]) => controller.editVisibleModels(ids),\n clearVisibleModels: () => controller.clearVisibleModels(),\n editContextWindowOverrides: (next: Record) => controller.editContextWindowOverrides(next),\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 // The Models-page provider card: a keyed slot the Models section dispatches\n // with `entryKey = settingsNs` on every provider row of an adapter family, so\n // the panel mounts beside the official editor on every Command Code row —\n // including the first-run setup posture, exactly where a user without a key\n // lands. While the official 编辑 toggle is open, the card hides the official\n // editor shell (for this namespace `layoutOf` returns \"unknown\", so that shell\n // carries only a config hint over a disabled apply) and shows the real\n // controls; see card.tsx. The registration carries its own inject face\n // because the declaring entry is ui-settings-models', not ours; the `t` seat\n // comes from the registration's own `locale` namespace.\n //\n // On a build without this slot the declaration never exists and `slots.inject`\n // never fires — the registration silently does not happen. Do not \"harden\"\n // that into an error.\n ctx.slots.inject('settings.models.provider-card', () => ctx.slots.register({\n name: 'settings.models.provider-card',\n key: 'llm-commandcode',\n locale: 'settings.commandcode',\n inject: () => ({\n hooks: { commandCodeSettings: store, commandCodeLogin: loginStore },\n edit: (field: string, text: string) => controller.edit(field, text),\n save: () => void controller.save().then(outcome => {\n if (outcome?.config === 'confirmed' || outcome?.credential === 'confirmed') void usageController.refresh()\n }),\n discard: () => controller.discard(),\n refreshCredentials: () => void controller.refreshCredentials(),\n beginLogin: () => void loginController.begin(),\n cancelLogin: () => void loginController.cancel(),\n }),\n }, CommandCodeProviderCard))\n\n // The plans & quota panel: a footer card pinned at the bottom of the sidebar,\n // on top of the Settings seat, that opens a dashboard in the center column.\n //\n // Two registrations, ONE navigation entry: `sidebar.footer.action` is the\n // list the sidebar shell renders in its foot area directly above the Settings\n // seat (`footArea` = `footerActions` then `settingsArea`), which is what puts\n // this card at the bottom of the column rather than at the top with the\n // global panel icons of `sidebar.panellist`. The layout's keyed `main` slot\n // holds the panel the card opens — `selectPanel(id)` resolves the id against\n // that registry and throws when no cell occupies it, so BOTH registrations\n // are required, and BOTH need the `inject` face below (an entry without one\n // receives none of the panel's data; see the `hooks` → `useX` rule in\n // panel-view.tsx).\n //\n // Unlike a `sidebar.panellist` row, the shell renders NO chrome around a\n // footer action: our component IS the button, it owns the label (so a title\n // carrying live quota needs no re-registration — that dance exists only\n // because the shell caches a panellist entry's label), and it selects the\n // panel itself through the `open` action below.\n //\n // Both registrations declare the panel's own `locale` namespace\n // (`panel.commandcode`, registered in `apply` above): that is what binds the\n // `t` seat the components feed into `buildPanelView`, so the panel follows\n // the harness's active language and a switch re-renders it.\n //\n // The footer card is gated on the `layout` SERVICE (below), not only on its\n // slot: a profile whose `main` declaration exists but whose layout never\n // mounted would otherwise register a card that renders and does nothing —\n // a dead button. The dashboard cell needs no such gate; registering against\n // a declaration that never arrives is a no-op by construction.\n //\n // Shape notes:\n // * The stylesheet gets its own `ctx.effect` rather than riding an `inject`\n // callback's return value, so the tag's lifetime is the plugin fiber's and\n // is unaffected by a slot declaration collapsing and re-declaring.\n // * Each registration is guarded so a failure in one surface cannot abort\n // `applyClientSurfaces` and take the OTHER surfaces down with it —\n // `slots.inject` rethrows a callback failure synchronously once the\n // declaration exists. The renderer contains a *render* crash by abdicating\n // the entry with no visible error, so a failure that leaves nothing on\n // screen must at least be loud in the console.\n const panelFace = (): PanelInjected => ({\n hooks: { commandCodeUsage: usageStore, commandCodeSettings: store, commandCodeAnalytics: analyticsStore, commandCodePanelMode: panelMode },\n selectPanelMode: (mode) => panelMode.set(mode),\n refreshAnalytics: (query?: AnalyticsQuery) => analyticsController?.refresh(query),\n refresh: () => { pricesController?.ensure(); void usageController.refresh() },\n // The Host resolves every credential source, including CLI auth and\n // literals. A browser credential-reference lookup cannot determine\n // availability.\n startAutoRefresh: () => startPanelAutoRefresh(usageController, () => true),\n // `layout` is read reflectively AT CLICK TIME, never captured at setup:\n // ui-layout is not a dependency of this bundle (its types are not imported\n // and its client module is never resolved), and it is not in the exported\n // inject list. The footer registration below is gated on the same seam, so\n // by the time this runs the method exists; the guard stays as the last line\n // of defence against a layout that renames it.\n open: () => {\n panelMode.set('quota')\n const layout = ctx.get('layout') as LayoutSelectionSeam | undefined\n layout?.selectPanel(PANEL_ID)\n },\n // The dashboard's way out (issue #41). It occupies the center column in\n // place of the Conversation, and `open()` above is the ONLY other panel\n // selection this plugin makes — so without an exit the panel is a one-way\n // door: clicking the sidebar card just re-selects it. `selectPanel(null)`\n // is layout's \"show the Conversation\" selection and leaves the current\n // Session untouched.\n close: () => {\n const layout = ctx.get('layout') as LayoutSelectionSeam | undefined\n layout?.selectPanel(null)\n },\n })\n\n ctx.effect(() => injectCss(PANEL_CSS_ID, PANEL_CSS), 'dsh-commandcode-provider: panel styles')\n\n try {\n ctx.slots.inject('main', () => ctx.slots.register(\n { name: 'main', key: PANEL_ID, locale: PANEL_LOCALE_NS, inject: panelFace },\n CommandCodePanel,\n ))\n } catch (error: unknown) {\n console.error('[dsh-commandcode-provider] could not register the plans & quota panel:', error)\n }\n\n // The footer card is registered only where the layout can actually open the\n // panel behind it: `ctx.inject(['layout'], …)` runs its body when that service\n // is live and re-runs it if the service is replaced, mirroring how the Remote\n // namespace is mounted — so a profile without ui-layout (the TUI, a headless\n // client) never registers the card at all.\n ctx.inject(['layout'], (layoutCtx) => {\n try {\n layoutCtx.slots.inject('sidebar.footer.action', () => layoutCtx.slots.register(\n // `order` is the only control over position inside a list slot, and the\n // renderer sorts ascending. ui-cordis's footer chip registers at the\n // default 0, so 1 sorts after it — but any sibling passing an order ≥ 1\n // lands between this card and Settings, so \"directly above Settings\" is\n // a preference, not a guarantee.\n { name: 'sidebar.footer.action', id: PANEL_ID, order: 1, locale: PANEL_LOCALE_NS, inject: panelFace },\n CommandCodeFooterEntry,\n ))\n } catch (error: unknown) {\n console.error('[dsh-commandcode-provider] could not register the sidebar footer card:', error)\n }\n })\n\n // The composer's session-cost figure: an entry in the dock below the input\n // that renders NO surface of its own. The cost is injected into the harness's\n // own token-usage UI — the amount as the last item of the shipped pill's text\n // run, the breakdown as rows inside the usage dialog that pill opens (see\n // `./session-cost-display.ts`).\n //\n // The entry exists for its SEATS, not for a surface: `useProjection` is a\n // standard prop the composer hands every dock occupant, so this registration\n // is the only way to read the session's token accounting. The token buckets\n // and the model selection arrive from the composer itself as standard dock\n // props, so the face carries only the price-table hook.\n //\n // No `locale` namespace and no `t` seat: the figure is English by\n // construction, from `./session-cost.ts`.\n const sessionCostFace = (): SessionCostInjected => ({\n hooks: { commandCodePrices: pricesStore },\n })\n\n try {\n ctx.slots.inject('conversation.composer.dock', () => ctx.slots.register(\n // No `order`: the entry renders nothing, so its position among the dock's\n // rows cannot matter — the sort only ever decides what a reader sees.\n { name: 'conversation.composer.dock', id: SESSION_COST_ID, inject: sessionCostFace },\n CommandCodeSessionCost,\n ))\n } catch (error: unknown) {\n console.error('[dsh-commandcode-provider] could not register the composer session-cost readout:', error)\n }\n}\n\nexport const inject: readonly string[] = [\n 'slots',\n 'locale',\n 'remote',\n]\n"],"mappings":"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"}
\ No newline at end of file
diff --git a/lib/index.js.map b/lib/index.js.map
deleted file mode 100644
index c9c2b68..0000000
--- a/lib/index.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"index.js","names":["record","tokensOf","record","counts","counts","parseCatalog","record","stringField","reject","createNetServer","createHttpServer"],"sources":["../src/cost-facts.ts","../src/plan-tiers.ts","../src/capabilities.ts","../src/model-prices.ts","../src/wire-guards.ts","../src/cost-projection.ts","../src/analytics.ts","../src/wire-shared.ts","../src/analytics-wire.ts","../src/analytics-history.ts","../src/response-encoding.ts","../src/timeout-limits.ts","../src/model-visibility.ts","../src/context-window.ts","../src/output-budget.ts","../src/readable-error.ts","../src/transient-retry.ts","../src/accounts.ts","../src/provider-errors.ts","../src/stream-trace.ts","../src/stream-response.ts","../src/image-request.ts","../src/image-tokens.ts","../src/request-timing.ts","../src/gateway-facts.ts","../src/adapter.ts","../src/command-locales.ts","../src/display-format.ts","../src/commands.ts","../src/usage-wire.ts","../src/login-wire.ts","../src/enrollment-wire.ts","../src/usage-remote.ts","../src/login.ts","../src/enrollment.ts","../src/config-volatile.ts","../src/web-search.ts","../src/tui-settings.ts","../src/transport-retry.ts","../src/index.ts"],"sourcesContent":["/** Shared, JSON-only billing facts. No Host or browser runtime imports. */\nimport type { CommandCodeModelPrice, CommandCodeModelRates, CommandCodePriceTable } from './usage-wire.ts'\n\nexport interface CostTokens {\n uncachedInputTokens: number\n outputTokens: number\n cacheReadTokens: number\n cacheWriteTokens: number\n}\n\n/** Requests with identical model/rates are folded into one group. */\nexport interface CostUsageGroup {\n provider: string\n model: string\n at: number | null\n contextTokens: number\n tokens: CostTokens\n}\n\nexport interface SessionCostFacts {\n pricingKey: number\n groups: CostUsageGroup[]\n /**\n * Token buckets contributed by summarization calls, already folded into\n * `groups` but deliberately NOT part of the harness's own `tokenUsage`\n * projection.\n *\n * Compaction issues its own `ctx.llm.stream()` call, so its cost is real\n * spend, but it produces no `assistant/message` or `assistant/attempt` event\n * — the only two the harness meter folds (see `token-meter/src/usage-projection.ts`).\n * The summary therefore lands in this projection alone, and the composer\n * readout subtracts this field before asserting that both projections\n * describe the same durable cut. Without the split the equality check fails\n * and the whole readout disappears whenever a session compacts.\n *\n * Always present: `parseState` backfills it to zero for state written before\n * this field existed.\n */\n summaryTokens: CostTokens\n}\n\nexport const zeroCostTokens = (): CostTokens => ({ uncachedInputTokens: 0, outputTokens: 0, cacheReadTokens: 0, cacheWriteTokens: 0 })\nexport const COST_TOKEN_KEYS = ['uncachedInputTokens', 'outputTokens', 'cacheReadTokens', 'cacheWriteTokens'] as const\n\nexport function peakHour(at: number, windows: ReadonlyArray): boolean {\n const time = new Date(at)\n return time.getUTCDay() !== 0 && time.getUTCDay() !== 6\n && windows.some(([start, end]) => time.getUTCHours() >= start && time.getUTCHours() < end)\n}\n\n/**\n * All prompt billing buckets determine a request's band, never cumulative\n * session input.\n *\n * A tiered model returns the matching band and does NOT then apply `peak`: the\n * page publishes those two dimensions independently and no row carries both\n * today, so the combination becoming real is visible before it reaches a user.\n * This ordering is a latent choice, not a verified upstream rule.\n */\nexport function requestRates(price: CommandCodeModelPrice, at: number | null, contextTokens: number, table: CommandCodePriceTable): CommandCodeModelRates {\n // ORDER IS LOAD-BEARING: the generator refuses non-ascending bounds or a\n // bounded last band and the wire parser rejects the same shapes, so a\n // conforming table cannot present bands out of order.\n const tier = price.contextTiers?.find(tier => tier.maxContext === undefined || contextTokens <= tier.maxContext)\n if (tier !== undefined) return tier\n return price.peak !== undefined && at !== null && peakHour(at, table.peakHours) ? price.peak : price\n}\n\n/** Cache version and wire guard: changing bands/rates must refold historical groups. */\nexport function pricingKey(table: CommandCodePriceTable): number {\n const rates = (r: CommandCodeModelRates) => [r.inputCost, r.outputCost, r.cacheReadCost, r.cacheWriteCost ?? null]\n const canonical = JSON.stringify(['commandCodeCost-v1', table.peakHours, table.models.map(p => [p.id, p.slug, p.free === true, rates(p), p.peak ? rates(p.peak) : null, p.contextTiers?.map(t => [t.maxContext ?? null, rates(t)]) ?? null])])\n let hash = 2166136261\n for (const c of canonical) hash = Math.imul(hash ^ c.charCodeAt(0), 16777619) >>> 0\n return hash\n}\n\n/** Only safe to merge requests whose billing classification is identical. */\nexport function costGroupKey(group: CostUsageGroup, table: CommandCodePriceTable): string {\n // The table is mutable, so an identity-keyed index can keep stale model\n // mappings after its rows are changed in place. The projection already\n // indexes its usage groups once per settlement; scan the small price table\n // here so every call observes the current rows.\n const price = table.models.find(p => p.id === group.model || p.slug === group.model)\n return JSON.stringify([group.provider, group.model, price === undefined ? null : requestRates(price, group.at, group.contextTokens, table), group.at === null])\n}\n","/** Shared plan-tier presentation facts; safe to inline into the browser bundle. */\n\nexport const PLAN_TIER_ORDER = ['go', 'goat', 'pro', 'provider', 'max'] as const\n\nexport const PLAN_LABELS: Readonly> = {\n go: 'Go',\n goat: 'GOAT',\n pro: 'Pro',\n provider: 'Provider',\n max: 'Max',\n}\n\nexport const PLAN_ORDER: Readonly> = Object.fromEntries(\n PLAN_TIER_ORDER.map((tier, index) => [tier, index]),\n)\n","/**\n * Static capability snapshot for the Command Code provider: model →\n * reasoning-effort levels, vision/thinking flags, model → minimum plan tier,\n * subscription-plan labels, deals, and hourly (peak/off-peak) pricing.\n *\n * Everything here is synced from official sources — the command-code CLI\n * bundle's model table (`dist/cli.mjs`, re-verified at command-code@1.84.0) and\n * the official plan/pricing/model docs; see the dsh-commandcode-upstream skill\n * for the extraction procedures. Keeping the snapshot in its own module\n * confines those frequent sync diffs here: src/adapter.ts holds only the stable\n * wire/runtime logic. The read helpers live here too, for the same reason.\n *\n * Ported from pi-commandcode-provider (MIT); originally part of src/adapter.ts\n * and split out so upstream syncs stay reviewable.\n */\n\nimport { peakHour } from './cost-facts.ts'\nimport { PLAN_LABELS, PLAN_ORDER } from './plan-tiers.ts'\nexport { PLAN_LABELS, PLAN_ORDER } from './plan-tiers.ts'\n\nexport const KNOWN_EFFORTS: Readonly> = {\n // Re-verified against the authoritative command-code@1.84.0 model table. From\n // 1.82.4 the CLI no longer keeps this map bundled: `getSupportedEfforts()`\n // resolves it through the model catalog (`reasoningEfforts`), served live at\n // `GET /provider/v1/models?view=client` and falling back to an embedded\n // snapshot. The embedded snapshot is a bootstrap only — it was one refresh\n // stale within two days of release (99 of the live catalog's 100 models, and\n // missing the three newest; 1.82.5 folded exactly those three in), so a sync\n // must read the live catalog, not the artifact: exactly these models carry\n // selectable efforts. Models marked 'reasoning:!0' without efforts\n // (e.g. Tencent Hy3, GLM-5/5.1/5.2-Fast)\n // think automatically and are absent here - the CLI omits\n // 'reasoning_effort' for them, so the picker must not offer a selector. Do\n // NOT add entries from the OAuth provider tables (anthropic/openai) - only\n // the Provider-API table is authoritative for this plugin's route.\n //\n // `off` is NOT a strength: it is the DeepSeek family's \"do not think\" level\n // (command-code@1.73.3), and the official CLI sends it verbatim as\n // `reasoning_effort:\"off\"` rather than omitting the field. Its presence here\n // is what makes the adapter treat `off` as a real choice for these models\n // instead of the host's \"no effort requested\" signal - see the lookup in\n // `stream()`. No other family lists it: the Messages transport's\n // `output_config.effort` has no such value, so `off` stays dropped there.\n 'Qwen/Qwen3.8-Max': ['low', 'medium', 'xhigh'],\n 'Qwen/Qwen3.8-Max-0902': ['low', 'medium', 'xhigh'],\n 'Qwen/Qwen3.8-27B': ['low', 'medium', 'xhigh'],\n 'Qwen/Qwen3.8-Flash': ['low', 'medium', 'xhigh'],\n // command-code@1.56.0; same effort set as its Qwen 3.8 siblings.\n 'Qwen/Qwen3.8-Omni-Flash': ['low', 'medium', 'xhigh'],\n // command-code@1.82.4; the GOAT-tier sibling of `Qwen/Qwen3.8-Max` with the\n // same three selectable levels. It is also the only model the 1.82.2 -> 1.82.4\n // train added to the artifact's own effort table.\n 'Qwen/Qwen3.8-Max-Prime': ['low', 'medium', 'xhigh'],\n 'claude-fable-5-1': ['low', 'medium', 'high', 'xhigh', 'max'],\n 'claude-fable-5': ['low', 'medium', 'high', 'xhigh', 'max'],\n 'claude-opus-4-7': ['low', 'medium', 'high', 'xhigh', 'max'],\n 'claude-opus-4-8': ['low', 'medium', 'high', 'xhigh', 'max'],\n 'claude-opus-5': ['low', 'medium', 'high', 'xhigh', 'max'],\n 'claude-sonnet-4-6': ['low', 'medium', 'high', 'xhigh', 'max'],\n 'claude-sonnet-5': ['low', 'medium', 'high', 'xhigh', 'max'],\n // command-code@1.68.0; the five-level set shared with the rest of the Sonnet /\n // Opus family. It takes the \"recommended\" slot from `claude-sonnet-5`.\n 'claude-sonnet-5-5': ['low', 'medium', 'high', 'xhigh', 'max'],\n // command-code@1.39.1 dropped `medium`; the 1.39.2 table ships these three.\n // Still a three-level set at 1.74.3: unlike its V4 siblings, this one never\n // gained `off`, so thinking cannot be switched off on this variant.\n 'deepseek/deepseek-v4-flash-fast': ['low', 'high', 'max'],\n // command-code@1.53.0.\n 'deepseek/deepseek-v4.1-flash': ['off', 'low', 'high', 'max'],\n // command-code@1.67.0; the same four-level set as its `deepseek-v4.1-flash`\n // sibling, whose throughput-focused variant this is.\n 'deepseek/deepseek-v4.1-flash-fast': ['off', 'low', 'high', 'max'],\n // command-code@1.73.3 added `off` (\"Allow disabling thinking for DeepSeek\n // models\") to the DeepSeek V4 line and the 4.1 pair above - but NOT to\n // `deepseek-v4-flash-fast`, which the 1.74.3 table still ships at three.\n 'deepseek/deepseek-v4-flash': ['off', 'high', 'max'],\n 'deepseek/deepseek-v4-flash-vision-exp': ['off', 'high', 'max'],\n 'deepseek/deepseek-v4-pro': ['off', 'high', 'max'],\n // command-code@1.82.0 (\"Gemini Argon\") and the only registry addition in the\n // 1.81.0 -> 1.82.1 train. Three selectable levels, the same set the Gemini\n // Flash family carries.\n 'google/gemini-4-argon': ['low', 'medium', 'high'],\n 'google/gemini-3.1-flash-lite': ['low', 'medium', 'high'],\n 'google/gemini-3.5-flash': ['low', 'medium', 'high'],\n 'google/gemini-3.5-flash-lite': ['low', 'medium', 'high'],\n 'google/gemini-3.6-flash': ['low', 'medium', 'high'],\n 'google/gemini-3.7-flash': ['low', 'medium', 'high'],\n 'gpt-5.3-codex': ['low', 'medium', 'high', 'xhigh'],\n 'gpt-5.4': ['low', 'medium', 'high', 'xhigh'],\n 'gpt-5.4-mini': ['low', 'medium', 'high'],\n 'gpt-5.5': ['low', 'medium', 'high', 'xhigh'],\n 'gpt-5.6-luna': ['low', 'medium', 'high', 'xhigh', 'max'],\n 'gpt-5.6-sol': ['low', 'medium', 'high', 'xhigh', 'max'],\n 'gpt-5.6-terra': ['low', 'medium', 'high', 'xhigh', 'max'],\n // command-code@1.39.3; it previously reasoned automatically with no levels.\n 'moonshotai/Kimi-K3': ['low', 'high', 'max'],\n // command-code@1.43.0.\n 'google/gemini-3.8-flash': ['low', 'medium', 'high'],\n // 2026-10-16, first seen at the 1.84.0 sync: the live `?view=client` catalog\n // serves five levels for Reflection's free Beam preview, and it is the only\n // row this map gained in that train. Catalog-only evidence — the 1.84.0\n // artifact registry does not name the model at all (see KNOWN_NON_ZDR_MODELS).\n 'reflection/beam:free': ['low', 'medium', 'high', 'xhigh', 'max'],\n 'sakana/fugu-ultra': ['high', 'xhigh'],\n // command-code@1.60.0; same three-level set as its Step 3.x Flash siblings,\n // which still reason automatically with no levels and stay out of this map.\n 'stepfun/Step-5-Preview': ['low', 'medium', 'high'],\n 'tencent/hy4-preview': ['low', 'medium', 'high'],\n 'xai/grok-4.5': ['low', 'medium', 'high'],\n 'xai/grok-4.6': ['low', 'medium', 'high', 'xhigh'],\n // command-code@1.59.0; same four-level set as Grok 4.6. 1.61.0 put it on a\n // 40% off launch deal (see KNOWN_DEALS).\n 'xai/grok-4.7': ['low', 'medium', 'high', 'xhigh'],\n 'z-ai/glm-5.3-flash': ['low', 'high', 'max'],\n // command-code@1.57.0; same effort set as its `z-ai/glm-5.3-flash` sibling.\n 'z-ai/glm-5.3-flashx': ['low', 'high', 'max'],\n 'zai-org/GLM-5.2': ['high', 'max'],\n 'zai-org/GLM-5.3': ['low', 'high', 'max'],\n // Muse Spark family: selectable levels in command-code@1.45.0, `max` added to\n // 1.3 in 1.48.0 (1.3-contributor keeps the four-level set).\n 'meta/muse-spark-1.1': ['low', 'medium', 'high', 'xhigh'],\n 'meta/muse-spark-1.2': ['low', 'medium', 'high', 'xhigh'],\n 'meta/muse-spark-1.2-contributor': ['low', 'medium', 'high', 'xhigh'],\n 'meta/muse-spark-1.3': ['low', 'medium', 'high', 'xhigh', 'max'],\n 'meta/muse-spark-1.3-contributor': ['low', 'medium', 'high', 'xhigh'],\n // command-code@1.80.0 (\"Add Muse Wonder\"): the Muse family's newest member and\n // the only registry addition in the 1.79.2 -> 1.81.0 train. It carries the\n // same four-level set as Muse Spark 1.1/1.2 (no `max`).\n 'meta/muse-wonder-1.0': ['low', 'medium', 'high', 'xhigh'],\n // 2026-10-15; the open-weight Muse Spark. Vision-capable, Go-tier and\n // served only by the live catalog - it postdates the 1.82.4 artifact's own\n // embedded snapshot, so it cannot be read out of `dist/cli.mjs`.\n 'meta/muse-spark-open': ['low', 'medium', 'high'],\n // 2026-10-14; open vision-language reasoning model, Go tier.\n 'nvidia/nemotron-3.5-super-vl': ['low', 'medium', 'high'],\n // command-code@1.49.0; the full five-level set.\n 'gpt-6-astra': ['low', 'medium', 'high', 'xhigh', 'max'],\n // command-code@1.64.0: Claude Opus 5.5 and the GPT-6 Sol / Luna pair, the only\n // registry additions in the 1.62.0 -> 1.64.0 train; all three reason with the\n // same five-level set as `gpt-6-astra`.\n 'claude-opus-5-5': ['low', 'medium', 'high', 'xhigh', 'max'],\n 'gpt-6-luna': ['low', 'medium', 'high', 'xhigh', 'max'],\n 'gpt-6-sol': ['low', 'medium', 'high', 'xhigh', 'max'],\n // command-code@1.51.3; it previously reasoned automatically with no levels\n // and lived in KNOWN_THINKING_MODELS. The hidden\n // `minimax/minimax-m3-free` sibling gained the same set in the bundle.\n 'MiniMaxAI/MiniMax-M3': ['low', 'medium', 'high'],\n // `stealth/space-bunny-alpha` (command-code@1.65.0, `max` added by 1.73.4)\n // was RETIRED by command-code@1.74.3: the artifact drops its own four-level\n // effort list and ships the row as `hidden` instead, the official Desktop\n // changelog for 2026-10-06 says \"Remove Space Bunny Alpha from the model\n // picker\", and the model is gone from `/provider/v1/models` as well as the\n // pricing page.\n // `stealth/pixel-canary` (the second stealth preview, `xhigh` instead of\n // `high`) was RETIRED by command-code@1.73.1: the CLI hides it behind\n // `isPixelCanaryEnded()` (past 2026-10-01T06:00:00Z) and it is gone from\n // `/provider/v1/models` and the pricing page.\n // command-code@1.77.0 closed both out here as well: neither carries an effort\n // list any more, both sit in the CLI's non-selectable set (its\n // `listSelectableModelIds()` filters them out), and both left the ZDR\n // exclusion set — so no table in this file names either one any more.\n // command-code@1.71.0. Max-and-above availability (see KNOWN_PLANS), Vision\n // per the official registry and inputModalities:[\"text\",\"image\"], and the\n // same five-level set as its `gpt-6-astra` / `gpt-6-sol` predecessors.\n 'gpt-6.1-sol': ['low', 'medium', 'high', 'xhigh', 'max'],\n // command-code@1.82.2. The paid graduation of the `ling-3.1-flash:free`\n // promo this table used to carry: that row is retired in the same release\n // (the CLI ships it `hidden`, it lost its effort list, and it is gone from\n // both `/provider/v1/models` and the pricing page), so it is named nowhere in\n // this file any more. Three selectable levels, text-only input, Go tier —\n // like its `mistral-large-4` neighbour, and unlike the free stealth previews.\n 'inclusionai/ling-3.1-flash': ['low', 'medium', 'high'],\n // command-code@1.75.0 (\"Add Mistral Large 4\") — the only model the 1.74.3 ->\n // 1.77.0 train added. A three-level set; Vision per the official registry and\n // the CLI's inputModalities:[\"text\",\"image\"] (see `KNOWN_IMAGE_MODELS`), and\n // Go-tier availability (see `KNOWN_PLANS`).\n 'mistral/mistral-large-4': ['low', 'medium', 'high'],\n // command-code@1.78.0 (\"Add Claude Haiku 5.5 (Pro and above)\") and 1.79.0\n // (\"Add Glyph Cluster as a free model, 100 requests a day\") are the only\n // registry additions in the 1.77.0 -> 1.79.1 train. Both carry selectable\n // efforts, so neither belongs in KNOWN_THINKING_MODELS; Claude Haiku 5.5 takes\n // the Claude family's five-level set, while the free Glyph Cluster preview\n // stops at four and offers no `max`.\n 'claude-haiku-5-5': ['low', 'medium', 'high', 'xhigh', 'max'],\n 'stealth/glyph-cluster:free': ['low', 'medium', 'high', 'xhigh'],\n // 2026-10-15; a free stealth preview (\"while the stealth preview lasts\") and\n // the only model in this train that carries the full five-level set. It is\n // text-only and NOT ZDR-covered, unlike its Glyph Cluster sibling - see\n // `KNOWN_NON_ZDR_MODELS`. Live-catalog only, not in the 1.82.4 artifact.\n 'stealth/cat-jam:free': ['low', 'medium', 'high', 'xhigh', 'max'],\n}\n\n/**\n * Models whose Capabilities include Vision, per the official Command Code\n * model registry (`https://commandcode.ai/docs/reference/cli/models`, generated\n * from the same registry as `cmd --list-models` / the `/model` picker).\n *\n * The Provider API does not expose modality metadata, so this snapshot is the\n * source of truth for image-input gating. Command Code's own CLI falls back to\n * a client-side VISION side-call for text-only models; this adapter does not\n * reproduce that interactive feature, so images sent to a model outside this\n * list are refused loudly (`UNSUPPORTED_CONTENT`) instead of being dropped or\n * sent to a model that cannot read them.\n *\n * Keep in sync with the official registry when new models ship (see the\n * dsh-commandcode-upstream skill).\n */\nexport const KNOWN_IMAGE_MODELS: ReadonlySet = new Set([\n 'MiniMaxAI/MiniMax-M3',\n 'Qwen/Qwen3.6-Plus',\n 'Qwen/Qwen3.7-Flash',\n 'Qwen/Qwen3.7-Plus',\n 'Qwen/Qwen3.8-27B',\n 'Qwen/Qwen3.8-Flash',\n 'Qwen/Qwen3.8-Max',\n // command-code@1.41.0; Vision per the official registry and the CLI's\n // inputModalities:[\"text\",\"image\"].\n 'Qwen/Qwen3.8-Max-0902',\n // command-code@1.56.0; Vision per the official registry and inputModalities.\n 'Qwen/Qwen3.8-Omni-Flash',\n // command-code@1.82.4; inputModalities:[\"text\",\"image\"] in both the artifact's\n // embedded catalog and the live `?view=client` catalog.\n 'Qwen/Qwen3.8-Max-Prime',\n 'claude-fable-5-1',\n 'claude-fable-5',\n 'claude-haiku-4-5-20251001',\n // command-code@1.78.0; Vision per the official registry and the CLI's\n // inputModalities:[\"text\",\"image\"].\n 'claude-haiku-5-5',\n 'claude-opus-4-7',\n 'claude-opus-4-8',\n // command-code@1.64.0; Vision per the official registry and inputModalities.\n 'claude-opus-5-5',\n 'claude-opus-5',\n 'claude-sonnet-4-6',\n 'claude-sonnet-5',\n // command-code@1.68.0; Vision per the official registry and the CLI's\n // inputModalities:[\"text\",\"image\"].\n 'claude-sonnet-5-5',\n 'deepseek/deepseek-v4-flash-vision-exp',\n // command-code@1.53.0; Vision per the official registry and inputModalities.\n 'deepseek/deepseek-v4.1-flash',\n // command-code@1.67.0; Vision per the official registry and inputModalities.\n 'deepseek/deepseek-v4.1-flash-fast',\n // command-code@1.82.0; Vision per the official registry, the CLI's\n // inputModalities:[\"text\",\"image\"] and the docs page's \"Text input, Vision,\n // Reasoning\" capability label.\n 'google/gemini-4-argon',\n 'google/gemini-3.1-flash-lite',\n 'google/gemini-3.5-flash',\n 'google/gemini-3.5-flash-lite',\n 'google/gemini-3.6-flash',\n 'google/gemini-3.7-flash',\n // command-code@1.43.0; Vision per the official registry and inputModalities.\n 'google/gemini-3.8-flash',\n 'gpt-5.3-codex',\n 'gpt-5.4',\n 'gpt-5.4-mini',\n 'gpt-5.5',\n 'gpt-5.6-luna',\n 'gpt-5.6-sol',\n 'gpt-5.6-terra',\n // command-code@1.49.0; Vision per the official registry and inputModalities.\n 'gpt-6-astra',\n // command-code@1.64.0 added the GPT-6 Sol / Luna pair; Vision per the\n // official registry and inputModalities.\n 'gpt-6-luna',\n 'gpt-6-sol',\n // command-code@1.71.0; Vision per the official registry and the CLI's\n // inputModalities:[\"text\",\"image\"] — unlike the text-only Ling free models.\n 'gpt-6.1-sol',\n // command-code@1.44.0 added Muse Spark 1.3 and its Contributor sibling; both\n // are Vision per the official registry and inputModalities.\n 'meta/muse-spark-1.1',\n 'meta/muse-spark-1.2',\n 'meta/muse-spark-1.2-contributor',\n 'meta/muse-spark-1.3',\n 'meta/muse-spark-1.3-contributor',\n // command-code@1.80.0; Vision per the official registry and the CLI's\n // inputModalities:[\"text\",\"image\",\"file\"] — the only model in this catalog\n // that also declares the `file` modality.\n 'meta/muse-wonder-1.0',\n // 2026-10-15; inputModalities:[\"text\",\"image\"] in the live catalog.\n 'meta/muse-spark-open',\n // 2026-10-14; inputModalities:[\"text\",\"image\"], and the only Nemotron row\n // in this catalog that carries vision.\n 'nvidia/nemotron-3.5-super-vl',\n // command-code@1.75.0; Vision per the official registry and the CLI's\n // inputModalities:[\"text\",\"image\"].\n 'mistral/mistral-large-4',\n 'moonshotai/Kimi-K2.5',\n 'moonshotai/Kimi-K2.6',\n 'moonshotai/Kimi-K2.7-Code',\n 'moonshotai/Kimi-K2.7-Code-Highspeed',\n 'moonshotai/Kimi-K3',\n 'sakana/fugu-ultra',\n // command-code@1.65.0; Vision per the official registry and inputModalities.\n 'stepfun/Step-3.7-Flash',\n // command-code@1.60.0; Vision per the official registry and inputModalities.\n 'stepfun/Step-5-Preview',\n 'thinkingmachines/inkling',\n 'thinkingmachines/inkling-small',\n 'xai/grok-4.5',\n // command-code@1.47.0 marked Grok 4.6 vision-capable (text-only in 1.46.0).\n 'xai/grok-4.6',\n // command-code@1.59.0; Vision per the official registry and inputModalities.\n 'xai/grok-4.7',\n 'xiaomi/mimo-v2.5',\n // command-code@1.62.0 added the MiMo V2.6 family (Flash, Pro, Pro\n // UltraSpeed); all three are Vision. None carries a reasoning flag in any\n // source, so no effort or automatic-reasoning entry belongs beside these.\n 'xiaomi/mimo-v2.6-flash',\n 'xiaomi/mimo-v2.6-pro',\n 'xiaomi/mimo-v2.6-pro-ultraspeed',\n 'z-ai/glm-5.3-flash',\n // command-code@1.57.0; Vision per the official registry and inputModalities.\n 'z-ai/glm-5.3-flashx',\n])\n\n/**\n * Models WITHOUT a zero-data-retention upstream. Through command-code@1.82.2\n * the CLI's own registry answered this: `modelSupportsZdr(id)` was exactly\n * `!nonZdrSet.has(canonicalize(id))`, and `knownModelSupportsZdr` carried the\n * membership in the sibling route table — the UNION of both was this set, and\n * the two anchors disagreed by one id (`meituan/LongCat-2.0:free`, which 1.74.1\n * dropped from the first anchor while the canonical helper kept it).\n * command-code@1.82.4 removes that disagreement by making the verdict a catalog\n * lookup — `resolveKnownCatalogModel({model,catalog})?.zdr ?? false` — so this\n * set is now the live catalog's `zdr:false` membership and nothing more. The\n * official docs (commandcode.ai/docs/resources/\n * zdr) put coverage in prose — \"99% of our models have ZDR-capable upstreams … only\n * a small handful of models are affected\" — so the CLI's exclusion list is\n * the only per-model evidence there is; a ZDR request naming one of these\n * fails with HTTP 422 `cmd_zdr_no_providers` instead of routing through a\n * provider that retains.\n *\n * Why a NEGATIVE set, and why \"not listed\" answers TRUE: 99% of the catalog is\n * covered, so the maintained difference is the exception list. This helper is\n * informational; the adapter sends the ZDR header for EVERY request when the\n * switch is on — the provider remains the routing authority and refuses an\n * unsupported model rather than silently dropping the privacy guarantee.\n *\n * `minimax/minimax-m3-free` is the one entry the public catalog's default view\n * (`/provider/v1/models`) does not serve through the picker (it is CLI/pricing-visible\n * and hidden from the picker); it stays listed because the CLI carries it and a Go-plan\n * request can still name it. Both this row and `stealth/cat-jam:free` ARE served\n * by the `?view=client` catalog, which is where the 1.82.4 verdict comes from.\n *\n * command-code@1.82.4 moved the authority for this verdict: `knownModelSupportsZdr`\n * no longer negates a bundled Set, it returns `resolveKnownCatalogModel({model,\n * catalog})?.zdr ?? false`, so an id the catalog does not carry (or carries with\n * `zdr:false`) is NOT covered. That inverts the default this helper was built on\n * (\"not listed\" answered TRUE); the snapshot keeps its negative-set shape because\n * 99% of the catalog is still covered, but membership is now read from the\n * `?view=client` catalog and confirmed against the canonical helper set.\n *\n * Keep in sync via the dsh-commandcode-upstream skill: the CLI's registry data\n * (its `zdr:{only:[…]}` provider routes and the per-provider `zdr`/`noTraining`\n * flags) is upstream-internal routing, not a per-model contract, so this table\n * is the snapshot of the exclusion set and nothing more. It is a rare change:\n * 20 members held across 1.62.0 → 1.64.0, 1.65.0 and 1.66.0 each added exactly\n * one (the two stealth-preview models), 1.67.0 added one\n * (`deepseek/deepseek-v4.1-flash-fast`), 1.68.0 changed nothing, and 1.74.1\n * removed one (`meituan/LongCat-2.0`). The 1.74.2/1.74.3 pair changed nothing\n * here either (22 members as of 2026-10-06); 1.77.0 dropped the two retired\n * stealth previews, back to 20 members as of 2026-10-07, and 1.79.0 added the\n * free `stealth/glyph-cluster:free` preview — 21 members as of 2026-10-08.\n *\n * 1.77.0 also settled the two retired stealth previews (see `KNOWN_EFFORTS`):\n * 1.74.3 still named both in the ZDR anchors, so they stayed listed here on\n * purpose — an id a stale session named still got a truthful answer. The 1.77.0\n * artifact names neither in its exclusion set and filters both out of\n * `listSelectableModelIds()`, so they are pruned along with the rest of the\n * tables and `supportsZeroDataRetention` now answers TRUE for them, matching\n * what the current CLI says.\n *\n * 1.82.4 then reversed 1.74.1's removal of `meituan/LongCat-2.0:free` and added\n * the `stealth/cat-jam:free` preview, taking this set to 24 members. The 1.84.0\n * sync (2026-10-16) moves it to 25 with no verdict flip: LongCat's exclusion\n * followed its rename to the paid id, and the free `reflection/beam:free`\n * preview joined on catalog evidence alone. The authoritative membership is the\n * UNION of the artifact's exclusion set and the catalog's `zdr:false` list —\n * neither source alone is complete, which is why this set is not simply \"what\n * the CLI says\".\n */\nexport const KNOWN_NON_ZDR_MODELS: ReadonlySet = new Set([\n 'MiniMaxAI/MiniMax-M3',\n 'Qwen/Qwen3.8-Max-0902',\n // command-code@1.67.0. The 1.67.0 artifact lists it in BOTH anchor sets, so\n // the CLI's own ZDR predicate excludes it. Unlike the retired stealth\n // previews, the pricing page carries no ZDR note for this row — the artifact\n // is the evidence, and the sibling `deepseek-v4.1-flash` stays ZDR-covered.\n 'deepseek/deepseek-v4.1-flash-fast',\n 'meta/muse-spark-1.1',\n 'meta/muse-spark-1.2',\n 'meta/muse-spark-1.2-contributor',\n 'meta/muse-spark-1.3',\n 'meta/muse-spark-1.3-contributor',\n // command-code@1.80.0. The CLI's exclusion set names it, so a ZDR request for\n // it is refused; the pricing page carries no ZDR note for this row, so the\n // artifact is the evidence. 22 members as of 1.82.1 — Gemini 4 Argon, the\n // only registry addition in the 1.81.0 -> 1.82.1 train, is NOT in the set.\n 'meta/muse-wonder-1.0',\n // 2026-10-16 (1.84.0 sync). LongCat's verdict followed the id, not the other\n // way round: the catalog now serves `zdr:false` for the paid\n // `meituan/LongCat-2.0` and `zdr:true` for the `:free` row that 1.82.4 had\n // listed. Both sources agree — the artifact's exclusion set names the paid id\n // too — so this is a plain rename with a positive counter-example for the old\n // alias, never a removal on missing evidence.\n 'meituan/LongCat-2.0',\n 'minimax/minimax-m3-free',\n 'poolside/laguna-s-2.1-free',\n // 2026-10-16 (1.84.0 sync). Catalog-only evidence: `?view=client` serves\n // `zdr:false` for Reflection's free Beam preview while the 1.84.0 artifact's\n // exclusion set never names it (that gap is the audit's single error). This\n // snapshot is the UNION of both sources, so the catalog verdict alone admits\n // it — the same path `stealth/cat-jam:free` took at 1.82.4.\n 'reflection/beam:free',\n 'sakana/fugu-ultra',\n // command-code@1.79.0. The free Glyph Cluster preview is the ONE entry here\n // whose exclusion the official pricing page states in prose rather than\n // leaving to the artifact: its tip reads \"Free while the preview lasts. Up to\n // 100 requests a day. Not routed under ZDR.\" The CLI's own exclusion set\n // carries the same membership.\n 'stealth/glyph-cluster:free',\n // 2026-10-15. The live catalog serves `zdr:false` for this free stealth\n // preview and no anchor set names it at all, so it is excluded on the\n // catalog verdict alone. Its pricing tip reads \"Free while the stealth\n // preview lasts\"; unlike its Glyph Cluster sibling the page states no ZDR\n // note for this row.\n 'stealth/cat-jam:free',\n 'stepfun/Step-3.7-Flash',\n 'stepfun/Step-5-Preview',\n 'xai/grok-4.5',\n 'xai/grok-4.6',\n 'xiaomi/mimo-v2.6-flash',\n 'xiaomi/mimo-v2.6-pro',\n 'xiaomi/mimo-v2.6-pro-ultraspeed',\n 'z-ai/glm-5.3-flashx',\n 'zai-org/GLM-5.2-Fast',\n])\n\n/**\n * Whether the CLI snapshot lists a ZDR-capable upstream for `modelId`. This is\n * informational, never a reason to omit the header when ZDR is enabled: the\n * provider may add coverage or lack capacity after this snapshot was taken.\n */\nexport function supportsZeroDataRetention(modelId: string): boolean {\n return !KNOWN_NON_ZDR_MODELS.has(modelId)\n}\n\n/**\n * Models the official CLI's model table marks `reasoning:!0` but defines no\n * selectable `reasoning_effort` levels — they think automatically, with\n * Command Code driving the depth. `KNOWN_EFFORTS` (which mirrors the CLI's\n * effort map exactly) stays the sole source for selectable effort levels, and\n * this snapshot is not surfaced in the picker's compact description — it exists\n * for programmatic consumers.\n *\n * Source: the bundled model table (dist/cli.mjs), cross-checked with\n * https://commandcode.ai/docs/reference/cli/models. Keep in sync via the\n * dsh-commandcode-upstream skill; a model that GAINS selectable efforts leaves\n * this set for `KNOWN_EFFORTS` (Tencent Hy4 Preview, Kimi K3, the Muse Spark\n * family and MiniMax M3 all took that path).\n */\nexport const KNOWN_THINKING_MODELS: ReadonlySet = new Set([\n 'Qwen/Qwen3.6-Max-Preview',\n 'Qwen/Qwen3.6-Plus',\n 'Qwen/Qwen3.7-Flash',\n 'Qwen/Qwen3.7-Max',\n 'Qwen/Qwen3.7-Plus',\n 'moonshotai/Kimi-K2.7-Code',\n 'moonshotai/Kimi-K2.7-Code-Highspeed',\n // command-code@1.65.2 corrected Step 3.5 Flash's registry context from\n // 1,000,000 to 262,144 tokens; the public catalog already served 262,144.\n // Reasoning and the absence of selectable efforts are unchanged.\n 'stepfun/Step-3.5-Flash',\n 'stepfun/Step-3.7-Flash',\n 'tencent/hy3-paid',\n 'nvidia/nemotron-3-ultra-550b-a55b',\n 'thinkingmachines/inkling',\n 'thinkingmachines/inkling-small',\n 'poolside/laguna-s-2.1-free',\n // LongCat 2.0 (command-code@1.42.0, Meituan's trillion-parameter coding\n // model, 1M context) is text-only with automatic reasoning. The free promo\n // ended 2026-09-19 and the backend catalog renamed it from\n // `meituan/LongCat-2.0:free` to the paid `meituan/LongCat-2.0`. The rename is\n // billing-only, so the new id keeps this entry: the pricing page still\n // carries `caps.reasoning: true` with no efforts, and command-code@1.58.0 —\n // the CLI release that retired the free tier — carries the new id with\n // `reasoning:!0` and no `reasoningEfforts`, one release after the backend\n // rename the 1.57.0 sync recorded here.\n 'meituan/LongCat-2.0',\n])\n\n/**\n * Catalog models the Provider API serves ONLY through `/provider/v1/messages`\n * (Anthropic Messages shape). Every other model in the catalog answers on\n * `/provider/v1/chat/completions`.\n *\n * Measured 2026-09-16 (command-code@1.54.0, 69 models posted to\n * `/provider/v1/chat/completions`): exactly the then-entire Claude family\n * refused with HTTP 400 `Model \"\" must be called via\n * /provider/v1/messages (Anthropic Messages shape)`, and every one of them is\n * routed normally by `/alpha/generate`.\n *\n * Re-measured 2026-09-29 against the 84-model catalog: the same ten\n * `claude-*` ids are the only ones carrying `supported_endpoints:\n * [\"/messages\"]`, and posting a non-Claude model to the endpoint answers 400\n * `Model \"\" is not supported on this endpoint. Use\n * /provider/v1/chat/completions for OpenAI and OSS models.` The adapter routes\n * on that field when the catalog supplies it, so this set is the FALLBACK for\n * a cached or hand-built catalog, not the primary source — see\n * `requiresMessagesEndpoint()`.\n *\n * Note what this list is NOT: it is not a plan gate. `claude-sonnet-5` is\n * Pro-tier and `claude-opus-4-8` Provider-tier, so the accounts entitled to\n * these models are exactly the non-Go ones, which `resolveProtocol()` sends to\n * the Provider API by default — picking any Claude model there failed every\n * request before this snapshot existed.\n *\n * `requiresMessagesEndpoint()` additionally treats any `claude-*` id as\n * Messages-only, so a Claude model added upstream is still routed correctly\n * by an un-updated plugin instead of hard-failing with the 400 above. The\n * worst case of that rule going stale the other way (upstream teaching\n * `/provider/v1/chat/completions` to serve Claude) is one model riding a\n * transport it already works on.\n *\n * Keep in sync when models ship (see the dsh-commandcode-upstream skill).\n */\nexport const MESSAGES_ONLY_MODELS: ReadonlySet = new Set([\n 'claude-sonnet-5-5',\n 'claude-sonnet-5',\n 'claude-sonnet-4-6',\n 'claude-fable-5-1',\n 'claude-fable-5',\n 'claude-opus-5-5',\n 'claude-opus-5',\n 'claude-opus-4-8',\n 'claude-opus-4-7',\n 'claude-haiku-4-5-20251001',\n])\n\n/** True when the Provider API will only serve `modelId` via `/provider/v1/messages`. */\nexport function requiresMessagesEndpoint(modelId: string): boolean {\n return MESSAGES_ONLY_MODELS.has(modelId) || modelId.startsWith('claude-')\n}\n\n/**\n * Per-model output ceilings, which `/provider/v1/models` does NOT publish (it\n * carries `context_length` and `supported_endpoints` only) while every endpoint\n * refuses a larger `max_tokens` per model. Sending the context window as the\n * output budget is what produced issue #71: `claude-sonnet-5-5` has a\n * 1 000 000-token window and a 128 000-token ceiling, the adapter derived\n * 131072, and the endpoint refused every request of a fresh process.\n *\n * **Generated — do not hand-edit.** `scripts/sync-output-limits.mjs` rewrites\n * this literal from models.dev; run it after a catalog sync, and use its\n * `--check` in CI. Command Code resells these models through their VENDOR's own\n * API, so the vendor's published ceiling is the value recorded: 76 of the 89\n * catalog ids as of 2026-10-15. Each row carries a comment naming the entry it\n * came from.\n *\n * No row needs a hand-recorded pin as of 2026-10-16: the one that did\n * (`inclusionai/ling-3.0-flash-sante:free`, pinned at 32768 because it had lost\n * both its vendor row and its unanimous third-party vote) left the live catalog\n * with the 1.82.4 catalog migration, so the script's `MANUAL_CEILINGS` map is\n * now empty and every remaining row resolves from a vendor row or a unanimous\n * third-party vote. (`gpt-6.1-sol` (128000) never needed a pin — OpenAI's own row\n * carries it and every other provider carrying the id agrees.) All are still\n * correctable — a stricter gateway costs one refused request, and\n * `streamRequest()` remembers what the endpoint said.\n *\n * The 13 unlisted models are ones no vendor publishes and the aggregators\n * disagree about. They are NOT a gap: a refusal states the ceiling in full, and\n * `streamRequest()` reads it off, retries once and remembers it for the model\n * (issue #71). A vendor figure the gateway turns out to be stricter than costs\n * one round trip; a conservative guess costs half of every answer, forever —\n * which is why the unlisted path defers to the endpoint rather than to a\n * fallback here.\n *\n * An unlisted Messages-route model still falls back to\n * {@link DEFAULT_MESSAGES_MAX_TOKENS} before any request is made, so a ceiling\n * is never absent when the body is built.\n */\nexport const MODEL_OUTPUT_TOKEN_LIMITS: ReadonlyMap = new Map([\n // anthropic\n ['claude-fable-5', 128000],\n // anthropic\n ['claude-fable-5-1', 128000],\n // anthropic\n ['claude-haiku-4-5-20251001', 64000],\n // anthropic\n ['claude-haiku-5-5', 128000],\n // anthropic\n ['claude-opus-4-7', 128000],\n // anthropic\n ['claude-opus-4-8', 128000],\n // anthropic\n ['claude-opus-5', 128000],\n // anthropic\n ['claude-opus-5-5', 128000],\n // anthropic\n ['claude-sonnet-4-6', 128000],\n // anthropic\n ['claude-sonnet-5', 128000],\n // anthropic\n ['claude-sonnet-5-5', 128000],\n // deepseek\n ['deepseek/deepseek-v4-flash', 393216],\n // 1 provider(s), unanimous\n ['deepseek/deepseek-v4-flash-fast', 384000],\n // deepseek\n ['deepseek/deepseek-v4-flash-vision-exp', 393216],\n // deepseek\n ['deepseek/deepseek-v4-pro', 393216],\n // google\n ['google/gemini-3.1-flash-lite', 65536],\n // google\n ['google/gemini-3.5-flash', 65536],\n // google\n ['google/gemini-3.5-flash-lite', 65536],\n // google\n ['google/gemini-3.6-flash', 65536],\n // google\n ['google/gemini-3.7-flash', 65536],\n // google\n ['google/gemini-3.8-flash', 65536],\n // google\n ['google/gemini-4-argon', 32768],\n // openai\n ['gpt-5.3-codex', 128000],\n // openai\n ['gpt-5.4', 128000],\n // openai\n ['gpt-5.4-mini', 128000],\n // openai\n ['gpt-5.5', 128000],\n // openai\n ['gpt-5.6-luna', 128000],\n // openai\n ['gpt-5.6-sol', 128000],\n // openai\n ['gpt-5.6-terra', 128000],\n // openai\n ['gpt-6-astra', 128000],\n // openai\n ['gpt-6-luna', 128000],\n // openai\n ['gpt-6-sol', 128000],\n // openai\n ['gpt-6.1-sol', 128000],\n // 1 provider(s), unanimous\n ['meituan/LongCat-2.0', 131072],\n // meta\n ['meta/muse-spark-1.1', 131072],\n // meta\n ['meta/muse-spark-1.2', 131072],\n // meta\n ['meta/muse-spark-1.2-contributor', 131072],\n // meta\n ['meta/muse-spark-1.3', 131072],\n // meta\n ['meta/muse-spark-1.3-contributor', 131072],\n // meta\n ['meta/muse-wonder-1.0', 131072],\n // minimax\n ['MiniMaxAI/MiniMax-M2.5', 131072],\n // minimax\n ['MiniMaxAI/MiniMax-M2.7', 131072],\n // minimax\n ['MiniMaxAI/MiniMax-M3', 512000],\n // moonshotai\n ['moonshotai/Kimi-K2.6', 262144],\n // moonshotai\n ['moonshotai/Kimi-K2.7-Code', 262144],\n // moonshotai\n ['moonshotai/Kimi-K2.7-Code-Highspeed', 262144],\n // moonshotai\n ['moonshotai/Kimi-K3', 1048576],\n // nvidia\n ['nvidia/nemotron-3-ultra-550b-a55b', 65536],\n // poolside\n ['poolside/laguna-s-2.1-free', 32768],\n // alibaba\n ['Qwen/Qwen3.6-Max-Preview', 65536],\n // alibaba\n ['Qwen/Qwen3.6-Plus', 65536],\n // alibaba\n ['Qwen/Qwen3.7-Flash', 131072],\n // alibaba\n ['Qwen/Qwen3.7-Max', 131072],\n // alibaba\n ['Qwen/Qwen3.7-Plus', 131072],\n // alibaba\n ['Qwen/Qwen3.8-Flash', 131072],\n // alibaba\n ['Qwen/Qwen3.8-Max', 131072],\n // 1 provider(s), unanimous\n ['Qwen/Qwen3.8-Max-0902', 131072],\n // alibaba\n ['Qwen/Qwen3.8-Omni-Flash', 131072],\n // sakana\n ['sakana/fugu-ultra', 1000000],\n // stepfun\n ['stepfun/Step-3.5-Flash', 256000],\n // stepfun\n ['stepfun/Step-3.7-Flash', 256000],\n // stepfun\n ['stepfun/Step-5-Preview', 65536],\n // 1 provider(s), unanimous\n ['tencent/hy3-paid', 128000],\n // thinkingmachines\n ['thinkingmachines/inkling', 65536],\n // xai\n ['xai/grok-4.5', 500000],\n // xai\n ['xai/grok-4.6', 500000],\n // xai\n ['xai/grok-4.7', 500000],\n // xiaomi\n ['xiaomi/mimo-v2.5', 131072],\n // xiaomi\n ['xiaomi/mimo-v2.5-pro', 131072],\n // xiaomi\n ['xiaomi/mimo-v2.6-flash', 131072],\n // xiaomi\n ['xiaomi/mimo-v2.6-pro', 131072],\n // xiaomi\n ['xiaomi/mimo-v2.6-pro-ultraspeed', 131072],\n // zai\n ['z-ai/glm-5.3-flash', 131072],\n // zai\n ['z-ai/glm-5.3-flashx', 131072],\n // zai\n ['zai-org/GLM-5', 131072],\n // zai\n ['zai-org/GLM-5.1', 131072],\n // zai\n ['zai-org/GLM-5.2', 131072],\n // zai\n ['zai-org/GLM-5.3', 131072],\n])\n\n/**\n * Output ceiling for a Messages-route model that {@link MODEL_OUTPUT_TOKEN_LIMITS}\n * does not carry — today only models no vendor publishes yet. Deliberately\n * conservative: a 400 on `max_tokens` is a wasted round trip on every request,\n * whereas a lower ceiling only shortens an answer, and the endpoint states the\n * real one the first time it refuses, at which point the runtime overrides this\n * anyway (issue #71).\n *\n * 64 000 is not arbitrary: it is `claude-haiku-4-5-20251001`'s actual ceiling,\n * the lowest in the Claude family. A Claude model added to the catalog before\n * its row exists here therefore answers at a size the family really supports,\n * and is corrected upward on its first rejection rather than clamped here\n * forever.\n */\nexport const DEFAULT_MESSAGES_MAX_TOKENS = 64_000\n\n/**\n * The minimum subscription plan a model is included in, per the official plan\n * pages (`/docs/plans/go`, `/docs/plans/goat`, `/docs/plans/pro`,\n * `/docs/plans/max` and `/docs/resources/pricing-limits`). Each plan's model\n * list is a superset of the one below it: Go ⊂ GOAT ⊂ Pro ⊂ Provider/Max.\n * Models absent from every plan list (Claude Opus/Fable, Fugu Ultra) are\n * Provider-tier. Re-verified at command-code@1.82.4 (2026-10-16) against the\n * live `?view=client` catalog: 93 ids, still a strict superset chain. Mistral\n * Large 4\n * (1.75.0) was the only addition at the 1.77.0 check; the 1.78.0/1.79.0 pair\n * added Claude Haiku 5.5 at Pro and the free Glyph Cluster preview at Go.\n * 1.79.2 lowers Haiku 5.5's minimum plan to GOAT; 1.80.0 adds Muse Wonder at\n * Max; 1.82.0 adds Gemini 4 Argon at Pro and nothing else moves. The 1.82.4\n * train adds Qwen 3.8 Max Prime at GOAT plus Muse Spark Open, Nemotron 3.5\n * Super VL and the free Cat Jam preview at Go, and drops Ling 3.0 Flash Sante,\n * which left the live catalog. Every other\n * tier is unchanged.\n * The only removals since 1.49.0 are the two retired stealth previews (Pixel\n * Canary at 1.73.1, Space Bunny Alpha at 1.74.3) and Ling 3.0 Flash Sante\n * (2026-10-16). Per-entry tags below name the\n * releases that added or moved each row.\n *\n * The Provider API exposes no plan metadata, so this snapshot is the source of\n * truth for the picker's plan annotation — it answers \"which plan do I need to\n * actually use this model?\" at a glance. Plan labels use the official tier\n * names (`Go`, `GOAT`, `Pro`, `Provider`), with `Max` implying Provider.\n *\n * Keep in sync with the official plan pages when they change (see the\n * dsh-commandcode-upstream skill).\n */\nexport const KNOWN_PLANS: Readonly> = {\n // --- Go (54) ---\n 'MiniMaxAI/MiniMax-M2.5': 'go',\n 'MiniMaxAI/MiniMax-M2.7': 'go',\n 'MiniMaxAI/MiniMax-M3': 'go',\n 'Qwen/Qwen3.6-Max-Preview': 'go',\n 'Qwen/Qwen3.6-Plus': 'go',\n 'Qwen/Qwen3.7-Flash': 'go',\n 'Qwen/Qwen3.7-Max': 'go',\n 'Qwen/Qwen3.7-Plus': 'go',\n 'Qwen/Qwen3.8-27B': 'go',\n 'Qwen/Qwen3.8-Flash': 'go',\n 'Qwen/Qwen3.8-Max': 'go',\n // command-code@1.41.0; listed on the Go plan page.\n 'Qwen/Qwen3.8-Max-0902': 'go',\n // command-code@1.82.4; individual-go is false and individual-goat true — the\n // one new model in this train that lands on GOAT rather than Go.\n 'Qwen/Qwen3.8-Max-Prime': 'goat',\n // command-code@1.56.0; the pricing page's embedded availability grants every\n // tier (individual-go through teams-pro) — the \"all\":true shape shared by the\n // Qwen 3.8 family and the stealth-preview models below.\n 'Qwen/Qwen3.8-Omni-Flash': 'go',\n // command-code@1.39.0; Go-tier like the rest of the DeepSeek V4 family.\n 'deepseek/deepseek-v4-flash-fast': 'go',\n // command-code@1.53.0; every plan including Go.\n 'deepseek/deepseek-v4.1-flash': 'go',\n // command-code@1.67.0; individual-go true, so Go-tier like the rest of the\n // DeepSeek V4 family.\n 'deepseek/deepseek-v4.1-flash-fast': 'go',\n 'deepseek/deepseek-v4-flash': 'go',\n 'deepseek/deepseek-v4-flash-vision-exp': 'go',\n 'deepseek/deepseek-v4-pro': 'go',\n 'gpt-5.6-luna': 'go', // command-code@1.64.0; the opensource-category GPT-6, on every plan including\n // Go, unlike its premium-category siblings Sol (Pro) and Astra (Provider/Max).\n 'gpt-6-luna': 'go',\n // command-code@1.42.0 added the free LongCat 2.0 on every plan; that promo\n // ended 2026-09-19 and the catalog renamed the id to the paid\n // `meituan/LongCat-2.0` ($0.30/$1.20/$0.006), which keeps this slot. The CLI\n // followed in command-code@1.58.0, marking the retired `:free` sibling\n // `hidden`, so its registry now agrees with the catalog this map is keyed by.\n 'meituan/LongCat-2.0': 'go',\n // command-code@1.82.2; the paid successor of the retired\n // `ling-3.1-flash:free` promo. The pricing page's embedded availability\n // grants every tier (individual-go through teams-pro) — the \"all\":true shape\n // shared with its `ling-3.0-flash-sante:free` predecessor.\n 'inclusionai/ling-3.1-flash': 'go',\n // command-code@1.44.0; on every plan including Go, like its 1.2 Contributor\n // sibling.\n 'meta/muse-spark-1.2-contributor': 'go',\n 'meta/muse-spark-1.3-contributor': 'go',\n // 2026-10-15; individual-go true (Go and every higher tier), the same\n // \"all\":true availability shape as its Muse siblings.\n 'meta/muse-spark-open': 'go',\n // command-code@1.75.0; the pricing page's embedded availability grants every\n // tier (individual-go through teams-pro) — the \"all\":true shape shared by the\n // Qwen 3.8 family above.\n 'mistral/mistral-large-4': 'go',\n\n 'moonshotai/Kimi-K2.5': 'go',\n 'moonshotai/Kimi-K2.6': 'go',\n 'moonshotai/Kimi-K2.7-Code': 'go',\n 'moonshotai/Kimi-K2.7-Code-Highspeed': 'go',\n 'moonshotai/Kimi-K3': 'go',\n 'nvidia/nemotron-3-ultra-550b-a55b': 'go',\n // 2026-10-14; individual-go true, the \"all\":true shape shared by the rest of\n // the open-weight Nemotron family.\n 'nvidia/nemotron-3.5-super-vl': 'go',\n 'poolside/laguna-s-2.1-free': 'go',\n // 2026-10-16, first seen at the 1.84.0 sync: the free Beam preview is the one\n // new id the DEFAULT catalog view serves (93 ids), so it lands here. This map\n // tracks that view: the eight `hidden:true` rows of `?view=client` do not\n // belong here, unlike `KNOWN_NON_ZDR_MODELS`, which carries their union (see\n // the decision record, chapter 7).\n 'reflection/beam:free': 'go',\n 'stepfun/Step-3.5-Flash': 'go',\n 'stepfun/Step-3.7-Flash': 'go',\n // command-code@1.60.0; every tier, and listed by the Go/GOAT/Pro/Max plan\n // pages alike — the superset chain this map encodes.\n 'stepfun/Step-5-Preview': 'go',\n // 2026-10-15; the free Cat Jam stealth preview, individual-go true like its\n // Glyph Cluster sibling, whose zero-credit deal also makes it lead the picker.\n 'stealth/cat-jam:free': 'go',\n // command-code@1.79.0 (\"Add Glyph Cluster as a free model, 100 requests a\n // day\"); the pricing page's embedded availability grants every tier\n // (individual-go through teams-pro) — the \"all\":true shape shared by the Ling\n // free models above. Its zero-credit deal (see KNOWN_DEALS) also makes it lead\n // the picker.\n 'stealth/glyph-cluster:free': 'go',\n 'tencent/hy3-paid': 'go',\n 'tencent/hy4-preview': 'go',\n 'thinkingmachines/inkling': 'go',\n 'thinkingmachines/inkling-small': 'go',\n 'xai/grok-4.5': 'go',\n 'xiaomi/mimo-v2.5': 'go',\n 'xiaomi/mimo-v2.5-pro': 'go',\n // command-code@1.62.0 added the MiMo V2.6 family; these two are on every tier\n // (the Go plan page lists both), while the Pro UltraSpeed sibling is GOAT —\n // individual-go is what separates them.\n 'xiaomi/mimo-v2.6-flash': 'go',\n 'xiaomi/mimo-v2.6-pro': 'go',\n 'z-ai/glm-5.3-flash': 'go',\n // command-code@1.57.0; the \"all\":true shape shared with its\n // `z-ai/glm-5.3-flash` sibling.\n 'z-ai/glm-5.3-flashx': 'go',\n 'zai-org/GLM-5': 'go',\n 'zai-org/GLM-5.1': 'go',\n 'zai-org/GLM-5.2': 'go',\n 'zai-org/GLM-5.2-Fast': 'go',\n 'zai-org/GLM-5.3': 'go',\n // --- GOAT (10 more) ---\n // command-code@1.79.2 lowers the 1.78.0 Pro gate to GOAT: individual-go\n // remains false, individual-goat and all higher tiers are true.\n 'claude-haiku-5-5': 'goat',\n // command-code@1.68.0; individual-go false, individual-goat true — \"Available\n // on GOAT and above\", one tier ABOVE its `claude-sonnet-5` predecessor, which\n // sits in the Pro block below.\n 'claude-sonnet-5-5': 'goat',\n 'google/gemini-3.7-flash': 'goat',\n // command-code@1.43.0; \"Available on GOAT and above\", like the rest of the\n // Gemini Flash family.\n 'google/gemini-3.8-flash': 'goat',\n 'gpt-5.6-sol': 'goat',\n 'meta/muse-spark-1.2': 'goat',\n // command-code@1.44.0; \"Available on GOAT and above\", like the 1.2/1.1 models.\n 'meta/muse-spark-1.3': 'goat',\n 'xai/grok-4.6': 'goat',\n // command-code@1.59.0; \"Available on GOAT and above\" (individual-go false).\n 'xai/grok-4.7': 'goat',\n // command-code@1.62.0; GOAT and above, the same split as its Grok 4.7\n // sibling. Its two cheaper V2.6 siblings are Go, above.\n 'xiaomi/mimo-v2.6-pro-ultraspeed': 'goat',\n // --- Pro (15 more) ---\n 'claude-haiku-4-5-20251001': 'pro',\n 'claude-sonnet-4-6': 'pro',\n 'claude-sonnet-5': 'pro',\n // command-code@1.82.0; individual-go / go-v1 / goat all false, Pro and every\n // higher tier true — one tier above the Gemini Flash family above it.\n 'google/gemini-4-argon': 'pro',\n 'google/gemini-3.1-flash-lite': 'pro',\n 'google/gemini-3.5-flash': 'pro',\n 'google/gemini-3.5-flash-lite': 'pro',\n 'google/gemini-3.6-flash': 'pro',\n 'gpt-5.3-codex': 'pro',\n 'gpt-5.4': 'pro',\n 'gpt-5.4-mini': 'pro',\n 'gpt-5.5': 'pro',\n 'gpt-5.6-terra': 'pro',\n // command-code@1.64.0; Pro and above (individual-go/goat false).\n 'gpt-6-sol': 'pro',\n 'meta/muse-spark-1.1': 'pro',\n // --- Provider (8) ---\n // command-code@1.40.0; Provider/Max exactly like its `claude-fable-5`\n // predecessor — individual-provider/max/ultra and teams-pro only.\n 'claude-fable-5-1': 'provider',\n 'claude-fable-5': 'provider',\n 'claude-opus-4-7': 'provider',\n 'claude-opus-4-8': 'provider',\n // command-code@1.64.0; Provider API only (go/goat/pro/pro-v1 all false), and\n // the catalog serves it with supported_endpoints ['/messages'] — the Claude\n // route, which the adapter's `claude-*` prefix rule already sends down the\n // CLI transport.\n 'claude-opus-5-5': 'provider',\n 'claude-opus-5': 'provider',\n // command-code@1.49.0; on Max.\n 'gpt-6-astra': 'provider',\n 'sakana/fugu-ultra': 'provider',\n // --- Max (2) ---\n // command-code@1.71.0; the FIRST Max-only model in this catalog and the only\n // one whose minimum plan is `max`: the embedded availability sets every lower\n // tier false (individual-go / go-v1 / goat / pro / pro-v1 / provider all\n // false) and only individual-max, individual-ultra and teams-pro true.\n // `PLAN_ORDER` already carries `max` above `provider`, so the picker sorts it\n // last without a change there (plan-tiers.ts).\n 'gpt-6.1-sol': 'max',\n // command-code@1.80.0; the same Max-and-above availability as `gpt-6.1-sol`\n // (every lower tier false, only individual-max / individual-ultra /\n // teams-pro true) and the note \"Available on Max and above.\"\n 'meta/muse-wonder-1.0': 'max',\n}\n\n/**\n * Whether a model is free (requests cost no credits), per the pricing page's\n * deals (`KNOWN_DEALS` `free: true`). Free models lead the picker regardless\n * of tier — they are usable by every account, so they are the best default\n * candidates.\n */\nexport function isFreeModel(modelId: string): boolean {\n return KNOWN_DEALS[modelId]?.free === true\n}\n\n/**\n * Comparator for the model picker: free models first (zero credit cost, usable\n * by every account), then by plan tier (lowest first), then by model name,\n * then by id as a tiebreak. Models with no known plan sort last.\n */\nexport function compareByPlan(\n a: { id: string; name: string },\n b: { id: string; name: string },\n): number {\n const freeDelta = Number(isFreeModel(b.id)) - Number(isFreeModel(a.id))\n if (freeDelta !== 0) return freeDelta\n const pa = PLAN_ORDER[KNOWN_PLANS[a.id] ?? ''] ?? Number.MAX_SAFE_INTEGER\n const pb = PLAN_ORDER[KNOWN_PLANS[b.id] ?? ''] ?? Number.MAX_SAFE_INTEGER\n if (pa !== pb) return pa - pb\n const nameDiff = a.name.localeCompare(b.name)\n if (nameDiff !== 0) return nameDiff\n return a.id.localeCompare(b.id)\n}\n\n/**\n * Subscription plan table, synced from the official CLI bundle's plan maps\n * (located by the `\"individual-go\"` key in `dist/cli.mjs`, re-verified unchanged\n * through command-code@1.73.0): subscription `planId` prefix → display name and\n * the plan's monthly credit total. This is the account's own subscription\n * (from `/alpha/billing/subscriptions`) — distinct from {@link KNOWN_PLANS},\n * which maps catalog models to their minimum tier.\n *\n * `tierWeight` is plugin-added (not from the CLI maps): the plan's rank on\n * the {@link PLAN_ORDER} scale, used by the picker's plan filter\n * ({@link modelVisibleInPlan}) to hide models above the account's tier.\n */\nexport const KNOWN_SUBSCRIPTION_PLANS: Readonly> = {\n 'individual-go': { name: 'Go', monthlyCredits: 10, tierWeight: 0 },\n // command-code@1.69.0 (\"Go plan moves to per-model credits\") added this second\n // Go row to the CLI's plan maps. Same display name and monthly total, so\n // `tierWeight` stays 0 alongside `individual-go` — exactly how the pre-existing\n // `individual-pro-v1` sits at Pro's weight 2. Resolution is longest-prefix\n // match (see below), so the explicit `-v1` suffix still wins over the base.\n 'individual-go-v1': { name: 'Go', monthlyCredits: 10, tierWeight: 0 },\n 'individual-goat': { name: 'GOAT', monthlyCredits: 70, tierWeight: 1 },\n 'individual-pro': { name: 'Pro', monthlyCredits: 30, tierWeight: 2 },\n 'individual-pro-v1': { name: 'Pro', monthlyCredits: 80, tierWeight: 2 },\n 'individual-provider': { name: 'Provider', monthlyCredits: 15, tierWeight: 3 },\n 'individual-max': { name: 'Max', monthlyCredits: 150, tierWeight: 4 },\n 'individual-ultra': { name: 'Ultra', monthlyCredits: 300, tierWeight: 4 },\n 'teams-pro': { name: 'Teams Pro', monthlyCredits: 40, tierWeight: 2 },\n}\n\n/** Plan-id prefixes, longest first — the CLI's prefix-match order. */\nconst SUBSCRIPTION_PLAN_PREFIXES = Object.keys(KNOWN_SUBSCRIPTION_PLANS).sort((a, b) => b.length - a.length)\n\n/**\n * Resolve a subscription `planId` (e.g. `individual-pro-v1`) to its display\n * name and monthly credit total, mirroring the CLI's `getPlanInfo`:\n * normalize (lowercase, `_` → `-`), then longest-prefix match so\n * `individual-pro-v1` wins over `individual-pro`. Unknown ids return\n * `undefined`.\n */\nexport function subscriptionPlanInfo(planId: string): { name: string; monthlyCredits: number; tierWeight: number } | undefined {\n const normalized = planId.toLowerCase().replace(/_/g, '-')\n const prefix = SUBSCRIPTION_PLAN_PREFIXES.find((candidate) => normalized.startsWith(candidate))\n return prefix === undefined ? undefined : KNOWN_SUBSCRIPTION_PLANS[prefix]\n}\n\n/**\n * The billing facts the picker's plan filter needs, fetched by mirroring the\n * CLI's `createBilling` flow (whoami → orgId, then `/alpha/billing/subscriptions`\n * for the plan id and `/alpha/billing/credits` for the on-demand balances).\n */\nexport interface CommandCodeBillingAccess {\n /** Account plan tier weight on the {@link PLAN_ORDER} scale; undefined when the plan is unknown. */\n tierWeight: number | undefined\n /**\n * Purchased + free on-demand credit balance. The official access model\n * (`evaluateModelAccess` in the CLI) allows every model when the account\n * holds any on-demand credits — the plan gate only applies at zero balance.\n */\n onDemandCredits: number\n}\n\n/**\n * Whether the picker lists `modelId` for an account with the given billing\n * access. Fails open at every uncertainty: no billing data, an unknown plan,\n * a non-finite weight (corrupt billing fact), or a model outside\n * {@link KNOWN_PLANS} all keep the model visible — the server remains the\n * final gate (`403 MODEL_NOT_IN_PLAN`).\n */\nexport function modelVisibleInPlan(modelId: string, access: CommandCodeBillingAccess | undefined): boolean {\n if (access === undefined) return true\n if (access.onDemandCredits > 0) return true\n if (access.tierWeight === undefined || !Number.isFinite(access.tierWeight)) return true\n const tier = KNOWN_PLANS[modelId]\n if (tier === undefined) return true\n const weight = PLAN_ORDER[tier]\n if (weight === undefined) return true\n return weight <= access.tierWeight\n}\n\n/**\n * Whether the picker lists `modelId` for a whole POOL of accounts: true when\n * at least one of them includes it. The picker's plan filter is asked this\n * rather than {@link modelVisibleInPlan} for a single account because the pool\n * — not any one account — is what serves a request: keying the list on\n * whichever account rotation happened to reach made models appear and vanish\n * as accounts rotated, and hid models the user's other accounts could run.\n *\n * An account whose facts are unknown counts as \"may include it\" (the same\n * fail-open rule `modelVisibleInPlan` applies one level down), and an empty\n * pool is \"show everything\": hiding a model somebody can run is the one\n * failure this filter must never cause.\n */\nexport function modelVisibleForAnyAccount(\n modelId: string,\n accounts: readonly (CommandCodeBillingAccess | undefined)[] | undefined,\n): boolean {\n if (accounts === undefined || accounts.length === 0) return true\n return accounts.some((access) => modelVisibleInPlan(modelId, access))\n}\n\n/**\n * Active pricing deals per the official pricing page\n * (`/docs/resources/pricing-limits#deals`). Each entry records the model's\n * promotional label and — critically — when it expires, so the picker never\n * shows a stale discount after the plugin's snapshot has gone out of date.\n *\n * - `expiresAt` is an ISO timestamp. When it is in the past (checked at\n * render time against `Date.now()`), the deal label is hidden until the\n * snapshot is refreshed from the official page. `undefined` means\n * \"no expiry\" (permanent).\n * - `free` marks models whose requests cost no credits, shown as a `FREE`\n * badge; it degrades to a plain discount once the deal lapses.\n *\n * A deal whose promo ENDS is removed here rather than left to lapse on\n * `expiresAt`: the pricing page drops the entry, so a lapsed row would badge a\n * model the catalog now serves at full price (Grok 4.7 reverts to $2.00 in /\n * $6.00 out after its 2026-09-27 window).\n *\n * Keep in sync with the official pricing page when deals change (see the\n * dsh-commandcode-upstream skill).\n */\nexport interface KnownDeal {\n /** Promotional label, e.g. \"50% off\" or \"2× usage\". */\n label: string\n /** Deal end date (ISO). `undefined` = permanent / no expiry. */\n expiresAt?: string\n /** Model is free (requests cost no credits). */\n free?: boolean\n}\n\nexport const KNOWN_DEALS: Readonly> = {\n 'MiniMaxAI/MiniMax-M3': { label: '50% off' },\n 'xiaomi/mimo-v2.5-pro': { label: '99% off' },\n 'xiaomi/mimo-v2.5': { label: '98% off' },\n 'poolside/laguna-s-2.1-free': { label: 'FREE', free: true },\n // 2026-10-16 (1.84.0 sync); the third live free preview in this map.\n // \"Free while capacity lasts\", no daily request limit, and — unlike its Glyph\n // Cluster sibling — the page states outright that it is \"Not routed under\n // ZDR\", which matches the catalog verdict in `KNOWN_NON_ZDR_MODELS`. The page\n // publishes it at a literal zero, so it gets no row in the vendored price\n // table either.\n 'reflection/beam:free': { label: 'FREE', free: true },\n // 2026-10-15; the second live stealth preview, \"Free while the stealth\n // preview lasts\" with no published end date — the same permanent-style deal\n // as Glyph Cluster above, and likewise served at a literal zero by the page.\n // Unlike Glyph Cluster it is text-only and not ZDR-routed (see\n // `KNOWN_NON_ZDR_MODELS`).\n 'stealth/cat-jam:free': { label: 'FREE', free: true },\n // `inclusionai/ling-3.1-flash:free` (command-code@1.70.0, 100% off \"Free\n // while it lasts\", the `ling-3.0-flash-sante:free` successor) left this map\n // on 2026-10-15: command-code@1.82.2 ships the row as `hidden`, drops its\n // selectable efforts, and the model is gone from both\n // `/provider/v1/models` and the pricing page — the same retirement path\n // `meituan/LongCat-2.0:free` and `stealth/space-bunny-alpha` took. Its paid\n // graduation `inclusionai/ling-3.1-flash` is priced normally and carries no\n // deal.\n // `inclusionai/ling-3.0-flash-sante:free` followed it out on 2026-10-16 with\n // the 1.82.4 catalog migration: it had already left the live catalog and the\n // pricing page, and it is absent from the 1.82.4 artifact's embedded snapshot\n // as well, so no official source names it any more.\n // command-code@1.79.0 (\"Add Glyph Cluster as a free model, 100 requests a\n // day\"): 100% off \"Free while the preview lasts\", the same 100-requests-a-day\n // cap as its Ling predecessors and likewise no published end date, so no\n // `expiresAt`. The pricing page publishes it at a literal zero, which\n // `modelPriceTable()` serves from this deal, so it gets no row in the vendored\n // price table either. Unlike those free models it is NOT ZDR-routed — the\n // page's own tip says so outright (see `KNOWN_NON_ZDR_MODELS`).\n 'stealth/glyph-cluster:free': { label: 'FREE', free: true },\n // `stealth/space-bunny-alpha` (command-code@1.65.0, 100% off \"Free while the\n // stealth preview lasts\", auto-applied, no published end date) left this map\n // on 2026-10-06: command-code@1.74.3 hides the model, the catalog and the\n // pricing page dropped it, and the official Desktop changelog says \"Remove\n // Space Bunny Alpha from the model picker\". Its twin Pixel Canary left the\n // same way when command-code@1.73.1 retired it.\n}\n\n/**\n * Models with time-of-day (peak/off-peak) pricing, per the official pricing\n * page (`/docs/resources/pricing-limits`). Since 2026-08-16 16:00 UTC, DeepSeek\n * charges by the hour: peak hours are 01:00–04:00 and 06:00–10:00 UTC (7h per\n * weekday, full price) **Monday to Friday only**; the other 17 hours of a\n * weekday and every hour of Saturday/Sunday (UTC) are off-peak at half price.\n * Exactly five models carry the page's `timeOfDay` block (the five rows below).\n * The picker shows the *current* state as a compact label (`Peak`/`Half`)\n * matching the English noun style of the other markers (`Image`, `FREE`), so a\n * developer can tell at a glance whether calling the model right now is cheap\n * or expensive.\n *\n * Extraction caution: the rendered HTML rows are a trap. Each annotation div\n * sits inside its OWN row's container, immediately before the NEXT row starts,\n * so flattening the page to text makes every annotation look like it belongs\n * to the model printed after it — that is how `deepseek/deepseek-v4-flash-fast`\n * was wrongly added here (its row is flat-priced at $0.28/$0.56/$0.07 and has\n * no `timeOfDay` block). Trust the embedded JSON's `timeOfDay` membership and\n * the 2× price relation, never the flat-text neighbor. A rate that is\n * internally consistent can still be the wrong row (the V4 Flash Vision (exp)\n * variant is priced from the page's own `timeOfDay` block, not from 2× its own\n * off-peak figures), which is why the vendored price table\n * (`./model-prices.ts`) is synced from the page and not hand-kept.\n *\n * Keep in sync with the official pricing page when the model set, the peak\n * windows, or the weekday rule change (see the dsh-commandcode-upstream skill).\n */\nexport const KNOWN_PEAK_PRICING: ReadonlySet = new Set([\n 'deepseek/deepseek-v4-pro',\n 'deepseek/deepseek-v4-flash',\n 'deepseek/deepseek-v4-flash-vision-exp',\n // command-code@1.53.0; the same `timeOfDay` block as the other three\n // (off-peak $0.15/$0.60, peak $0.30/$1.20, 01–04 & 06–10 UTC Mon–Fri).\n 'deepseek/deepseek-v4.1-flash',\n // command-code@1.67.0; the same 01–04 & 06–10 UTC Mon–Fri windows and the same\n // 2026-08-16T16:00Z effective date, at its own rates (off-peak\n // $0.16/$0.58/$0.016, peak $0.32/$1.16/$0.032) — note these are NOT 2× the\n // sibling's, so this row must come from its own `timeOfDay` block.\n 'deepseek/deepseek-v4.1-flash-fast',\n])\n\n/**\n * Peak hours (UTC, hour-of-day range end-exclusive): 01–03 and 06–09.\n * Weekday-only — see `peakPricingState()`; weekends are fully off-peak.\n *\n * Exported because the vendored price table (`./model-prices.ts`) ships these\n * windows to the browser with the table itself: the composer prices a session\n * against the very schedule this snapshot knows rather than restating it, so\n * there is one place to update when the windows move.\n */\nexport const PEAK_HOUR_RANGES: ReadonlyArray = [\n [1, 4],\n [6, 10],\n]\n\n/**\n * Whether `now` (defaults to `Date.now()`) falls inside a peak-pricing window,\n * ignoring which model is asking. Peak rates apply Monday–Friday (UTC) only,\n * so a weekend timestamp is off-peak even inside {@link PEAK_HOUR_RANGES}.\n *\n * Model-independent on purpose: `peakPricingState()` adds the membership test\n * on top for the picker's label, while the price table selects peak rates from\n * a row's own `peak` block — so a model whose catalog id spelling differs from\n * the one in {@link KNOWN_PEAK_PRICING} still gets the right half of the day.\n */\nexport function isPeakPricingHour(now: number = Date.now()): boolean {\n return peakHour(now, PEAK_HOUR_RANGES)\n}\n\n/**\n * As {@link isPeakPricingHour}, plus the {@link KNOWN_PEAK_PRICING} membership\n * test; `undefined` for models outside the snapshot.\n */\nexport function peakPricingState(\n modelId: string,\n now: number = Date.now(),\n): 'peak' | 'off-peak' | undefined {\n if (!KNOWN_PEAK_PRICING.has(modelId)) return undefined\n return isPeakPricingHour(now) ? 'peak' : 'off-peak'\n}\n\n/**\n * Compact label for the current peak/off-peak state: `Peak` (full price) or\n * `Half` (off-peak, half price). These English nouns match the picker's other\n * markers (`Go`, `Image`, `FREE`), and since they appear only on time-of-day\n * priced models they double as a \"priced by the hour\" signal. Returns undefined\n * for models without time-of-day pricing.\n */\nexport function peakPricingLabel(\n modelId: string,\n now: number = Date.now(),\n): string | undefined {\n const state = peakPricingState(modelId, now)\n if (state === undefined) return undefined\n return state === 'peak' ? 'Peak' : 'Half'\n}\n\n/**\n * Official display label for a model's minimum plan, or undefined for models\n * outside the snapshot (e.g. future catalog additions).\n */\nexport function planLabel(modelId: string): string | undefined {\n const plan = KNOWN_PLANS[modelId]\n return plan === undefined ? undefined : PLAN_LABELS[plan]\n}\n\n/**\n * The active deal label for a model, or undefined when the model has no deal\n * or the deal has expired. Expiry is judged against `now` (defaults to\n * `Date.now()`), so a snapshot that has gone stale stops showing its discount\n * the moment the official end date passes — the user never believes a lapsed\n * deal is still live. Permanent deals (no `expiresAt`) never lapse.\n */\nexport function dealLabel(modelId: string, now: number = Date.now()): string | undefined {\n const deal = KNOWN_DEALS[modelId]\n if (deal === undefined) return undefined\n if (deal.expiresAt !== undefined && now >= Date.parse(deal.expiresAt)) return undefined\n return deal.label\n}\n\n/**\n * Compact human-readable context window, e.g. `1_000_000 -> \"1M\"`,\n * `256_000 -> \"256K\"`, `262_144 -> \"262K\"` (floor to the nearest K).\n * Returns undefined for unknown/absent sizes; values under 1K render raw.\n */\nexport function formatContext(contextWindow: number | undefined): string | undefined {\n if (contextWindow === undefined || !Number.isFinite(contextWindow) || contextWindow <= 0) {\n return undefined\n }\n if (contextWindow >= 1_000_000) {\n const m = contextWindow / 1_000_000\n // Round to one decimal only when it adds information: 1_048_576 -> \"1M\",\n // 1_050_000 -> \"1.1M\".\n const rounded = Math.round(m * 10) / 10\n return `${Number.isInteger(rounded) ? rounded : rounded.toFixed(1)}M`\n }\n if (contextWindow < 1_000) return String(Math.floor(contextWindow))\n return `${Math.floor(contextWindow / 1_000)}K`\n}\n\n/**\n * Compact one-line summary for the model picker: plan tier, then any active\n * deal (discount or FREE), then the current peak/off-peak state (`Peak`/`Half`)\n * for time-of-day-priced models, then `Image` for Vision-capable models, then\n * the context window. Text-only models simply omit the Image marker — \"Text\n * only\" adds nothing the picker needs to show.\n */\nexport function capabilityDescription(\n modelId: string,\n contextWindow?: number,\n now: number = Date.now(),\n): string {\n const parts: string[] = []\n const plan = planLabel(modelId)\n if (plan !== undefined) parts.push(plan)\n const deal = dealLabel(modelId, now)\n if (deal !== undefined) parts.push(deal)\n const peak = peakPricingLabel(modelId, now)\n if (peak !== undefined) parts.push(peak)\n if (KNOWN_IMAGE_MODELS.has(modelId)) parts.push('Image')\n const ctx = formatContext(contextWindow)\n if (ctx !== undefined) parts.push(ctx)\n return parts.join(' · ')\n}\n","/**\n * Vendored Command Code model prices: the per-token rates the official pricing\n * page publishes, which is what lets the composer price a session in dollars.\n * Every figure is USD per 1,000,000 tokens.\n *\n * Source: the model array embedded in\n * https://commandcode.ai/docs/resources/pricing-limits, read out of its\n * Next.js flight payload. That payload is the only place the `timeOfDay` and\n * `contextTiers` blocks exist, so it is what the generator parses — but it is\n * NOT trusted on its own: the generator also reads the page's rendered table\n * and reports any rate where the two disagree. A figure can be internally\n * consistent and still be the wrong row (this table once carried\n * `0.22 → 0.44` for a model the page prices `0.15 → 0.30` — exactly the 2× the\n * peak/off-peak rule promises), so the cross-check exists to catch that class\n * of error rather than to restate the invariant.\n *\n * Three buckets are always published (inputCost, outputCost, cacheReadCost);\n * cacheWriteCost is published for a minority of models. A model without the\n * key has UNPRICED cache-write tokens: never invent a multiplier for them, and\n * never fold them into the input rate. A published `0` is a different fact and\n * is kept as a real zero — see the note on the GPT rows below.\n *\n * Time-of-day models store a `peak` triplet only. The page repeats the flat\n * rates inside its own offPeak block, so the top-level rates ARE the off-peak\n * rates and only the peak override is worth keeping — the generator asserts\n * that equality and refuses to emit otherwise. Whether \"now\" counts as peak is\n * decided by `isPeakPricingHour()` in ./capabilities.ts, on the same\n * Monday-Friday UTC schedule the model picker labels.\n *\n * Context-tiered models carry every band, with inclusive prompt-token bounds\n * and an unbounded final band. The durable cost projection selects each\n * request's band from its input/cache buckets, never from session totals.\n *\n * Discounted rows carry both price sets. The page publishes a deal's\n * PROMOTIONAL rates as the row's ordinary figures and its pre-discount\n * `listRates` alongside, so the generator copies both and the table picks\n * between them with `dealLabel()`'s clock. That keeps a lapsed discount from\n * pricing a session below what the provider now charges — the same \"a stale\n * snapshot never shows a lapsed discount\" rule the picker badge follows, applied\n * to dollars rather than to a label. The page's own `discountPercent` is NOT\n * used for this: it is a marketing figure that does not divide out (MiMo V2.5's\n * \"98% off\" prices three buckets at 5.7×, 14.3× and 57× of list).\n *\n * Do not hand-edit the table below: run `node scripts/sync-model-prices.mjs`,\n * which re-reads the page, asserts the structure and the off-peak equality,\n * prints cross-check warnings for a human, and rewrites only the rows.\n * `--check` reports drift without writing (exit 1 on drift, exit 2 when the\n * page could not be read, so a network failure never reads as \"up to date\").\n * Everything else in this file — this doc, the types, the slug rules, the\n * table builder — is written by hand and survives that rewrite.\n *\n * @module dsh-commandcode-provider/model-prices\n */\n\nimport type { CommandCodeModelPrice, CommandCodeModelRates, CommandCodePriceTable } from './usage-wire.ts'\nimport { KNOWN_PLANS, PEAK_HOUR_RANGES, dealLabel, isFreeModel } from './capabilities.ts'\nimport { PLAN_ORDER } from './plan-tiers.ts'\n\n/** One pricing-page context band: the rates charged inside `maxContext` tokens. */\ninterface ModelPriceContextTier {\n readonly maxContext?: number\n readonly rates: readonly number[]\n /**\n * The band's pre-discount rates, present only for a row carrying a deal. See\n * {@link ModelPriceRow.listRates}.\n */\n readonly listRates?: readonly number[]\n}\n\n/**\n * A model's per-model monthly allowance, in USD, per plan tier.\n *\n * This is the page's `planAllowanceUsd`: how much of the plan's monthly credit\n * pool this ONE model may draw. It is not extra money — every allowance draws\n * on the same pool. Go、GOAT、Pro 按官网各自的数字展示;旧来源缺少 Go\n * 时保留缺失状态,零额度也不等于接口权限。\n * Max/Provider 不借用相邻套餐的额度。Deals are baked in:\n * `MiniMaxAI/MiniMax-M3` carries `$47 / $57` precisely because its 2× promotion\n * is already folded into the allowance.\n */\nexport interface ModelAllowance {\n readonly go?: number\n readonly goat: number\n readonly pro: number\n}\n\n/**\n * The plan tiers a per-model allowance exists for, cheapest first. Ordering\n * matters: {@link allowanceTierForWeight} matches a tier weight against these\n * rather than against hard-coded numbers, so this table and the subscription\n * table cannot drift apart silently.\n */\nconst ALLOWANCE_TIERS = ['go', 'goat', 'pro'] as const\n\n/**\n * Which allowance bracket a plan-tier weight belongs to, or undefined when that\n * plan has no per-model allowance.\n *\n * Weights come from `KNOWN_SUBSCRIPTION_PLANS` (go 0 · goat 1 · pro 2 ·\n * provider 3 · max/ultra 4) and {@link PLAN_ORDER} is the same scale, which is\n * what makes the lookup exact: Provider、Max、Ultra\n * 没有本地额度;缺项时不能用相邻套餐的数字代替。\n */\nexport function allowanceTierForWeight(\n tierWeight: number | undefined,\n): keyof ModelAllowance | undefined {\n if (tierWeight === undefined) return undefined\n return ALLOWANCE_TIERS.find((tier) => PLAN_ORDER[tier] === tierWeight)\n}\n\n/**\n * One pricing-page row. `rates` is `[input, output, cacheRead, cacheWrite?]`\n * and `peak` is the `[input, output, cacheRead]` triplet charged inside the\n * peak windows. All figures are USD per 1,000,000 tokens.\n *\n * `listRates` appears only on rows whose page record carries a `deal`: those\n * `rates` are the PROMOTIONAL figures, and `listRates` is what the row reverts\n * to when the deal lapses. {@link modelPriceTable} picks between the two with\n * the same clock {@link dealLabel} uses, so a discount that has expired stops\n * pricing a session at the promotional rate even before the next sync — the\n * badge and the dollars always agree. A permanent deal (no `expiresAt`) never\n * lapses, and a row with no `listRates` has nothing to fall back to.\n *\n * `allowance` is a different KIND of number from everything else here: dollars\n * per month, not dollars per million tokens. It never enters the price table —\n * {@link modelAllowanceFor} serves it to the settings page instead.\n */\ninterface ModelPriceRow {\n readonly id: string\n readonly rates: readonly number[]\n readonly listRates?: readonly number[]\n readonly peak?: readonly number[]\n readonly allowance?: ModelAllowance\n readonly contextTiers?: readonly ModelPriceContextTier[]\n}\n\n/**\n * Every price row the page publishes, ordered by its own slug.\n *\n * Note on the GPT rows: `gpt-5.3-codex`, `gpt-5.4`, `gpt-5.4-mini` and\n * `gpt-5.5` carry a LITERAL `cacheWriteCost: 0` — a different fact from a\n * missing key, because `ratesOf()` keeps it and the readout then charges\n * cache writes at zero instead of reporting them unpriced. That is what the\n * page's JSON says; its rendered column shows `—` for exactly these four while\n * rendering a genuine zero as `$0.00` elsewhere, so the page contradicts\n * itself. The table stays faithful to the machine-readable source and the\n * discrepancy is recorded in AGENTS.md rather than papered over here.\n */\nconst MODEL_PRICE_ROWS: readonly ModelPriceRow[] = [\n { id: 'claude-fable-5', rates: [10, 50, 1, 12.5], allowance: { go: 6, goat: 20, pro: 20 } },\n { id: 'claude-fable-5-1', rates: [10, 50, 0.25, 12.5], allowance: { go: 6, goat: 20, pro: 20 } },\n { id: 'claude-haiku-4-5', rates: [1, 5, 0.1, 1.25], allowance: { go: 6, goat: 20, pro: 20 } },\n { id: 'claude-haiku-5-5', rates: [0.1, 0.5, 0.01, 0.125], allowance: { go: 6, goat: 20, pro: 30 }, contextTiers: [{\"maxContext\":100000,\"rates\":[0.1,0.5,0.01,0.125]},{\"rates\":[0.5,2.5,0.05,0.625]}] },\n { id: 'claude-opus-4-6', rates: [5, 25, 0.5, 6.25], allowance: { go: 6, goat: 20, pro: 20 } },\n { id: 'claude-opus-4-7', rates: [5, 25, 0.5, 6.25], allowance: { go: 6, goat: 20, pro: 20 } },\n { id: 'claude-opus-4-8', rates: [5, 25, 0.5, 6.25], allowance: { go: 6, goat: 20, pro: 20 } },\n { id: 'claude-opus-5', rates: [5, 25, 0.5, 6.25], allowance: { go: 6, goat: 20, pro: 20 } },\n { id: 'claude-opus-5-5', rates: [4, 20, 0.2, 5], allowance: { go: 6, goat: 20, pro: 20 } },\n { id: 'claude-sonnet-4-6', rates: [3, 15, 0.3, 3.75], allowance: { go: 6, goat: 20, pro: 20 } },\n { id: 'claude-sonnet-5', rates: [2, 10, 0.2, 2.5], allowance: { go: 6, goat: 20, pro: 20 } },\n { id: 'claude-sonnet-5-5', rates: [2, 10, 0.1, 2.5], allowance: { go: 6, goat: 10, pro: 20 } },\n { id: 'deepseek-v4-flash', rates: [0.15, 0.6, 0.003], peak: [0.3, 1.2, 0.006], allowance: { go: 6, goat: 60, pro: 70 } },\n { id: 'deepseek-v4-flash-fast', rates: [0.28, 0.56, 0.07], allowance: { go: 8, goat: 20, pro: 30 } },\n { id: 'deepseek-v4-flash-vision-exp', rates: [0.15, 0.6, 0.003], peak: [0.3, 1.2, 0.006], allowance: { go: 6, goat: 20, pro: 30 } },\n { id: 'deepseek-v4-pro', rates: [0.66, 1.98, 0.022], peak: [1.32, 3.96, 0.044], allowance: { go: 6, goat: 20, pro: 30 } },\n { id: 'deepseek-v4.1-flash', rates: [0.15, 0.6, 0.003], peak: [0.3, 1.2, 0.006], allowance: { go: 10, goat: 80, pro: 90 } },\n { id: 'deepseek-v4.1-flash-fast', rates: [0.16, 0.58, 0.016], peak: [0.32, 1.16, 0.032], allowance: { go: 6, goat: 60, pro: 70 } },\n { id: 'fugu-ultra', rates: [5, 30, 0.5], allowance: { go: 6, goat: 20, pro: 20 } },\n { id: 'gemini-3.1-flash-lite', rates: [0.25, 1.5, 0.03], allowance: { go: 6, goat: 20, pro: 20 } },\n { id: 'gemini-3.5-flash', rates: [1.5, 9, 0.15], allowance: { go: 6, goat: 20, pro: 20 } },\n { id: 'gemini-3.5-flash-lite', rates: [0.3, 2.5, 0.03], allowance: { go: 6, goat: 20, pro: 20 } },\n { id: 'gemini-3.6-flash', rates: [1.5, 7.5, 0.15], allowance: { go: 6, goat: 20, pro: 20 } },\n { id: 'gemini-3.7-flash', rates: [1.5, 7.5, 0.15, 0.08334], allowance: { go: 6, goat: 40, pro: 50 } },\n { id: 'gemini-3.8-flash', rates: [1.5, 7.5, 0.15], allowance: { go: 6, goat: 40, pro: 50 } },\n { id: 'gemini-4-argon', rates: [2, 10, 0.1], allowance: { go: 6, goat: 20, pro: 20 } },\n { id: 'glm-5', rates: [1, 3.2, 0.2], allowance: { go: 6, goat: 20, pro: 30 } },\n { id: 'glm-5.1', rates: [1.4, 4.4, 0.26], allowance: { go: 6, goat: 20, pro: 30 } },\n { id: 'glm-5.2', rates: [1.4, 4.4, 0.26], allowance: { go: 10, goat: 70, pro: 80 } },\n { id: 'glm-5.2-fast', rates: [3, 10.25, 0.5], allowance: { go: 9, goat: 20, pro: 30 } },\n { id: 'glm-5.3', rates: [1.4, 4.4, 0.26], allowance: { go: 10, goat: 20, pro: 30 } },\n { id: 'glm-5.3-flash', rates: [0.15, 0.5, 0.03], allowance: { go: 10, goat: 80, pro: 90 } },\n { id: 'glm-5.3-flashx', rates: [0.37, 1.25, 0.075], allowance: { go: 6, goat: 20, pro: 30 } },\n { id: 'gpt-5.3-codex', rates: [2, 8, 0.5, 0], allowance: { go: 6, goat: 20, pro: 20 } },\n { id: 'gpt-5.4', rates: [2.5, 15, 0.25, 0], allowance: { go: 6, goat: 20, pro: 20 } },\n { id: 'gpt-5.4-mini', rates: [0.75, 4.5, 0.075, 0], allowance: { go: 6, goat: 20, pro: 20 } },\n { id: 'gpt-5.5', rates: [5, 30, 0.5, 0], allowance: { go: 6, goat: 20, pro: 20 } },\n { id: 'gpt-5.6-luna', rates: [0.2, 1.2, 0.02, 0.25], allowance: { go: 6, goat: 20, pro: 30 }, contextTiers: [{\"maxContext\":272000,\"rates\":[0.2,1.2,0.02,0.25]},{\"rates\":[0.4,1.8,0.04,0.5]}] },\n { id: 'gpt-5.6-sol', rates: [5, 30, 0.5, 6.25], allowance: { go: 6, goat: 20, pro: 30 }, contextTiers: [{\"maxContext\":272000,\"rates\":[5,30,0.5,6.25]},{\"rates\":[10,45,1,12.5]}] },\n { id: 'gpt-5.6-terra', rates: [2, 12, 0.2, 2.5], allowance: { go: 6, goat: 20, pro: 20 }, contextTiers: [{\"maxContext\":272000,\"rates\":[2,12,0.2,2.5]},{\"rates\":[4,18,0.4,5]}] },\n { id: 'gpt-6-astra', rates: [10, 50, 1, 12.5], allowance: { go: 6, goat: 20, pro: 20 }, contextTiers: [{\"maxContext\":272000,\"rates\":[10,50,1,12.5]},{\"rates\":[20,75,2,25]}] },\n { id: 'gpt-6-luna', rates: [0.1, 0.5, 0.01, 0.125], allowance: { go: 6, goat: 20, pro: 30 }, contextTiers: [{\"maxContext\":272000,\"rates\":[0.1,0.5,0.01,0.125]},{\"rates\":[0.2,0.75,0.02,0.25]}] },\n { id: 'gpt-6-sol', rates: [2, 10, 0.2, 2.5], allowance: { go: 6, goat: 20, pro: 20 }, contextTiers: [{\"maxContext\":272000,\"rates\":[2,10,0.2,2.5]},{\"rates\":[4,15,0.4,5]}] },\n { id: 'gpt-6.1-sol', rates: [2, 10, 0.1, 2.5], allowance: { go: 6, goat: 20, pro: 20 }, contextTiers: [{\"maxContext\":272000,\"rates\":[2,10,0.1,2.5]},{\"rates\":[4,15,0.2,5]}] },\n { id: 'grok-4.5', rates: [2, 6, 0.5], allowance: { go: 6, goat: 20, pro: 30 } },\n { id: 'grok-4.6', rates: [2, 6, 0.5], allowance: { go: 6, goat: 20, pro: 30 }, contextTiers: [{\"maxContext\":200000,\"rates\":[2,6,0.5]},{\"rates\":[4,12,1]}] },\n { id: 'grok-4.7', rates: [2, 6, 0.5], allowance: { go: 6, goat: 20, pro: 30 }, contextTiers: [{\"maxContext\":200000,\"rates\":[2,6,0.5]},{\"rates\":[4,12,1]}] },\n { id: 'inkling', rates: [1, 4.05, 0.17], allowance: { go: 6, goat: 20, pro: 30 } },\n { id: 'inkling-small', rates: [0.5, 1.2, 0.1], allowance: { go: 6, goat: 20, pro: 30 } },\n { id: 'kimi-k2.5', rates: [0.6, 3, 0.1], allowance: { go: 6, goat: 20, pro: 30 } },\n { id: 'kimi-k2.6', rates: [0.95, 4, 0.16], allowance: { go: 6, goat: 20, pro: 30 } },\n { id: 'kimi-k2.7-code', rates: [0.95, 4, 0.19], allowance: { go: 9, goat: 60, pro: 70 } },\n { id: 'kimi-k2.7-code-highspeed', rates: [1.9, 8, 0.38], allowance: { go: 6, goat: 20, pro: 30 } },\n { id: 'kimi-k3', rates: [3, 15, 0.3], allowance: { go: 8, goat: 20, pro: 30 } },\n { id: 'ling-3.1-flash', rates: [0.3, 0.9, 0.06], allowance: { go: 6, goat: 100, pro: 110 } },\n { id: 'longcat-2.0', rates: [0.3, 1.2, 0.006], allowance: { go: 10, goat: 50, pro: 60 } },\n { id: 'mimo-v2.5', rates: [0.14, 0.28, 0.0028], listRates: [0.8, 4, 0.16], allowance: { go: 6, goat: 30, pro: 40 } },\n { id: 'mimo-v2.5-pro', rates: [0.435, 0.87, 0.0036], listRates: [2, 6, 0.4], allowance: { go: 6, goat: 20, pro: 30 } },\n { id: 'mimo-v2.6-flash', rates: [0.14, 0.28, 0.0028], allowance: { go: 6, goat: 20, pro: 30 } },\n { id: 'mimo-v2.6-pro', rates: [0.435, 0.87, 0.0036], allowance: { go: 6, goat: 20, pro: 30 } },\n { id: 'mimo-v2.6-pro-ultraspeed', rates: [4.35, 8.7, 0.036], allowance: { go: 6, goat: 10, pro: 20 } },\n { id: 'minimax-m2.5', rates: [0.3, 1.2, 0.03], allowance: { go: 6, goat: 20, pro: 30 } },\n { id: 'minimax-m2.7', rates: [0.3, 1.2, 0.06], allowance: { go: 6, goat: 20, pro: 30 } },\n { id: 'minimax-m3', rates: [0.3, 1.2, 0.06], listRates: [0.6, 2.4, 0.12], allowance: { go: 8, goat: 47, pro: 57 } },\n { id: 'mistral-large-4', rates: [1.36, 4.18, 0.14], allowance: { go: 10, goat: 40, pro: 50 } },\n { id: 'muse-spark-1.1', rates: [1.25, 4.25, 0.15], allowance: { go: 6, goat: 20, pro: 20 } },\n { id: 'muse-spark-1.2', rates: [1.25, 4.25, 0.15], allowance: { go: 6, goat: 20, pro: 30 } },\n { id: 'muse-spark-1.2-contributor', rates: [0.1, 0.2, 0.002], allowance: { go: 6, goat: 20, pro: 30 } },\n { id: 'muse-spark-1.3', rates: [1.25, 4.25, 0.15], allowance: { go: 6, goat: 20, pro: 30 } },\n { id: 'muse-spark-1.3-contributor', rates: [0.1, 0.2, 0.002], allowance: { go: 6, goat: 20, pro: 30 } },\n { id: 'muse-spark-open', rates: [1.25, 4.25, 0.15], allowance: { go: 6, goat: 20, pro: 30 } },\n { id: 'muse-wonder-1.0', rates: [4, 20, 0.2], allowance: { go: 6, goat: 20, pro: 20 } },\n { id: 'nemotron-3-ultra', rates: [0.6, 2.4, 0.12], allowance: { go: 6, goat: 20, pro: 30 } },\n { id: 'nemotron-3.5-super-vl', rates: [0.2, 0.5, 0.04], allowance: { go: 6, goat: 20, pro: 30 } },\n { id: 'qwen-3.6-max', rates: [1.3, 7.8, 0.26, 1.63], allowance: { go: 6, goat: 20, pro: 30 } },\n { id: 'qwen-3.6-plus', rates: [0.5, 3, 0.1], allowance: { go: 10, goat: 33, pro: 43 }, contextTiers: [{\"maxContext\":256000,\"rates\":[0.5,3,0.1]},{\"rates\":[2,6,0.2]}] },\n { id: 'qwen-3.7-flash', rates: [0.03, 0.13, 0.006, 0.038], allowance: { go: 6, goat: 20, pro: 30 }, contextTiers: [{\"maxContext\":32000,\"rates\":[0.03,0.13,0.006,0.038]},{\"maxContext\":256000,\"rates\":[0.1,0.4,0.02,0.125]},{\"rates\":[0.2,0.8,0.04,0.25]}] },\n { id: 'qwen-3.7-max', rates: [2.5, 7.5, 0.5, 3.13], allowance: { go: 10, goat: 33, pro: 43 } },\n { id: 'qwen-3.7-plus', rates: [0.4, 1.6, 0.08, 0.5], allowance: { go: 10, goat: 33, pro: 43 }, contextTiers: [{\"maxContext\":256000,\"rates\":[0.4,1.6,0.08,0.5]},{\"rates\":[1.2,4.8,0.24,1.5]}] },\n { id: 'qwen-3.8-27b', rates: [0.4, 3, 0.04], allowance: { go: 10, goat: 70, pro: 80 } },\n { id: 'qwen-3.8-flash', rates: [0.16, 0.47, 0.016], allowance: { go: 6, goat: 20, pro: 30 } },\n { id: 'qwen-3.8-max', rates: [2, 6, 0.25, 2.5], allowance: { go: 7, goat: 20, pro: 30 } },\n { id: 'qwen-3.8-max-0902', rates: [2, 6, 0.25], allowance: { go: 7, goat: 20, pro: 30 } },\n { id: 'qwen-3.8-max-prime', rates: [4, 12, 0.5, 5], allowance: { go: 6, goat: 20, pro: 30 } },\n { id: 'qwen-3.8-omni-flash', rates: [0.15, 0.47, 0.016], allowance: { go: 6, goat: 20, pro: 30 } },\n { id: 'step-3.5-flash', rates: [0.09, 0.3, 0.02], allowance: { go: 6, goat: 20, pro: 30 } },\n { id: 'step-3.7-flash', rates: [0.2, 1.15, 0.04], allowance: { go: 6, goat: 20, pro: 30 } },\n { id: 'step-5-preview', rates: [1, 2.7, 0.05], allowance: { go: 6, goat: 20, pro: 30 } },\n { id: 'tencent/hy3-paid', rates: [0.14, 0.58, 0.035], allowance: { go: 10, goat: 70, pro: 80 } },\n { id: 'tencent/hy4-preview', rates: [0.834, 2.501, 0.042], allowance: { go: 6, goat: 20, pro: 30 } },\n { id: 'typesafe/jev', rates: [0.042, 0, 0], allowance: { go: 6, goat: 20, pro: 30 } },\n { id: 'typesafe/jev-1.14.0', rates: [0.042, 0, 0], allowance: { go: 6, goat: 20, pro: 30 } },\n]\n\n/**\n * Catalog ids no candidate rule can reach, because the page names the model\n * differently from the catalog. `tests/model-prices.test.ts` fails whenever a\n * catalog model has no price, so a new miss lands here as a visible decision\n * rather than a silently unpriced model.\n */\nconst PRICE_SLUG_OVERRIDES: Readonly> = {\n // The page lists it by its short name; the catalog carries the full one.\n 'nvidia/nemotron-3-ultra-550b-a55b': 'nemotron-3-ultra',\n}\n\n/**\n * Plausible price slugs for one catalog model id, most specific first.\n *\n * The page normalizes to lowercase and usually drops the vendor segment, but\n * not consistently: `tencent/hy4-preview` keeps its prefix while\n * `Qwen/Qwen3.8-Max-0902` becomes `qwen-3.8-max-0902`, with a hyphen the\n * catalog id does not have. Generating candidates and taking the first that\n * exists in the vendored table absorbs that drift without a hand-maintained map\n * of eighty ids.\n */\nfunction priceSlugCandidates(modelId: string): string[] {\n const lower = modelId.toLowerCase()\n const bare = lower.includes('/') ? lower.slice(lower.indexOf('/') + 1) : lower\n const out = new Set()\n const add = (slug: string): void => {\n const hyphenated = slug.replace(/^([a-z]+)(\\d)/, '$1-$2')\n out.add(slug)\n out.add(hyphenated)\n out.add(slug.replace(/-\\d{8}$/, ''))\n out.add(slug.replace(/-(preview|latest)$/, ''))\n out.add(hyphenated.replace(/-\\d{8}$/, ''))\n out.add(hyphenated.replace(/-(preview|latest)$/, ''))\n }\n add(lower)\n add(bare)\n return [...out]\n}\n\n/** The pricing-page slug for one catalog model id, or undefined when unpriced. */\nfunction priceSlugFor(modelId: string, known: ReadonlySet): string | undefined {\n const override = PRICE_SLUG_OVERRIDES[modelId]\n if (override !== undefined) return known.has(override) ? override : undefined\n return priceSlugCandidates(modelId).find((slug) => known.has(slug))\n}\n\n/** Split a stored triplet/quadruplet into the wire rate shape. */\nfunction ratesOf(values: readonly number[]): CommandCodeModelRates {\n // Indexed access is asserted rather than defaulted: the generator only ever\n // emits rows with the three published rates, so a short row is a broken table\n // and must not silently become a free model.\n const rates: CommandCodeModelRates = {\n inputCost: values[0]!,\n outputCost: values[1]!,\n cacheReadCost: values[2]!,\n }\n if (values[3] !== undefined) rates.cacheWriteCost = values[3]\n return rates\n}\n\n/**\n * Build the full price row the browser prices a session with.\n *\n * Every figure switches together: once the deal stops being live, the base\n * rates AND each context band come from the pre-discount set, so a session\n * priced after a promotion ends can never mix the two.\n */\nfunction wireRow(id: string, slug: string, row: ModelPriceRow, now: number): CommandCodeModelPrice {\n // `dealLabel()` answers undefined both for \"no deal\" and for \"deal expired\";\n // `listRates` exist only on discounted rows, so the pair settles which set\n // applies. A row with one and not the other falls back to its current rates.\n const promotional = dealLabel(id, now) !== undefined\n const price: CommandCodeModelPrice = {\n id,\n slug,\n ...ratesOf(promotional ? row.rates : (row.listRates ?? row.rates)),\n }\n if (row.peak !== undefined) price.peak = ratesOf(row.peak)\n if (row.contextTiers !== undefined) {\n price.contextTiers = row.contextTiers.map((tier) => ({\n ...ratesOf(promotional ? tier.rates : (tier.listRates ?? tier.rates)),\n ...(tier.maxContext === undefined ? {} : { maxContext: tier.maxContext }),\n }))\n }\n return price\n}\n\n/**\n * Build the table the composer prices a session with.\n *\n * Rows are keyed by CATALOG id wherever the two namespaces reconcile, because\n * that is what a session reports, and every row also carries its page slug as a\n * second lookup key. Price rows no catalog model claims are served under the\n * slug alone, so drift in either direction still prices. Free models are served\n * explicitly at zero so the composer can say so instead of showing nothing; the\n * peak windows travel with the table so the browser applies the very schedule\n * this snapshot knows instead of restating it.\n *\n * `now` (defaults to `Date.now()`) resolves lapsed promotions: a discounted row\n * whose `expiresAt` has passed is served at its pre-discount `listRates`, the\n * same instant {@link dealLabel} stops showing its badge. The table is rebuilt\n * per request, so that switch needs no redeploy.\n */\nexport function modelPriceTable(now: number = Date.now()): CommandCodePriceTable {\n const bySlug = new Map(MODEL_PRICE_ROWS.map((row) => [row.id, row]))\n const known = new Set(bySlug.keys())\n const models: CommandCodeModelPrice[] = []\n const claimed = new Set()\n\n for (const catalogId of Object.keys(KNOWN_PLANS)) {\n if (isFreeModel(catalogId) || catalogId.endsWith(':free')) {\n models.push({ id: catalogId, slug: catalogId, inputCost: 0, outputCost: 0, cacheReadCost: 0, free: true })\n continue\n }\n const slug = priceSlugFor(catalogId, known)\n if (slug === undefined) continue\n const row = bySlug.get(slug)\n if (row === undefined) continue\n claimed.add(slug)\n models.push(wireRow(catalogId, slug, row, now))\n }\n\n for (const row of MODEL_PRICE_ROWS) {\n if (claimed.has(row.id)) continue\n models.push(wireRow(row.id, row.id, row, now))\n }\n\n return {\n models,\n peakHours: PEAK_HOUR_RANGES.map(([start, end]) => [start, end] as [number, number]),\n }\n}\n\n/** Slug-keyed view of the rows, built once: neither table nor allowance mutates. */\nconst ROWS_BY_SLUG: ReadonlyMap = new Map(\n MODEL_PRICE_ROWS.map((row) => [row.id, row]),\n)\nconst KNOWN_SLUGS: ReadonlySet = new Set(ROWS_BY_SLUG.keys())\n\n/**\n * The per-model monthly allowance for a CATALOG model id, or undefined when the\n * page carries none (a model without a price row, or the free stealth previews\n * the estimator array omits).\n *\n * Resolution rides the same slug rules as the price table, so\n * `MiniMaxAI/MiniMax-M3` finds the row the page files under `minimax-m3` — the\n * settings page must not grow a second mapping that can drift from this one.\n * The settings page asks for a model only while rendering a list it already\n * has, so this stays a pure lookup with no clock: an allowance is not\n * time-dependent (a plan's figure does not lapse the way a promotional rate\n * does; when the page re-prices it, the next sync carries it).\n */\nexport function modelAllowanceFor(modelId: string): ModelAllowance | undefined {\n const slug = priceSlugFor(modelId, KNOWN_SLUGS)\n if (slug === undefined) return undefined\n return ROWS_BY_SLUG.get(slug)?.allowance\n}\n","/** Non-throwing value guards for untrusted provider payloads. */\n\nexport function isRecord(value: unknown): value is Record {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nexport function stringValue(value: unknown): string | undefined {\n return typeof value === 'string' ? value : undefined\n}\n\nexport function numberValue(value: unknown): number | undefined {\n return typeof value === 'number' && Number.isFinite(value) ? value : undefined\n}\n\nexport function booleanValue(value: unknown): boolean | undefined {\n return typeof value === 'boolean' ? value : undefined\n}\n\n/** 工具参数可为对象或完整 JSON 字符串;不把未完成的字符串片段当作完整参数。 */\n\nexport function recordOrEmpty(value: unknown): Record {\n if (isRecord(value)) return value\n if (typeof value === 'string') {\n try {\n const parsed: unknown = JSON.parse(value)\n if (isRecord(parsed)) return parsed\n } catch {\n // Some providers stream incomplete JSON argument fragments.\n }\n }\n return {}\n}\n","/** Durable cost facts: mirrors token-meter's replacement/retry rules across v1/v2 logs. */\nimport type { Context } from '@deepseek-ai/cordis'\nimport { modelPriceTable } from './model-prices.ts'\nimport { COST_TOKEN_KEYS, costGroupKey, pricingKey, zeroCostTokens, type CostTokens, type CostUsageGroup, type SessionCostFacts } from './cost-facts.ts'\nimport { isRecord } from './wire-guards.ts'\n\ninterface CostState {\n selection: { provider: string; model: string } | null\n at: number | null\n last: { turn: number; step: number; group: CostUsageGroup } | null\n facts: SessionCostFacts\n}\ninterface LogEvent { type: string; time: number; data: unknown }\nconst record = (v: unknown): Record | undefined => isRecord(v) ? v : undefined\nconst finite = (v: unknown): v is number => typeof v === 'number' && Number.isFinite(v) && v >= 0\n\nfunction tokensOf(value: unknown): CostTokens | undefined {\n const u = record(value)\n if (!u || !finite(u.inputTokens) || !finite(u.outputTokens)) return undefined\n if (u.cacheReadTokens !== undefined && !finite(u.cacheReadTokens) || u.cacheWriteTokens !== undefined && !finite(u.cacheWriteTokens)) return undefined\n return { uncachedInputTokens: u.inputTokens, outputTokens: u.outputTokens, cacheReadTokens: u.cacheReadTokens as number ?? 0, cacheWriteTokens: u.cacheWriteTokens as number ?? 0 }\n}\n\n/** The four buckets of an already-parsed record, or undefined when one is missing. */\nfunction costTokensOf(value: unknown): CostTokens | undefined {\n const t = record(value)\n if (!t || !COST_TOKEN_KEYS.every(k => finite(t[k]))) return undefined\n return t as unknown as CostTokens\n}\n\n/** Current v2 settlements store the last usage in their stream; v1 stores chunk events. */\nfunction usageOf(type: string, data: Record): CostTokens | undefined {\n if (type === 'assistant/chunk') {\n const chunk = record(data.chunk)\n return chunk?.type === 'usage' ? tokensOf(chunk.usage) : undefined\n }\n if (type !== 'assistant/message' && type !== 'assistant/attempt') return undefined\n const direct = tokensOf(data.usage)\n if (direct !== undefined) return direct\n if (!Array.isArray(data.stream)) return undefined\n for (let i = data.stream.length - 1; i >= 0; i--) {\n const item = record(data.stream[i])\n const chunk = item?.type === 'chunk' ? record(item.chunk) : undefined\n if (chunk?.type === 'usage') return tokensOf(chunk.usage)\n }\n return undefined\n}\n\nfunction parseState(value: unknown): CostState {\n const s = record(value), facts = record(s?.facts)\n if (!s || !facts || !finite(facts.pricingKey) || !Array.isArray(facts.groups)) throw new TypeError('invalid commandCodeCost state')\n const group = (v: unknown): boolean => {\n const g = record(v)\n return !!g && typeof g.provider === 'string' && typeof g.model === 'string'\n && (g.at === null || finite(g.at)) && finite(g.contextTokens) && costTokensOf(g.tokens) !== undefined\n }\n const sel = record(s.selection), last = record(s.last)\n // `summaryTokens` arrived with the compaction-summary fold. State written\n // before it carries no such key, so backfill zero instead of rejecting:\n // refusing would make every already-persisted session lose its readout on\n // upgrade. A present-but-malformed value is still an error.\n const summaryTokens = facts.summaryTokens === undefined ? zeroCostTokens() : costTokensOf(facts.summaryTokens)\n if (summaryTokens === undefined\n || !(s.selection === null || sel && typeof sel.provider === 'string' && typeof sel.model === 'string')\n || !(s.at === null || finite(s.at)) || !facts.groups.every(group)\n || !(s.last === null || last && finite(last.turn) && finite(last.step) && group(last.group))) throw new TypeError('invalid commandCodeCost state')\n return { ...(value as CostState), facts: { ...(facts as unknown as SessionCostFacts), summaryTokens } }\n}\n\n/** Optional registry uses only synchronous parse/view; no new runtime module is required. */\nexport function createCostProjection(table = modelPriceTable()) {\n const version = pricingKey(table)\n /** Groups that still carry tokens; a retry that replaced a group can drive one to zero. */\n const liveGroups = (groups: CostUsageGroup[]): CostUsageGroup[] =>\n groups.filter(g => COST_TOKEN_KEYS.some(k => g.tokens[k] > 0))\n /**\n * Fold one settled usage group into `groups`, first undoing the group a retry\n * supersedes. Shared by turn/step settlements and summary calls, which have\n * no turn/step of their own.\n */\n const foldGroup = (groups: CostUsageGroup[], previous: CostUsageGroup | undefined, group: CostUsageGroup, tokens: CostTokens): void => {\n // One pass over the groups replaces the two linear `find` scans; the\n // first index wins, matching `find` on duplicate keys.\n const byKey = new Map()\n groups.forEach((g, i) => { const key = costGroupKey(g, table); if (!byKey.has(key)) byKey.set(key, i) })\n if (previous) {\n const old = byKey.get(costGroupKey(previous, table))\n if (old !== undefined) for (const k of COST_TOKEN_KEYS) groups[old]!.tokens[k] -= previous.tokens[k]\n }\n const targetIdx = byKey.get(costGroupKey(group, table))\n let target = targetIdx === undefined ? undefined : groups[targetIdx]\n if (!target) { target = { ...group, tokens: zeroCostTokens() }; groups.push(target) }\n for (const k of COST_TOKEN_KEYS) target.tokens[k] += tokens[k]\n }\n return {\n key: 'commandCodeCost', stateVersion: version,\n stateSchema: { parse: parseState },\n init: (): CostState => ({ selection: null, at: null, last: null, facts: { pricingKey: version, groups: [], summaryTokens: zeroCostTokens() } }),\n apply(state: CostState, event: LogEvent): CostState {\n const data = record(event.data)\n if (!data) return state\n if (event.type === 'request/header') {\n const config = record(record(data.header)?.config)\n return { ...state, selection: config && typeof config.provider === 'string' && typeof config.model === 'string' ? { provider: config.provider, model: config.model } : null }\n }\n if (event.type === 'step/start' || event.type === 'llm/retry-started') return { ...state, at: finite(event.time) ? event.time : null, last: null }\n // A compaction summary is the compactor's own `ctx.llm.stream()` call. It\n // is real spend, but it settles on no turn/step and emits none of the\n // `assistant/*` events the harness meter folds, so its usage exists only\n // here. Price it into `groups` AND count it in `summaryTokens`: the\n // readout subtracts the latter before checking that this projection and\n // `tokenUsage` still describe the same durable cut.\n if (event.type === 'compaction/summary') {\n const summary = tokensOf(data.usage)\n if (summary === undefined) return state\n const group: CostUsageGroup = {\n provider: typeof data.provider === 'string' ? data.provider : '',\n model: typeof data.model === 'string' ? data.model : '',\n at: finite(event.time) ? event.time : null,\n contextTokens: summary.uncachedInputTokens + summary.cacheReadTokens + summary.cacheWriteTokens,\n tokens: summary,\n }\n const groups = state.facts.groups.map(g => ({ ...g, tokens: { ...g.tokens } }))\n foldGroup(groups, undefined, group, summary)\n const summaryTokens = { ...state.facts.summaryTokens }\n for (const k of COST_TOKEN_KEYS) summaryTokens[k] += summary[k]\n return { ...state, facts: { pricingKey: version, groups: liveGroups(groups), summaryTokens } }\n }\n const tokens = usageOf(event.type, data)\n if (tokens === undefined || !finite(data.turn) || !finite(data.step)) return state\n const previous = state.last?.turn === data.turn && state.last.step === data.step ? state.last.group : undefined\n const group: CostUsageGroup = { provider: state.selection?.provider ?? '', model: state.selection?.model ?? '', at: state.at, contextTokens: tokens.uncachedInputTokens + tokens.cacheReadTokens + tokens.cacheWriteTokens, tokens }\n if (previous && JSON.stringify(previous) === JSON.stringify(group)) return state\n const groups = state.facts.groups.map(g => ({ ...g, tokens: { ...g.tokens } }))\n foldGroup(groups, previous, group, tokens)\n return { ...state, last: { turn: data.turn, step: data.step, group }, facts: { pricingKey: version, groups: liveGroups(groups), summaryTokens: state.facts.summaryTokens } }\n },\n wire: {\n view: (state: CostState) => state.facts,\n viewSchema: { parse(value: unknown): SessionCostFacts { return parseState({ selection: null, at: null, last: null, facts: value }).facts } },\n },\n }\n}\n\nexport function installCostProjection(ctx: Context): void {\n ctx.inject(['sessionProjections'], c => {\n const registry = c.get('sessionProjections') as { register(definition: ReturnType): () => void } | undefined\n if (typeof registry?.register === 'function') c.effect(() => registry.register(createCostProjection()), 'commandcode cost projection')\n })\n}\n","/** 在宿主内折叠原始历史;每次请求保留计价时间和上下文,禁止使用已合并的会话成本桶。 */\nimport { assistantStreamFirstTokenTime } from '@deepseek-ai/dsh-llm'\nimport type { AssistantStreamRecord } from '@deepseek-ai/dsh-llm'\nimport { COST_TOKEN_KEYS, pricingKey, requestRates, zeroCostTokens, type CostTokens } from './cost-facts.ts'\nimport type { CommandCodeModelPrice, CommandCodePriceTable } from './usage-wire.ts'\nimport type { AnalyticsMetrics, AnalyticsQuery, AnalyticsReport, AnalyticsScenario } from './analytics-wire.ts'\nimport { isRecord } from './wire-guards.ts'\n\nexport interface AnalyticsEvent { seq: number; type: string; time: number; data: unknown }\nexport interface AnalyticsLog { inheritedEventCount: number; events: readonly AnalyticsEvent[] }\nexport interface RequestFact {\n session: string; model: string; at: number; retry: boolean; outcome: 'completed' | 'failed' | 'cancelled' | 'unknown'\n tokens?: CostTokens; latencyMs?: number; ttftMs?: number; decodeMs?: number\n}\nconst record = (v: unknown): Record | undefined => isRecord(v) ? v : undefined\nconst number = (v: unknown): v is number => typeof v === 'number' && Number.isFinite(v) && v >= 0\nfunction tokensOf(v: unknown): CostTokens | undefined {\n const u = record(v)\n if (!u || !number(u.inputTokens) || !number(u.outputTokens)) return undefined\n if (u.cacheReadTokens !== undefined && !number(u.cacheReadTokens) || u.cacheWriteTokens !== undefined && !number(u.cacheWriteTokens)) return undefined\n return { uncachedInputTokens: u.inputTokens, outputTokens: u.outputTokens, cacheReadTokens: u.cacheReadTokens as number ?? 0, cacheWriteTokens: u.cacheWriteTokens as number ?? 0 }\n}\n/** 同一次尝试的用量覆盖前值;重试开始才新建请求,继承前缀只恢复模型选择。 */\nexport function foldRequests(session: string, log: AnalyticsLog): RequestFact[] {\n const facts: RequestFact[] = []\n let provider = '', model = '', current: RequestFact | undefined, own = false, started = false, listed = false, turn = -1, step = -1\n const begin = (event: AnalyticsEvent, data: Record, retry: boolean) => {\n turn = Number(data.turn); step = Number(data.step); own = event.seq >= log.inheritedEventCount; started = true\n current = { session, model, at: event.time, retry, outcome: 'unknown' }\n listed = own && provider === 'commandcode'\n if (listed) facts.push(current)\n }\n for (const event of log.events) {\n const d = record(event.data)\n if (!d) continue\n if (event.type === 'request/header') {\n const config = record(record(d.header)?.config)\n provider = typeof config?.provider === 'string' ? config.provider : ''\n model = typeof config?.model === 'string' ? config.model : ''\n if (current && current.outcome === 'unknown') {\n current.model = model\n if (own && provider === 'commandcode' && !listed) { facts.push(current); listed = true }\n // 当前尝试始终是最后一条;避免每次请求扫描全部历史。\n if (provider !== 'commandcode' && listed) { facts.pop(); listed = false }\n }\n continue\n }\n // 压缩摘要是压缩器自己发的一次 `ctx.llm.stream()`:它不落在任何 turn/step 上,\n // 也不产生 `request/header`,用量只出现在这个事件里。只登记本路由的摘要,并且\n // 不碰 current / listed / provider 状态 —— 摘要在两次请求之间发生,不属于它们。\n // provider 与 model 由事件自带(后端上报),不从上一个 header 继承。\n if (event.type === 'compaction/summary') {\n if (event.seq >= log.inheritedEventCount && d.provider === 'commandcode') {\n const tokens = tokensOf(d.usage)\n facts.push({\n session, model: typeof d.model === 'string' ? d.model : '', at: event.time, retry: false, outcome: 'completed',\n ...tokens === undefined ? {} : { tokens },\n })\n }\n continue\n }\n if (event.type === 'step/start' || event.type === 'llm/retry-started') { begin(event, d, event.type === 'llm/retry-started'); continue }\n if (!current && ['assistant/message', 'assistant/attempt', 'assistant/chunk'].includes(event.type)) {\n begin(event, d, false); started = false\n }\n if (!current) continue\n if (event.type === 'turn/end' && d.turn === turn) {\n const reason = record(d.reason)?.kind\n if (current.outcome === 'unknown') {\n if (reason === 'error') current.outcome = 'failed'\n else if (reason === 'aborted') current.outcome = 'cancelled'\n }\n current = undefined\n continue\n }\n if (d.turn !== turn || d.step !== step) continue\n if (event.type === 'llm/retry') { current.outcome = 'failed'; continue }\n if (!['assistant/message', 'assistant/attempt', 'assistant/chunk'].includes(event.type)) continue\n const chunk = record(d.chunk)\n let tokens = tokensOf(d.usage)\n if (event.type === 'assistant/chunk' && chunk?.type === 'usage') tokens = tokensOf(chunk.usage)\n if (tokens === undefined && Array.isArray(d.stream)) {\n for (let i = d.stream.length - 1; i >= 0; i--) {\n const item = record(d.stream[i]), c = item?.type === 'chunk' ? record(item.chunk) : undefined\n if (c?.type === 'usage') { tokens = tokensOf(c.usage); if (tokens) break }\n }\n }\n if (tokens) current.tokens = tokens\n if (event.type === 'assistant/message') current.outcome = d.interrupted === true ? 'cancelled' : 'completed'\n // 只有保存了定时流的结算才测速度。旧消息的落盘时间不能冒充模型耗时。\n if (started && Array.isArray(d.stream) && event.time >= current.at) {\n current.latencyMs = event.time - current.at\n const first = assistantStreamFirstTokenTime(d.stream as AssistantStreamRecord[])\n if (first !== undefined && first >= current.at && first <= event.time) {\n current.ttftMs = first - current.at\n if (current.tokens) current.decodeMs = event.time - first\n }\n }\n }\n return facts\n}\n\nexport const emptyMetrics = (): AnalyticsMetrics => ({ sessions: 0, requests: 0, completed: 0, failed: 0, cancelled: 0, unknown: 0, retries: 0, usageSamples: 0, pricedRequests: 0, cost: 0, tokens: zeroCostTokens(), latencySamples: 0, latencyMs: 0, ttftSamples: 0, ttftMs: 0, decodeSamples: 0, decodeMs: 0, decodeTokens: 0 })\nfunction priceRequest(f: RequestFact, id: string, table: CommandCodePriceTable, prices: ReadonlyMap): number | undefined {\n if (!f.tokens) return undefined\n const price = prices.get(id)\n if (!price) return undefined\n if (price.free === true) return 0\n const context = f.tokens.uncachedInputTokens + f.tokens.cacheReadTokens + f.tokens.cacheWriteTokens\n const r = requestRates(price, f.at, context, table)\n if (f.tokens.cacheWriteTokens > 0 && r.cacheWriteCost === undefined) return undefined\n return (f.tokens.uncachedInputTokens * r.inputCost + f.tokens.outputTokens * r.outputCost + f.tokens.cacheReadTokens * r.cacheReadCost + f.tokens.cacheWriteTokens * (r.cacheWriteCost ?? 0)) / 1e6\n}\nfunction aggregate(facts: RequestFact[], table: CommandCodePriceTable, prices: ReadonlyMap): AnalyticsMetrics {\n const m = emptyMetrics(); m.sessions = new Set(facts.map(f => f.session)).size\n for (const f of facts) {\n m.requests++; m[f.outcome]++; if (f.retry) m.retries++\n if (f.tokens) { m.usageSamples++; for (const k of COST_TOKEN_KEYS) m.tokens[k] += f.tokens[k] }\n const cost = priceRequest(f, f.model, table, prices)\n if (cost !== undefined) { m.pricedRequests++; m.cost += cost }\n if (f.latencyMs !== undefined) { m.latencySamples++; m.latencyMs += f.latencyMs }\n if (f.ttftMs !== undefined) { m.ttftSamples++; m.ttftMs += f.ttftMs }\n if (f.decodeMs !== undefined && f.decodeMs > 0 && f.tokens) { m.decodeSamples++; m.decodeMs += f.decodeMs; m.decodeTokens += f.tokens.outputTokens }\n }\n return m\n}\nexport interface ScenarioModel { id: string; name: string; contextWindow: number | null; images: boolean; efforts: string[] }\nexport function buildAnalytics(facts: RequestFact[], query: AnalyticsQuery, table: CommandCodePriceTable, catalog: ScenarioModel[], now = Date.now()): AnalyticsReport {\n const selected = query.mode === 'range' ? facts.filter(f => f.at >= query.from && f.at < query.to) : facts\n const prices = new Map()\n for (const p of table.models) for (const id of [p.id, p.slug]) if (!prices.has(id)) prices.set(id, p)\n const totals = aggregate(selected, table, prices)\n const models = [...new Set(selected.map(f => f.model))].map(id => ({ id, ...aggregate(selected.filter(f => f.model === id), table, prices) })).sort((a, b) => b.cost - a.cost || a.id.localeCompare(b.id))\n const scenarios: AnalyticsScenario[] = catalog.map(model => {\n let cost = 0, pricedRequests = 0, excludedRequests = 0, unknownRequests = 0\n for (const f of selected) {\n if (!f.tokens) { unknownRequests++; continue }\n const context = f.tokens.uncachedInputTokens + f.tokens.cacheReadTokens + f.tokens.cacheWriteTokens\n // 输入和输出同时占据上下文;不适配的请求不得混进可比较的成本。\n if (model.contextWindow !== null && context + f.tokens.outputTokens > model.contextWindow) { excludedRequests++; continue }\n const priced = priceRequest(f, model.id, table, prices)\n if (priced === undefined) unknownRequests++\n else { cost += priced; pricedRequests++ }\n }\n return { ...model, cost, pricedRequests, excludedRequests, unknownRequests }\n })\n const elapsed = query.mode === 'range' ? Math.min(query.to, now) - query.from : 0\n const monthlyEstimate = elapsed >= 86400000 && totals.requests > 0 && totals.pricedRequests === totals.requests\n ? totals.cost * (30 * 86400000 / elapsed) : null\n return { generatedAt: now, pricingKey: pricingKey(table), query, status: 'ready', scannedSessions: 0, matchedSessions: totals.sessions, unreadableSessions: 0, skippedSessions: 0, truncated: false, catalogUnavailable: false, totals, models, scenarios, monthlyEstimate }\n}\n","/**\n * Shared boundary-validation and Remote-descriptor plumbing for the plugin's\n * hand-rolled Typert wire contracts (`commandcode/report`, `commandcode/models`,\n * `commandcode/prices`, `commandcode/login*`).\n *\n * Every Remote this plugin serves crosses the Typert Gateway with a strict\n * result schema: the Host half registers a descriptor against a Cordis service\n * (`src/usage-remote.ts`) and the browser half mounts the matching contribution\n * on `ctx.remote` (`src/client/index.ts`). This module is dependency-free so\n * the client bundle can inline it, and it holds the schema helpers and\n * descriptor boilerplate the wire files used to duplicate.\n *\n * @module dsh-commandcode-provider/wire-shared\n */\nimport type { InvocationDescriptor, TypertSchema } from '@deepseek-ai/dsh-typert-protocol'\n\n/** The npm package identity every contribution and descriptor claims. */\nexport const REMOTE_PACKAGE = '@mars-sea/dsh-commandcode-provider'\n\n/** The Cordis service key the Gateway resolves every Command Code Remote from. */\nexport const REMOTE_SERVICE = 'commandcodeUsage'\n\n/** The wire namespace all Command Code endpoints share. */\nexport const REMOTE_NAMESPACE = 'commandcode'\n\n/** The read/validate helpers one boundary codec needs. */\nexport interface BoundaryValidator {\n /** Reject one boundary value with a field-naming error. */\n reject(field: string): never\n /** Narrow an unknown value to a plain record, or reject. */\n record(value: unknown, field: string): Record\n /** Read one required string field (`field` is the dotted error label). */\n stringField(source: Record, key: string, field: string): string\n /** Read one required finite number field (`field` is the dotted error label). */\n numberField(source: Record, key: string, field: string): number\n /** Read one required boolean field (`field` is the dotted error label). */\n booleanField(source: Record, key: string, field: string): boolean\n}\n\n/**\n * Build the validator helpers one endpoint uses. `prefix` names the endpoint\n * in the rejection message (e.g. `commandcode/report result:`), so each wire\n * file keeps its own diagnostic phrasing while sharing the helper bodies.\n *\n * The helpers return the reject call directly in the failure branch: since\n * `reject` is typed `never`, the ternary's union collapses to the success type\n * without relying on TypeScript's control-flow analysis of a never-returning\n * call (which only recognizes function declarations, not the destructured\n * arrow `reject` callers receive from this factory). Callers that need the\n * narrowing in an `if` must therefore assign inside the positive branch.\n */\nexport function makeBoundaryValidator(prefix: string): BoundaryValidator {\n const reject = (field: string): never => {\n throw new TypeError(`${prefix} invalid ${field}`)\n }\n const record = (value: unknown, field: string): Record =>\n typeof value === 'object' && value !== null && !Array.isArray(value)\n ? value as Record\n : reject(field)\n const stringField = (source: Record, key: string, field: string): string =>\n typeof source[key] === 'string' ? source[key] as string : reject(field)\n const numberField = (source: Record, key: string, field: string): number =>\n typeof source[key] === 'number' && Number.isFinite(source[key] as number)\n ? source[key] as number\n : reject(field)\n const booleanField = (source: Record, key: string, field: string): boolean =>\n typeof source[key] === 'boolean' ? source[key] as boolean : reject(field)\n return { reject, record, stringField, numberField, booleanField }\n}\n\n/**\n * One strict result codec: `mode: 'strict'` carries the LAZY schema factory\n * (`create()`) the registry requires and the Gateway validates with\n * (`codec.create().parse`). There is NO `schema` member — issue #49.\n */\ninterface StrictCodec {\n readonly mode: 'strict'\n readonly typeSymbol: string\n readonly create: () => TypertSchema\n}\n\n/** Use the same strict-codec shape for invocation parameters and results. */\nexport function makeStrictCodec(typeSymbol: string, schema: TypertSchema): StrictCodec {\n return { mode: 'strict', typeSymbol, create: () => schema }\n}\n\n/**\n * Build one strict invocation descriptor. Every Command Code Remote shares the\n * `commandcode` namespace, the `commandcodeUsage` service, and a strict result\n * — only the endpoint, method, result type symbol, and schema differ.\n */\nexport function makeRemoteDescriptor(\n endpoint: string,\n method: string,\n typeSymbol: string,\n schema: TypertSchema,\n): InvocationDescriptor {\n return {\n id: `${REMOTE_PACKAGE}#${endpoint}`,\n service: REMOTE_SERVICE,\n namespace: REMOTE_NAMESPACE,\n method,\n invocation: { kind: 'direct' },\n parameters: [],\n result: makeStrictCodec(typeSymbol, schema),\n }\n}\n","/** 模型分析的只读契约;只传数字和模型能力,不传会话正文、标题、路径或密钥。 */\nimport type { InvocationDescriptor, TypertRemoteContribution } from '@deepseek-ai/dsh-typert-protocol'\nimport { makeBoundaryValidator, makeRemoteDescriptor, makeStrictCodec, REMOTE_PACKAGE } from './wire-shared.ts'\nimport type { CostTokens } from './cost-facts.ts'\n\nexport type AnalyticsQuery = { mode: 'recent'; limit: number } | { mode: 'range'; from: number; to: number }\nexport interface AnalyticsMetrics {\n sessions: number; requests: number; completed: number; failed: number; cancelled: number; unknown: number; retries: number\n usageSamples: number; pricedRequests: number; cost: number; tokens: CostTokens\n latencySamples: number; latencyMs: number; ttftSamples: number; ttftMs: number; decodeSamples: number; decodeMs: number; decodeTokens: number\n}\nexport interface AnalyticsModel extends AnalyticsMetrics { id: string }\nexport interface AnalyticsScenario {\n id: string; name: string; contextWindow: number | null; images: boolean; efforts: string[]\n cost: number; pricedRequests: number; excludedRequests: number; unknownRequests: number\n}\nexport interface AnalyticsReport {\n generatedAt: number; pricingKey: number; query: AnalyticsQuery\n status: 'ready' | 'unavailable'\n scannedSessions: number; matchedSessions: number; unreadableSessions: number; skippedSessions: number; truncated: boolean; catalogUnavailable: boolean\n totals: AnalyticsMetrics; models: AnalyticsModel[]; scenarios: AnalyticsScenario[]\n monthlyEstimate: number | null\n}\nconst g = makeBoundaryValidator('commandcode/analytics')\nconst nonnegative = (s: Record, k: string): number => {\n const n = g.numberField(s, k, k)\n return n >= 0 ? n : g.reject(k)\n}\nconst count = (s: Record, k: string): number => {\n const n = nonnegative(s, k)\n return Number.isSafeInteger(n) ? n : g.reject(k)\n}\nexport function parseAnalyticsQuery(value: unknown): AnalyticsQuery {\n const s = g.record(value, 'query')\n if (s.mode === 'recent') {\n const limit = count(s, 'limit')\n if (limit < 1 || limit > 100) return g.reject('limit')\n return { mode: 'recent', limit }\n }\n if (s.mode !== 'range') return g.reject('mode')\n const from = count(s, 'from'), to = count(s, 'to')\n if (to <= from || to - from > 366 * 86400000 || to > 8640000000000000) return g.reject('range')\n return { mode: 'range', from, to }\n}\nconst counts = ['sessions', 'requests', 'completed', 'failed', 'cancelled', 'unknown', 'retries', 'usageSamples', 'pricedRequests', 'latencySamples', 'ttftSamples', 'decodeSamples'] as const\nconst quantities = ['cost', 'latencyMs', 'ttftMs', 'decodeMs', 'decodeTokens'] as const\nconst tokenKeys = ['uncachedInputTokens', 'outputTokens', 'cacheReadTokens', 'cacheWriteTokens'] as const\nfunction metrics(value: unknown): AnalyticsMetrics {\n const s = g.record(value, 'metrics'), result = {} as AnalyticsMetrics\n for (const k of counts) result[k] = count(s, k)\n for (const k of quantities) result[k] = nonnegative(s, k)\n const tokens = g.record(s.tokens, 'tokens')\n result.tokens = Object.fromEntries(tokenKeys.map(k => [k, nonnegative(tokens, k)])) as unknown as CostTokens\n if (result.completed + result.failed + result.cancelled + result.unknown !== result.requests\n || result.pricedRequests > result.usageSamples || result.usageSamples > result.requests\n || result.retries > result.requests || result.ttftSamples > result.requests || result.latencySamples > result.requests || result.decodeSamples > result.requests) return g.reject('coverage')\n return result\n}\nconst nullable = (s: Record, k: string): number | null => s[k] === null ? null : nonnegative(s, k)\nexport function parseAnalyticsReport(value: unknown): AnalyticsReport {\n const s = g.record(value, 'report')\n if (s.status !== 'ready' && s.status !== 'unavailable') return g.reject('status')\n if (!Array.isArray(s.models) || !Array.isArray(s.scenarios) || s.models.length > 1000 || s.scenarios.length > 1000) return g.reject('models')\n return {\n generatedAt: count(s, 'generatedAt'), pricingKey: count(s, 'pricingKey'), query: parseAnalyticsQuery(s.query), status: s.status,\n scannedSessions: count(s, 'scannedSessions'), matchedSessions: count(s, 'matchedSessions'), unreadableSessions: count(s, 'unreadableSessions'), skippedSessions: count(s, 'skippedSessions'),\n truncated: g.booleanField(s, 'truncated', 'truncated'), catalogUnavailable: g.booleanField(s, 'catalogUnavailable', 'catalogUnavailable'),\n totals: metrics(s.totals), monthlyEstimate: nullable(s, 'monthlyEstimate'),\n models: s.models.map(value => { const m = g.record(value, 'model'); return { ...metrics(m), id: g.stringField(m, 'id', 'id') } }),\n scenarios: s.scenarios.map(value => {\n const m = g.record(value, 'scenario')\n if (!Array.isArray(m.efforts) || !m.efforts.every(v => typeof v === 'string')) return g.reject('efforts')\n return { id: g.stringField(m, 'id', 'id'), name: g.stringField(m, 'name', 'name'), contextWindow: nullable(m, 'contextWindow'), images: g.booleanField(m, 'images', 'images'), efforts: m.efforts as string[], cost: nonnegative(m, 'cost'), pricedRequests: count(m, 'pricedRequests'), excludedRequests: count(m, 'excludedRequests'), unknownRequests: count(m, 'unknownRequests') }\n }),\n }\n}\nexport const ANALYTICS_DESCRIPTOR: InvocationDescriptor = {\n ...makeRemoteDescriptor('commandcode/analytics', 'analytics', `${REMOTE_PACKAGE}#AnalyticsReport`, { parse: parseAnalyticsReport }),\n parameters: [{ name: 'query', wire: 'query', source: 'json' as const, codec: makeStrictCodec(`${REMOTE_PACKAGE}#AnalyticsQuery`, { parse: parseAnalyticsQuery }) }],\n}\nexport const ANALYTICS_REMOTE_CONTRIBUTION: TypertRemoteContribution = { package: REMOTE_PACKAGE, descriptors: [ANALYTICS_DESCRIPTOR] }\n","/** 可选宿主历史服务:读实时优先的完整语料库,绝不加载会话为实时或写回日志。 */\nimport type { Context } from '@deepseek-ai/cordis'\nimport type { CommandCodeAdapter } from './adapter.ts'\nimport { KNOWN_EFFORTS } from './capabilities.ts'\nimport { buildAnalytics, foldRequests, type AnalyticsLog, type RequestFact, type ScenarioModel } from './analytics.ts'\nimport { parseAnalyticsQuery, type AnalyticsQuery, type AnalyticsReport } from './analytics-wire.ts'\nimport { modelPriceTable } from './model-prices.ts'\n\nexport interface HistoryQuery {\n listSessions(signal?: AbortSignal): Promise>\n readSession(id: string): Promise\n}\nexport const ANALYTICS_SESSION_LIMIT = 500\nexport const ANALYTICS_EVENT_LIMIT = 200000\n/** 逐会话失败隔离;上限和遗漏计数会返回界面,部分结果不能伪装成完整历史。 */\nexport async function readAnalyticsHistory(history: HistoryQuery | undefined, input: AnalyticsQuery, catalog: () => Promise, signal?: AbortSignal): Promise {\n const query = parseAnalyticsQuery(input), table = modelPriceTable()\n if (!history) return { ...buildAnalytics([], query, table, []), status: 'unavailable' }\n const records = await history.listSessions(signal)\n const facts: RequestFact[] = []\n let scannedSessions = 0, unreadableSessions = 0, skippedSessions = 0, events = 0, truncated = records.length > ANALYTICS_SESSION_LIMIT\n for (const entry of records.slice(0, ANALYTICS_SESSION_LIMIT)) {\n if (signal?.aborted) throw new Error('模型分析已取消')\n if (events >= ANALYTICS_EVENT_LIMIT) { truncated = true; break }\n scannedSessions++\n try {\n const log = await history.readSession(entry.header.id)\n // 老宿主或第三方服务缺少精确继承边界时跳过,不能猜测分支切点。\n if (!Number.isSafeInteger(log.inheritedEventCount) || log.inheritedEventCount < 0 || log.inheritedEventCount > log.events.length) { skippedSessions++; continue }\n events += log.events.length\n if (events > ANALYTICS_EVENT_LIMIT) { skippedSessions++; truncated = true; break }\n facts.push(...foldRequests(entry.header.id, log))\n } catch { unreadableSessions++ }\n }\n let selected = facts\n if (query.mode === 'recent') {\n const latest = new Map()\n for (const f of facts) latest.set(f.session, Math.max(latest.get(f.session) ?? 0, f.at))\n const ids = new Set([...latest].sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0])).slice(0, query.limit).map(([id]) => id))\n selected = facts.filter(f => ids.has(f.session))\n }\n let models: ScenarioModel[] = [], catalogUnavailable = false\n if (signal?.aborted) throw new Error('模型分析已取消')\n try { models = await catalog() } catch { catalogUnavailable = true }\n const report = buildAnalytics(selected, query, table, models)\n return { ...report, scannedSessions, unreadableSessions, skippedSessions, truncated, catalogUnavailable, monthlyEstimate: truncated || unreadableSessions > 0 || skippedSessions > 0 ? null : report.monthlyEstimate }\n}\n/** 用反射和可选 fiber 对接,保持未挂载历史服务的无界面/TUI 配置可用。 */\nexport function createAnalyticsReader(ctx: Context, adapter: Pick) {\n let history: HistoryQuery | undefined, busy = false\n ctx.inject(['sessionQuery'], c => {\n const service = c.get('sessionQuery') as HistoryQuery | undefined\n if (typeof service?.listSessions !== 'function' || typeof service.readSession !== 'function') return\n history = service\n c.effect(() => () => { if (history === service) history = undefined }, 'commandcode analytics history')\n })\n return async (query: AnalyticsQuery, signal?: AbortSignal): Promise => {\n if (busy) throw new Error('模型分析正在读取历史,请稍后刷新')\n busy = true\n try {\n return await readAnalyticsHistory(history, query, async () => {\n const available = await adapter.listModels('commandcode')\n return Promise.all(available.map(async m => {\n const resolved = await adapter.resolveModel('commandcode', m.id)\n return { id: m.id, name: m.name.replace(/ \\(CC\\)$/, ''), contextWindow: resolved.context?.contextWindow ?? null, images: resolved.inputModalities?.includes('image') ?? false, efforts: [...(KNOWN_EFFORTS[m.id] ?? [])] }\n }))\n }, signal)\n } finally { busy = false }\n }\n}\n","/**\n * Ask Command Code for plain response bodies. A DSH host using an incompatible\n * undici global dispatcher can lose response headers and leave compressed\n * JSON, SSE, and pre-stream error bodies undecoded.\n */\nexport const IDENTITY_ENCODING_HEADER = { 'accept-encoding': 'identity' } as const\n","/** 两端共用可编辑超时范围,存储仍是整数毫秒;提示不能借用重试退避上限。 */\nexport const MIN_TIMEOUT_SECONDS = 0.001\nexport const MAX_TIMEOUT_SECONDS = 3600\n","/** 网页、终端与模型目录共用的选择规则;显式开关优先于白名单。 */\nexport function modelIsVisible(id: string, allowlist: readonly string[], overrides: unknown): boolean {\n const flag = overrides !== null && typeof overrides === 'object' && !Array.isArray(overrides)\n ? (overrides as Record)[id] : undefined\n return typeof flag === 'boolean' ? flag : allowlist.length === 0 || allowlist.includes(id)\n}\n\n/** 只接收布尔事实,手工配置中的其他值不能成为可见性开关。 */\nexport function readVisibility(raw: unknown): Record {\n if (raw === null || typeof raw !== 'object' || Array.isArray(raw)) return {}\n return Object.fromEntries(Object.entries(raw).filter(([id, value]) => id !== '' && typeof value === 'boolean'))\n}\n","/** 自定义上下文长度(issue #86):按模型覆盖优先于全局值,全局值优先于目录公布值。\n * 本模块保持纯函数(无 node 依赖),浏览器设置页与 Host 侧共用同一套边界与判定。 */\n\n/** 自定义上下文长度接受的下界(token);0 或负数不是窗口。 */\nexport const CONTEXT_WINDOW_MIN = 1\n/** 自定义上下文长度接受的上界(token);覆盖任何已知模型窗口仍留有余量。 */\nexport const CONTEXT_WINDOW_MAX = 10_000_000\n\n/** 源头可携带自定义上下文长度的配置面(Config 与连接选项结构相同)。 */\nexport interface ContextWindowOptions {\n /** 全局自定义值:覆盖目录公布值,对没有按模型覆盖的模型生效。 */\n contextWindow?: number | undefined\n /** 按模型覆盖,键为目录模型 id;优先于 {@link contextWindow}。 */\n contextWindowOverrides?: Readonly> | undefined\n}\n\n/**\n * 判定一个值能否作为自定义上下文长度:边界内的安全整数,符合宿主模型元数据约束。\n *\n * 程序化构造的连接可能绕过 schemastery 归一化,所以 `resolveAdapterOptions`\n * 也要重新判定——越界或非数值直接丢弃,回落到目录公布值,而不是让请求带着\n * 一个网关会拒绝的窗口上线。\n */\nexport function isValidContextWindow(value: unknown): value is number {\n return typeof value === 'number' && Number.isSafeInteger(value)\n && value >= CONTEXT_WINDOW_MIN && value <= CONTEXT_WINDOW_MAX\n}\n\n/**\n * 只接收合法条目的按模型覆盖表;空表、非对象与非法数值一律视为未设置。\n * 配置校验会拒绝非整数或越界值;本函数额外保护绕过配置校验的程序化调用,\n * 丢弃坏条目,不把非法窗口交给宿主。返回新对象;未设置时为 `undefined`。\n */\nexport function readContextWindowOverrides(raw: unknown): Readonly> | undefined {\n if (raw === null || typeof raw !== 'object' || Array.isArray(raw)) return undefined\n const entries = Object.entries(raw).filter(\n (entry): entry is [string, number] => entry[0] !== '' && isValidContextWindow(entry[1]),\n )\n return entries.length === 0 ? undefined : Object.fromEntries(entries)\n}\n\n/**\n * 一次模型解析的有效上下文长度:按模型覆盖 → 全局值 → 目录公布值。\n *\n * 适配器只在有目录条目时调用(未知模型保持既有的「无上下文宣告」形状),\n * 所以 `catalog` 是已知的正数;按模型覆盖与全局值在 `resolveAdapterOptions`\n * 已清洗,这里对程序化构造的连接再判一次,坏值静默回落到目录值。\n */\nexport function effectiveContextWindow(\n catalog: number,\n model: string,\n options: ContextWindowOptions,\n): number {\n const perModel = options.contextWindowOverrides?.[model]\n if (isValidContextWindow(perModel)) return perModel\n if (isValidContextWindow(options.contextWindow)) return options.contextWindow\n return catalog\n}\n","/**\n * Output-budget bounds shared by the Host, the browser settings page and the\n * adapter (issue #74).\n *\n * The module stays pure (no node imports) so the client bundle can inline it,\n * exactly like `context-window.ts`. The report behind issue #74 asked for a\n * knob that stops the adapter from writing `max_tokens` at all; that is the\n * `0` sentinel here rather than a separate `null` spelling, because the value\n * travels through one numeric settings field on both surfaces.\n */\n\n/**\n * The output budget this bundle asks for, and the ceiling it will never exceed.\n *\n * 131 072, chosen against a measured provider limit rather than a round guess.\n * Probing `/alpha/generate` directly on 2026-09-28: 64 000 → 200, 131 072 → 200,\n * 196 608 → 200, **200 000 → 200, 200 704 → 400**, 1 000 000 → 400. The server\n * therefore caps `max_tokens` at 200 000, and it does so identically for a\n * 262 144-window model (`stealth/pixel-canary`, retired by Command Code on\n * 2026-10-01 and named here only as the probe's subject) and a 1 000 000-window\n * one (`stealth/space-bunny-alpha`) — the cap is global, not per model. 131 072\n * keeps a 35 % margin under it while covering the real output ceiling of the\n * models that have one (Claude 64 K, Gemini 64 K, several at 128 K).\n *\n * The old 64 000 was never a provider requirement: it cost nothing in latency\n * (a 64 000 request answered headers in 1.28 s against 1.57 s for 131 072) but\n * it did cap what a model could ever say in one turn.\n *\n * No client-side clamp is applied on top of this: an earlier version pre-shrank\n * `max_tokens` from an estimate of the prompt already sent (`requestContextBudget()`,\n * issue #67), but that estimate over-corrected on ordinary long conversations —\n * exactly the \"output gets cut short as the conversation grows\" symptom issue #74\n * reported — while a live A/B probe (2026-09-30, `stealth/space-bunny-alpha`,\n * ~19.6% over its 1,000,000-token window with no client-side shrink) showed the\n * endpoint answers a genuine overflow with an unambiguous `400 … exceeds the\n * model's context window`, which `isContextOverflowDetail()` classifies as\n * `CONTEXT_WINDOW_EXCEEDED` independently of this constant.\n *\n * A user-set positive budget can only TIGHTEN this, never raise it — a figure\n * above the cap would be refused by the gateway anyway, so the settings field\n * refuses it at the input instead of spending a round trip to learn that.\n *\n * Lives here rather than in `adapter.ts` so the browser settings page can bound\n * its input by the same figure the Host enforces; `adapter.ts` re-exports it\n * under its historical name.\n */\nexport const MAX_OUTPUT_TOKEN_LIMIT = 131_072\n\n/**\n * The `maxOutputTokens` value that asks the adapter to send NO `max_tokens`\n * field at all, leaving the per-turn output size to the platform (issue #74).\n * Only the CLI and OpenAI transports can honour it: Anthropic's Messages\n * endpoint requires the field, so that route keeps sending its derived budget.\n *\n * This is also the field's lower bound, which is why no separate `MIN_` constant\n * exists: zero is not a small budget, it is the instruction.\n */\nexport const OMIT_OUTPUT_TOKENS = 0\n\n/**\n * Whether a value can serve as a user output budget: the omit sentinel, or a\n * whole token count inside the gateway's own ceiling.\n *\n * Programmatically built connections can bypass schemastery normalization, so\n * the resolve step re-judges every value here and drops an out-of-range one\n * back to \"unset\" instead of letting the request carry a budget the gateway\n * refuses.\n */\nexport function isValidMaxOutputTokens(value: unknown): value is number {\n return typeof value === 'number' && Number.isSafeInteger(value)\n && value >= OMIT_OUTPUT_TOKENS && value <= MAX_OUTPUT_TOKEN_LIMIT\n}\n\n/**\n * Apply a user output budget to a derived one.\n *\n * `undefined` means the user set nothing, so the derived ceiling stands\n * unchanged — the default path, and the one every existing profile takes.\n * {@link OMIT_OUTPUT_TOKENS} is a wire instruction rather than a number, so it\n * also leaves the derived budget alone; {@link omitOutputTokens} is what turns\n * it into an absent field.\n */\nexport function applyMaxOutputTokens(derived: number, configured: number | undefined): number {\n if (configured === undefined || configured === OMIT_OUTPUT_TOKENS) return derived\n return Math.min(derived, configured)\n}\n\n/**\n * Whether this attempt must send no `max_tokens` field at all.\n *\n * Two guards narrow this beyond the user's own setting, and both are\n * correctness requirements rather than conveniences:\n *\n * - The Messages route is excluded deliberately: the endpoint rejects a body\n * without the field (`Invalid input: expected number, received undefined at\n * max_tokens`), so omitting it there would not lengthen an answer, it would\n * make the whole Claude family unusable. The CLI and OpenAI transports accept\n * an absent field, which is where the setting does what it promises.\n * - An explicit per-call budget from the host is an instruction, not a default,\n * so it wins over the plugin-wide setting. `session-title` is the concrete\n * case: it asks for 64 tokens precisely because its output must stay bounded,\n * and dropping the field there would let a title generation run long instead\n * of making a long answer fit (issue #88's fix depends on that bound).\n */\nexport function omitOutputTokens(\n configured: number | undefined,\n protocol: string,\n hostRequestedTokens?: number,\n): boolean {\n if (configured !== OMIT_OUTPUT_TOKENS) return false\n if (protocol === 'messages') return false\n return hostRequestedTokens === undefined\n}\n","/**\n * Readable error text for the settings page AND the Host-side failure paths.\n *\n * @module dsh-commandcode-provider/readable-error\n */\n\n/**\n * Turn a caught value into readable text.\n *\n * `error instanceof Error ? error.message : String(error)` degrades to the\n * literal string `[object Object]` for a plain object with no `Error`\n * prototype — which is exactly what a Remote call across the webview/host\n * boundary can hand back: `dsh-typert-protocol` serializes a rejection for\n * the wire, and a structurally-cloned value loses its prototype chain even\n * when the host threw a real `Error` (issue #74). Reading a `message` string\n * off the plain object first recovers the original text in that case; only a\n * value with neither an `Error` prototype nor a usable `message` field falls\n * through to a JSON dump.\n *\n * Shared by both halves on purpose. The browser client needs it for rejections\n * that crossed the RPC boundary, and the Host needs it for values that reached\n * it from a transport, a JSON body, or a user-thrown non-Error — the same\n * degradation, one owner.\n */\nexport function readableErrorText(error: unknown): string {\n if (error instanceof Error) return error.message\n if (typeof error === 'string') return error\n if (error !== null && typeof error === 'object') {\n const message = (error as { message?: unknown }).message\n if (typeof message === 'string' && message !== '') return message\n try {\n return JSON.stringify(error)\n } catch {\n return Object.prototype.toString.call(error)\n }\n }\n return String(error)\n}\n","/** 普通临时故障与额度窗口分开计数;预算按智能体的一次模型请求重置。 */\nexport const TRANSIENT_MAX_RETRIES = 3\nexport const THROTTLED_CODE = 'THROTTLED'\nconst boundedCodes = new Set(['EMPTY_RESPONSE', 'SERVER', 'TIMEOUT', THROTTLED_CODE])\nconst counts = new WeakMap