@eddyskywalker/dsh-chatgpt-subscription 0.1.15 → 0.1.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/client.js CHANGED
@@ -671,26 +671,51 @@ window.__ModuleLoader__.load({
671
671
  className: "dsh-codex-muted",
672
672
  children: t("contextWindowsHint")
673
673
  })] }), CONFIGURABLE_CONTEXT_MODEL_IDS.map((model) => {
674
- const fallback = status?.preferences.contextWindowOverrides[model] ?? resolveCodexCatalogEntry(model).contextWindow;
675
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
674
+ const entry = resolveCodexCatalogEntry(model);
675
+ const fallback = status?.preferences.contextWindowOverrides[model] ?? entry.contextWindow;
676
+ const draft = contextDrafts[model];
677
+ const parsedDraft = draft === void 0 ? fallback : parseCapacity(draft);
678
+ const dirty = draft !== void 0 && parsedDraft !== fallback;
679
+ const inputId = `dsh-codex-context-${model}`;
680
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
676
681
  className: "dsh-codex-context-row",
677
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: resolveCodexCatalogEntry(model).name }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
682
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
683
+ htmlFor: inputId,
684
+ children: entry.name
685
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
678
686
  className: "dsh-codex-capacity-control",
679
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
680
- type: "text",
681
- inputMode: "numeric",
682
- value: contextDrafts[model] ?? formatCapacity(fallback),
683
- disabled: busy !== null,
684
- "aria-label": resolveCodexCatalogEntry(model).name + " " + t("contextWindow"),
685
- onChange: (event) => setContextDrafts((drafts) => ({
686
- ...drafts,
687
- [model]: event.currentTarget.value
688
- })),
689
- onBlur: () => void updateContextWindow(model),
690
- onKeyDown: (event) => {
691
- if (event.key === "Enter") event.currentTarget.blur();
692
- }
693
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("small", { children: t("tokens") })]
687
+ children: [
688
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
689
+ id: inputId,
690
+ type: "text",
691
+ inputMode: "numeric",
692
+ value: draft ?? formatCapacity(fallback),
693
+ disabled: busy !== null,
694
+ "aria-label": entry.name + " " + t("contextWindow"),
695
+ onChange: (event) => {
696
+ const value = event.currentTarget.value;
697
+ setContextDrafts((drafts) => ({
698
+ ...drafts,
699
+ [model]: value
700
+ }));
701
+ },
702
+ onKeyDown: (event) => {
703
+ if (event.key !== "Enter" || !dirty) return;
704
+ event.preventDefault();
705
+ updateContextWindow(model);
706
+ }
707
+ }),
708
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("small", { children: t("tokens") }),
709
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
710
+ className: "dsh-codex-context-save",
711
+ type: "button",
712
+ "data-model": model,
713
+ "aria-label": entry.name + " " + t("saveContextWindow"),
714
+ disabled: busy !== null || !dirty,
715
+ onClick: () => void updateContextWindow(model),
716
+ children: t("save")
717
+ })
718
+ ]
694
719
  })]
695
720
  }, model);
696
721
  })]
@@ -997,6 +1022,8 @@ window.__ModuleLoader__.load({
997
1022
  contextWindowsHint: "默认 272K;可选启用最高 1M。该值用于 DSH 的压缩与溢出判断,可输入 1M、512K 等容量。",
998
1023
  contextWindow: "上下文窗口",
999
1024
  contextWindowInvalid: "上下文窗口必须是 1 到 1M 的整数,可使用 K 或 M 后缀。",
1025
+ saveContextWindow: "保存上下文窗口",
1026
+ save: "保存",
1000
1027
  tokens: "tokens",
1001
1028
  quickQuota: "在输入框旁显示快捷用量",
1002
1029
  quickQuotaHint: "仅在当前会话选中 codex-chatgpt 模型时显示。",
@@ -1095,6 +1122,8 @@ window.__ModuleLoader__.load({
1095
1122
  contextWindowsHint: "Defaults to 272K, with an optional value up to 1M. DSH uses it for compaction and overflow detection; values such as 1M and 512K are accepted.",
1096
1123
  contextWindow: "Context window",
1097
1124
  contextWindowInvalid: "The context window must be an integer from 1 to 1M. K and M suffixes are accepted.",
1125
+ saveContextWindow: "Save context window",
1126
+ save: "Save",
1098
1127
  tokens: "tokens",
1099
1128
  quickQuota: "Show quick usage beside the composer",
1100
1129
  quickQuotaHint: "Shown only when the current session uses a codex-chatgpt model.",
@@ -1182,6 +1211,10 @@ window.__ModuleLoader__.load({
1182
1211
  .dsh-codex-capacity-control{align-items:center;display:flex;gap:7px}
1183
1212
  .dsh-codex-capacity-control input{font-family:ui-monospace,SFMono-Regular,Consolas,monospace;text-align:right;width:90px}
1184
1213
  .dsh-codex-capacity-control small{color:var(--dsw-alias-label-tertiary);font-size:11px;width:42px}
1214
+ .dsh-codex-context-save{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:7px;color:var(--dsw-alias-label-primary);cursor:pointer;font:inherit;font-size:12px;line-height:1;padding:8px 10px;white-space:nowrap}
1215
+ .dsh-codex-context-save:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}
1216
+ .dsh-codex-context-save:focus-visible{outline:2px solid var(--dsw-alias-button-info-fill,#397ee8);outline-offset:2px}
1217
+ .dsh-codex-context-save:disabled{cursor:default;opacity:.45}
1185
1218
  .dsh-codex-check{align-items:flex-start;border-bottom:1px solid var(--dsw-alias-border-l2);cursor:pointer;display:flex;gap:10px;padding:12px 0}
1186
1219
  .dsh-codex-check input{flex:none;margin-top:2px}
1187
1220
  .dsh-codex-check small{color:var(--dsw-alias-label-secondary);display:block;font-size:12px;line-height:1.45;margin-top:2px}
package/lib/client.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","names":["formatPercent"],"sources":["../src/compat.ts","../src/client/quota.ts","../src/client/CodexComposerQuota.tsx","../src/client/CodexImageToolView.tsx","../src/shared/model-catalog.ts","../src/client/api.ts","../src/client/CodexSubscriptionSection.tsx","../src/client/locales.ts","../src/client/styles.ts","../src/client/index.tsx"],"sourcesContent":["/**\n * Compatibility constants for the ChatGPT-backed Codex flow. The backend and\n * OAuth parameters are not a public third-party API contract, so every such\n * value is isolated here for review and rollback.\n */\nexport const CHATGPT_OAUTH_ISSUER = 'https://auth.openai.com' as const\nexport const CHATGPT_OAUTH_CLIENT_ID = 'app_EMoamEEZ73f0CkXaXp7hrann' as const\nexport const OAUTH_CALLBACK_HOST = 'localhost' as const\nexport const OAUTH_CALLBACK_PORT = 1455 as const\nexport const OAUTH_CALLBACK_PATH = '/auth/callback' as const\nexport const OAUTH_REDIRECT_URI = `http://${OAUTH_CALLBACK_HOST}:${OAUTH_CALLBACK_PORT}${OAUTH_CALLBACK_PATH}` as const\nexport const OAUTH_SCOPE = 'openid profile email offline_access' as const\nexport const OAUTH_ORIGINATOR = 'opencode' as const\nexport const OAUTH_LOGIN_TIMEOUT_MS = 5 * 60_000\nexport const TOKEN_REFRESH_MARGIN_MS = 60_000\nexport const ROUTE_PREFIX = '/api/dsh-chatgpt-subscription' as const\nexport const PLUGIN_VERSION = '0.1.0-alpha.0' as const\nexport const CODEX_CHATGPT_PROVIDER_ID = 'codex-chatgpt' as const\n\nexport const CODEX_API_BASE = 'https://chatgpt.com/backend-api/codex' as const\nexport const CODEX_RESPONSES_URL = `${CODEX_API_BASE}/responses` as const\nexport const CODEX_IMAGE_GENERATION_URL = `${CODEX_API_BASE}/images/generations` as const\nexport const CODEX_SEARCH_URL = `${CODEX_API_BASE}/alpha/search` as const\nexport const CODEX_USAGE_URL = 'https://chatgpt.com/backend-api/wham/usage' as const\nexport const CODEX_ORIGINATOR = 'opencode' as const\nexport const CODEX_ENHANCED_ORIGINATOR = 'pi' as const\nexport const CODEX_IMAGE_TOOL_NAME = 'codex_image_generate' as const\nexport const CODEX_IMAGE_MODEL = 'gpt-image-2' as const\nexport const CODEX_SEARCH_PROVIDER_ID = 'codex-subscription' as const\nexport const QUOTA_CACHE_MS = 60_000\nexport const QUOTA_MIN_UPSTREAM_INTERVAL_MS = 15_000\n\nexport const OAUTH_AUTHORIZE_URL = `${CHATGPT_OAUTH_ISSUER}/oauth/authorize` as const\nexport const OAUTH_TOKEN_URL = `${CHATGPT_OAUTH_ISSUER}/oauth/token` as const\n","import type { QuotaBucketDto, QuotaStatusDto, QuotaWindowDto } from '../shared/contracts.ts'\n\nexport interface SelectedQuotaWindow {\n bucket: QuotaBucketDto\n window: QuotaWindowDto\n remainingPercent: number\n}\n\nexport function selectQuotaForModel(quota: QuotaStatusDto | undefined, modelId: string | undefined): SelectedQuotaWindow | null {\n if (quota === undefined || quota.buckets.length === 0) return null\n const model = modelId?.toLowerCase() ?? ''\n const wantsSpark = model.includes('spark')\n const bucket = wantsSpark\n ? quota.buckets.find(candidate => `${candidate.id} ${candidate.name}`.toLowerCase().includes('spark'))\n : quota.buckets.find(candidate => candidate.id === 'codex')\n ?? quota.buckets.find(candidate => candidate.name.toLowerCase() === 'codex')\n if (bucket === undefined) return null\n const windows = quotaWindows(bucket)\n if (windows.length === 0) return null\n const window = windows.reduce((tightest, candidate) => (\n candidate.usedPercent > tightest.usedPercent ? candidate : tightest\n ), windows[0]!)\n return {\n bucket,\n window,\n remainingPercent: Math.max(0, 100 - window.usedPercent),\n }\n}\n\nexport function quotaWindows(bucket: QuotaBucketDto): QuotaWindowDto[] {\n if (bucket.windows.length > 0) return bucket.windows\n return [bucket.primary, bucket.secondary].filter((window): window is QuotaWindowDto => window !== null)\n}\n","import { useEffect, useMemo, useRef, useState, useSyncExternalStore } from 'react'\nimport type { SnapshotStore } from '@deepseek-ai/dsh-client-runtime/client'\nimport type { ModelDirectoryState } from '@deepseek-ai/dsh-client-ui-model-selection/client'\nimport type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport { CODEX_CHATGPT_PROVIDER_ID } from '../compat.ts'\nimport type { PluginStatusDto } from '../shared/contracts.ts'\nimport { SubscriptionApi } from './api.ts'\nimport { NS } from './locales.ts'\nimport { selectQuotaForModel } from './quota.ts'\n\ntype Props = PropsRuntime<'conversation.input.right'> & PropsLocale<typeof NS> & {\n api: SubscriptionApi\n directory: SnapshotStore<ModelDirectoryState>\n loadModelDirectory: () => void\n}\n\nexport function CodexComposerQuota({ api, directory, loadModelDirectory, t }: Props): React.JSX.Element | null {\n const modelState = useStore(directory)\n const [status, setStatus] = useState<PluginStatusDto | null>(null)\n const [loading, setLoading] = useState(false)\n const mountedRef = useRef(false)\n const selected = modelState.current\n const isCodex = selected?.provider === CODEX_CHATGPT_PROVIDER_ID\n\n useEffect(() => {\n loadModelDirectory()\n }, [loadModelDirectory])\n\n useEffect(() => {\n mountedRef.current = true\n return () => {\n mountedRef.current = false\n }\n }, [])\n\n useEffect(() => {\n if (!isCodex) return\n let disposed = false\n const refresh = async (): Promise<void> => {\n setLoading(true)\n try {\n const next = await api.status()\n if (!disposed && mountedRef.current) setStatus(next)\n } catch {\n if (!disposed && mountedRef.current) setStatus(null)\n } finally {\n if (!disposed && mountedRef.current) setLoading(false)\n }\n }\n void refresh()\n const timer = window.setInterval(() => {\n if (document.visibilityState === 'visible') void refresh()\n }, 60_000)\n return () => {\n disposed = true\n window.clearInterval(timer)\n }\n }, [api, isCodex])\n\n const quota = useMemo(() => selectQuotaForModel(status?.quota, selected?.model), [selected?.model, status?.quota])\n if (!isCodex || status?.preferences.quickQuotaVisible !== true) return null\n const level = quota === null\n ? 'normal'\n : quota.remainingPercent <= 5\n ? 'danger'\n : quota.remainingPercent <= 20\n ? 'warning'\n : 'normal'\n return <span className=\"dsh-codex-composer-quota\" data-level={level} aria-label={quota === null ? t('quickQuotaLoading') : `${t('quickQuotaLabel')}: ${formatPercent(quota.remainingPercent)}`}>\n <span>{t('quickQuotaLabel')}</span>\n <strong>{quota === null ? (loading ? t('quickQuotaLoading') : '—') : formatPercent(quota.remainingPercent)}</strong>\n </span>\n}\n\nfunction useStore<T>(store: SnapshotStore<T>): T {\n return useSyncExternalStore(\n (listener) => store.subscribe(listener),\n () => store.getSnapshot(),\n () => store.getSnapshot(),\n )\n}\n\nfunction formatPercent(value: number): string {\n return `${new Intl.NumberFormat(undefined, { maximumFractionDigits: 0 }).format(value)}%`\n}\n","import { useEffect, useState } from 'react'\nimport type { ImageAttachmentRef } from '@deepseek-ai/dsh-attachment'\nimport type { ContentBlock } from '@deepseek-ai/dsh-client-connection/client'\nimport type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport { NS } from './locales.ts'\n\nexport type ImageLoader = (attachment: ImageAttachmentRef) => Promise<string>\n\ntype Props = PropsRuntime<'tool.call.toolview'> & PropsLocale<typeof NS> & {\n loadImage: ImageLoader\n}\n\nexport function CodexImageToolView({ block, loadImage, t }: Props): React.JSX.Element {\n const settled = 'kind' in block\n const isError = settled ? block.isError : false\n const prompt = promptFromBlock(block)\n const images = settled && !isError ? imageBlocks(block.content) : []\n const label = isError ? t('imageToolFailed') : settled ? t('imageToolDone') : t('imageToolRunning')\n const summary = prompt ?? textSummary(settled ? block.content : [])\n return <div className=\"dsh-codex-image-tool\" data-state={isError ? 'error' : settled ? 'done' : 'running'}>\n <div className=\"dsh-codex-image-tool-head\">\n <span className=\"dsh-codex-image-dot\" aria-hidden=\"true\" />\n <span className=\"dsh-codex-image-title\">{label}</span>\n {summary !== null ? <span className=\"dsh-codex-image-summary\">{summary}</span> : null}\n </div>\n {images.length > 0 ? <div className=\"dsh-codex-image-grid\">\n {images.map((attachment) => <GeneratedImage key={String(attachment.attachmentId)} attachment={attachment} load={loadImage} label={attachment.name ?? t('image')} t={t} />)}\n </div> : null}\n </div>\n}\n\nfunction GeneratedImage({ attachment, load, label, t }: {\n attachment: ImageAttachmentRef\n load: ImageLoader\n label: string\n t: Props['t']\n}): React.JSX.Element {\n const [src, setSrc] = useState<string | null>(null)\n const [failed, setFailed] = useState(false)\n useEffect(() => {\n let disposed = false\n setSrc(null)\n setFailed(false)\n load(attachment).then((url) => {\n if (!disposed) setSrc(url)\n }, () => {\n if (!disposed) setFailed(true)\n })\n return () => {\n disposed = true\n }\n }, [attachment, load])\n if (failed) return <span className=\"dsh-codex-image-failed\">{t('imageLoadFailed')}</span>\n if (src === null) return <span className=\"dsh-codex-image-loading\">{t('imageLoading')}</span>\n return <img className=\"dsh-codex-image-preview\" src={src} alt={label} />\n}\n\nfunction promptFromBlock(block: Props['block']): string | null {\n const raw = 'kind' in block ? block.call?.argsRaw : block.argsRaw\n if (typeof raw !== 'string' || raw.trim() === '') return null\n try {\n const value = JSON.parse(raw) as unknown\n return typeof value === 'object'\n && value !== null\n && !Array.isArray(value)\n && typeof (value as { prompt?: unknown }).prompt === 'string'\n ? (value as { prompt: string }).prompt\n : null\n } catch {\n return null\n }\n}\n\nfunction imageBlocks(blocks: readonly ContentBlock[]): ImageAttachmentRef[] {\n const result: ImageAttachmentRef[] = []\n for (const block of blocks) {\n if (block.type === 'image') result.push(block.attachment)\n if (block.type === 'tool-result') result.push(...imageBlocks(block.content))\n }\n return result\n}\n\nfunction textSummary(blocks: readonly ContentBlock[]): string | null {\n const text = blocks\n .map((block) => block.type === 'text' || block.type === 'reasoning' ? block.text : '')\n .filter(Boolean)\n .join(' ')\n .trim()\n return text === '' ? null : text\n}\n","export type CodexModelModality = 'text' | 'image'\n\nexport const GPT_56_MAX_CONTEXT_WINDOW = 1_000_000\n\nexport interface CodexModelCatalogEntry {\n id: string\n name: string\n contextWindow: number\n inputModalities: readonly CodexModelModality[]\n defaultReasoningEffort: string\n reasoningProfile: 'standard' | 'gpt-5.6'\n supportsReasoningSummary: boolean\n}\n\nexport const CODEX_MODEL_CATALOG = [\n {\n id: 'gpt-5.6-sol',\n name: '5.6 Sol',\n contextWindow: 272_000,\n inputModalities: ['text', 'image'],\n defaultReasoningEffort: 'medium',\n reasoningProfile: 'gpt-5.6',\n supportsReasoningSummary: true,\n },\n {\n id: 'gpt-5.6-terra',\n name: '5.6 Terra',\n contextWindow: 272_000,\n inputModalities: ['text', 'image'],\n defaultReasoningEffort: 'medium',\n reasoningProfile: 'gpt-5.6',\n supportsReasoningSummary: true,\n },\n {\n id: 'gpt-5.6-luna',\n name: '5.6 Luna',\n contextWindow: 272_000,\n inputModalities: ['text', 'image'],\n defaultReasoningEffort: 'medium',\n reasoningProfile: 'gpt-5.6',\n supportsReasoningSummary: true,\n },\n {\n id: 'gpt-5.5',\n name: '5.5',\n contextWindow: 272_000,\n inputModalities: ['text', 'image'],\n defaultReasoningEffort: 'medium',\n reasoningProfile: 'standard',\n supportsReasoningSummary: true,\n },\n {\n id: 'gpt-5.4',\n name: '5.4',\n contextWindow: 272_000,\n inputModalities: ['text', 'image'],\n defaultReasoningEffort: 'none',\n reasoningProfile: 'standard',\n supportsReasoningSummary: true,\n },\n {\n id: 'gpt-5.4-mini',\n name: '5.4 Mini',\n contextWindow: 272_000,\n inputModalities: ['text', 'image'],\n defaultReasoningEffort: 'none',\n reasoningProfile: 'standard',\n supportsReasoningSummary: true,\n },\n {\n id: 'gpt-5.3-codex-spark',\n name: '5.3 Codex Spark',\n contextWindow: 258_000,\n inputModalities: ['text'],\n defaultReasoningEffort: 'high',\n reasoningProfile: 'standard',\n supportsReasoningSummary: false,\n },\n] as const satisfies readonly CodexModelCatalogEntry[]\n\nexport type CodexModelId = typeof CODEX_MODEL_CATALOG[number]['id']\n\nexport const DEFAULT_CODEX_MODEL = CODEX_MODEL_CATALOG[0]\n\nexport const CONFIGURABLE_CONTEXT_MODEL_IDS = [\n 'gpt-5.6-sol',\n 'gpt-5.6-terra',\n 'gpt-5.6-luna',\n] as const satisfies readonly CodexModelId[]\n\nexport type ConfigurableContextModelId = typeof CONFIGURABLE_CONTEXT_MODEL_IDS[number]\n\nexport const STANDARD_REASONING_EFFORTS = ['none', 'low', 'medium', 'high', 'xhigh'] as const\nexport const GPT_56_REASONING_EFFORTS = [...STANDARD_REASONING_EFFORTS, 'max'] as const\nexport type CodexReasoningEffort = typeof GPT_56_REASONING_EFFORTS[number]\n\nexport function reasoningEffortsForModel(model: string): readonly CodexReasoningEffort[] {\n return resolveCodexCatalogEntry(model).reasoningProfile === 'gpt-5.6'\n ? GPT_56_REASONING_EFFORTS\n : STANDARD_REASONING_EFFORTS\n}\n\nexport function isCodexReasoningEffort(value: unknown): value is CodexReasoningEffort {\n return typeof value === 'string' && GPT_56_REASONING_EFFORTS.some((effort) => effort === value)\n}\n\nexport function modelSupportsReasoningEffort(model: string, effort: unknown): effort is CodexReasoningEffort {\n return isCodexReasoningEffort(effort) && reasoningEffortsForModel(model).some((candidate) => candidate === effort)\n}\n\nexport function isCodexModelId(model: unknown): model is CodexModelId {\n return typeof model === 'string' && CODEX_MODEL_CATALOG.some((entry) => entry.id === model)\n}\n\nexport function isConfigurableContextModelId(model: unknown): model is ConfigurableContextModelId {\n return typeof model === 'string' && CONFIGURABLE_CONTEXT_MODEL_IDS.some((id) => id === model)\n}\n\nexport function resolveCodexCatalogEntry(model: string): CodexModelCatalogEntry {\n return CODEX_MODEL_CATALOG.find((entry) => entry.id === model) ?? DEFAULT_CODEX_MODEL\n}\n\nexport function codexModelSupportsImageInput(model: string): boolean {\n return resolveCodexCatalogEntry(model).inputModalities.includes('image')\n}\n\nexport function codexModelSupportsReasoningSummary(model: string): boolean {\n return resolveCodexCatalogEntry(model).supportsReasoningSummary\n}\n","import { ROUTE_PREFIX } from '../compat.ts'\r\nimport type {\r\n ApiEnvelope,\r\n LoginEventDto,\r\n LoginStartDto,\r\n PluginStatusDto,\n QuotaStatusDto,\n ConnectionTestDto,\n SubscriptionPreferencesDto,\n SubscriptionPreferencesUpdateDto,\n} from '../shared/contracts.ts'\n\r\nexport class SubscriptionApi {\r\n status(): Promise<PluginStatusDto> {\r\n return request<PluginStatusDto>(`${ROUTE_PREFIX}/status`)\r\n }\r\n\r\n startLogin(): Promise<LoginStartDto> {\r\n return post<LoginStartDto>(`${ROUTE_PREFIX}/login/start`, {})\r\n }\r\n\r\n cancelLogin(loginId: string): Promise<{ cancelled: boolean }> {\r\n return post(`${ROUTE_PREFIX}/login/cancel`, { loginId })\r\n }\r\n\r\n logout(): Promise<{ authenticated: false }> {\r\n return post(`${ROUTE_PREFIX}/logout`, {})\r\n }\r\n\r\n refresh(): Promise<PluginStatusDto> {\r\n return post(`${ROUTE_PREFIX}/token/refresh`, {})\r\n }\r\n\r\n refreshQuota(): Promise<QuotaStatusDto> {\r\n return post(`${ROUTE_PREFIX}/quota/refresh`, {})\r\n }\r\n\r\n testConnection(): Promise<ConnectionTestDto> {\n return post(`${ROUTE_PREFIX}/connection/test`, {})\n }\n\n updatePreferences(patch: SubscriptionPreferencesUpdateDto): Promise<SubscriptionPreferencesDto> {\n return post(`${ROUTE_PREFIX}/preferences/update`, patch)\n }\n\n events(loginId: string): EventSource {\n return new EventSource(`${ROUTE_PREFIX}/login/events?loginId=${encodeURIComponent(loginId)}`)\n }\n}\n\r\nasync function post<T>(url: string, body: object): Promise<T> {\n return request<T>(url, {\r\n method: 'POST',\r\n headers: { 'content-type': 'application/json' },\r\n body: JSON.stringify(body),\r\n })\r\n}\r\n\r\nasync function request<T>(url: string, init?: RequestInit): Promise<T> {\r\n const response = await fetch(url, { ...init, credentials: 'same-origin' })\r\n const envelope = await response.json() as ApiEnvelope<T>\r\n if (!response.ok || !envelope.ok) {\r\n throw new Error(envelope.ok ? `Request failed (${response.status})` : envelope.error.message)\r\n }\r\n return envelope.value\r\n}\r\n\r\nexport function parseLoginEvent(event: MessageEvent<string>): LoginEventDto | null {\r\n try {\r\n const value = JSON.parse(event.data) as LoginEventDto\r\n return typeof value === 'object' && value !== null && typeof value.type === 'string' ? value : null\r\n } catch {\r\n return null\r\n }\r\n}\r\n","import { useCallback, useEffect, useRef, useState } from 'react'\r\nimport type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\r\nimport type { CredentialStorageDto, PluginStatusDto, QuotaBucketDto, QuotaWindowDto, SubscriptionPreferencesUpdateDto } from '../shared/contracts.ts'\r\nimport { CODEX_MODEL_CATALOG, CONFIGURABLE_CONTEXT_MODEL_IDS, GPT_56_MAX_CONTEXT_WINDOW, reasoningEffortsForModel, resolveCodexCatalogEntry } from '../shared/model-catalog.ts'\r\nimport { SubscriptionApi, parseLoginEvent } from './api.ts'\r\nimport { NS } from './locales.ts'\r\nimport { quotaWindows } from './quota.ts'\r\n\r\ntype Props = PropsRuntime<'settings.section'> & PropsLocale<typeof NS>\r\ntype BusyAction = 'login' | 'token' | 'quota' | 'test' | 'logout' | 'preferences' | null\r\ntype Translate = Props['t']\r\n\r\nexport function CodexSubscriptionSection({ t }: Props): React.JSX.Element {\r\n const apiRef = useRef(new SubscriptionApi())\r\n const eventSourceRef = useRef<EventSource | null>(null)\r\n const [status, setStatus] = useState<PluginStatusDto | null>(null)\r\n const [busy, setBusy] = useState<BusyAction>(null)\r\n const [error, setError] = useState<string | null>(null)\r\n const [authUrl, setAuthUrl] = useState<string | null>(null)\r\n const [popupBlocked, setPopupBlocked] = useState(false)\r\n const [connection, setConnection] = useState<{ latencyMs: number; checkedAt: number } | null>(null)\r\n const [contextDrafts, setContextDrafts] = useState<Record<string, string>>({})\r\n\r\n const load = useCallback(async (quiet = false) => {\r\n if (!quiet) setError(null)\r\n try {\r\n const next = await apiRef.current.status()\r\n setStatus(next)\r\n if (next.error !== undefined) setError(next.error.message)\r\n } catch (cause) {\r\n if (!quiet) setError(messageOf(cause))\r\n }\r\n }, [])\r\n\r\n useEffect(() => {\r\n void load()\r\n const refreshWhenVisible = (): void => {\r\n if (document.visibilityState === 'visible') void load(true)\r\n }\r\n document.addEventListener('visibilitychange', refreshWhenVisible)\r\n const timer = window.setInterval(refreshWhenVisible, 60_000)\r\n return () => {\r\n window.clearInterval(timer)\r\n document.removeEventListener('visibilitychange', refreshWhenVisible)\r\n eventSourceRef.current?.close()\r\n }\r\n }, [load])\r\n\r\n const watchLogin = useCallback((loginId: string) => {\r\n eventSourceRef.current?.close()\r\n const source = apiRef.current.events(loginId)\r\n eventSourceRef.current = source\r\n const finish = async (message?: string): Promise<void> => {\r\n source.close()\r\n eventSourceRef.current = null\r\n setBusy(null)\r\n setAuthUrl(null)\r\n if (message !== undefined) setError(message)\r\n // Preserve the terminal OAuth error while refreshing the account DTO.\r\n await load(true)\r\n }\r\n source.addEventListener('completed', (event) => {\r\n const parsed = parseLoginEvent(event as MessageEvent<string>)\r\n if (parsed?.type === 'completed') void finish()\r\n })\r\n source.addEventListener('cancelled', () => void finish())\r\n source.addEventListener('failed', (event) => {\r\n const parsed = parseLoginEvent(event as MessageEvent<string>)\r\n void finish(parsed?.type === 'failed' ? parsed.error.message : 'ChatGPT sign-in failed.')\r\n })\r\n }, [load])\r\n\r\n useEffect(() => {\r\n const loginId = status?.login.active ? status.login.loginId : null\r\n if (loginId !== null && loginId !== undefined && eventSourceRef.current === null) watchLogin(loginId)\r\n }, [status?.login.active, status?.login.loginId, watchLogin])\r\n\r\n const startLogin = async (): Promise<void> => {\r\n setBusy('login')\r\n setError(null)\r\n setPopupBlocked(false)\r\n const popup = window.open('about:blank', 'dsh-chatgpt-oauth', 'popup,width=560,height=760')\r\n try {\r\n const login = await apiRef.current.startLogin()\r\n setAuthUrl(login.authUrl)\r\n if (popup === null) setPopupBlocked(true)\r\n else popup.location.replace(login.authUrl)\r\n watchLogin(login.loginId)\r\n await load(true)\r\n } catch (cause) {\r\n popup?.close()\r\n setBusy(null)\r\n setError(messageOf(cause))\r\n }\r\n }\r\n\r\n const cancelLogin = async (): Promise<void> => {\r\n const loginId = status?.login.loginId\r\n if (loginId === null || loginId === undefined) return\r\n setBusy('login')\r\n try {\r\n await apiRef.current.cancelLogin(loginId)\r\n eventSourceRef.current?.close()\r\n eventSourceRef.current = null\r\n setAuthUrl(null)\r\n await load()\r\n } catch (cause) {\r\n setError(messageOf(cause))\r\n } finally {\r\n setBusy(null)\r\n }\r\n }\r\n\r\n const refreshToken = async (): Promise<void> => run('token', async () => {\r\n setStatus(await apiRef.current.refresh())\r\n })\r\n\r\n const refreshQuota = async (): Promise<void> => run('quota', async () => {\r\n const quota = await apiRef.current.refreshQuota()\r\n setStatus((current) => current === null ? current : { ...current, quota })\r\n })\r\n\r\n const testConnection = async (): Promise<void> => run('test', async () => {\r\n const result = await apiRef.current.testConnection()\r\n setConnection({ latencyMs: result.latencyMs, checkedAt: result.checkedAt })\r\n })\r\n\r\n const updatePreferences = async (patch: SubscriptionPreferencesUpdateDto): Promise<void> => run('preferences', async () => {\r\n const preferences = await apiRef.current.updatePreferences(patch)\r\n setStatus((current) => current === null ? current : { ...current, preferences })\r\n })\r\n\r\n const updateContextWindow = async (model: (typeof CONFIGURABLE_CONTEXT_MODEL_IDS)[number]): Promise<void> => {\r\n const current = status?.preferences.contextWindowOverrides[model] ?? resolveCodexCatalogEntry(model).contextWindow\r\n const parsed = parseCapacity(contextDrafts[model] ?? String(current))\r\n if (parsed === null) {\r\n setError(t('contextWindowInvalid'))\r\n return\r\n }\r\n await updatePreferences({ contextWindowOverrides: { [model]: parsed } })\r\n setContextDrafts((drafts) => ({ ...drafts, [model]: String(parsed) }))\r\n }\r\n\r\n const logout = async (): Promise<void> => run('logout', async () => {\r\n await apiRef.current.logout()\r\n eventSourceRef.current?.close()\r\n eventSourceRef.current = null\r\n setAuthUrl(null)\r\n setConnection(null)\r\n await load()\r\n })\r\n\r\n const run = async (action: Exclude<BusyAction, null>, task: () => Promise<void>): Promise<void> => {\r\n setBusy(action)\r\n setError(null)\r\n try {\r\n await task()\r\n } catch (cause) {\r\n setError(messageOf(cause))\r\n } finally {\r\n setBusy(null)\r\n }\r\n }\r\n\r\n const account = status?.account\r\n return <section className=\"dsh-codex-page\" aria-labelledby=\"dsh-codex-title\">\r\n <header>\r\n <h2 id=\"dsh-codex-title\" className=\"dsh-codex-title\">{t('title')}</h2>\r\n <p className=\"dsh-codex-intro\">{t('intro')}</p>\r\n </header>\r\n\r\n {error !== null ? <div className=\"dsh-codex-errorbar\" role=\"alert\">\r\n <span>{error}</span>\r\n {status === null ? <Button disabled={busy !== null} onClick={() => load()}>{t('retry')}</Button> : null}\r\n </div> : null}\r\n\r\n {status === null && error === null ? <Skeleton label={t('loading')} /> : <>\r\n <Section title={t('account')}>\r\n <InfoRow label={status?.authenticated ? t('signedIn') : t('signedOut')} value={account?.email ?? '—'} />\r\n {status?.authenticated ? <>\r\n <InfoRow label={t('plan')} value={account?.planType ?? t('unknown')} />\r\n <InfoRow label={t('accountId')} value={account?.accountIdSuffix ?? '—'} />\r\n <InfoRow label={t('expires')} value={formatDate(account?.tokenExpiresAt)} />\r\n </> : null}\r\n <InfoRow label={t('storage')} value={storageLabel(status?.storage, t)} />\r\n <p className=\"dsh-codex-notice\">{storageNotice(status?.storage, t)}</p>\r\n {status?.login.active ? <p className=\"dsh-codex-muted\" role=\"status\">{t('pending')}</p> : null}\r\n {popupBlocked ? <p className=\"dsh-codex-error\">{t('popupBlocked')}</p> : null}\r\n {authUrl !== null ? <a className=\"dsh-codex-link\" href={authUrl} target=\"_blank\" rel=\"noreferrer\">{t('continueLogin')}</a> : null}\r\n <div className=\"dsh-codex-actions\">\r\n {status?.login.active\r\n ? <Button disabled={busy !== null} onClick={cancelLogin}>{t('cancel')}</Button>\r\n : <Button primary disabled={busy !== null || status?.storage.available === false} onClick={startLogin}>{status?.authenticated ? t('signInAgain') : t('signIn')}</Button>}\r\n {status?.authenticated ? <>\r\n <Button disabled={busy !== null} onClick={refreshToken}>{t('refreshToken')}</Button>\r\n <Button disabled={busy !== null} onClick={logout}>{t('signOut')}</Button>\r\n </> : null}\r\n </div>\r\n </Section>\r\n\r\n <Section title={t('connection')}>\r\n <InfoRow label={t('provider')} value=\"Codex(ChatGPT 订阅) · codex-chatgpt\" />\r\n <InfoRow label={t('connectionState')} value={connection === null ? t('untested') : t('connected')} />\r\n {connection !== null ? <InfoRow label={t('latency')} value={`${connection.latencyMs} ms · ${formatDate(connection.checkedAt)}`} /> : null}\r\n <div className=\"dsh-codex-models\" aria-label={t('models')}>\r\n {CODEX_MODEL_CATALOG.map((model) => <code key={model.id} title={model.id}>{model.name}</code>)}\r\n </div>\r\n <div className=\"dsh-codex-actions\">\r\n <Button disabled={!status?.authenticated || busy !== null} onClick={testConnection}>{busy === 'test' ? t('testing') : t('testConnection')}</Button>\r\n </div>\r\n </Section>\r\n\r\n <Section title={t('enhancements')}>\r\n <div className=\"dsh-codex-pref-row\">\r\n <div>\r\n <strong>{t('searchProvider')}</strong>\r\n <p className=\"dsh-codex-muted\">{t('searchProviderHint')}</p>\r\n </div>\r\n <div className=\"dsh-codex-segments\" role=\"radiogroup\" aria-label={t('searchProvider')}>\r\n <label>\r\n <input type=\"radio\" name=\"dsh-codex-search-provider\" checked={status?.preferences.searchProvider === 'dsh'} disabled={busy !== null} onChange={() => updatePreferences({ searchProvider: 'dsh' })} />\r\n <span>{t('searchProviderDsh')}</span>\r\n </label>\r\n <label>\r\n <input type=\"radio\" name=\"dsh-codex-search-provider\" checked={status?.preferences.searchProvider === 'codex'} disabled={busy !== null} onChange={() => updatePreferences({ searchProvider: 'codex' })} />\r\n <span>{t('searchProviderCodex')}</span>\r\n </label>\r\n </div>\r\n </div>\r\n <div className=\"dsh-codex-pref-row\">\r\n <div>\r\n <strong>{t('subagentModel')}</strong>\r\n <p className=\"dsh-codex-muted\">{t('subagentModelHint')}</p>\r\n </div>\r\n <select className=\"dsh-codex-select\" aria-label={t('subagentModel')} value={status?.preferences.subagentModel ?? CODEX_MODEL_CATALOG[0].id} disabled={busy !== null} onChange={(event) => {\r\n const subagentModel = event.currentTarget.value\r\n const currentEffort = status?.preferences.subagentReasoningEffort ?? resolveCodexCatalogEntry(subagentModel).defaultReasoningEffort\r\n const supportedEfforts = reasoningEffortsForModel(subagentModel)\r\n void updatePreferences({\r\n subagentModel,\r\n subagentReasoningEffort: supportedEfforts.includes(currentEffort as never)\r\n ? currentEffort\r\n : resolveCodexCatalogEntry(subagentModel).defaultReasoningEffort,\r\n })\r\n }}>\r\n {CODEX_MODEL_CATALOG.map((model) => <option key={model.id} value={model.id}>{model.name}</option>)}\r\n </select>\r\n </div>\r\n <div className=\"dsh-codex-pref-row\">\r\n <div>\r\n <strong>{t('subagentReasoningEffort')}</strong>\r\n <p className=\"dsh-codex-muted\">{t('subagentReasoningEffortHint')}</p>\r\n </div>\r\n <select className=\"dsh-codex-select\" aria-label={t('subagentReasoningEffort')} value={status?.preferences.subagentReasoningEffort ?? 'medium'} disabled={busy !== null} onChange={(event) => void updatePreferences({ subagentModel: status?.preferences.subagentModel ?? CODEX_MODEL_CATALOG[0].id, subagentReasoningEffort: event.currentTarget.value })}>\r\n {reasoningEffortsForModel(status?.preferences.subagentModel ?? CODEX_MODEL_CATALOG[0].id).map((effort) => <option key={effort} value={effort}>{reasoningEffortLabel(effort, t)}</option>)}\r\n </select>\r\n </div>\r\n <div className=\"dsh-codex-context-settings\">\r\n <div>\r\n <strong>{t('contextWindows')}</strong>\r\n <p className=\"dsh-codex-muted\">{t('contextWindowsHint')}</p>\r\n </div>\r\n {CONFIGURABLE_CONTEXT_MODEL_IDS.map((model) => {\r\n const fallback = status?.preferences.contextWindowOverrides[model] ?? resolveCodexCatalogEntry(model).contextWindow\r\n return <label className=\"dsh-codex-context-row\" key={model}>\r\n <span>{resolveCodexCatalogEntry(model).name}</span>\r\n <span className=\"dsh-codex-capacity-control\">\r\n <input type=\"text\" inputMode=\"numeric\" value={contextDrafts[model] ?? formatCapacity(fallback)} disabled={busy !== null} aria-label={resolveCodexCatalogEntry(model).name + ' ' + t('contextWindow')} onChange={(event) => setContextDrafts((drafts) => ({ ...drafts, [model]: event.currentTarget.value }))} onBlur={() => void updateContextWindow(model)} onKeyDown={(event) => { if (event.key === 'Enter') event.currentTarget.blur() }} />\r\n <small>{t('tokens')}</small>\r\n </span>\r\n </label>\r\n })}\r\n </div>\r\n <label className=\"dsh-codex-check\">\r\n <input type=\"checkbox\" checked={status?.preferences.quickQuotaVisible === true} disabled={busy !== null} onChange={(event) => updatePreferences({ quickQuotaVisible: event.currentTarget.checked })} />\r\n <span>\r\n <strong>{t('quickQuota')}</strong>\r\n <small>{t('quickQuotaHint')}</small>\r\n </span>\r\n </label>\r\n </Section>\r\n\r\n <Section title={t('quota')} aside={<Button disabled={!status?.authenticated || busy !== null} onClick={refreshQuota}>{busy === 'quota' ? t('refreshing') : t('refreshQuota')}</Button>}>\r\n <p className=\"dsh-codex-muted\">{t('quotaIntro')}</p>\r\n {status?.quota.state === 'signed-out' ? <p className=\"dsh-codex-empty\">{t('quotaSignedOut')}</p> : null}\r\n {status?.quota.buckets.map((bucket) => <QuotaBucket key={bucket.id} bucket={bucket} t={t} />)}\r\n {status?.quota.credits !== null && status?.quota.credits !== undefined ? <QuotaFact label={t('credits')} value={status.quota.credits.unlimited ? t('unlimited') : status.quota.credits.balance ?? (status.quota.credits.hasCredits ? t('available') : t('unavailable'))} /> : null}\r\n {status?.quota.individualLimit !== null && status?.quota.individualLimit !== undefined ? <QuotaFact label={t('monthlySpend')} value={individualLimitLabel(status.quota.individualLimit, t)} /> : null}\r\n {status?.quota.resetCredits !== null && status?.quota.resetCredits !== undefined ? <QuotaFact label={t('resetCredits')} value={String(status.quota.resetCredits.availableCount)} /> : null}\r\n {status?.quota.spendControlReached === true ? <p className=\"dsh-codex-warning\" role=\"status\">{t('spendControlReached')}</p> : null}\r\n {status?.quota.state === 'empty' ? <p className=\"dsh-codex-empty\">{t('noQuota')}</p> : null}\r\n {status?.quota.stale ? <p className=\"dsh-codex-warning\" role=\"status\">{t('stale')}</p> : null}\r\n {status?.quota.error ? <p className=\"dsh-codex-error\" role=\"alert\">{status.quota.error.message}</p> : null}\r\n {status?.quota.fetchedAt ? <p className=\"dsh-codex-timestamp\">{t('updated')}: {formatDate(status.quota.fetchedAt)}</p> : null}\r\n </Section>\r\n </>}\r\n\r\n <span className=\"dsh-codex-sr\" aria-live=\"polite\">{busy === null ? '' : busy}</span>\r\n </section>\r\n}\r\n\r\nfunction Section({ title, aside, children }: { title: string; aside?: React.ReactNode; children: React.ReactNode }): React.JSX.Element {\r\n return <section className=\"dsh-codex-group\">\r\n <div className=\"dsh-codex-grouphead\"><h3>{title}</h3>{aside}</div>\r\n {children}\r\n </section>\r\n}\r\n\r\nfunction Button({ primary = false, disabled, onClick, children }: { primary?: boolean; disabled?: boolean; onClick: () => void | Promise<void>; children: React.ReactNode }): React.JSX.Element {\r\n return <button className={`dsh-codex-button${primary ? ' dsh-codex-button-primary' : ''}`} type=\"button\" disabled={disabled} onClick={() => void onClick()}>{children}</button>\r\n}\r\n\r\nfunction InfoRow({ label, value }: { label: string; value: string }): React.JSX.Element {\r\n return <div className=\"dsh-codex-row\"><span className=\"dsh-codex-label\">{label}</span><span className=\"dsh-codex-value\">{value}</span></div>\r\n}\r\n\r\nexport function storageLabel(storage: CredentialStorageDto | undefined, t: Translate): string {\r\n if (storage === undefined || !storage.available) return t('storageUnavailable')\r\n if (storage.kind === 'windows-dpapi') return t('storageWindows')\r\n if (storage.kind === 'macos-keychain') return t('storageMacKeychain')\r\n if (storage.kind === 'linux-file') return t('storageLinuxFile')\r\n if (storage.kind === 'memory') return t('storageMemory')\r\n return t('storageUnavailable')\r\n}\r\n\r\nexport function storageNotice(storage: CredentialStorageDto | undefined, t: Translate): string {\r\n if (storage === undefined || !storage.available) return t('securityUnavailable')\r\n if (storage.kind === 'windows-dpapi') return t('securityWindows')\r\n if (storage.kind === 'macos-keychain') return t('securityMacKeychain')\r\n if (storage.kind === 'linux-file') return t('securityLinuxFile')\r\n if (storage.kind === 'memory') return t('securityMemory')\r\n return t('securityUnavailable')\r\n}\r\n\r\nfunction QuotaBucket({ bucket, t }: { bucket: QuotaBucketDto; t: Translate }): React.JSX.Element {\r\n const windows = quotaWindows(bucket)\r\n return <article className=\"dsh-codex-quota-card\">\r\n <div className=\"dsh-codex-quota-title\"><strong>{bucket.name}</strong>{bucket.planType ? <span>{bucket.planType}</span> : null}</div>\r\n {windows.map((window, index) => <QuotaBar key={`${window.windowDurationMins ?? 'x'}:${window.resetsAt ?? 'x'}:${index}`} label={windowLabel(window.windowDurationMins, t)} window={window} t={t} />)}\r\n </article>\r\n}\r\n\r\nfunction QuotaFact({ label, value }: { label: string; value: string }): React.JSX.Element {\r\n return <div className=\"dsh-codex-quota-fact\"><span>{label}</span><strong>{value}</strong></div>\r\n}\r\n\r\nexport function QuotaBar({ label, window, t }: { label: string; window: QuotaWindowDto; t: Translate }): React.JSX.Element {\r\n const percent = window.usedPercent\r\n const level = percent >= 95 ? 'danger' : percent >= 80 ? 'warning' : 'normal'\r\n const remaining = Math.max(0, 100 - percent)\r\n return <div className=\"dsh-codex-meter-wrap\">\r\n <div className=\"dsh-codex-meter-label\"><span>{label}</span><strong>{formatPercent(percent)}</strong></div>\r\n <div className={`dsh-codex-meter dsh-codex-meter-${level}`} role=\"progressbar\" aria-label={`${label}: ${formatPercent(percent)} ${t('used')}`} aria-valuemin={0} aria-valuemax={100} aria-valuenow={percent}>\r\n <span style={{ width: `${percent}%` }} />\r\n </div>\r\n <div className=\"dsh-codex-meter-meta\">\r\n <span>{percent >= 100 ? `${t('exhausted')} · ${formatPercent(remaining)} ${t('remaining')}` : `${formatPercent(percent)} ${t('used')} · ${formatPercent(remaining)} ${t('remaining')}`}</span>\r\n <span>{window.resetsAt === null ? '—' : `${t('resets')}: ${formatReset(window.resetsAt)}`}</span>\r\n </div>\r\n </div>\r\n}\r\n\r\nfunction Skeleton({ label }: { label: string }): React.JSX.Element {\r\n return <div className=\"dsh-codex-skeleton\" role=\"status\" aria-label={label}><span /><span /></div>\r\n}\r\n\r\nexport function windowLabel(minutes: number | null, t: Translate): string {\r\n if (minutes === null) return t('limitWindow')\r\n const [value, unit]: [number, Intl.NumberFormatOptions['unit']] = minutes >= 1440 && minutes % 1440 === 0\r\n ? [minutes / 1440, 'day']\r\n : minutes >= 60 && minutes % 60 === 0\r\n ? [minutes / 60, 'hour']\r\n : [Math.round(minutes), 'minute']\r\n return `${new Intl.NumberFormat(undefined, { style: 'unit', unit, unitDisplay: 'long' }).format(value)} ${t('limitWindow')}`\r\n}\r\n\r\nfunction reasoningEffortLabel(effort: string, t: Translate): string {\r\n const labels: Record<string, keyof typeof import('./locales.ts').zh> = {\r\n none: 'reasoningNone',\r\n low: 'reasoningLow',\r\n medium: 'reasoningMedium',\r\n high: 'reasoningHigh',\r\n xhigh: 'reasoningXhigh',\r\n max: 'reasoningMax',\r\n }\r\n return t(labels[effort] ?? 'unknown')\r\n}\r\n\r\nexport function parseCapacity(value: string): number | null {\r\n const normalized = value.trim().toLowerCase().replace(/[,_\\s]/g, '')\r\n const matched = normalized.match(/^(\\d+(?:\\.\\d+)?)(k|m)?$/)\r\n if (matched === null) return null\r\n const multiplier = matched[2] === 'm' ? 1_000_000 : matched[2] === 'k' ? 1_000 : 1\r\n const parsed = Number(matched[1]) * multiplier\r\n return Number.isSafeInteger(parsed) && parsed >= 1 && parsed <= GPT_56_MAX_CONTEXT_WINDOW ? parsed : null\r\n}\r\n\r\nfunction formatCapacity(value: number): string {\r\n if (value % 1_000 === 0) return `${value / 1_000}K`\r\n return String(value)\r\n}\r\n\r\nfunction formatPercent(value: number): string {\r\n return `${new Intl.NumberFormat(undefined, { maximumFractionDigits: 1 }).format(value)}%`\r\n}\r\n\r\nfunction individualLimitLabel(limit: NonNullable<PluginStatusDto['quota']['individualLimit']>, t: Translate): string {\r\n const parts = [\r\n limit.remainingPercent !== null ? `${formatPercent(limit.remainingPercent)} ${t('remaining')}` : null,\r\n limit.limit !== null ? `${t('limit')}: ${limit.limit}` : null,\r\n limit.used !== null ? `${t('used')}: ${limit.used}` : null,\r\n limit.resetsAt !== null ? `${t('resets')}: ${formatReset(limit.resetsAt)}` : null,\r\n ].filter((part): part is string => part !== null)\r\n return parts.length > 0 ? parts.join(' · ') : t('unknown')\r\n}\r\n\r\nfunction formatDate(seconds: number | undefined): string {\r\n if (seconds === undefined) return '—'\r\n return new Intl.DateTimeFormat(undefined, { dateStyle: 'medium', timeStyle: 'short' }).format(seconds * 1000)\r\n}\r\n\r\nexport function formatReset(seconds: number): string {\r\n const absolute = formatDate(seconds)\r\n const diff = seconds * 1000 - Date.now()\r\n const abs = Math.abs(diff)\r\n const [amount, unit]: [number, Intl.RelativeTimeFormatUnit] = abs >= 86_400_000\r\n ? [Math.round(diff / 86_400_000), 'day']\r\n : abs >= 3_600_000\r\n ? [Math.round(diff / 3_600_000), 'hour']\r\n : [Math.round(diff / 60_000), 'minute']\r\n return `${absolute} (${new Intl.RelativeTimeFormat(undefined, { numeric: 'auto' }).format(amount, unit)})`\r\n}\r\n\r\nfunction messageOf(error: unknown): string {\r\n return error instanceof Error ? error.message : String(error)\r\n}\r\n","export const NS = 'dsh-chatgpt-subscription' as const\n\nexport const zh = {\n title: 'Codex 订阅',\n intro: '使用 ChatGPT 账号登录,在 DSH 中使用订阅可用的 Codex 模型。',\n account: '账号',\n signedOut: '尚未登录',\n signedIn: '已登录',\n plan: '套餐',\n accountId: '账号 ID',\n expires: '令牌到期',\n storage: '凭据存储',\n storageWindows: 'Windows DPAPI(当前用户加密)',\n storageMacKeychain: 'macOS 钥匙串(Keychain 加密)',\n storageLinuxFile: 'Linux 用户私有文件(权限 0600)',\n storageMemory: '仅 Host 内存(不持久化)',\n storageUnavailable: '凭据存储不可用',\n securityWindows: '令牌由 Host 使用 Windows CurrentUser DPAPI 加密,不会进入浏览器、settings.yaml 或日志。',\n securityMacKeychain: '令牌由 Host 存入 macOS 登录钥匙串(Keychain),在本机加密保存,不会进入浏览器、settings.yaml 或日志。',\n securityLinuxFile: '令牌仅写入 Host 上当前 Linux 用户可读的 0600 文件,但不会额外加密;同 UID 进程、root、备份和磁盘快照仍可能读取。',\n securityMemory: '令牌仅保留在 Host 内存中,Host 退出后丢失。',\n securityUnavailable: 'Host 无法安全访问凭据存储;请修复文件所有者或权限后重试。',\n signIn: '使用 ChatGPT 登录',\n signInAgain: '重新登录',\n cancel: '取消登录',\n signOut: '注销',\n refreshToken: '刷新凭据',\n pending: '请在浏览器中完成登录。',\n popupBlocked: '浏览器拦截了登录窗口,请使用下面的链接继续。',\n continueLogin: '打开 ChatGPT 登录页',\n loading: '正在读取状态…',\n connection: '连接',\n provider: 'Provider',\n connectionState: '连接状态',\n connected: '可用',\n untested: '尚未测试',\n testConnection: '测试连接',\n testing: '测试中…',\n latency: '最近延迟',\n models: '可用模型',\n enhancements: '增强功能',\n searchProvider: '搜索来源',\n searchProviderHint: '选择 DSH Web 搜索工具使用默认来源,或改用当前 ChatGPT 订阅的 Codex 搜索来源。',\n searchProviderDsh: 'DSH 默认',\n searchProviderCodex: 'Codex 订阅',\n subagentModel: '子代理模型',\n subagentModelHint: '新启动的内置子代理使用此 ChatGPT 订阅模型;父会话的模型选择不受影响。',\n subagentReasoningEffort: '子代理思考深度',\n subagentReasoningEffortHint: '控制子代理请求的 reasoning effort;可选项会随所选模型变化。',\n reasoningNone: '无',\n reasoningLow: '低',\n reasoningMedium: '中',\n reasoningHigh: '高',\n reasoningXhigh: '超高',\n reasoningMax: '最大',\n contextWindows: 'GPT-5.6 上下文窗口',\n contextWindowsHint: '默认 272K;可选启用最高 1M。该值用于 DSH 的压缩与溢出判断,可输入 1M、512K 等容量。',\n contextWindow: '上下文窗口',\n contextWindowInvalid: '上下文窗口必须是 1 到 1M 的整数,可使用 K 或 M 后缀。',\n tokens: 'tokens',\n quickQuota: '在输入框旁显示快捷用量',\n quickQuotaHint: '仅在当前会话选中 codex-chatgpt 模型时显示。',\n quota: '用量与限额',\n quotaIntro: '数据来自 ChatGPT Codex 用量服务。页面可见时最多每 60 秒刷新一次。',\n refreshQuota: '刷新用量',\n refreshing: '刷新中…',\n noQuota: '当前套餐未返回可显示的限额窗口。',\n quotaSignedOut: '登录后可查看订阅限额。',\n stale: '显示的是上次成功获取的数据。',\n updated: '更新时间',\n primary: '主要窗口',\n secondary: '次要窗口',\n limitWindow: '额度',\n used: '已使用',\n remaining: '剩余',\n available: '可用',\n unavailable: '不可用',\n unlimited: '无限',\n credits: 'Credits',\n monthlySpend: '月度消费控制',\n resetCredits: '重置次数',\n spendControlReached: '已触发月度消费控制,新的订阅调用可能被限制。',\n limit: '上限',\n exhausted: '额度已用尽',\n resets: '重置',\n quickQuotaLabel: 'Codex 剩余',\n quickQuotaLoading: '用量…',\n imageToolRunning: '正在生成图片',\n imageToolDone: '已生成图片',\n imageToolFailed: '图片生成失败',\n image: '图片',\n openImage: '打开图片',\n openNamedImage: '打开 {name}',\n imageLoading: '加载图片…',\n imageLoadFailed: '图片加载失败,点击重试',\n imagePreviewClose: '关闭',\n imagePreviewOpenOriginal: '打开原图',\n retry: '重试',\n unknown: '未知',\n} as const\n\nexport const en: Record<keyof typeof zh, string> = {\n title: 'Codex subscription',\n intro: 'Sign in with ChatGPT to use Codex models available to your subscription in DSH.',\n account: 'Account',\n signedOut: 'Not signed in',\n signedIn: 'Signed in',\n plan: 'Plan',\n accountId: 'Account ID',\n expires: 'Token expires',\n storage: 'Credential storage',\n storageWindows: 'Windows DPAPI (current-user encrypted)',\n storageMacKeychain: 'macOS Keychain (encrypted)',\n storageLinuxFile: 'Linux user-private file (mode 0600)',\n storageMemory: 'Host memory only (not persistent)',\n storageUnavailable: 'Credential storage unavailable',\n securityWindows: 'The Host encrypts tokens with Windows CurrentUser DPAPI; they never enter the browser, settings.yaml, or logs.',\n securityMacKeychain: 'The Host stores tokens in the macOS login Keychain, encrypted on this machine; they never enter the browser, settings.yaml, or logs.',\n securityLinuxFile: 'Tokens are stored in a mode-0600 file readable only by the current Linux user, but are not additionally encrypted; same-UID processes, root, backups, and disk snapshots can still read them.',\n securityMemory: 'Tokens remain only in Host memory and are lost when the Host exits.',\n securityUnavailable: 'The Host cannot safely access credential storage. Fix the file owner or permissions and retry.',\n signIn: 'Sign in with ChatGPT',\n signInAgain: 'Sign in again',\n cancel: 'Cancel sign-in',\n signOut: 'Sign out',\n refreshToken: 'Refresh credentials',\n pending: 'Complete sign-in in your browser.',\n popupBlocked: 'The sign-in window was blocked. Use the link below to continue.',\n continueLogin: 'Open ChatGPT sign-in',\n loading: 'Reading status…',\n connection: 'Connection',\n provider: 'Provider',\n connectionState: 'Connection status',\n connected: 'Available',\n untested: 'Not tested',\n testConnection: 'Test connection',\n testing: 'Testing…',\n latency: 'Last latency',\n models: 'Available models',\n enhancements: 'Enhancements',\n searchProvider: 'Search provider',\n searchProviderHint: 'Choose whether DSH web search uses its default provider or the Codex search source from this ChatGPT subscription.',\n searchProviderDsh: 'DSH default',\n searchProviderCodex: 'Codex subscription',\n subagentModel: 'Subagent model',\n subagentModelHint: 'New built-in subagents use this ChatGPT subscription model; the parent session selection is unchanged.',\n subagentReasoningEffort: 'Subagent reasoning effort',\n subagentReasoningEffortHint: 'Controls reasoning effort for subagent requests. Available values follow the selected model.',\n reasoningNone: 'None',\n reasoningLow: 'Low',\n reasoningMedium: 'Medium',\n reasoningHigh: 'High',\n reasoningXhigh: 'Extra high',\n reasoningMax: 'Maximum',\n contextWindows: 'GPT-5.6 context windows',\n contextWindowsHint: 'Defaults to 272K, with an optional value up to 1M. DSH uses it for compaction and overflow detection; values such as 1M and 512K are accepted.',\n contextWindow: 'Context window',\n contextWindowInvalid: 'The context window must be an integer from 1 to 1M. K and M suffixes are accepted.',\n tokens: 'tokens',\n quickQuota: 'Show quick usage beside the composer',\n quickQuotaHint: 'Shown only when the current session uses a codex-chatgpt model.',\n quota: 'Usage and limits',\n quotaIntro: 'Data comes from the ChatGPT Codex usage service and refreshes at most once per minute while visible.',\n refreshQuota: 'Refresh usage',\n refreshing: 'Refreshing…',\n noQuota: 'Your plan did not return any displayable limit windows.',\n quotaSignedOut: 'Sign in to view subscription limits.',\n stale: 'Showing the last successfully fetched data.',\n updated: 'Updated',\n primary: 'Primary window',\n secondary: 'Secondary window',\n limitWindow: 'limit',\n used: 'used',\n remaining: 'remaining',\n available: 'Available',\n unavailable: 'Unavailable',\n unlimited: 'Unlimited',\n credits: 'Credits',\n monthlySpend: 'Monthly spend control',\n resetCredits: 'Reset credits',\n spendControlReached: 'Monthly spend control has been reached; new subscription calls may be limited.',\n limit: 'Limit',\n exhausted: 'Quota exhausted',\n resets: 'Resets',\n quickQuotaLabel: 'Codex left',\n quickQuotaLoading: 'Usage…',\n imageToolRunning: 'Generating image',\n imageToolDone: 'Generated image',\n imageToolFailed: 'Image generation failed',\n image: 'Image',\n openImage: 'Open image',\n openNamedImage: 'Open {name}',\n imageLoading: 'Loading image…',\n imageLoadFailed: 'Image failed to load. Click to retry',\n imagePreviewClose: 'Close',\n imagePreviewOpenOriginal: 'Open original',\n retry: 'Retry',\n unknown: 'Unknown',\n}\n\nexport type LocaleKey = keyof typeof zh\nexport const dictionaries = { zh, en }\n","const STYLE_ID = '@eddyskywalker/dsh-chatgpt-subscription/main'\r\n\r\nconst CSS = `\r\n.dsh-codex-page{box-sizing:border-box;color:var(--dsw-alias-label-primary);display:flex;flex-direction:column;gap:20px;max-width:780px;min-width:0;padding:2px 0 30px}\r\n.dsh-codex-page *{box-sizing:border-box}\r\n.dsh-codex-title{font-size:15px;font-weight:650;line-height:1.4;margin:0 0 5px}\r\n.dsh-codex-intro,.dsh-codex-muted{color:var(--dsw-alias-label-secondary);font-size:13px;line-height:1.55;margin:0}\r\n.dsh-codex-group{border-top:1px solid var(--dsw-alias-border-l2);min-width:0}\r\n.dsh-codex-grouphead{align-items:center;display:flex;gap:12px;justify-content:space-between;min-height:48px}\r\n.dsh-codex-grouphead h3{font-size:14px;font-weight:650;margin:0}\r\n.dsh-codex-row{align-items:center;border-bottom:1px solid var(--dsw-alias-border-l2);display:flex;gap:20px;justify-content:space-between;min-height:44px;padding:8px 0}\r\n.dsh-codex-label{color:var(--dsw-alias-label-secondary);font-size:13px;flex:0 0 auto}\r\n.dsh-codex-value{font-size:13px;min-width:0;overflow-wrap:anywhere;text-align:right}\r\n.dsh-codex-actions{display:flex;flex-wrap:wrap;gap:8px;justify-content:flex-end;padding-top:12px}\r\n.dsh-codex-button{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:999px;color:var(--dsw-alias-label-primary);cursor:pointer;font:inherit;font-size:13px;line-height:1;padding:8px 13px;white-space:nowrap}\r\n.dsh-codex-button:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}\r\n.dsh-codex-button:focus-visible,.dsh-codex-link:focus-visible{outline:2px solid var(--dsw-alias-button-info-fill,#397ee8);outline-offset:2px}\r\n.dsh-codex-button:disabled{cursor:default;opacity:.5}\r\n.dsh-codex-button-primary{background:var(--dsw-alias-button-info-fill,#397ee8);border-color:transparent;color:var(--dsw-alias-button-info-label,#fff)}\r\n.dsh-codex-notice{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:7px;color:var(--dsw-alias-label-secondary);font-size:12px;line-height:1.55;margin:12px 0 0;padding:10px 12px}\r\n.dsh-codex-error,.dsh-codex-warning{font-size:12px;line-height:1.5;margin:8px 0 0}\r\n.dsh-codex-error{color:var(--dsw-alias-label-danger,#d94b4b)}\r\n.dsh-codex-warning{color:var(--dsw-alias-label-warning,#c77a18)}\r\n.dsh-codex-errorbar{align-items:center;background:color-mix(in srgb,var(--dsw-alias-label-danger,#d94b4b) 9%,transparent);border:1px solid color-mix(in srgb,var(--dsw-alias-label-danger,#d94b4b) 28%,transparent);border-radius:7px;color:var(--dsw-alias-label-danger,#d94b4b);display:flex;font-size:13px;gap:12px;justify-content:space-between;padding:10px 12px}\r\n.dsh-codex-link{color:var(--dsw-alias-label-link,#3278d4);display:inline-block;font-size:13px;margin-top:8px}\r\n.dsh-codex-models{display:flex;flex-wrap:wrap;gap:6px;padding-top:12px}\r\n.dsh-codex-models code{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:5px;font-family:ui-monospace,SFMono-Regular,Consolas,monospace;font-size:11px;padding:4px 6px}\r\n.dsh-codex-pref-row{align-items:center;border-bottom:1px solid var(--dsw-alias-border-l2);display:flex;gap:16px;justify-content:space-between;min-height:58px;padding:10px 0}\r\n.dsh-codex-pref-row strong,.dsh-codex-check strong{display:block;font-size:13px;font-weight:600;line-height:1.35}\r\n.dsh-codex-segments{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:8px;display:flex;flex:none;gap:2px;padding:2px}\r\n.dsh-codex-segments label{cursor:pointer;display:block}\r\n.dsh-codex-segments input{position:absolute;opacity:0;pointer-events:none}\r\n.dsh-codex-segments span{border-radius:6px;color:var(--dsw-alias-label-secondary);display:block;font-size:12px;line-height:1;padding:7px 10px;white-space:nowrap}\r\n.dsh-codex-segments input:checked+span{background:var(--dsw-alias-bg-base);box-shadow:0 1px 2px rgba(0,0,0,.08);color:var(--dsw-alias-label-primary)}\r\n.dsh-codex-segments input:focus-visible+span{outline:2px solid var(--dsw-alias-button-info-fill,#397ee8);outline-offset:2px}\r\n.dsh-codex-segments input:disabled+span{cursor:default;opacity:.5}\r\n.dsh-codex-select,.dsh-codex-capacity-control input{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:7px;color:var(--dsw-alias-label-primary);font:inherit;font-size:12px;padding:7px 9px}\r\n.dsh-codex-select{max-width:210px;min-width:150px}\r\n.dsh-codex-context-settings{border-bottom:1px solid var(--dsw-alias-border-l2);display:grid;gap:10px;padding:12px 0}\r\n.dsh-codex-context-settings>div>strong{font-size:13px;font-weight:600}\r\n.dsh-codex-context-row{align-items:center;display:flex;font-size:12px;gap:14px;justify-content:space-between}\r\n.dsh-codex-capacity-control{align-items:center;display:flex;gap:7px}\r\n.dsh-codex-capacity-control input{font-family:ui-monospace,SFMono-Regular,Consolas,monospace;text-align:right;width:90px}\r\n.dsh-codex-capacity-control small{color:var(--dsw-alias-label-tertiary);font-size:11px;width:42px}\r\n.dsh-codex-check{align-items:flex-start;border-bottom:1px solid var(--dsw-alias-border-l2);cursor:pointer;display:flex;gap:10px;padding:12px 0}\r\n.dsh-codex-check input{flex:none;margin-top:2px}\r\n.dsh-codex-check small{color:var(--dsw-alias-label-secondary);display:block;font-size:12px;line-height:1.45;margin-top:2px}\r\n.dsh-codex-quota-card{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:8px;margin-top:12px;padding:12px}\r\n.dsh-codex-quota-title{align-items:center;display:flex;font-size:13px;gap:8px;justify-content:space-between}\r\n.dsh-codex-quota-title span{color:var(--dsw-alias-label-tertiary);font-size:11px;text-transform:uppercase}\r\n.dsh-codex-quota-fact{align-items:flex-start;border-bottom:1px solid var(--dsw-alias-border-l2);display:flex;font-size:12px;gap:12px;justify-content:space-between;line-height:1.45;padding:10px 0}\r\n.dsh-codex-quota-fact span{color:var(--dsw-alias-label-secondary);flex:none}\r\n.dsh-codex-quota-fact strong{font-weight:600;min-width:0;overflow-wrap:anywhere;text-align:right}\r\n.dsh-codex-meter-wrap{margin-top:13px}\r\n.dsh-codex-meter-label,.dsh-codex-meter-meta{display:flex;gap:10px;justify-content:space-between}\r\n.dsh-codex-meter-label{font-size:12px;margin-bottom:6px}\r\n.dsh-codex-meter-meta{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:1.45;margin-top:6px}\r\n.dsh-codex-meter{background:var(--dsw-alias-bg-layer-1,rgba(127,127,127,.15));border-radius:999px;height:7px;overflow:hidden;width:100%}\r\n.dsh-codex-meter>span{background:var(--dsw-alias-button-info-fill,#397ee8);border-radius:inherit;display:block;height:100%;max-width:100%;min-width:0;transition:width .25s ease}\r\n.dsh-codex-meter-warning>span{background:var(--dsw-alias-label-warning,#d58a24)}\r\n.dsh-codex-meter-danger>span{background:var(--dsw-alias-label-danger,#d94b4b)}\r\n.dsh-codex-empty{border:1px dashed var(--dsw-alias-border-l2);border-radius:7px;color:var(--dsw-alias-label-tertiary);font-size:12px;margin:12px 0 0;padding:16px;text-align:center}\r\n.dsh-codex-timestamp{color:var(--dsw-alias-label-tertiary);font-size:11px;margin:10px 0 0;text-align:right}\r\n.dsh-codex-skeleton{display:grid;gap:9px;padding-top:10px}\r\n.dsh-codex-skeleton span{animation:dsh-codex-pulse 1.4s ease-in-out infinite;background:var(--dsw-alias-bg-layer-2);border-radius:5px;height:42px}\r\n.dsh-codex-skeleton span:nth-child(2){animation-delay:.12s}.dsh-codex-skeleton span:nth-child(3){animation-delay:.24s}\r\n.dsh-codex-sr{height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;clip:rect(0 0 0 0);white-space:nowrap}\r\n.dsh-codex-composer-quota{align-items:center;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:999px;color:var(--dsw-alias-label-secondary);display:inline-flex;font-size:11px;gap:6px;height:28px;line-height:1;max-width:160px;padding:0 9px;white-space:nowrap}\r\n.dsh-codex-composer-quota strong{color:var(--dsw-alias-label-primary);font-size:11px;font-weight:650}\r\n.dsh-codex-composer-quota[data-level=warning] strong{color:var(--dsw-alias-label-warning,#d58a24)}\r\n.dsh-codex-composer-quota[data-level=danger] strong{color:var(--dsw-alias-label-danger,#d94b4b)}\r\n.dsh-codex-image-tool{border:1px solid var(--dsw-alias-border-l2);border-radius:8px;display:flex;flex-direction:column;gap:8px;margin:4px 0 4px 4px;max-width:520px;padding:10px 12px}\r\n.dsh-codex-image-tool-head{align-items:center;display:flex;font-size:13px;gap:8px;min-width:0}\r\n.dsh-codex-image-dot{background:var(--dsw-alias-button-info-fill,#397ee8);border-radius:50%;display:inline-block;flex:none;height:8px;width:8px}\r\n.dsh-codex-image-tool[data-state=error] .dsh-codex-image-dot{background:var(--dsw-alias-label-danger,#d94b4b)}\r\n.dsh-codex-image-title{font-weight:600}\r\n.dsh-codex-image-summary{color:var(--dsw-alias-label-tertiary);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\r\n.dsh-codex-image-grid{display:flex;flex-wrap:wrap;gap:8px}\r\n.dsh-codex-image-preview{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:8px;display:block;max-height:260px;max-width:min(100%,360px);object-fit:contain}\r\n.dsh-codex-image-loading,.dsh-codex-image-failed{border:1px dashed var(--dsw-alias-border-l2);border-radius:8px;color:var(--dsw-alias-label-tertiary);display:inline-flex;font-size:12px;line-height:1.4;padding:18px 20px}\r\n.dsh-codex-image-failed{color:var(--dsw-alias-label-danger,#d94b4b)}\r\n@keyframes dsh-codex-pulse{0%,100%{opacity:.55}50%{opacity:1}}\r\n@media(max-width:560px){.dsh-codex-row,.dsh-codex-pref-row,.dsh-codex-quota-fact{align-items:flex-start;flex-direction:column;gap:3px}.dsh-codex-value,.dsh-codex-quota-fact strong{text-align:left}.dsh-codex-actions{justify-content:flex-start}.dsh-codex-grouphead{align-items:flex-start;flex-direction:column;gap:0;padding:12px 0}.dsh-codex-meter-meta{align-items:flex-start;flex-direction:column;gap:2px}.dsh-codex-errorbar{align-items:flex-start;flex-direction:column}.dsh-codex-segments{width:100%}.dsh-codex-select{max-width:none;width:100%}.dsh-codex-context-row{align-items:flex-start;flex-direction:column;gap:5px}.dsh-codex-segments label{flex:1}.dsh-codex-segments span{text-align:center}.dsh-codex-image-tool{max-width:100%;margin-left:0}}\r\n@media(prefers-reduced-motion:reduce){.dsh-codex-meter>span{transition:none}.dsh-codex-skeleton span{animation:none}}\r\n`\r\n\r\nexport function installStyles(): () => void {\r\n if (document.querySelector(`style[data-plugin-css=\"${STYLE_ID}\"]`) !== null) return () => undefined\r\n const element = document.createElement('style')\r\n element.dataset.plugin = '@eddyskywalker/dsh-chatgpt-subscription'\r\n element.dataset.pluginCss = STYLE_ID\r\n element.textContent = CSS\r\n document.head.appendChild(element)\r\n return () => element.remove()\r\n}\r\n","import type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client'\nimport type { ImageAttachmentRef } from '@deepseek-ai/dsh-attachment'\nimport type {} from '@deepseek-ai/dsh-client-ui-settings/client'\nimport type {} from '@deepseek-ai/dsh-client-locale/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-slots'\nimport type {} from '@deepseek-ai/dsh-client-ui-model-selection/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-conversation/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-tool/client'\nimport { CODEX_IMAGE_TOOL_NAME } from '../compat.ts'\nimport { CodexComposerQuota } from './CodexComposerQuota.tsx'\nimport { CodexImageToolView, type ImageLoader } from './CodexImageToolView.tsx'\nimport { CodexSubscriptionSection } from './CodexSubscriptionSection.tsx'\nimport { SubscriptionApi } from './api.ts'\nimport { dictionaries, NS, type LocaleKey } from './locales.ts'\nimport { installStyles } from './styles.ts'\n\r\ndeclare module '@deepseek-ai/dsh-client-ui-slots' {\r\n interface LocaleNamespaceMap {\r\n 'dsh-chatgpt-subscription': LocaleKey\r\n }\r\n}\r\n\r\nexport const inject = ['slots', 'locale', 'modelDirectories', 'conversation']\n\r\nexport function apply(ctx: ClientContext): void {\r\n ctx.effect(() => ctx.locale.register(NS, dictionaries), 'dsh-chatgpt-subscription: dictionaries')\r\n ctx.effect(() => installStyles(), 'dsh-chatgpt-subscription: styles')\r\n ctx.slots.inject('settings.section', () => ctx.slots.register({\n name: 'settings.section',\n id: 'codex-subscription',\n order: 45,\n label: 'Codex 订阅',\n locale: NS,\n }, CodexSubscriptionSection))\n ctx.slots.inject('conversation.input.right', () => ctx.slots.register({\n name: 'conversation.input.right',\n id: 'codex-subscription-quota',\n order: 35,\n locale: NS,\n inject: (sessionId) => {\n const directory = ctx.modelDirectories.directoryFor(sessionId)\n return {\n api: new SubscriptionApi(),\n directory: directory.store,\n loadModelDirectory: () => {\n void directory.load().catch(() => undefined)\n },\n }\n },\n }, CodexComposerQuota))\n ctx.slots.inject('tool.call.toolview', () => ctx.slots.register({\n name: 'tool.call.toolview',\n key: CODEX_IMAGE_TOOL_NAME,\n locale: NS,\n inject: (sessionId) => ({\n loadImage: imageLoader(ctx, sessionId),\n }),\n }, CodexImageToolView))\n}\n\nfunction imageLoader(ctx: ClientContext, sessionId: string): ImageLoader {\n const conversation = ctx.conversation as unknown as {\n resolveImage(sessionId: string, attachment: ImageAttachmentRef): Promise<string>\n }\n return (attachment) => conversation.resolveImage(sessionId, attachment)\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"client.js","names":["formatPercent"],"sources":["../src/compat.ts","../src/client/quota.ts","../src/client/CodexComposerQuota.tsx","../src/client/CodexImageToolView.tsx","../src/shared/model-catalog.ts","../src/client/api.ts","../src/client/CodexSubscriptionSection.tsx","../src/client/locales.ts","../src/client/styles.ts","../src/client/index.tsx"],"sourcesContent":["/**\n * Compatibility constants for the ChatGPT-backed Codex flow. The backend and\n * OAuth parameters are not a public third-party API contract, so every such\n * value is isolated here for review and rollback.\n */\nexport const CHATGPT_OAUTH_ISSUER = 'https://auth.openai.com' as const\nexport const CHATGPT_OAUTH_CLIENT_ID = 'app_EMoamEEZ73f0CkXaXp7hrann' as const\nexport const OAUTH_CALLBACK_HOST = 'localhost' as const\nexport const OAUTH_CALLBACK_PORT = 1455 as const\nexport const OAUTH_CALLBACK_PATH = '/auth/callback' as const\nexport const OAUTH_REDIRECT_URI = `http://${OAUTH_CALLBACK_HOST}:${OAUTH_CALLBACK_PORT}${OAUTH_CALLBACK_PATH}` as const\nexport const OAUTH_SCOPE = 'openid profile email offline_access' as const\nexport const OAUTH_ORIGINATOR = 'opencode' as const\nexport const OAUTH_LOGIN_TIMEOUT_MS = 5 * 60_000\nexport const TOKEN_REFRESH_MARGIN_MS = 60_000\nexport const ROUTE_PREFIX = '/api/dsh-chatgpt-subscription' as const\nexport const PLUGIN_VERSION = '0.1.0-alpha.0' as const\nexport const CODEX_CHATGPT_PROVIDER_ID = 'codex-chatgpt' as const\n\nexport const CODEX_API_BASE = 'https://chatgpt.com/backend-api/codex' as const\nexport const CODEX_RESPONSES_URL = `${CODEX_API_BASE}/responses` as const\nexport const CODEX_IMAGE_GENERATION_URL = `${CODEX_API_BASE}/images/generations` as const\nexport const CODEX_SEARCH_URL = `${CODEX_API_BASE}/alpha/search` as const\nexport const CODEX_USAGE_URL = 'https://chatgpt.com/backend-api/wham/usage' as const\nexport const CODEX_ORIGINATOR = 'opencode' as const\nexport const CODEX_ENHANCED_ORIGINATOR = 'pi' as const\nexport const CODEX_IMAGE_TOOL_NAME = 'codex_image_generate' as const\nexport const CODEX_IMAGE_MODEL = 'gpt-image-2' as const\nexport const CODEX_SEARCH_PROVIDER_ID = 'codex-subscription' as const\nexport const QUOTA_CACHE_MS = 60_000\nexport const QUOTA_MIN_UPSTREAM_INTERVAL_MS = 15_000\n\nexport const OAUTH_AUTHORIZE_URL = `${CHATGPT_OAUTH_ISSUER}/oauth/authorize` as const\nexport const OAUTH_TOKEN_URL = `${CHATGPT_OAUTH_ISSUER}/oauth/token` as const\n","import type { QuotaBucketDto, QuotaStatusDto, QuotaWindowDto } from '../shared/contracts.ts'\n\nexport interface SelectedQuotaWindow {\n bucket: QuotaBucketDto\n window: QuotaWindowDto\n remainingPercent: number\n}\n\nexport function selectQuotaForModel(quota: QuotaStatusDto | undefined, modelId: string | undefined): SelectedQuotaWindow | null {\n if (quota === undefined || quota.buckets.length === 0) return null\n const model = modelId?.toLowerCase() ?? ''\n const wantsSpark = model.includes('spark')\n const bucket = wantsSpark\n ? quota.buckets.find(candidate => `${candidate.id} ${candidate.name}`.toLowerCase().includes('spark'))\n : quota.buckets.find(candidate => candidate.id === 'codex')\n ?? quota.buckets.find(candidate => candidate.name.toLowerCase() === 'codex')\n if (bucket === undefined) return null\n const windows = quotaWindows(bucket)\n if (windows.length === 0) return null\n const window = windows.reduce((tightest, candidate) => (\n candidate.usedPercent > tightest.usedPercent ? candidate : tightest\n ), windows[0]!)\n return {\n bucket,\n window,\n remainingPercent: Math.max(0, 100 - window.usedPercent),\n }\n}\n\nexport function quotaWindows(bucket: QuotaBucketDto): QuotaWindowDto[] {\n if (bucket.windows.length > 0) return bucket.windows\n return [bucket.primary, bucket.secondary].filter((window): window is QuotaWindowDto => window !== null)\n}\n","import { useEffect, useMemo, useRef, useState, useSyncExternalStore } from 'react'\nimport type { SnapshotStore } from '@deepseek-ai/dsh-client-runtime/client'\nimport type { ModelDirectoryState } from '@deepseek-ai/dsh-client-ui-model-selection/client'\nimport type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport { CODEX_CHATGPT_PROVIDER_ID } from '../compat.ts'\nimport type { PluginStatusDto } from '../shared/contracts.ts'\nimport { SubscriptionApi } from './api.ts'\nimport { NS } from './locales.ts'\nimport { selectQuotaForModel } from './quota.ts'\n\ntype Props = PropsRuntime<'conversation.input.right'> & PropsLocale<typeof NS> & {\n api: SubscriptionApi\n directory: SnapshotStore<ModelDirectoryState>\n loadModelDirectory: () => void\n}\n\nexport function CodexComposerQuota({ api, directory, loadModelDirectory, t }: Props): React.JSX.Element | null {\n const modelState = useStore(directory)\n const [status, setStatus] = useState<PluginStatusDto | null>(null)\n const [loading, setLoading] = useState(false)\n const mountedRef = useRef(false)\n const selected = modelState.current\n const isCodex = selected?.provider === CODEX_CHATGPT_PROVIDER_ID\n\n useEffect(() => {\n loadModelDirectory()\n }, [loadModelDirectory])\n\n useEffect(() => {\n mountedRef.current = true\n return () => {\n mountedRef.current = false\n }\n }, [])\n\n useEffect(() => {\n if (!isCodex) return\n let disposed = false\n const refresh = async (): Promise<void> => {\n setLoading(true)\n try {\n const next = await api.status()\n if (!disposed && mountedRef.current) setStatus(next)\n } catch {\n if (!disposed && mountedRef.current) setStatus(null)\n } finally {\n if (!disposed && mountedRef.current) setLoading(false)\n }\n }\n void refresh()\n const timer = window.setInterval(() => {\n if (document.visibilityState === 'visible') void refresh()\n }, 60_000)\n return () => {\n disposed = true\n window.clearInterval(timer)\n }\n }, [api, isCodex])\n\n const quota = useMemo(() => selectQuotaForModel(status?.quota, selected?.model), [selected?.model, status?.quota])\n if (!isCodex || status?.preferences.quickQuotaVisible !== true) return null\n const level = quota === null\n ? 'normal'\n : quota.remainingPercent <= 5\n ? 'danger'\n : quota.remainingPercent <= 20\n ? 'warning'\n : 'normal'\n return <span className=\"dsh-codex-composer-quota\" data-level={level} aria-label={quota === null ? t('quickQuotaLoading') : `${t('quickQuotaLabel')}: ${formatPercent(quota.remainingPercent)}`}>\n <span>{t('quickQuotaLabel')}</span>\n <strong>{quota === null ? (loading ? t('quickQuotaLoading') : '—') : formatPercent(quota.remainingPercent)}</strong>\n </span>\n}\n\nfunction useStore<T>(store: SnapshotStore<T>): T {\n return useSyncExternalStore(\n (listener) => store.subscribe(listener),\n () => store.getSnapshot(),\n () => store.getSnapshot(),\n )\n}\n\nfunction formatPercent(value: number): string {\n return `${new Intl.NumberFormat(undefined, { maximumFractionDigits: 0 }).format(value)}%`\n}\n","import { useEffect, useState } from 'react'\nimport type { ImageAttachmentRef } from '@deepseek-ai/dsh-attachment'\nimport type { ContentBlock } from '@deepseek-ai/dsh-client-connection/client'\nimport type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport { NS } from './locales.ts'\n\nexport type ImageLoader = (attachment: ImageAttachmentRef) => Promise<string>\n\ntype Props = PropsRuntime<'tool.call.toolview'> & PropsLocale<typeof NS> & {\n loadImage: ImageLoader\n}\n\nexport function CodexImageToolView({ block, loadImage, t }: Props): React.JSX.Element {\n const settled = 'kind' in block\n const isError = settled ? block.isError : false\n const prompt = promptFromBlock(block)\n const images = settled && !isError ? imageBlocks(block.content) : []\n const label = isError ? t('imageToolFailed') : settled ? t('imageToolDone') : t('imageToolRunning')\n const summary = prompt ?? textSummary(settled ? block.content : [])\n return <div className=\"dsh-codex-image-tool\" data-state={isError ? 'error' : settled ? 'done' : 'running'}>\n <div className=\"dsh-codex-image-tool-head\">\n <span className=\"dsh-codex-image-dot\" aria-hidden=\"true\" />\n <span className=\"dsh-codex-image-title\">{label}</span>\n {summary !== null ? <span className=\"dsh-codex-image-summary\">{summary}</span> : null}\n </div>\n {images.length > 0 ? <div className=\"dsh-codex-image-grid\">\n {images.map((attachment) => <GeneratedImage key={String(attachment.attachmentId)} attachment={attachment} load={loadImage} label={attachment.name ?? t('image')} t={t} />)}\n </div> : null}\n </div>\n}\n\nfunction GeneratedImage({ attachment, load, label, t }: {\n attachment: ImageAttachmentRef\n load: ImageLoader\n label: string\n t: Props['t']\n}): React.JSX.Element {\n const [src, setSrc] = useState<string | null>(null)\n const [failed, setFailed] = useState(false)\n useEffect(() => {\n let disposed = false\n setSrc(null)\n setFailed(false)\n load(attachment).then((url) => {\n if (!disposed) setSrc(url)\n }, () => {\n if (!disposed) setFailed(true)\n })\n return () => {\n disposed = true\n }\n }, [attachment, load])\n if (failed) return <span className=\"dsh-codex-image-failed\">{t('imageLoadFailed')}</span>\n if (src === null) return <span className=\"dsh-codex-image-loading\">{t('imageLoading')}</span>\n return <img className=\"dsh-codex-image-preview\" src={src} alt={label} />\n}\n\nfunction promptFromBlock(block: Props['block']): string | null {\n const raw = 'kind' in block ? block.call?.argsRaw : block.argsRaw\n if (typeof raw !== 'string' || raw.trim() === '') return null\n try {\n const value = JSON.parse(raw) as unknown\n return typeof value === 'object'\n && value !== null\n && !Array.isArray(value)\n && typeof (value as { prompt?: unknown }).prompt === 'string'\n ? (value as { prompt: string }).prompt\n : null\n } catch {\n return null\n }\n}\n\nfunction imageBlocks(blocks: readonly ContentBlock[]): ImageAttachmentRef[] {\n const result: ImageAttachmentRef[] = []\n for (const block of blocks) {\n if (block.type === 'image') result.push(block.attachment)\n if (block.type === 'tool-result') result.push(...imageBlocks(block.content))\n }\n return result\n}\n\nfunction textSummary(blocks: readonly ContentBlock[]): string | null {\n const text = blocks\n .map((block) => block.type === 'text' || block.type === 'reasoning' ? block.text : '')\n .filter(Boolean)\n .join(' ')\n .trim()\n return text === '' ? null : text\n}\n","export type CodexModelModality = 'text' | 'image'\n\nexport const GPT_56_MAX_CONTEXT_WINDOW = 1_000_000\n\nexport interface CodexModelCatalogEntry {\n id: string\n name: string\n contextWindow: number\n inputModalities: readonly CodexModelModality[]\n defaultReasoningEffort: string\n reasoningProfile: 'standard' | 'gpt-5.6'\n supportsReasoningSummary: boolean\n}\n\nexport const CODEX_MODEL_CATALOG = [\n {\n id: 'gpt-5.6-sol',\n name: '5.6 Sol',\n contextWindow: 272_000,\n inputModalities: ['text', 'image'],\n defaultReasoningEffort: 'medium',\n reasoningProfile: 'gpt-5.6',\n supportsReasoningSummary: true,\n },\n {\n id: 'gpt-5.6-terra',\n name: '5.6 Terra',\n contextWindow: 272_000,\n inputModalities: ['text', 'image'],\n defaultReasoningEffort: 'medium',\n reasoningProfile: 'gpt-5.6',\n supportsReasoningSummary: true,\n },\n {\n id: 'gpt-5.6-luna',\n name: '5.6 Luna',\n contextWindow: 272_000,\n inputModalities: ['text', 'image'],\n defaultReasoningEffort: 'medium',\n reasoningProfile: 'gpt-5.6',\n supportsReasoningSummary: true,\n },\n {\n id: 'gpt-5.5',\n name: '5.5',\n contextWindow: 272_000,\n inputModalities: ['text', 'image'],\n defaultReasoningEffort: 'medium',\n reasoningProfile: 'standard',\n supportsReasoningSummary: true,\n },\n {\n id: 'gpt-5.4',\n name: '5.4',\n contextWindow: 272_000,\n inputModalities: ['text', 'image'],\n defaultReasoningEffort: 'none',\n reasoningProfile: 'standard',\n supportsReasoningSummary: true,\n },\n {\n id: 'gpt-5.4-mini',\n name: '5.4 Mini',\n contextWindow: 272_000,\n inputModalities: ['text', 'image'],\n defaultReasoningEffort: 'none',\n reasoningProfile: 'standard',\n supportsReasoningSummary: true,\n },\n {\n id: 'gpt-5.3-codex-spark',\n name: '5.3 Codex Spark',\n contextWindow: 258_000,\n inputModalities: ['text'],\n defaultReasoningEffort: 'high',\n reasoningProfile: 'standard',\n supportsReasoningSummary: false,\n },\n] as const satisfies readonly CodexModelCatalogEntry[]\n\nexport type CodexModelId = typeof CODEX_MODEL_CATALOG[number]['id']\n\nexport const DEFAULT_CODEX_MODEL = CODEX_MODEL_CATALOG[0]\n\nexport const CONFIGURABLE_CONTEXT_MODEL_IDS = [\n 'gpt-5.6-sol',\n 'gpt-5.6-terra',\n 'gpt-5.6-luna',\n] as const satisfies readonly CodexModelId[]\n\nexport type ConfigurableContextModelId = typeof CONFIGURABLE_CONTEXT_MODEL_IDS[number]\n\nexport const STANDARD_REASONING_EFFORTS = ['none', 'low', 'medium', 'high', 'xhigh'] as const\nexport const GPT_56_REASONING_EFFORTS = [...STANDARD_REASONING_EFFORTS, 'max'] as const\nexport type CodexReasoningEffort = typeof GPT_56_REASONING_EFFORTS[number]\n\nexport function reasoningEffortsForModel(model: string): readonly CodexReasoningEffort[] {\n return resolveCodexCatalogEntry(model).reasoningProfile === 'gpt-5.6'\n ? GPT_56_REASONING_EFFORTS\n : STANDARD_REASONING_EFFORTS\n}\n\nexport function isCodexReasoningEffort(value: unknown): value is CodexReasoningEffort {\n return typeof value === 'string' && GPT_56_REASONING_EFFORTS.some((effort) => effort === value)\n}\n\nexport function modelSupportsReasoningEffort(model: string, effort: unknown): effort is CodexReasoningEffort {\n return isCodexReasoningEffort(effort) && reasoningEffortsForModel(model).some((candidate) => candidate === effort)\n}\n\nexport function isCodexModelId(model: unknown): model is CodexModelId {\n return typeof model === 'string' && CODEX_MODEL_CATALOG.some((entry) => entry.id === model)\n}\n\nexport function isConfigurableContextModelId(model: unknown): model is ConfigurableContextModelId {\n return typeof model === 'string' && CONFIGURABLE_CONTEXT_MODEL_IDS.some((id) => id === model)\n}\n\nexport function resolveCodexCatalogEntry(model: string): CodexModelCatalogEntry {\n return CODEX_MODEL_CATALOG.find((entry) => entry.id === model) ?? DEFAULT_CODEX_MODEL\n}\n\nexport function codexModelSupportsImageInput(model: string): boolean {\n return resolveCodexCatalogEntry(model).inputModalities.includes('image')\n}\n\nexport function codexModelSupportsReasoningSummary(model: string): boolean {\n return resolveCodexCatalogEntry(model).supportsReasoningSummary\n}\n","import { ROUTE_PREFIX } from '../compat.ts'\r\nimport type {\r\n ApiEnvelope,\r\n LoginEventDto,\r\n LoginStartDto,\r\n PluginStatusDto,\n QuotaStatusDto,\n ConnectionTestDto,\n SubscriptionPreferencesDto,\n SubscriptionPreferencesUpdateDto,\n} from '../shared/contracts.ts'\n\r\nexport class SubscriptionApi {\r\n status(): Promise<PluginStatusDto> {\r\n return request<PluginStatusDto>(`${ROUTE_PREFIX}/status`)\r\n }\r\n\r\n startLogin(): Promise<LoginStartDto> {\r\n return post<LoginStartDto>(`${ROUTE_PREFIX}/login/start`, {})\r\n }\r\n\r\n cancelLogin(loginId: string): Promise<{ cancelled: boolean }> {\r\n return post(`${ROUTE_PREFIX}/login/cancel`, { loginId })\r\n }\r\n\r\n logout(): Promise<{ authenticated: false }> {\r\n return post(`${ROUTE_PREFIX}/logout`, {})\r\n }\r\n\r\n refresh(): Promise<PluginStatusDto> {\r\n return post(`${ROUTE_PREFIX}/token/refresh`, {})\r\n }\r\n\r\n refreshQuota(): Promise<QuotaStatusDto> {\r\n return post(`${ROUTE_PREFIX}/quota/refresh`, {})\r\n }\r\n\r\n testConnection(): Promise<ConnectionTestDto> {\n return post(`${ROUTE_PREFIX}/connection/test`, {})\n }\n\n updatePreferences(patch: SubscriptionPreferencesUpdateDto): Promise<SubscriptionPreferencesDto> {\n return post(`${ROUTE_PREFIX}/preferences/update`, patch)\n }\n\n events(loginId: string): EventSource {\n return new EventSource(`${ROUTE_PREFIX}/login/events?loginId=${encodeURIComponent(loginId)}`)\n }\n}\n\r\nasync function post<T>(url: string, body: object): Promise<T> {\n return request<T>(url, {\r\n method: 'POST',\r\n headers: { 'content-type': 'application/json' },\r\n body: JSON.stringify(body),\r\n })\r\n}\r\n\r\nasync function request<T>(url: string, init?: RequestInit): Promise<T> {\r\n const response = await fetch(url, { ...init, credentials: 'same-origin' })\r\n const envelope = await response.json() as ApiEnvelope<T>\r\n if (!response.ok || !envelope.ok) {\r\n throw new Error(envelope.ok ? `Request failed (${response.status})` : envelope.error.message)\r\n }\r\n return envelope.value\r\n}\r\n\r\nexport function parseLoginEvent(event: MessageEvent<string>): LoginEventDto | null {\r\n try {\r\n const value = JSON.parse(event.data) as LoginEventDto\r\n return typeof value === 'object' && value !== null && typeof value.type === 'string' ? value : null\r\n } catch {\r\n return null\r\n }\r\n}\r\n","import { useCallback, useEffect, useRef, useState } from 'react'\r\nimport type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\r\nimport type { CredentialStorageDto, PluginStatusDto, QuotaBucketDto, QuotaWindowDto, SubscriptionPreferencesUpdateDto } from '../shared/contracts.ts'\r\nimport { CODEX_MODEL_CATALOG, CONFIGURABLE_CONTEXT_MODEL_IDS, GPT_56_MAX_CONTEXT_WINDOW, reasoningEffortsForModel, resolveCodexCatalogEntry } from '../shared/model-catalog.ts'\r\nimport { SubscriptionApi, parseLoginEvent } from './api.ts'\r\nimport { NS } from './locales.ts'\r\nimport { quotaWindows } from './quota.ts'\r\n\r\ntype Props = PropsRuntime<'settings.section'> & PropsLocale<typeof NS>\r\ntype BusyAction = 'login' | 'token' | 'quota' | 'test' | 'logout' | 'preferences' | null\r\ntype Translate = Props['t']\r\n\r\nexport function CodexSubscriptionSection({ t }: Props): React.JSX.Element {\r\n const apiRef = useRef(new SubscriptionApi())\r\n const eventSourceRef = useRef<EventSource | null>(null)\r\n const [status, setStatus] = useState<PluginStatusDto | null>(null)\r\n const [busy, setBusy] = useState<BusyAction>(null)\r\n const [error, setError] = useState<string | null>(null)\r\n const [authUrl, setAuthUrl] = useState<string | null>(null)\r\n const [popupBlocked, setPopupBlocked] = useState(false)\r\n const [connection, setConnection] = useState<{ latencyMs: number; checkedAt: number } | null>(null)\r\n const [contextDrafts, setContextDrafts] = useState<Record<string, string>>({})\r\n\r\n const load = useCallback(async (quiet = false) => {\r\n if (!quiet) setError(null)\r\n try {\r\n const next = await apiRef.current.status()\r\n setStatus(next)\r\n if (next.error !== undefined) setError(next.error.message)\r\n } catch (cause) {\r\n if (!quiet) setError(messageOf(cause))\r\n }\r\n }, [])\r\n\r\n useEffect(() => {\r\n void load()\r\n const refreshWhenVisible = (): void => {\r\n if (document.visibilityState === 'visible') void load(true)\r\n }\r\n document.addEventListener('visibilitychange', refreshWhenVisible)\r\n const timer = window.setInterval(refreshWhenVisible, 60_000)\r\n return () => {\r\n window.clearInterval(timer)\r\n document.removeEventListener('visibilitychange', refreshWhenVisible)\r\n eventSourceRef.current?.close()\r\n }\r\n }, [load])\r\n\r\n const watchLogin = useCallback((loginId: string) => {\r\n eventSourceRef.current?.close()\r\n const source = apiRef.current.events(loginId)\r\n eventSourceRef.current = source\r\n const finish = async (message?: string): Promise<void> => {\r\n source.close()\r\n eventSourceRef.current = null\r\n setBusy(null)\r\n setAuthUrl(null)\r\n if (message !== undefined) setError(message)\r\n // Preserve the terminal OAuth error while refreshing the account DTO.\r\n await load(true)\r\n }\r\n source.addEventListener('completed', (event) => {\r\n const parsed = parseLoginEvent(event as MessageEvent<string>)\r\n if (parsed?.type === 'completed') void finish()\r\n })\r\n source.addEventListener('cancelled', () => void finish())\r\n source.addEventListener('failed', (event) => {\r\n const parsed = parseLoginEvent(event as MessageEvent<string>)\r\n void finish(parsed?.type === 'failed' ? parsed.error.message : 'ChatGPT sign-in failed.')\r\n })\r\n }, [load])\r\n\r\n useEffect(() => {\r\n const loginId = status?.login.active ? status.login.loginId : null\r\n if (loginId !== null && loginId !== undefined && eventSourceRef.current === null) watchLogin(loginId)\r\n }, [status?.login.active, status?.login.loginId, watchLogin])\r\n\r\n const startLogin = async (): Promise<void> => {\r\n setBusy('login')\r\n setError(null)\r\n setPopupBlocked(false)\r\n const popup = window.open('about:blank', 'dsh-chatgpt-oauth', 'popup,width=560,height=760')\r\n try {\r\n const login = await apiRef.current.startLogin()\r\n setAuthUrl(login.authUrl)\r\n if (popup === null) setPopupBlocked(true)\r\n else popup.location.replace(login.authUrl)\r\n watchLogin(login.loginId)\r\n await load(true)\r\n } catch (cause) {\r\n popup?.close()\r\n setBusy(null)\r\n setError(messageOf(cause))\r\n }\r\n }\r\n\r\n const cancelLogin = async (): Promise<void> => {\r\n const loginId = status?.login.loginId\r\n if (loginId === null || loginId === undefined) return\r\n setBusy('login')\r\n try {\r\n await apiRef.current.cancelLogin(loginId)\r\n eventSourceRef.current?.close()\r\n eventSourceRef.current = null\r\n setAuthUrl(null)\r\n await load()\r\n } catch (cause) {\r\n setError(messageOf(cause))\r\n } finally {\r\n setBusy(null)\r\n }\r\n }\r\n\r\n const refreshToken = async (): Promise<void> => run('token', async () => {\r\n setStatus(await apiRef.current.refresh())\r\n })\r\n\r\n const refreshQuota = async (): Promise<void> => run('quota', async () => {\r\n const quota = await apiRef.current.refreshQuota()\r\n setStatus((current) => current === null ? current : { ...current, quota })\r\n })\r\n\r\n const testConnection = async (): Promise<void> => run('test', async () => {\r\n const result = await apiRef.current.testConnection()\r\n setConnection({ latencyMs: result.latencyMs, checkedAt: result.checkedAt })\r\n })\r\n\r\n const updatePreferences = async (patch: SubscriptionPreferencesUpdateDto): Promise<void> => run('preferences', async () => {\r\n const preferences = await apiRef.current.updatePreferences(patch)\r\n setStatus((current) => current === null ? current : { ...current, preferences })\r\n })\r\n\r\n const updateContextWindow = async (model: (typeof CONFIGURABLE_CONTEXT_MODEL_IDS)[number]): Promise<void> => {\r\n const current = status?.preferences.contextWindowOverrides[model] ?? resolveCodexCatalogEntry(model).contextWindow\r\n const parsed = parseCapacity(contextDrafts[model] ?? String(current))\r\n if (parsed === null) {\r\n setError(t('contextWindowInvalid'))\r\n return\r\n }\r\n await updatePreferences({ contextWindowOverrides: { [model]: parsed } })\r\n setContextDrafts((drafts) => ({ ...drafts, [model]: String(parsed) }))\r\n }\r\n\r\n const logout = async (): Promise<void> => run('logout', async () => {\r\n await apiRef.current.logout()\r\n eventSourceRef.current?.close()\r\n eventSourceRef.current = null\r\n setAuthUrl(null)\r\n setConnection(null)\r\n await load()\r\n })\r\n\r\n const run = async (action: Exclude<BusyAction, null>, task: () => Promise<void>): Promise<void> => {\r\n setBusy(action)\r\n setError(null)\r\n try {\r\n await task()\r\n } catch (cause) {\r\n setError(messageOf(cause))\r\n } finally {\r\n setBusy(null)\r\n }\r\n }\r\n\r\n const account = status?.account\r\n return <section className=\"dsh-codex-page\" aria-labelledby=\"dsh-codex-title\">\r\n <header>\r\n <h2 id=\"dsh-codex-title\" className=\"dsh-codex-title\">{t('title')}</h2>\r\n <p className=\"dsh-codex-intro\">{t('intro')}</p>\r\n </header>\r\n\r\n {error !== null ? <div className=\"dsh-codex-errorbar\" role=\"alert\">\r\n <span>{error}</span>\r\n {status === null ? <Button disabled={busy !== null} onClick={() => load()}>{t('retry')}</Button> : null}\r\n </div> : null}\r\n\r\n {status === null && error === null ? <Skeleton label={t('loading')} /> : <>\r\n <Section title={t('account')}>\r\n <InfoRow label={status?.authenticated ? t('signedIn') : t('signedOut')} value={account?.email ?? '—'} />\r\n {status?.authenticated ? <>\r\n <InfoRow label={t('plan')} value={account?.planType ?? t('unknown')} />\r\n <InfoRow label={t('accountId')} value={account?.accountIdSuffix ?? '—'} />\r\n <InfoRow label={t('expires')} value={formatDate(account?.tokenExpiresAt)} />\r\n </> : null}\r\n <InfoRow label={t('storage')} value={storageLabel(status?.storage, t)} />\r\n <p className=\"dsh-codex-notice\">{storageNotice(status?.storage, t)}</p>\r\n {status?.login.active ? <p className=\"dsh-codex-muted\" role=\"status\">{t('pending')}</p> : null}\r\n {popupBlocked ? <p className=\"dsh-codex-error\">{t('popupBlocked')}</p> : null}\r\n {authUrl !== null ? <a className=\"dsh-codex-link\" href={authUrl} target=\"_blank\" rel=\"noreferrer\">{t('continueLogin')}</a> : null}\r\n <div className=\"dsh-codex-actions\">\r\n {status?.login.active\r\n ? <Button disabled={busy !== null} onClick={cancelLogin}>{t('cancel')}</Button>\r\n : <Button primary disabled={busy !== null || status?.storage.available === false} onClick={startLogin}>{status?.authenticated ? t('signInAgain') : t('signIn')}</Button>}\r\n {status?.authenticated ? <>\r\n <Button disabled={busy !== null} onClick={refreshToken}>{t('refreshToken')}</Button>\r\n <Button disabled={busy !== null} onClick={logout}>{t('signOut')}</Button>\r\n </> : null}\r\n </div>\r\n </Section>\r\n\r\n <Section title={t('connection')}>\r\n <InfoRow label={t('provider')} value=\"Codex(ChatGPT 订阅) · codex-chatgpt\" />\r\n <InfoRow label={t('connectionState')} value={connection === null ? t('untested') : t('connected')} />\r\n {connection !== null ? <InfoRow label={t('latency')} value={`${connection.latencyMs} ms · ${formatDate(connection.checkedAt)}`} /> : null}\r\n <div className=\"dsh-codex-models\" aria-label={t('models')}>\r\n {CODEX_MODEL_CATALOG.map((model) => <code key={model.id} title={model.id}>{model.name}</code>)}\r\n </div>\r\n <div className=\"dsh-codex-actions\">\r\n <Button disabled={!status?.authenticated || busy !== null} onClick={testConnection}>{busy === 'test' ? t('testing') : t('testConnection')}</Button>\r\n </div>\r\n </Section>\r\n\r\n <Section title={t('enhancements')}>\r\n <div className=\"dsh-codex-pref-row\">\r\n <div>\r\n <strong>{t('searchProvider')}</strong>\r\n <p className=\"dsh-codex-muted\">{t('searchProviderHint')}</p>\r\n </div>\r\n <div className=\"dsh-codex-segments\" role=\"radiogroup\" aria-label={t('searchProvider')}>\r\n <label>\r\n <input type=\"radio\" name=\"dsh-codex-search-provider\" checked={status?.preferences.searchProvider === 'dsh'} disabled={busy !== null} onChange={() => updatePreferences({ searchProvider: 'dsh' })} />\r\n <span>{t('searchProviderDsh')}</span>\r\n </label>\r\n <label>\r\n <input type=\"radio\" name=\"dsh-codex-search-provider\" checked={status?.preferences.searchProvider === 'codex'} disabled={busy !== null} onChange={() => updatePreferences({ searchProvider: 'codex' })} />\r\n <span>{t('searchProviderCodex')}</span>\r\n </label>\r\n </div>\r\n </div>\r\n <div className=\"dsh-codex-pref-row\">\r\n <div>\r\n <strong>{t('subagentModel')}</strong>\r\n <p className=\"dsh-codex-muted\">{t('subagentModelHint')}</p>\r\n </div>\r\n <select className=\"dsh-codex-select\" aria-label={t('subagentModel')} value={status?.preferences.subagentModel ?? CODEX_MODEL_CATALOG[0].id} disabled={busy !== null} onChange={(event) => {\r\n const subagentModel = event.currentTarget.value\r\n const currentEffort = status?.preferences.subagentReasoningEffort ?? resolveCodexCatalogEntry(subagentModel).defaultReasoningEffort\r\n const supportedEfforts = reasoningEffortsForModel(subagentModel)\r\n void updatePreferences({\r\n subagentModel,\r\n subagentReasoningEffort: supportedEfforts.includes(currentEffort as never)\r\n ? currentEffort\r\n : resolveCodexCatalogEntry(subagentModel).defaultReasoningEffort,\r\n })\r\n }}>\r\n {CODEX_MODEL_CATALOG.map((model) => <option key={model.id} value={model.id}>{model.name}</option>)}\r\n </select>\r\n </div>\r\n <div className=\"dsh-codex-pref-row\">\r\n <div>\r\n <strong>{t('subagentReasoningEffort')}</strong>\r\n <p className=\"dsh-codex-muted\">{t('subagentReasoningEffortHint')}</p>\r\n </div>\r\n <select className=\"dsh-codex-select\" aria-label={t('subagentReasoningEffort')} value={status?.preferences.subagentReasoningEffort ?? 'medium'} disabled={busy !== null} onChange={(event) => void updatePreferences({ subagentModel: status?.preferences.subagentModel ?? CODEX_MODEL_CATALOG[0].id, subagentReasoningEffort: event.currentTarget.value })}>\r\n {reasoningEffortsForModel(status?.preferences.subagentModel ?? CODEX_MODEL_CATALOG[0].id).map((effort) => <option key={effort} value={effort}>{reasoningEffortLabel(effort, t)}</option>)}\r\n </select>\r\n </div>\r\n <div className=\"dsh-codex-context-settings\">\r\n <div>\r\n <strong>{t('contextWindows')}</strong>\r\n <p className=\"dsh-codex-muted\">{t('contextWindowsHint')}</p>\r\n </div>\r\n {CONFIGURABLE_CONTEXT_MODEL_IDS.map((model) => {\r\n const entry = resolveCodexCatalogEntry(model)\r\n const fallback = status?.preferences.contextWindowOverrides[model] ?? entry.contextWindow\r\n const draft = contextDrafts[model]\r\n const parsedDraft = draft === undefined ? fallback : parseCapacity(draft)\r\n const dirty = draft !== undefined && parsedDraft !== fallback\r\n const inputId = `dsh-codex-context-${model}`\r\n return <div className=\"dsh-codex-context-row\" key={model}>\r\n <label htmlFor={inputId}>{entry.name}</label>\r\n <span className=\"dsh-codex-capacity-control\">\r\n <input id={inputId} type=\"text\" inputMode=\"numeric\" value={draft ?? formatCapacity(fallback)} disabled={busy !== null} aria-label={entry.name + ' ' + t('contextWindow')} onChange={(event) => {\r\n const value = event.currentTarget.value\r\n setContextDrafts((drafts) => ({ ...drafts, [model]: value }))\r\n }} onKeyDown={(event) => {\r\n if (event.key !== 'Enter' || !dirty) return\r\n event.preventDefault()\r\n void updateContextWindow(model)\r\n }} />\r\n <small>{t('tokens')}</small>\r\n <button className=\"dsh-codex-context-save\" type=\"button\" data-model={model} aria-label={entry.name + ' ' + t('saveContextWindow')} disabled={busy !== null || !dirty} onClick={() => void updateContextWindow(model)}>{t('save')}</button>\r\n </span>\r\n </div>\r\n })}\r\n </div>\r\n <label className=\"dsh-codex-check\">\r\n <input type=\"checkbox\" checked={status?.preferences.quickQuotaVisible === true} disabled={busy !== null} onChange={(event) => updatePreferences({ quickQuotaVisible: event.currentTarget.checked })} />\r\n <span>\r\n <strong>{t('quickQuota')}</strong>\r\n <small>{t('quickQuotaHint')}</small>\r\n </span>\r\n </label>\r\n </Section>\r\n\r\n <Section title={t('quota')} aside={<Button disabled={!status?.authenticated || busy !== null} onClick={refreshQuota}>{busy === 'quota' ? t('refreshing') : t('refreshQuota')}</Button>}>\r\n <p className=\"dsh-codex-muted\">{t('quotaIntro')}</p>\r\n {status?.quota.state === 'signed-out' ? <p className=\"dsh-codex-empty\">{t('quotaSignedOut')}</p> : null}\r\n {status?.quota.buckets.map((bucket) => <QuotaBucket key={bucket.id} bucket={bucket} t={t} />)}\r\n {status?.quota.credits !== null && status?.quota.credits !== undefined ? <QuotaFact label={t('credits')} value={status.quota.credits.unlimited ? t('unlimited') : status.quota.credits.balance ?? (status.quota.credits.hasCredits ? t('available') : t('unavailable'))} /> : null}\r\n {status?.quota.individualLimit !== null && status?.quota.individualLimit !== undefined ? <QuotaFact label={t('monthlySpend')} value={individualLimitLabel(status.quota.individualLimit, t)} /> : null}\r\n {status?.quota.resetCredits !== null && status?.quota.resetCredits !== undefined ? <QuotaFact label={t('resetCredits')} value={String(status.quota.resetCredits.availableCount)} /> : null}\r\n {status?.quota.spendControlReached === true ? <p className=\"dsh-codex-warning\" role=\"status\">{t('spendControlReached')}</p> : null}\r\n {status?.quota.state === 'empty' ? <p className=\"dsh-codex-empty\">{t('noQuota')}</p> : null}\r\n {status?.quota.stale ? <p className=\"dsh-codex-warning\" role=\"status\">{t('stale')}</p> : null}\r\n {status?.quota.error ? <p className=\"dsh-codex-error\" role=\"alert\">{status.quota.error.message}</p> : null}\r\n {status?.quota.fetchedAt ? <p className=\"dsh-codex-timestamp\">{t('updated')}: {formatDate(status.quota.fetchedAt)}</p> : null}\r\n </Section>\r\n </>}\r\n\r\n <span className=\"dsh-codex-sr\" aria-live=\"polite\">{busy === null ? '' : busy}</span>\r\n </section>\r\n}\r\n\r\nfunction Section({ title, aside, children }: { title: string; aside?: React.ReactNode; children: React.ReactNode }): React.JSX.Element {\r\n return <section className=\"dsh-codex-group\">\r\n <div className=\"dsh-codex-grouphead\"><h3>{title}</h3>{aside}</div>\r\n {children}\r\n </section>\r\n}\r\n\r\nfunction Button({ primary = false, disabled, onClick, children }: { primary?: boolean; disabled?: boolean; onClick: () => void | Promise<void>; children: React.ReactNode }): React.JSX.Element {\r\n return <button className={`dsh-codex-button${primary ? ' dsh-codex-button-primary' : ''}`} type=\"button\" disabled={disabled} onClick={() => void onClick()}>{children}</button>\r\n}\r\n\r\nfunction InfoRow({ label, value }: { label: string; value: string }): React.JSX.Element {\r\n return <div className=\"dsh-codex-row\"><span className=\"dsh-codex-label\">{label}</span><span className=\"dsh-codex-value\">{value}</span></div>\r\n}\r\n\r\nexport function storageLabel(storage: CredentialStorageDto | undefined, t: Translate): string {\r\n if (storage === undefined || !storage.available) return t('storageUnavailable')\r\n if (storage.kind === 'windows-dpapi') return t('storageWindows')\r\n if (storage.kind === 'macos-keychain') return t('storageMacKeychain')\r\n if (storage.kind === 'linux-file') return t('storageLinuxFile')\r\n if (storage.kind === 'memory') return t('storageMemory')\r\n return t('storageUnavailable')\r\n}\r\n\r\nexport function storageNotice(storage: CredentialStorageDto | undefined, t: Translate): string {\r\n if (storage === undefined || !storage.available) return t('securityUnavailable')\r\n if (storage.kind === 'windows-dpapi') return t('securityWindows')\r\n if (storage.kind === 'macos-keychain') return t('securityMacKeychain')\r\n if (storage.kind === 'linux-file') return t('securityLinuxFile')\r\n if (storage.kind === 'memory') return t('securityMemory')\r\n return t('securityUnavailable')\r\n}\r\n\r\nfunction QuotaBucket({ bucket, t }: { bucket: QuotaBucketDto; t: Translate }): React.JSX.Element {\r\n const windows = quotaWindows(bucket)\r\n return <article className=\"dsh-codex-quota-card\">\r\n <div className=\"dsh-codex-quota-title\"><strong>{bucket.name}</strong>{bucket.planType ? <span>{bucket.planType}</span> : null}</div>\r\n {windows.map((window, index) => <QuotaBar key={`${window.windowDurationMins ?? 'x'}:${window.resetsAt ?? 'x'}:${index}`} label={windowLabel(window.windowDurationMins, t)} window={window} t={t} />)}\r\n </article>\r\n}\r\n\r\nfunction QuotaFact({ label, value }: { label: string; value: string }): React.JSX.Element {\r\n return <div className=\"dsh-codex-quota-fact\"><span>{label}</span><strong>{value}</strong></div>\r\n}\r\n\r\nexport function QuotaBar({ label, window, t }: { label: string; window: QuotaWindowDto; t: Translate }): React.JSX.Element {\r\n const percent = window.usedPercent\r\n const level = percent >= 95 ? 'danger' : percent >= 80 ? 'warning' : 'normal'\r\n const remaining = Math.max(0, 100 - percent)\r\n return <div className=\"dsh-codex-meter-wrap\">\r\n <div className=\"dsh-codex-meter-label\"><span>{label}</span><strong>{formatPercent(percent)}</strong></div>\r\n <div className={`dsh-codex-meter dsh-codex-meter-${level}`} role=\"progressbar\" aria-label={`${label}: ${formatPercent(percent)} ${t('used')}`} aria-valuemin={0} aria-valuemax={100} aria-valuenow={percent}>\r\n <span style={{ width: `${percent}%` }} />\r\n </div>\r\n <div className=\"dsh-codex-meter-meta\">\r\n <span>{percent >= 100 ? `${t('exhausted')} · ${formatPercent(remaining)} ${t('remaining')}` : `${formatPercent(percent)} ${t('used')} · ${formatPercent(remaining)} ${t('remaining')}`}</span>\r\n <span>{window.resetsAt === null ? '—' : `${t('resets')}: ${formatReset(window.resetsAt)}`}</span>\r\n </div>\r\n </div>\r\n}\r\n\r\nfunction Skeleton({ label }: { label: string }): React.JSX.Element {\r\n return <div className=\"dsh-codex-skeleton\" role=\"status\" aria-label={label}><span /><span /></div>\r\n}\r\n\r\nexport function windowLabel(minutes: number | null, t: Translate): string {\r\n if (minutes === null) return t('limitWindow')\r\n const [value, unit]: [number, Intl.NumberFormatOptions['unit']] = minutes >= 1440 && minutes % 1440 === 0\r\n ? [minutes / 1440, 'day']\r\n : minutes >= 60 && minutes % 60 === 0\r\n ? [minutes / 60, 'hour']\r\n : [Math.round(minutes), 'minute']\r\n return `${new Intl.NumberFormat(undefined, { style: 'unit', unit, unitDisplay: 'long' }).format(value)} ${t('limitWindow')}`\r\n}\r\n\r\nfunction reasoningEffortLabel(effort: string, t: Translate): string {\r\n const labels: Record<string, keyof typeof import('./locales.ts').zh> = {\r\n none: 'reasoningNone',\r\n low: 'reasoningLow',\r\n medium: 'reasoningMedium',\r\n high: 'reasoningHigh',\r\n xhigh: 'reasoningXhigh',\r\n max: 'reasoningMax',\r\n }\r\n return t(labels[effort] ?? 'unknown')\r\n}\r\n\r\nexport function parseCapacity(value: string): number | null {\r\n const normalized = value.trim().toLowerCase().replace(/[,_\\s]/g, '')\r\n const matched = normalized.match(/^(\\d+(?:\\.\\d+)?)(k|m)?$/)\r\n if (matched === null) return null\r\n const multiplier = matched[2] === 'm' ? 1_000_000 : matched[2] === 'k' ? 1_000 : 1\r\n const parsed = Number(matched[1]) * multiplier\r\n return Number.isSafeInteger(parsed) && parsed >= 1 && parsed <= GPT_56_MAX_CONTEXT_WINDOW ? parsed : null\r\n}\r\n\r\nfunction formatCapacity(value: number): string {\r\n if (value % 1_000 === 0) return `${value / 1_000}K`\r\n return String(value)\r\n}\r\n\r\nfunction formatPercent(value: number): string {\r\n return `${new Intl.NumberFormat(undefined, { maximumFractionDigits: 1 }).format(value)}%`\r\n}\r\n\r\nfunction individualLimitLabel(limit: NonNullable<PluginStatusDto['quota']['individualLimit']>, t: Translate): string {\r\n const parts = [\r\n limit.remainingPercent !== null ? `${formatPercent(limit.remainingPercent)} ${t('remaining')}` : null,\r\n limit.limit !== null ? `${t('limit')}: ${limit.limit}` : null,\r\n limit.used !== null ? `${t('used')}: ${limit.used}` : null,\r\n limit.resetsAt !== null ? `${t('resets')}: ${formatReset(limit.resetsAt)}` : null,\r\n ].filter((part): part is string => part !== null)\r\n return parts.length > 0 ? parts.join(' · ') : t('unknown')\r\n}\r\n\r\nfunction formatDate(seconds: number | undefined): string {\r\n if (seconds === undefined) return '—'\r\n return new Intl.DateTimeFormat(undefined, { dateStyle: 'medium', timeStyle: 'short' }).format(seconds * 1000)\r\n}\r\n\r\nexport function formatReset(seconds: number): string {\r\n const absolute = formatDate(seconds)\r\n const diff = seconds * 1000 - Date.now()\r\n const abs = Math.abs(diff)\r\n const [amount, unit]: [number, Intl.RelativeTimeFormatUnit] = abs >= 86_400_000\r\n ? [Math.round(diff / 86_400_000), 'day']\r\n : abs >= 3_600_000\r\n ? [Math.round(diff / 3_600_000), 'hour']\r\n : [Math.round(diff / 60_000), 'minute']\r\n return `${absolute} (${new Intl.RelativeTimeFormat(undefined, { numeric: 'auto' }).format(amount, unit)})`\r\n}\r\n\r\nfunction messageOf(error: unknown): string {\r\n return error instanceof Error ? error.message : String(error)\r\n}\r\n","export const NS = 'dsh-chatgpt-subscription' as const\n\nexport const zh = {\n title: 'Codex 订阅',\n intro: '使用 ChatGPT 账号登录,在 DSH 中使用订阅可用的 Codex 模型。',\n account: '账号',\n signedOut: '尚未登录',\n signedIn: '已登录',\n plan: '套餐',\n accountId: '账号 ID',\n expires: '令牌到期',\n storage: '凭据存储',\n storageWindows: 'Windows DPAPI(当前用户加密)',\n storageMacKeychain: 'macOS 钥匙串(Keychain 加密)',\n storageLinuxFile: 'Linux 用户私有文件(权限 0600)',\n storageMemory: '仅 Host 内存(不持久化)',\n storageUnavailable: '凭据存储不可用',\n securityWindows: '令牌由 Host 使用 Windows CurrentUser DPAPI 加密,不会进入浏览器、settings.yaml 或日志。',\n securityMacKeychain: '令牌由 Host 存入 macOS 登录钥匙串(Keychain),在本机加密保存,不会进入浏览器、settings.yaml 或日志。',\n securityLinuxFile: '令牌仅写入 Host 上当前 Linux 用户可读的 0600 文件,但不会额外加密;同 UID 进程、root、备份和磁盘快照仍可能读取。',\n securityMemory: '令牌仅保留在 Host 内存中,Host 退出后丢失。',\n securityUnavailable: 'Host 无法安全访问凭据存储;请修复文件所有者或权限后重试。',\n signIn: '使用 ChatGPT 登录',\n signInAgain: '重新登录',\n cancel: '取消登录',\n signOut: '注销',\n refreshToken: '刷新凭据',\n pending: '请在浏览器中完成登录。',\n popupBlocked: '浏览器拦截了登录窗口,请使用下面的链接继续。',\n continueLogin: '打开 ChatGPT 登录页',\n loading: '正在读取状态…',\n connection: '连接',\n provider: 'Provider',\n connectionState: '连接状态',\n connected: '可用',\n untested: '尚未测试',\n testConnection: '测试连接',\n testing: '测试中…',\n latency: '最近延迟',\n models: '可用模型',\n enhancements: '增强功能',\n searchProvider: '搜索来源',\n searchProviderHint: '选择 DSH Web 搜索工具使用默认来源,或改用当前 ChatGPT 订阅的 Codex 搜索来源。',\n searchProviderDsh: 'DSH 默认',\n searchProviderCodex: 'Codex 订阅',\n subagentModel: '子代理模型',\n subagentModelHint: '新启动的内置子代理使用此 ChatGPT 订阅模型;父会话的模型选择不受影响。',\n subagentReasoningEffort: '子代理思考深度',\n subagentReasoningEffortHint: '控制子代理请求的 reasoning effort;可选项会随所选模型变化。',\n reasoningNone: '无',\n reasoningLow: '低',\n reasoningMedium: '中',\n reasoningHigh: '高',\n reasoningXhigh: '超高',\n reasoningMax: '最大',\n contextWindows: 'GPT-5.6 上下文窗口',\n contextWindowsHint: '默认 272K;可选启用最高 1M。该值用于 DSH 的压缩与溢出判断,可输入 1M、512K 等容量。',\n contextWindow: '上下文窗口',\n contextWindowInvalid: '上下文窗口必须是 1 到 1M 的整数,可使用 K 或 M 后缀。',\n saveContextWindow: '保存上下文窗口',\n save: '保存',\n tokens: 'tokens',\n quickQuota: '在输入框旁显示快捷用量',\n quickQuotaHint: '仅在当前会话选中 codex-chatgpt 模型时显示。',\n quota: '用量与限额',\n quotaIntro: '数据来自 ChatGPT Codex 用量服务。页面可见时最多每 60 秒刷新一次。',\n refreshQuota: '刷新用量',\n refreshing: '刷新中…',\n noQuota: '当前套餐未返回可显示的限额窗口。',\n quotaSignedOut: '登录后可查看订阅限额。',\n stale: '显示的是上次成功获取的数据。',\n updated: '更新时间',\n primary: '主要窗口',\n secondary: '次要窗口',\n limitWindow: '额度',\n used: '已使用',\n remaining: '剩余',\n available: '可用',\n unavailable: '不可用',\n unlimited: '无限',\n credits: 'Credits',\n monthlySpend: '月度消费控制',\n resetCredits: '重置次数',\n spendControlReached: '已触发月度消费控制,新的订阅调用可能被限制。',\n limit: '上限',\n exhausted: '额度已用尽',\n resets: '重置',\n quickQuotaLabel: 'Codex 剩余',\n quickQuotaLoading: '用量…',\n imageToolRunning: '正在生成图片',\n imageToolDone: '已生成图片',\n imageToolFailed: '图片生成失败',\n image: '图片',\n openImage: '打开图片',\n openNamedImage: '打开 {name}',\n imageLoading: '加载图片…',\n imageLoadFailed: '图片加载失败,点击重试',\n imagePreviewClose: '关闭',\n imagePreviewOpenOriginal: '打开原图',\n retry: '重试',\n unknown: '未知',\n} as const\n\nexport const en: Record<keyof typeof zh, string> = {\n title: 'Codex subscription',\n intro: 'Sign in with ChatGPT to use Codex models available to your subscription in DSH.',\n account: 'Account',\n signedOut: 'Not signed in',\n signedIn: 'Signed in',\n plan: 'Plan',\n accountId: 'Account ID',\n expires: 'Token expires',\n storage: 'Credential storage',\n storageWindows: 'Windows DPAPI (current-user encrypted)',\n storageMacKeychain: 'macOS Keychain (encrypted)',\n storageLinuxFile: 'Linux user-private file (mode 0600)',\n storageMemory: 'Host memory only (not persistent)',\n storageUnavailable: 'Credential storage unavailable',\n securityWindows: 'The Host encrypts tokens with Windows CurrentUser DPAPI; they never enter the browser, settings.yaml, or logs.',\n securityMacKeychain: 'The Host stores tokens in the macOS login Keychain, encrypted on this machine; they never enter the browser, settings.yaml, or logs.',\n securityLinuxFile: 'Tokens are stored in a mode-0600 file readable only by the current Linux user, but are not additionally encrypted; same-UID processes, root, backups, and disk snapshots can still read them.',\n securityMemory: 'Tokens remain only in Host memory and are lost when the Host exits.',\n securityUnavailable: 'The Host cannot safely access credential storage. Fix the file owner or permissions and retry.',\n signIn: 'Sign in with ChatGPT',\n signInAgain: 'Sign in again',\n cancel: 'Cancel sign-in',\n signOut: 'Sign out',\n refreshToken: 'Refresh credentials',\n pending: 'Complete sign-in in your browser.',\n popupBlocked: 'The sign-in window was blocked. Use the link below to continue.',\n continueLogin: 'Open ChatGPT sign-in',\n loading: 'Reading status…',\n connection: 'Connection',\n provider: 'Provider',\n connectionState: 'Connection status',\n connected: 'Available',\n untested: 'Not tested',\n testConnection: 'Test connection',\n testing: 'Testing…',\n latency: 'Last latency',\n models: 'Available models',\n enhancements: 'Enhancements',\n searchProvider: 'Search provider',\n searchProviderHint: 'Choose whether DSH web search uses its default provider or the Codex search source from this ChatGPT subscription.',\n searchProviderDsh: 'DSH default',\n searchProviderCodex: 'Codex subscription',\n subagentModel: 'Subagent model',\n subagentModelHint: 'New built-in subagents use this ChatGPT subscription model; the parent session selection is unchanged.',\n subagentReasoningEffort: 'Subagent reasoning effort',\n subagentReasoningEffortHint: 'Controls reasoning effort for subagent requests. Available values follow the selected model.',\n reasoningNone: 'None',\n reasoningLow: 'Low',\n reasoningMedium: 'Medium',\n reasoningHigh: 'High',\n reasoningXhigh: 'Extra high',\n reasoningMax: 'Maximum',\n contextWindows: 'GPT-5.6 context windows',\n contextWindowsHint: 'Defaults to 272K, with an optional value up to 1M. DSH uses it for compaction and overflow detection; values such as 1M and 512K are accepted.',\n contextWindow: 'Context window',\n contextWindowInvalid: 'The context window must be an integer from 1 to 1M. K and M suffixes are accepted.',\n saveContextWindow: 'Save context window',\n save: 'Save',\n tokens: 'tokens',\n quickQuota: 'Show quick usage beside the composer',\n quickQuotaHint: 'Shown only when the current session uses a codex-chatgpt model.',\n quota: 'Usage and limits',\n quotaIntro: 'Data comes from the ChatGPT Codex usage service and refreshes at most once per minute while visible.',\n refreshQuota: 'Refresh usage',\n refreshing: 'Refreshing…',\n noQuota: 'Your plan did not return any displayable limit windows.',\n quotaSignedOut: 'Sign in to view subscription limits.',\n stale: 'Showing the last successfully fetched data.',\n updated: 'Updated',\n primary: 'Primary window',\n secondary: 'Secondary window',\n limitWindow: 'limit',\n used: 'used',\n remaining: 'remaining',\n available: 'Available',\n unavailable: 'Unavailable',\n unlimited: 'Unlimited',\n credits: 'Credits',\n monthlySpend: 'Monthly spend control',\n resetCredits: 'Reset credits',\n spendControlReached: 'Monthly spend control has been reached; new subscription calls may be limited.',\n limit: 'Limit',\n exhausted: 'Quota exhausted',\n resets: 'Resets',\n quickQuotaLabel: 'Codex left',\n quickQuotaLoading: 'Usage…',\n imageToolRunning: 'Generating image',\n imageToolDone: 'Generated image',\n imageToolFailed: 'Image generation failed',\n image: 'Image',\n openImage: 'Open image',\n openNamedImage: 'Open {name}',\n imageLoading: 'Loading image…',\n imageLoadFailed: 'Image failed to load. Click to retry',\n imagePreviewClose: 'Close',\n imagePreviewOpenOriginal: 'Open original',\n retry: 'Retry',\n unknown: 'Unknown',\n}\n\nexport type LocaleKey = keyof typeof zh\nexport const dictionaries = { zh, en }\n","const STYLE_ID = '@eddyskywalker/dsh-chatgpt-subscription/main'\r\n\r\nconst CSS = `\r\n.dsh-codex-page{box-sizing:border-box;color:var(--dsw-alias-label-primary);display:flex;flex-direction:column;gap:20px;max-width:780px;min-width:0;padding:2px 0 30px}\r\n.dsh-codex-page *{box-sizing:border-box}\r\n.dsh-codex-title{font-size:15px;font-weight:650;line-height:1.4;margin:0 0 5px}\r\n.dsh-codex-intro,.dsh-codex-muted{color:var(--dsw-alias-label-secondary);font-size:13px;line-height:1.55;margin:0}\r\n.dsh-codex-group{border-top:1px solid var(--dsw-alias-border-l2);min-width:0}\r\n.dsh-codex-grouphead{align-items:center;display:flex;gap:12px;justify-content:space-between;min-height:48px}\r\n.dsh-codex-grouphead h3{font-size:14px;font-weight:650;margin:0}\r\n.dsh-codex-row{align-items:center;border-bottom:1px solid var(--dsw-alias-border-l2);display:flex;gap:20px;justify-content:space-between;min-height:44px;padding:8px 0}\r\n.dsh-codex-label{color:var(--dsw-alias-label-secondary);font-size:13px;flex:0 0 auto}\r\n.dsh-codex-value{font-size:13px;min-width:0;overflow-wrap:anywhere;text-align:right}\r\n.dsh-codex-actions{display:flex;flex-wrap:wrap;gap:8px;justify-content:flex-end;padding-top:12px}\r\n.dsh-codex-button{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:999px;color:var(--dsw-alias-label-primary);cursor:pointer;font:inherit;font-size:13px;line-height:1;padding:8px 13px;white-space:nowrap}\r\n.dsh-codex-button:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}\r\n.dsh-codex-button:focus-visible,.dsh-codex-link:focus-visible{outline:2px solid var(--dsw-alias-button-info-fill,#397ee8);outline-offset:2px}\r\n.dsh-codex-button:disabled{cursor:default;opacity:.5}\r\n.dsh-codex-button-primary{background:var(--dsw-alias-button-info-fill,#397ee8);border-color:transparent;color:var(--dsw-alias-button-info-label,#fff)}\r\n.dsh-codex-notice{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:7px;color:var(--dsw-alias-label-secondary);font-size:12px;line-height:1.55;margin:12px 0 0;padding:10px 12px}\r\n.dsh-codex-error,.dsh-codex-warning{font-size:12px;line-height:1.5;margin:8px 0 0}\r\n.dsh-codex-error{color:var(--dsw-alias-label-danger,#d94b4b)}\r\n.dsh-codex-warning{color:var(--dsw-alias-label-warning,#c77a18)}\r\n.dsh-codex-errorbar{align-items:center;background:color-mix(in srgb,var(--dsw-alias-label-danger,#d94b4b) 9%,transparent);border:1px solid color-mix(in srgb,var(--dsw-alias-label-danger,#d94b4b) 28%,transparent);border-radius:7px;color:var(--dsw-alias-label-danger,#d94b4b);display:flex;font-size:13px;gap:12px;justify-content:space-between;padding:10px 12px}\r\n.dsh-codex-link{color:var(--dsw-alias-label-link,#3278d4);display:inline-block;font-size:13px;margin-top:8px}\r\n.dsh-codex-models{display:flex;flex-wrap:wrap;gap:6px;padding-top:12px}\r\n.dsh-codex-models code{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:5px;font-family:ui-monospace,SFMono-Regular,Consolas,monospace;font-size:11px;padding:4px 6px}\r\n.dsh-codex-pref-row{align-items:center;border-bottom:1px solid var(--dsw-alias-border-l2);display:flex;gap:16px;justify-content:space-between;min-height:58px;padding:10px 0}\r\n.dsh-codex-pref-row strong,.dsh-codex-check strong{display:block;font-size:13px;font-weight:600;line-height:1.35}\r\n.dsh-codex-segments{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:8px;display:flex;flex:none;gap:2px;padding:2px}\r\n.dsh-codex-segments label{cursor:pointer;display:block}\r\n.dsh-codex-segments input{position:absolute;opacity:0;pointer-events:none}\r\n.dsh-codex-segments span{border-radius:6px;color:var(--dsw-alias-label-secondary);display:block;font-size:12px;line-height:1;padding:7px 10px;white-space:nowrap}\r\n.dsh-codex-segments input:checked+span{background:var(--dsw-alias-bg-base);box-shadow:0 1px 2px rgba(0,0,0,.08);color:var(--dsw-alias-label-primary)}\r\n.dsh-codex-segments input:focus-visible+span{outline:2px solid var(--dsw-alias-button-info-fill,#397ee8);outline-offset:2px}\r\n.dsh-codex-segments input:disabled+span{cursor:default;opacity:.5}\r\n.dsh-codex-select,.dsh-codex-capacity-control input{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:7px;color:var(--dsw-alias-label-primary);font:inherit;font-size:12px;padding:7px 9px}\r\n.dsh-codex-select{max-width:210px;min-width:150px}\r\n.dsh-codex-context-settings{border-bottom:1px solid var(--dsw-alias-border-l2);display:grid;gap:10px;padding:12px 0}\r\n.dsh-codex-context-settings>div>strong{font-size:13px;font-weight:600}\r\n.dsh-codex-context-row{align-items:center;display:flex;font-size:12px;gap:14px;justify-content:space-between}\r\n.dsh-codex-capacity-control{align-items:center;display:flex;gap:7px}\r\n.dsh-codex-capacity-control input{font-family:ui-monospace,SFMono-Regular,Consolas,monospace;text-align:right;width:90px}\r\n.dsh-codex-capacity-control small{color:var(--dsw-alias-label-tertiary);font-size:11px;width:42px}\r\n.dsh-codex-context-save{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:7px;color:var(--dsw-alias-label-primary);cursor:pointer;font:inherit;font-size:12px;line-height:1;padding:8px 10px;white-space:nowrap}\r\n.dsh-codex-context-save:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}\r\n.dsh-codex-context-save:focus-visible{outline:2px solid var(--dsw-alias-button-info-fill,#397ee8);outline-offset:2px}\r\n.dsh-codex-context-save:disabled{cursor:default;opacity:.45}\r\n.dsh-codex-check{align-items:flex-start;border-bottom:1px solid var(--dsw-alias-border-l2);cursor:pointer;display:flex;gap:10px;padding:12px 0}\r\n.dsh-codex-check input{flex:none;margin-top:2px}\r\n.dsh-codex-check small{color:var(--dsw-alias-label-secondary);display:block;font-size:12px;line-height:1.45;margin-top:2px}\r\n.dsh-codex-quota-card{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:8px;margin-top:12px;padding:12px}\r\n.dsh-codex-quota-title{align-items:center;display:flex;font-size:13px;gap:8px;justify-content:space-between}\r\n.dsh-codex-quota-title span{color:var(--dsw-alias-label-tertiary);font-size:11px;text-transform:uppercase}\r\n.dsh-codex-quota-fact{align-items:flex-start;border-bottom:1px solid var(--dsw-alias-border-l2);display:flex;font-size:12px;gap:12px;justify-content:space-between;line-height:1.45;padding:10px 0}\r\n.dsh-codex-quota-fact span{color:var(--dsw-alias-label-secondary);flex:none}\r\n.dsh-codex-quota-fact strong{font-weight:600;min-width:0;overflow-wrap:anywhere;text-align:right}\r\n.dsh-codex-meter-wrap{margin-top:13px}\r\n.dsh-codex-meter-label,.dsh-codex-meter-meta{display:flex;gap:10px;justify-content:space-between}\r\n.dsh-codex-meter-label{font-size:12px;margin-bottom:6px}\r\n.dsh-codex-meter-meta{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:1.45;margin-top:6px}\r\n.dsh-codex-meter{background:var(--dsw-alias-bg-layer-1,rgba(127,127,127,.15));border-radius:999px;height:7px;overflow:hidden;width:100%}\r\n.dsh-codex-meter>span{background:var(--dsw-alias-button-info-fill,#397ee8);border-radius:inherit;display:block;height:100%;max-width:100%;min-width:0;transition:width .25s ease}\r\n.dsh-codex-meter-warning>span{background:var(--dsw-alias-label-warning,#d58a24)}\r\n.dsh-codex-meter-danger>span{background:var(--dsw-alias-label-danger,#d94b4b)}\r\n.dsh-codex-empty{border:1px dashed var(--dsw-alias-border-l2);border-radius:7px;color:var(--dsw-alias-label-tertiary);font-size:12px;margin:12px 0 0;padding:16px;text-align:center}\r\n.dsh-codex-timestamp{color:var(--dsw-alias-label-tertiary);font-size:11px;margin:10px 0 0;text-align:right}\r\n.dsh-codex-skeleton{display:grid;gap:9px;padding-top:10px}\r\n.dsh-codex-skeleton span{animation:dsh-codex-pulse 1.4s ease-in-out infinite;background:var(--dsw-alias-bg-layer-2);border-radius:5px;height:42px}\r\n.dsh-codex-skeleton span:nth-child(2){animation-delay:.12s}.dsh-codex-skeleton span:nth-child(3){animation-delay:.24s}\r\n.dsh-codex-sr{height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;clip:rect(0 0 0 0);white-space:nowrap}\r\n.dsh-codex-composer-quota{align-items:center;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:999px;color:var(--dsw-alias-label-secondary);display:inline-flex;font-size:11px;gap:6px;height:28px;line-height:1;max-width:160px;padding:0 9px;white-space:nowrap}\r\n.dsh-codex-composer-quota strong{color:var(--dsw-alias-label-primary);font-size:11px;font-weight:650}\r\n.dsh-codex-composer-quota[data-level=warning] strong{color:var(--dsw-alias-label-warning,#d58a24)}\r\n.dsh-codex-composer-quota[data-level=danger] strong{color:var(--dsw-alias-label-danger,#d94b4b)}\r\n.dsh-codex-image-tool{border:1px solid var(--dsw-alias-border-l2);border-radius:8px;display:flex;flex-direction:column;gap:8px;margin:4px 0 4px 4px;max-width:520px;padding:10px 12px}\r\n.dsh-codex-image-tool-head{align-items:center;display:flex;font-size:13px;gap:8px;min-width:0}\r\n.dsh-codex-image-dot{background:var(--dsw-alias-button-info-fill,#397ee8);border-radius:50%;display:inline-block;flex:none;height:8px;width:8px}\r\n.dsh-codex-image-tool[data-state=error] .dsh-codex-image-dot{background:var(--dsw-alias-label-danger,#d94b4b)}\r\n.dsh-codex-image-title{font-weight:600}\r\n.dsh-codex-image-summary{color:var(--dsw-alias-label-tertiary);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\r\n.dsh-codex-image-grid{display:flex;flex-wrap:wrap;gap:8px}\r\n.dsh-codex-image-preview{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:8px;display:block;max-height:260px;max-width:min(100%,360px);object-fit:contain}\r\n.dsh-codex-image-loading,.dsh-codex-image-failed{border:1px dashed var(--dsw-alias-border-l2);border-radius:8px;color:var(--dsw-alias-label-tertiary);display:inline-flex;font-size:12px;line-height:1.4;padding:18px 20px}\r\n.dsh-codex-image-failed{color:var(--dsw-alias-label-danger,#d94b4b)}\r\n@keyframes dsh-codex-pulse{0%,100%{opacity:.55}50%{opacity:1}}\r\n@media(max-width:560px){.dsh-codex-row,.dsh-codex-pref-row,.dsh-codex-quota-fact{align-items:flex-start;flex-direction:column;gap:3px}.dsh-codex-value,.dsh-codex-quota-fact strong{text-align:left}.dsh-codex-actions{justify-content:flex-start}.dsh-codex-grouphead{align-items:flex-start;flex-direction:column;gap:0;padding:12px 0}.dsh-codex-meter-meta{align-items:flex-start;flex-direction:column;gap:2px}.dsh-codex-errorbar{align-items:flex-start;flex-direction:column}.dsh-codex-segments{width:100%}.dsh-codex-select{max-width:none;width:100%}.dsh-codex-context-row{align-items:flex-start;flex-direction:column;gap:5px}.dsh-codex-segments label{flex:1}.dsh-codex-segments span{text-align:center}.dsh-codex-image-tool{max-width:100%;margin-left:0}}\r\n@media(prefers-reduced-motion:reduce){.dsh-codex-meter>span{transition:none}.dsh-codex-skeleton span{animation:none}}\r\n`\r\n\r\nexport function installStyles(): () => void {\r\n if (document.querySelector(`style[data-plugin-css=\"${STYLE_ID}\"]`) !== null) return () => undefined\r\n const element = document.createElement('style')\r\n element.dataset.plugin = '@eddyskywalker/dsh-chatgpt-subscription'\r\n element.dataset.pluginCss = STYLE_ID\r\n element.textContent = CSS\r\n document.head.appendChild(element)\r\n return () => element.remove()\r\n}\r\n","import type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client'\nimport type { ImageAttachmentRef } from '@deepseek-ai/dsh-attachment'\nimport type {} from '@deepseek-ai/dsh-client-ui-settings/client'\nimport type {} from '@deepseek-ai/dsh-client-locale/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-slots'\nimport type {} from '@deepseek-ai/dsh-client-ui-model-selection/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-conversation/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-tool/client'\nimport { CODEX_IMAGE_TOOL_NAME } from '../compat.ts'\nimport { CodexComposerQuota } from './CodexComposerQuota.tsx'\nimport { CodexImageToolView, type ImageLoader } from './CodexImageToolView.tsx'\nimport { CodexSubscriptionSection } from './CodexSubscriptionSection.tsx'\nimport { SubscriptionApi } from './api.ts'\nimport { dictionaries, NS, type LocaleKey } from './locales.ts'\nimport { installStyles } from './styles.ts'\n\r\ndeclare module '@deepseek-ai/dsh-client-ui-slots' {\r\n interface LocaleNamespaceMap {\r\n 'dsh-chatgpt-subscription': LocaleKey\r\n }\r\n}\r\n\r\nexport const inject = ['slots', 'locale', 'modelDirectories', 'conversation']\n\r\nexport function apply(ctx: ClientContext): void {\r\n ctx.effect(() => ctx.locale.register(NS, dictionaries), 'dsh-chatgpt-subscription: dictionaries')\r\n ctx.effect(() => installStyles(), 'dsh-chatgpt-subscription: styles')\r\n ctx.slots.inject('settings.section', () => ctx.slots.register({\n name: 'settings.section',\n id: 'codex-subscription',\n order: 45,\n label: 'Codex 订阅',\n locale: NS,\n }, CodexSubscriptionSection))\n ctx.slots.inject('conversation.input.right', () => ctx.slots.register({\n name: 'conversation.input.right',\n id: 'codex-subscription-quota',\n order: 35,\n locale: NS,\n inject: (sessionId) => {\n const directory = ctx.modelDirectories.directoryFor(sessionId)\n return {\n api: new SubscriptionApi(),\n directory: directory.store,\n loadModelDirectory: () => {\n void directory.load().catch(() => undefined)\n },\n }\n },\n }, CodexComposerQuota))\n ctx.slots.inject('tool.call.toolview', () => ctx.slots.register({\n name: 'tool.call.toolview',\n key: CODEX_IMAGE_TOOL_NAME,\n locale: NS,\n inject: (sessionId) => ({\n loadImage: imageLoader(ctx, sessionId),\n }),\n }, CodexImageToolView))\n}\n\nfunction imageLoader(ctx: ClientContext, sessionId: string): ImageLoader {\n const conversation = ctx.conversation as unknown as {\n resolveImage(sessionId: string, attachment: ImageAttachmentRef): Promise<string>\n }\n return (attachment) => conversation.resolveImage(sessionId, attachment)\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"CodexSubscriptionSection.d.ts","sourceRoot":"","sources":["../../../src/client/CodexSubscriptionSection.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAA;AACjF,OAAO,KAAK,EAAE,oBAAoB,EAAmC,cAAc,EAAoC,MAAM,wBAAwB,CAAA;AAGrJ,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAA;AAGjC,KAAK,KAAK,GAAG,YAAY,CAAC,kBAAkB,CAAC,GAAG,WAAW,CAAC,OAAO,EAAE,CAAC,CAAA;AAEtE,KAAK,SAAS,GAAG,KAAK,CAAC,GAAG,CAAC,CAAA;AAE3B,wBAAgB,wBAAwB,CAAC,EAAE,CAAC,EAAE,EAAE,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CA+RxE;AAiBD,wBAAgB,YAAY,CAAC,OAAO,EAAE,oBAAoB,GAAG,SAAS,EAAE,CAAC,EAAE,SAAS,GAAG,MAAM,CAO5F;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,SAAS,EAAE,CAAC,EAAE,SAAS,GAAG,MAAM,CAO7F;AAcD,wBAAgB,QAAQ,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,cAAc,CAAC;IAAC,CAAC,EAAE,SAAS,CAAA;CAAE,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CAczH;AAMD,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,EAAE,CAAC,EAAE,SAAS,GAAG,MAAM,CAQxE;AAcD,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAO1D;AA0BD,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAUnD"}
1
+ {"version":3,"file":"CodexSubscriptionSection.d.ts","sourceRoot":"","sources":["../../../src/client/CodexSubscriptionSection.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAA;AACjF,OAAO,KAAK,EAAE,oBAAoB,EAAmC,cAAc,EAAoC,MAAM,wBAAwB,CAAA;AAGrJ,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAA;AAGjC,KAAK,KAAK,GAAG,YAAY,CAAC,kBAAkB,CAAC,GAAG,WAAW,CAAC,OAAO,EAAE,CAAC,CAAA;AAEtE,KAAK,SAAS,GAAG,KAAK,CAAC,GAAG,CAAC,CAAA;AAE3B,wBAAgB,wBAAwB,CAAC,EAAE,CAAC,EAAE,EAAE,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CA4SxE;AAiBD,wBAAgB,YAAY,CAAC,OAAO,EAAE,oBAAoB,GAAG,SAAS,EAAE,CAAC,EAAE,SAAS,GAAG,MAAM,CAO5F;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,SAAS,EAAE,CAAC,EAAE,SAAS,GAAG,MAAM,CAO7F;AAcD,wBAAgB,QAAQ,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,cAAc,CAAC;IAAC,CAAC,EAAE,SAAS,CAAA;CAAE,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CAczH;AAMD,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,EAAE,CAAC,EAAE,SAAS,GAAG,MAAM,CAQxE;AAcD,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAO1D;AA0BD,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAUnD"}
@@ -56,6 +56,8 @@ export declare const zh: {
56
56
  readonly contextWindowsHint: "默认 272K;可选启用最高 1M。该值用于 DSH 的压缩与溢出判断,可输入 1M、512K 等容量。";
57
57
  readonly contextWindow: "上下文窗口";
58
58
  readonly contextWindowInvalid: "上下文窗口必须是 1 到 1M 的整数,可使用 K 或 M 后缀。";
59
+ readonly saveContextWindow: "保存上下文窗口";
60
+ readonly save: "保存";
59
61
  readonly tokens: "tokens";
60
62
  readonly quickQuota: "在输入框旁显示快捷用量";
61
63
  readonly quickQuotaHint: "仅在当前会话选中 codex-chatgpt 模型时显示。";
@@ -157,6 +159,8 @@ export declare const dictionaries: {
157
159
  readonly contextWindowsHint: "默认 272K;可选启用最高 1M。该值用于 DSH 的压缩与溢出判断,可输入 1M、512K 等容量。";
158
160
  readonly contextWindow: "上下文窗口";
159
161
  readonly contextWindowInvalid: "上下文窗口必须是 1 到 1M 的整数,可使用 K 或 M 后缀。";
162
+ readonly saveContextWindow: "保存上下文窗口";
163
+ readonly save: "保存";
160
164
  readonly tokens: "tokens";
161
165
  readonly quickQuota: "在输入框旁显示快捷用量";
162
166
  readonly quickQuotaHint: "仅在当前会话选中 codex-chatgpt 模型时显示。";
@@ -198,6 +202,6 @@ export declare const dictionaries: {
198
202
  readonly retry: "重试";
199
203
  readonly unknown: "未知";
200
204
  };
201
- en: Record<"quota" | "account" | "storage" | "stale" | "pending" | "tokens" | "title" | "intro" | "signedOut" | "signedIn" | "plan" | "accountId" | "expires" | "storageWindows" | "storageMacKeychain" | "storageLinuxFile" | "storageMemory" | "storageUnavailable" | "securityWindows" | "securityMacKeychain" | "securityLinuxFile" | "securityMemory" | "securityUnavailable" | "signIn" | "signInAgain" | "cancel" | "signOut" | "refreshToken" | "popupBlocked" | "continueLogin" | "loading" | "connection" | "provider" | "connectionState" | "connected" | "untested" | "testConnection" | "testing" | "latency" | "models" | "enhancements" | "searchProvider" | "searchProviderHint" | "searchProviderDsh" | "searchProviderCodex" | "subagentModel" | "subagentModelHint" | "subagentReasoningEffort" | "subagentReasoningEffortHint" | "reasoningNone" | "reasoningLow" | "reasoningMedium" | "reasoningHigh" | "reasoningXhigh" | "reasoningMax" | "contextWindows" | "contextWindowsHint" | "contextWindow" | "contextWindowInvalid" | "quickQuota" | "quickQuotaHint" | "quotaIntro" | "refreshQuota" | "refreshing" | "noQuota" | "quotaSignedOut" | "updated" | "primary" | "secondary" | "limitWindow" | "used" | "remaining" | "available" | "unavailable" | "unlimited" | "credits" | "monthlySpend" | "resetCredits" | "spendControlReached" | "limit" | "exhausted" | "resets" | "quickQuotaLabel" | "quickQuotaLoading" | "imageToolRunning" | "imageToolDone" | "imageToolFailed" | "image" | "openImage" | "openNamedImage" | "imageLoading" | "imageLoadFailed" | "imagePreviewClose" | "imagePreviewOpenOriginal" | "retry" | "unknown", string>;
205
+ en: Record<"tokens" | "title" | "intro" | "account" | "signedOut" | "signedIn" | "plan" | "accountId" | "expires" | "storage" | "storageWindows" | "storageMacKeychain" | "storageLinuxFile" | "storageMemory" | "storageUnavailable" | "securityWindows" | "securityMacKeychain" | "securityLinuxFile" | "securityMemory" | "securityUnavailable" | "signIn" | "signInAgain" | "cancel" | "signOut" | "refreshToken" | "pending" | "popupBlocked" | "continueLogin" | "loading" | "connection" | "provider" | "connectionState" | "connected" | "untested" | "testConnection" | "testing" | "latency" | "models" | "enhancements" | "searchProvider" | "searchProviderHint" | "searchProviderDsh" | "searchProviderCodex" | "subagentModel" | "subagentModelHint" | "subagentReasoningEffort" | "subagentReasoningEffortHint" | "reasoningNone" | "reasoningLow" | "reasoningMedium" | "reasoningHigh" | "reasoningXhigh" | "reasoningMax" | "contextWindows" | "contextWindowsHint" | "contextWindow" | "contextWindowInvalid" | "saveContextWindow" | "save" | "quickQuota" | "quickQuotaHint" | "quota" | "quotaIntro" | "refreshQuota" | "refreshing" | "noQuota" | "quotaSignedOut" | "stale" | "updated" | "primary" | "secondary" | "limitWindow" | "used" | "remaining" | "available" | "unavailable" | "unlimited" | "credits" | "monthlySpend" | "resetCredits" | "spendControlReached" | "limit" | "exhausted" | "resets" | "quickQuotaLabel" | "quickQuotaLoading" | "imageToolRunning" | "imageToolDone" | "imageToolFailed" | "image" | "openImage" | "openNamedImage" | "imageLoading" | "imageLoadFailed" | "imagePreviewClose" | "imagePreviewOpenOriginal" | "retry" | "unknown", string>;
202
206
  };
203
207
  //# sourceMappingURL=locales.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"locales.d.ts","sourceRoot":"","sources":["../../../src/client/locales.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,EAAE,EAAG,0BAAmC,CAAA;AAErD,eAAO,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiGL,CAAA;AAEV,eAAO,MAAM,EAAE,EAAE,MAAM,CAAC,MAAM,OAAO,EAAE,EAAE,MAAM,CAiG9C,CAAA;AAED,MAAM,MAAM,SAAS,GAAG,MAAM,OAAO,EAAE,CAAA;AACvC,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAAa,CAAA"}
1
+ {"version":3,"file":"locales.d.ts","sourceRoot":"","sources":["../../../src/client/locales.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,EAAE,EAAG,0BAAmC,CAAA;AAErD,eAAO,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmGL,CAAA;AAEV,eAAO,MAAM,EAAE,EAAE,MAAM,CAAC,MAAM,OAAO,EAAE,EAAE,MAAM,CAmG9C,CAAA;AAED,MAAM,MAAM,SAAS,GAAG,MAAM,OAAO,EAAE,CAAA;AACvC,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAAa,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../../src/client/styles.ts"],"names":[],"mappings":"AAsFA,wBAAgB,aAAa,IAAI,MAAM,IAAI,CAQ1C"}
1
+ {"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../../src/client/styles.ts"],"names":[],"mappings":"AA0FA,wBAAgB,aAAa,IAAI,MAAM,IAAI,CAQ1C"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eddyskywalker/dsh-chatgpt-subscription",
3
- "version": "0.1.15",
3
+ "version": "0.1.16",
4
4
  "description": "DSH provider plugin for Codex access through a ChatGPT subscription.",
5
5
  "author": {
6
6
  "name": "eddyskywalker",