@eddyskywalker/dsh-chatgpt-subscription 0.1.4 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,40 +1,30 @@
1
- # Changelog
2
-
3
- ## 0.1.4 - 2026-08-16
4
-
5
- - 修复过程详情折叠在 0.1.3 版本引入后丢失部分初始状态的问题。
6
- - 优化折叠与展开的动画时长,提升用户体验。
7
- - 增强对新旧消息 ID 映射的鲁棒性处理。
8
-
9
- ## 0.1.3 - 2026-08-16
10
-
11
- - 优化过程详情折叠(Process folding)初始化重试机制与防抖探测逻辑。
12
- - 增强客户端 DOM 观察与挂载测试用例覆盖。
13
-
14
- ## 0.1.2 - 2026-08-16
15
-
16
- - 优化过程详情折叠的节点匹配逻辑。
17
-
18
- ## 0.1.1 - 2026-08-16
19
-
20
- - 新增执行过程详情与思考过程的可折叠展示机制(Collapsible process detail folding)。
21
- - 增强客户端与服务端 Responses 过程解析及 UI 交互。
22
-
23
- ## 0.1.0 - 2026-08-16
24
-
25
- - 首个正式版本发布。
26
- - 完善客户端 UI 样式体系与 `@eddyskywalker` 命名空间配置。
27
- - 增强命令执行工具与无状态安全重试机制。
28
-
29
- ## 0.1.0-alpha.0 - 2026-08-14
30
-
31
- - 新增 DSH Host/Client 双端插件与一级“Codex 订阅”设置入口。
32
- - 新增 ChatGPT OAuth PKCE、localhost callback、DPAPI TokenStore、刷新和注销。
33
- - 新增 `codex-chatgpt` LLM Adapter、固定 Responses SSE、vision、reasoning 与工具调用映射。
34
- - 新增 401 单次刷新重试、DSH 有界 retry policy、取消与安全工具参数校验。
35
- - 新增 Wham usage 双 bucket/双窗口解析、缓存、节流、连接测试和可访问进度条。
36
- - 新增 OAuth、路由、DPAPI、Responses、额度与 Client 注册测试。
37
- - 修复 OAuth 失败详情被状态刷新清空、旧 keep-alive 回调连接复用,以及 refresh token 失效后重复尝试的问题;token exchange 现在显示脱敏错误标识。
38
- - 修复工具调用 replay 缺失时仍发送孤立 `function_call_output` 导致 Codex 返回 400;现在会补全调用配对,并安全处理被压缩历史中的孤立结果。
39
-
40
- 这是首个 prerelease;没有稳定版升级承诺。ChatGPT backend compatibility 可能随上游变化。
1
+ # Changelog
2
+
3
+ ## 0.1.2 - 2026-08-16
4
+
5
+ - 优化过程详情折叠(Process folding)的初始化时机与节点匹配探测逻辑。
6
+ - 增强客户端 DOM 观察与挂载测试用例覆盖。
7
+
8
+ ## 0.1.1 - 2026-08-16
9
+
10
+ - 新增执行过程详情与思考过程的可折叠展示机制(Collapsible process detail folding)。
11
+ - 增强客户端与服务端 Responses 过程解析及 UI 交互。
12
+
13
+ ## 0.1.0 - 2026-08-16
14
+
15
+ - 首个正式版本发布。
16
+ - 完善客户端 UI 样式体系与 `@eddyskywalker` 命名空间配置。
17
+ - 增强命令执行工具与无状态安全重试机制。
18
+
19
+ ## 0.1.0-alpha.0 - 2026-08-14
20
+
21
+ - 新增 DSH Host/Client 双端插件与一级“Codex 订阅”设置入口。
22
+ - 新增 ChatGPT OAuth PKCE、localhost callback、DPAPI TokenStore、刷新和注销。
23
+ - 新增 `codex-chatgpt` LLM Adapter、固定 Responses SSE、vision、reasoning 与工具调用映射。
24
+ - 新增 401 单次刷新重试、DSH 有界 retry policy、取消与安全工具参数校验。
25
+ - 新增 Wham usage 双 bucket/双窗口解析、缓存、节流、连接测试和可访问进度条。
26
+ - 新增 OAuth、路由、DPAPI、Responses、额度与 Client 注册测试。
27
+ - 修复 OAuth 失败详情被状态刷新清空、旧 keep-alive 回调连接复用,以及 refresh token 失效后重复尝试的问题;token exchange 现在显示脱敏错误标识。
28
+ - 修复工具调用 replay 缺失时仍发送孤立 `function_call_output` 导致 Codex 返回 400;现在会补全调用配对,并安全处理被压缩历史中的孤立结果。
29
+
30
+ 这是首个 prerelease;没有稳定版升级承诺。ChatGPT backend compatibility 可能随上游变化。
package/lib/client.js CHANGED
@@ -605,12 +605,11 @@ window.__ModuleLoader__.load({
605
605
  const MAX_SCAN_ROOTS_PER_FRAME = 80;
606
606
  const MAX_TEXT_SAMPLE = 2e4;
607
607
  const PROCESS_CANDIDATE_SELECTOR = "article,section,li,div,p,span,button,h1,h2,h3,h4,h5,h6,[role=\"button\"],[role=\"listitem\"]";
608
- const PROCESS_MARKER_PREFIX = "(?:[•●◦▪▫·#▸▶▾▼›>-]\\s*)*";
609
- const PROCESS_PREFIX_PATTERN = "(?:上下文注入|思考过程|运行了命令|已运行(?:命令)?|Think|Search|Code|代码|Pwsh|PowerShell|Bash|Shell|Read|Glob|Grep|Web(?:\\s+Search)?|Tool|工具|思考)";
610
- const COMMAND_PATTERN = /(?:运行了命令|已运行|Code|代码|Pwsh|PowerShell|Bash|Shell|Read|Glob|Grep|Tool|工具)/i;
608
+ const PROCESS_PREFIX_PATTERN = "(?:上下文注入|Think|Search|Code|代码|Pwsh|PowerShell|Bash|Shell|Read|Glob|Grep|Web(?:\\s+Search)?|Tool|工具|思考)";
609
+ const COMMAND_PATTERN = /(?:Code|代码|Pwsh|PowerShell|Bash|Shell|Read|Glob|Grep|Tool|工具)/i;
611
610
  const SEARCH_PATTERN = /(?:Search|Web\s+Search|搜索)/i;
612
- const PROCESS_PREFIX_RE = new RegExp(`^\\s*${PROCESS_MARKER_PREFIX}${PROCESS_PREFIX_PATTERN}\\s*(?:[·::-]|$)`, "i");
613
- const PROCESS_LINE_RE = new RegExp(`(?:^|\\n)\\s*${PROCESS_MARKER_PREFIX}${PROCESS_PREFIX_PATTERN}\\s*(?:[·::-]|$)`, "gi");
611
+ const PROCESS_PREFIX_RE = new RegExp(`^\\s*(?:[•●◦▪▫·#-]\\s*)?${PROCESS_PREFIX_PATTERN}\\s*(?:[·::-]|$)`, "i");
612
+ const PROCESS_LINE_RE = new RegExp(`(?:^|\\n)\\s*(?:[•●◦▪▫·#-]\\s*)?${PROCESS_PREFIX_PATTERN}\\s*(?:[·::-]|$)`, "gi");
614
613
  function installProcessFolding(options = {}) {
615
614
  if (typeof document === "undefined") return () => void 0;
616
615
  if (document.body === null) {
package/lib/client.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","names":[],"sources":["../src/compat.ts","../src/client/api.ts","../src/client/CodexSubscriptionSection.tsx","../src/client/locales.ts","../src/client/process-folding.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\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_USAGE_URL = 'https://chatgpt.com/backend-api/wham/usage' as const\nexport const CODEX_ORIGINATOR = 'opencode' 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 { ROUTE_PREFIX } from '../compat.ts'\nimport type {\n ApiEnvelope,\n LoginEventDto,\n LoginStartDto,\n PluginStatusDto,\n QuotaStatusDto,\n ConnectionTestDto,\n} from '../shared/contracts.ts'\n\nexport class SubscriptionApi {\n status(): Promise<PluginStatusDto> {\n return request<PluginStatusDto>(`${ROUTE_PREFIX}/status`)\n }\n\n startLogin(): Promise<LoginStartDto> {\n return post<LoginStartDto>(`${ROUTE_PREFIX}/login/start`, {})\n }\n\n cancelLogin(loginId: string): Promise<{ cancelled: boolean }> {\n return post(`${ROUTE_PREFIX}/login/cancel`, { loginId })\n }\n\n logout(): Promise<{ authenticated: false }> {\n return post(`${ROUTE_PREFIX}/logout`, {})\n }\n\n refresh(): Promise<PluginStatusDto> {\n return post(`${ROUTE_PREFIX}/token/refresh`, {})\n }\n\n refreshQuota(): Promise<QuotaStatusDto> {\n return post(`${ROUTE_PREFIX}/quota/refresh`, {})\n }\n\n testConnection(): Promise<ConnectionTestDto> {\n return post(`${ROUTE_PREFIX}/connection/test`, {})\n }\n\n events(loginId: string): EventSource {\n return new EventSource(`${ROUTE_PREFIX}/login/events?loginId=${encodeURIComponent(loginId)}`)\n }\n}\n\nasync function post<T>(url: string, body: Record<string, unknown>): Promise<T> {\n return request<T>(url, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(body),\n })\n}\n\nasync function request<T>(url: string, init?: RequestInit): Promise<T> {\n const response = await fetch(url, { ...init, credentials: 'same-origin' })\n const envelope = await response.json() as ApiEnvelope<T>\n if (!response.ok || !envelope.ok) {\n throw new Error(envelope.ok ? `Request failed (${response.status})` : envelope.error.message)\n }\n return envelope.value\n}\n\nexport function parseLoginEvent(event: MessageEvent<string>): LoginEventDto | null {\n try {\n const value = JSON.parse(event.data) as LoginEventDto\n return typeof value === 'object' && value !== null && typeof value.type === 'string' ? value : null\n } catch {\n return null\n }\n}\n","import { useCallback, useEffect, useRef, useState } from 'react'\nimport type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { PluginStatusDto, QuotaBucketDto, QuotaWindowDto } from '../shared/contracts.ts'\nimport { SubscriptionApi, parseLoginEvent } from './api.ts'\nimport { NS } from './locales.ts'\n\ntype Props = PropsRuntime<'settings.section'> & PropsLocale<typeof NS>\ntype BusyAction = 'login' | 'token' | 'quota' | 'test' | 'logout' | null\ntype Translate = Props['t']\n\nconst MODELS = ['gpt-5.6-sol', 'gpt-5.6-terra', 'gpt-5.6-luna', 'gpt-5.5', 'gpt-5.4', 'gpt-5.4-mini', 'gpt-5.2']\n\nexport function CodexSubscriptionSection({ t }: Props): React.JSX.Element {\n const apiRef = useRef(new SubscriptionApi())\n const eventSourceRef = useRef<EventSource | null>(null)\n const [status, setStatus] = useState<PluginStatusDto | null>(null)\n const [busy, setBusy] = useState<BusyAction>(null)\n const [error, setError] = useState<string | null>(null)\n const [authUrl, setAuthUrl] = useState<string | null>(null)\n const [popupBlocked, setPopupBlocked] = useState(false)\n const [connection, setConnection] = useState<{ latencyMs: number; checkedAt: number } | null>(null)\n\n const load = useCallback(async (quiet = false) => {\n if (!quiet) setError(null)\n try {\n const next = await apiRef.current.status()\n setStatus(next)\n if (next.error !== undefined) setError(next.error.message)\n } catch (cause) {\n if (!quiet) setError(messageOf(cause))\n }\n }, [])\n\n useEffect(() => {\n void load()\n const refreshWhenVisible = (): void => {\n if (document.visibilityState === 'visible') void load(true)\n }\n document.addEventListener('visibilitychange', refreshWhenVisible)\n const timer = window.setInterval(refreshWhenVisible, 60_000)\n return () => {\n window.clearInterval(timer)\n document.removeEventListener('visibilitychange', refreshWhenVisible)\n eventSourceRef.current?.close()\n }\n }, [load])\n\n const watchLogin = useCallback((loginId: string) => {\n eventSourceRef.current?.close()\n const source = apiRef.current.events(loginId)\n eventSourceRef.current = source\n const finish = async (message?: string): Promise<void> => {\n source.close()\n eventSourceRef.current = null\n setBusy(null)\n setAuthUrl(null)\n if (message !== undefined) setError(message)\n // Preserve the terminal OAuth error while refreshing the account DTO.\n await load(true)\n }\n source.addEventListener('completed', (event) => {\n const parsed = parseLoginEvent(event as MessageEvent<string>)\n if (parsed?.type === 'completed') void finish()\n })\n source.addEventListener('cancelled', () => void finish())\n source.addEventListener('failed', (event) => {\n const parsed = parseLoginEvent(event as MessageEvent<string>)\n void finish(parsed?.type === 'failed' ? parsed.error.message : 'ChatGPT sign-in failed.')\n })\n }, [load])\n\n useEffect(() => {\n const loginId = status?.login.active ? status.login.loginId : null\n if (loginId !== null && loginId !== undefined && eventSourceRef.current === null) watchLogin(loginId)\n }, [status?.login.active, status?.login.loginId, watchLogin])\n\n const startLogin = async (): Promise<void> => {\n setBusy('login')\n setError(null)\n setPopupBlocked(false)\n const popup = window.open('about:blank', 'dsh-chatgpt-oauth', 'popup,width=560,height=760')\n try {\n const login = await apiRef.current.startLogin()\n setAuthUrl(login.authUrl)\n if (popup === null) setPopupBlocked(true)\n else popup.location.replace(login.authUrl)\n watchLogin(login.loginId)\n await load(true)\n } catch (cause) {\n popup?.close()\n setBusy(null)\n setError(messageOf(cause))\n }\n }\n\n const cancelLogin = async (): Promise<void> => {\n const loginId = status?.login.loginId\n if (loginId === null || loginId === undefined) return\n setBusy('login')\n try {\n await apiRef.current.cancelLogin(loginId)\n eventSourceRef.current?.close()\n eventSourceRef.current = null\n setAuthUrl(null)\n await load()\n } catch (cause) {\n setError(messageOf(cause))\n } finally {\n setBusy(null)\n }\n }\n\n const refreshToken = async (): Promise<void> => run('token', async () => {\n setStatus(await apiRef.current.refresh())\n })\n\n const refreshQuota = async (): Promise<void> => run('quota', async () => {\n const quota = await apiRef.current.refreshQuota()\n setStatus((current) => current === null ? current : { ...current, quota })\n })\n\n const testConnection = async (): Promise<void> => run('test', async () => {\n const result = await apiRef.current.testConnection()\n setConnection({ latencyMs: result.latencyMs, checkedAt: result.checkedAt })\n })\n\n const logout = async (): Promise<void> => run('logout', async () => {\n await apiRef.current.logout()\n eventSourceRef.current?.close()\n eventSourceRef.current = null\n setAuthUrl(null)\n setConnection(null)\n await load()\n })\n\n const run = async (action: Exclude<BusyAction, null>, task: () => Promise<void>): Promise<void> => {\n setBusy(action)\n setError(null)\n try {\n await task()\n } catch (cause) {\n setError(messageOf(cause))\n } finally {\n setBusy(null)\n }\n }\n\n const account = status?.account\n return <section className=\"dsh-codex-page\" aria-labelledby=\"dsh-codex-title\">\n <header>\n <h2 id=\"dsh-codex-title\" className=\"dsh-codex-title\">{t('title')}</h2>\n <p className=\"dsh-codex-intro\">{t('intro')}</p>\n </header>\n\n {error !== null ? <div className=\"dsh-codex-errorbar\" role=\"alert\">\n <span>{error}</span>\n {status === null ? <Button disabled={busy !== null} onClick={() => load()}>{t('retry')}</Button> : null}\n </div> : null}\n\n {status === null && error === null ? <Skeleton label={t('loading')} /> : <>\n <Section title={t('account')}>\n <InfoRow label={status?.authenticated ? t('signedIn') : t('signedOut')} value={account?.email ?? '—'} />\n {status?.authenticated ? <>\n <InfoRow label={t('plan')} value={account?.planType ?? t('unknown')} />\n <InfoRow label={t('accountId')} value={account?.accountIdSuffix ?? '—'} />\n <InfoRow label={t('expires')} value={formatDate(account?.tokenExpiresAt)} />\n </> : null}\n <InfoRow label={t('storage')} value={t('storageValue')} />\n <p className=\"dsh-codex-notice\">{t('securityNotice')}</p>\n {status?.login.active ? <p className=\"dsh-codex-muted\" role=\"status\">{t('pending')}</p> : null}\n {popupBlocked ? <p className=\"dsh-codex-error\">{t('popupBlocked')}</p> : null}\n {authUrl !== null ? <a className=\"dsh-codex-link\" href={authUrl} target=\"_blank\" rel=\"noreferrer\">{t('continueLogin')}</a> : null}\n <div className=\"dsh-codex-actions\">\n {status?.login.active\n ? <Button disabled={busy !== null} onClick={cancelLogin}>{t('cancel')}</Button>\n : <Button primary disabled={busy !== null} onClick={startLogin}>{status?.authenticated ? t('signInAgain') : t('signIn')}</Button>}\n {status?.authenticated ? <>\n <Button disabled={busy !== null} onClick={refreshToken}>{t('refreshToken')}</Button>\n <Button disabled={busy !== null} onClick={logout}>{t('signOut')}</Button>\n </> : null}\n </div>\n </Section>\n\n <Section title={t('connection')}>\n <InfoRow label={t('provider')} value=\"Codex(ChatGPT 订阅) · codex-chatgpt\" />\n <InfoRow label={t('connectionState')} value={connection === null ? t('untested') : t('connected')} />\n {connection !== null ? <InfoRow label={t('latency')} value={`${connection.latencyMs} ms · ${formatDate(connection.checkedAt)}`} /> : null}\n <div className=\"dsh-codex-models\" aria-label={t('models')}>\n {MODELS.map((model) => <code key={model}>{model}</code>)}\n </div>\n <div className=\"dsh-codex-actions\">\n <Button disabled={!status?.authenticated || busy !== null} onClick={testConnection}>{busy === 'test' ? t('testing') : t('testConnection')}</Button>\n </div>\n </Section>\n\n <Section title={t('quota')} aside={<Button disabled={!status?.authenticated || busy !== null} onClick={refreshQuota}>{busy === 'quota' ? t('refreshing') : t('refreshQuota')}</Button>}>\n <p className=\"dsh-codex-muted\">{t('quotaIntro')}</p>\n {status?.quota.state === 'signed-out' ? <p className=\"dsh-codex-empty\">{t('quotaSignedOut')}</p> : null}\n {status?.quota.buckets.map((bucket) => <QuotaBucket key={bucket.id} bucket={bucket} t={t} />)}\n {status?.quota.state === 'empty' ? <p className=\"dsh-codex-empty\">{t('noQuota')}</p> : null}\n {status?.quota.stale ? <p className=\"dsh-codex-warning\" role=\"status\">{t('stale')}</p> : null}\n {status?.quota.error ? <p className=\"dsh-codex-error\" role=\"alert\">{status.quota.error.message}</p> : null}\n {status?.quota.fetchedAt ? <p className=\"dsh-codex-timestamp\">{t('updated')}: {formatDate(status.quota.fetchedAt)}</p> : null}\n </Section>\n </>}\n\n <span className=\"dsh-codex-sr\" aria-live=\"polite\">{busy === null ? '' : busy}</span>\n </section>\n}\n\nfunction Section({ title, aside, children }: { title: string; aside?: React.ReactNode; children: React.ReactNode }): React.JSX.Element {\n return <section className=\"dsh-codex-group\">\n <div className=\"dsh-codex-grouphead\"><h3>{title}</h3>{aside}</div>\n {children}\n </section>\n}\n\nfunction Button({ primary = false, disabled, onClick, children }: { primary?: boolean; disabled?: boolean; onClick: () => void | Promise<void>; children: React.ReactNode }): React.JSX.Element {\n return <button className={`dsh-codex-button${primary ? ' dsh-codex-button-primary' : ''}`} type=\"button\" disabled={disabled} onClick={() => void onClick()}>{children}</button>\n}\n\nfunction InfoRow({ label, value }: { label: string; value: string }): React.JSX.Element {\n return <div className=\"dsh-codex-row\"><span className=\"dsh-codex-label\">{label}</span><span className=\"dsh-codex-value\">{value}</span></div>\n}\n\nfunction QuotaBucket({ bucket, t }: { bucket: QuotaBucketDto; t: Translate }): React.JSX.Element {\n return <article className=\"dsh-codex-quota-card\">\n <div className=\"dsh-codex-quota-title\"><strong>{bucket.name}</strong>{bucket.planType ? <span>{bucket.planType}</span> : null}</div>\n {bucket.primary ? <QuotaBar label={windowLabel(bucket.primary.windowDurationMins, t)} window={bucket.primary} t={t} /> : null}\n {bucket.secondary ? <QuotaBar label={windowLabel(bucket.secondary.windowDurationMins, t)} window={bucket.secondary} t={t} /> : null}\n </article>\n}\n\nexport function QuotaBar({ label, window, t }: { label: string; window: QuotaWindowDto; t: Translate }): React.JSX.Element {\n const percent = window.usedPercent\n const level = percent >= 95 ? 'danger' : percent >= 80 ? 'warning' : 'normal'\n const remaining = Math.max(0, 100 - percent)\n return <div className=\"dsh-codex-meter-wrap\">\n <div className=\"dsh-codex-meter-label\"><span>{label}</span><strong>{formatPercent(percent)}</strong></div>\n <div className={`dsh-codex-meter dsh-codex-meter-${level}`} role=\"progressbar\" aria-label={`${label}: ${formatPercent(percent)} ${t('used')}`} aria-valuemin={0} aria-valuemax={100} aria-valuenow={percent}>\n <span style={{ width: `${percent}%` }} />\n </div>\n <div className=\"dsh-codex-meter-meta\">\n <span>{percent >= 100 ? `${t('exhausted')} · ${formatPercent(remaining)} ${t('remaining')}` : `${formatPercent(percent)} ${t('used')} · ${formatPercent(remaining)} ${t('remaining')}`}</span>\n <span>{window.resetsAt === null ? '—' : `${t('resets')}: ${formatReset(window.resetsAt)}`}</span>\n </div>\n </div>\n}\n\nfunction Skeleton({ label }: { label: string }): React.JSX.Element {\n return <div className=\"dsh-codex-skeleton\" role=\"status\" aria-label={label}><span /><span /></div>\n}\n\nexport function windowLabel(minutes: number | null, t: Translate): string {\n if (minutes === null) return t('limitWindow')\n const [value, unit]: [number, Intl.NumberFormatOptions['unit']] = minutes >= 1440 && minutes % 1440 === 0\n ? [minutes / 1440, 'day']\n : minutes >= 60 && minutes % 60 === 0\n ? [minutes / 60, 'hour']\n : [Math.round(minutes), 'minute']\n return `${new Intl.NumberFormat(undefined, { style: 'unit', unit, unitDisplay: 'long' }).format(value)} ${t('limitWindow')}`\n}\n\nfunction formatPercent(value: number): string {\n return `${new Intl.NumberFormat(undefined, { maximumFractionDigits: 1 }).format(value)}%`\n}\n\nfunction formatDate(seconds: number | undefined): string {\n if (seconds === undefined) return '—'\n return new Intl.DateTimeFormat(undefined, { dateStyle: 'medium', timeStyle: 'short' }).format(seconds * 1000)\n}\n\nexport function formatReset(seconds: number): string {\n const absolute = formatDate(seconds)\n const diff = seconds * 1000 - Date.now()\n const abs = Math.abs(diff)\n const [amount, unit]: [number, Intl.RelativeTimeFormatUnit] = abs >= 86_400_000\n ? [Math.round(diff / 86_400_000), 'day']\n : abs >= 3_600_000\n ? [Math.round(diff / 3_600_000), 'hour']\n : [Math.round(diff / 60_000), 'minute']\n return `${absolute} (${new Intl.RelativeTimeFormat(undefined, { numeric: 'auto' }).format(amount, unit)})`\n}\n\nfunction messageOf(error: unknown): string {\n return error instanceof Error ? error.message : String(error)\n}\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 storageValue: 'Windows DPAPI(当前用户加密)',\n securityNotice: '令牌仅保存在 Host 端的 DPAPI 加密文件中,不会进入浏览器、settings.yaml 或日志。',\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 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 exhausted: '额度已用尽',\n resets: '重置',\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 storageValue: 'Windows DPAPI (current-user encrypted)',\n securityNotice: 'Tokens stay in a Host-side DPAPI-encrypted file and never enter the browser, settings.yaml, or logs.',\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 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 exhausted: 'Quota exhausted',\n resets: 'Resets',\n retry: 'Retry',\n unknown: 'Unknown',\n}\n\nexport type LocaleKey = keyof typeof zh\nexport const dictionaries = { zh, en }\n","const ROW_CLASS = 'dsh-codex-process-row'\nconst GROUP_HEAD_CLASS = 'dsh-codex-process-group-head'\nconst GROUP_COLLAPSED_CLASS = 'dsh-codex-process-group-collapsed'\nconst GROUP_HIDDEN_CLASS = 'dsh-codex-process-group-hidden'\nconst USER_TOGGLED_ATTR = 'data-dsh-codex-process-user-toggled'\nconst TITLE_ATTR = 'data-dsh-codex-process-title'\nconst TITLE = 'Click to expand or collapse process details'\nconst DEFAULT_AUTO_COLLAPSE_MS = 350\nconst MAX_PROCESS_LABELS_PER_ROW = 3\nconst MAX_SCAN_ROOTS_PER_FRAME = 80\nconst MAX_TEXT_SAMPLE = 20_000\nconst PROCESS_CANDIDATE_SELECTOR = 'article,section,li,div,p,span,button,h1,h2,h3,h4,h5,h6,[role=\"button\"],[role=\"listitem\"]'\nconst PROCESS_MARKER_PREFIX = '(?:[•●◦▪▫·#▸▶▾▼›>-]\\\\s*)*'\nconst PROCESS_PREFIX_PATTERN = '(?:上下文注入|思考过程|运行了命令|已运行(?:命令)?|Think|Search|Code|代码|Pwsh|PowerShell|Bash|Shell|Read|Glob|Grep|Web(?:\\\\s+Search)?|Tool|工具|思考)'\nconst COMMAND_PATTERN = /(?:运行了命令|已运行|Code|代码|Pwsh|PowerShell|Bash|Shell|Read|Glob|Grep|Tool|工具)/i\nconst SEARCH_PATTERN = /(?:Search|Web\\s+Search|搜索)/i\nconst PROCESS_PREFIX_RE = new RegExp(`^\\\\s*${PROCESS_MARKER_PREFIX}${PROCESS_PREFIX_PATTERN}\\\\s*(?:[·::-]|$)`, 'i')\nconst PROCESS_LINE_RE = new RegExp(`(?:^|\\\\n)\\\\s*${PROCESS_MARKER_PREFIX}${PROCESS_PREFIX_PATTERN}\\\\s*(?:[·::-]|$)`, 'gi')\n\nexport interface ProcessFoldingOptions {\n autoCollapseMs?: number\n}\n\ninterface GroupState {\n rows: HTMLElement[]\n click: (event: MouseEvent) => void\n keydown: (event: KeyboardEvent) => void\n timer: ReturnType<typeof setTimeout> | null\n}\n\ninterface PreviousGroupState {\n collapsed: boolean\n userToggled: boolean\n}\n\nexport function installProcessFolding(options: ProcessFoldingOptions = {}): () => void {\n if (typeof document === 'undefined') return () => undefined\n if (document.body === null) {\n let dispose: () => void = () => undefined\n let started = false\n const start = () => {\n if (started) return\n started = true\n dispose = installProcessFolding(options)\n }\n document.addEventListener('DOMContentLoaded', start, { once: true })\n return () => {\n document.removeEventListener('DOMContentLoaded', start)\n dispose()\n }\n }\n\n const autoCollapseMs = options.autoCollapseMs ?? DEFAULT_AUTO_COLLAPSE_MS\n const groups = new Map<HTMLElement, GroupState>()\n const pending = new Set<Element>()\n let frame: number | null = null\n\n const scheduleFlush = () => {\n if (frame !== null) return\n frame = requestAnimationFrame(() => {\n frame = null\n flush()\n })\n }\n\n const queue = (element: Element | null) => {\n if (element === null || !element.isConnected) return\n pending.add(element)\n scheduleFlush()\n }\n\n const scheduleAutoCollapse = (head: HTMLElement) => {\n const state = groups.get(head)\n if (state === undefined || head.hasAttribute(USER_TOGGLED_ATTR)) return\n if (state.timer !== null) clearTimeout(state.timer)\n state.timer = setTimeout(() => {\n state.timer = null\n if (head.isConnected && !head.hasAttribute(USER_TOGGLED_ATTR)) setGroupCollapsed(head, true)\n }, autoCollapseMs)\n }\n\n const syncGroup = (rows: HTMLElement[], previous: PreviousGroupState | undefined) => {\n const head = rows[0]\n const title = titleForProcessRows(rows)\n const click = (event: MouseEvent) => {\n if (isInteractiveTarget(event.target, head)) return\n markUserToggled(head)\n setGroupCollapsed(head, !head.classList.contains(GROUP_COLLAPSED_CLASS))\n }\n const keydown = (event: KeyboardEvent) => {\n if (event.key !== 'Enter' && event.key !== ' ') return\n event.preventDefault()\n markUserToggled(head)\n setGroupCollapsed(head, !head.classList.contains(GROUP_COLLAPSED_CLASS))\n }\n\n groups.set(head, { rows, click, keydown, timer: null })\n for (const row of rows) row.classList.add(ROW_CLASS)\n head.classList.add(GROUP_HEAD_CLASS)\n if (!head.hasAttribute('tabindex')) head.tabIndex = 0\n head.setAttribute('aria-expanded', String(!(previous?.collapsed ?? false)))\n head.setAttribute(TITLE_ATTR, title)\n head.title ||= TITLE\n if (previous?.userToggled === true) head.setAttribute(USER_TOGGLED_ATTR, 'true')\n head.addEventListener('click', click)\n head.addEventListener('keydown', keydown)\n setGroupCollapsed(head, previous?.collapsed ?? false)\n scheduleAutoCollapse(head)\n }\n\n const rebuildParentGroups = (parent: Element) => {\n const previous = new Map<HTMLElement, PreviousGroupState>()\n for (const [head, state] of groups) {\n if (head.parentElement !== parent) continue\n previous.set(head, {\n collapsed: head.classList.contains(GROUP_COLLAPSED_CLASS),\n userToggled: head.hasAttribute(USER_TOGGLED_ATTR),\n })\n cleanupGroup(head, state)\n groups.delete(head)\n }\n\n let rows: HTMLElement[] = []\n const flushRows = () => {\n if (rows.length > 0) syncGroup(rows, previous.get(rows[0]))\n rows = []\n }\n\n for (const child of Array.from(parent.children)) {\n if (child instanceof HTMLElement && isProcessRow(child)) {\n rows.push(child)\n } else {\n flushRows()\n }\n }\n flushRows()\n }\n\n const flush = () => {\n const parents = new Set<Element>()\n let scanned = 0\n for (const root of Array.from(pending)) {\n pending.delete(root)\n if (!root.isConnected) continue\n for (const row of findProcessRows(root)) {\n if (row.parentElement !== null) parents.add(row.parentElement)\n }\n const grouped = nearestGroupHead(root)\n if (grouped !== null && grouped.parentElement !== null) parents.add(grouped.parentElement)\n scanned++\n if (scanned >= MAX_SCAN_ROOTS_PER_FRAME && pending.size > 0) {\n scheduleFlush()\n break\n }\n }\n for (const parent of parents) rebuildParentGroups(parent)\n }\n\n const observer = new MutationObserver((mutations) => {\n for (const mutation of mutations) {\n if (mutation.type === 'characterData') {\n queue(nodeElement(mutation.target)?.closest(PROCESS_CANDIDATE_SELECTOR) ?? nodeElement(mutation.target))\n continue\n }\n for (const node of mutation.addedNodes) queue(nodeElement(node))\n }\n })\n observer.observe(document.body, { childList: true, characterData: true, subtree: true })\n queue(document.body)\n\n return () => {\n observer.disconnect()\n if (frame !== null) cancelAnimationFrame(frame)\n pending.clear()\n for (const [head, state] of groups) cleanupGroup(head, state)\n groups.clear()\n }\n}\n\nfunction cleanupGroup(head: HTMLElement, state: GroupState): void {\n if (state.timer !== null) clearTimeout(state.timer)\n head.removeEventListener('click', state.click)\n head.removeEventListener('keydown', state.keydown)\n for (const row of state.rows) row.classList.remove(ROW_CLASS, GROUP_HIDDEN_CLASS)\n head.classList.remove(GROUP_HEAD_CLASS, GROUP_COLLAPSED_CLASS)\n head.removeAttribute('aria-expanded')\n head.removeAttribute(USER_TOGGLED_ATTR)\n head.removeAttribute(TITLE_ATTR)\n if (head.title === TITLE) head.removeAttribute('title')\n}\n\nfunction findProcessRows(root: Element): HTMLElement[] {\n const rows: HTMLElement[] = []\n if (root instanceof HTMLElement && isProcessRow(root)) pushProcessRow(rows, root)\n for (const element of root.querySelectorAll(PROCESS_CANDIDATE_SELECTOR)) {\n if (element instanceof HTMLElement && isProcessRow(element)) pushProcessRow(rows, element)\n }\n return rows\n}\n\nfunction pushProcessRow(rows: HTMLElement[], row: HTMLElement): void {\n if (rows.some((existing) => existing.contains(row))) return\n rows.push(row)\n}\n\nfunction isProcessRow(element: HTMLElement): boolean {\n if (element.closest('.dsh-codex-page') !== null || shouldIgnore(element)) return false\n const raw = (element.textContent ?? '').slice(0, MAX_TEXT_SAMPLE)\n const normalized = raw.replace(/\\s+/g, ' ').trim()\n if (!PROCESS_PREFIX_RE.test(normalized)) return false\n const stats = processTextStats(raw)\n if (stats.processLabels === 0 || stats.processLabels > MAX_PROCESS_LABELS_PER_ROW) return false\n return !(element.children.length > 0 && stats.hasNonProcessLine)\n}\n\nfunction processTextStats(text: string): { processLabels: number; hasNonProcessLine: boolean } {\n PROCESS_LINE_RE.lastIndex = 0\n let processLabels = 0\n while (PROCESS_LINE_RE.exec(text) !== null) processLabels++\n const hasNonProcessLine = text.split(/\\r?\\n/)\n .map((line) => line.replace(/\\s+/g, ' ').trim())\n .some((line) => line !== '' && !PROCESS_PREFIX_RE.test(line))\n return { processLabels, hasNonProcessLine }\n}\n\nfunction setGroupCollapsed(head: HTMLElement, collapsed: boolean): void {\n const state = findCurrentGroupState(head)\n if (state === null) return\n head.classList.toggle(GROUP_COLLAPSED_CLASS, collapsed)\n head.setAttribute('aria-expanded', String(!collapsed))\n for (const row of state.rows.slice(1)) row.classList.toggle(GROUP_HIDDEN_CLASS, collapsed)\n}\n\nfunction findCurrentGroupState(head: HTMLElement): { rows: HTMLElement[] } | null {\n const rows: HTMLElement[] = [head]\n let sibling = head.nextElementSibling\n while (sibling instanceof HTMLElement && isProcessRow(sibling)) {\n rows.push(sibling)\n sibling = sibling.nextElementSibling\n }\n return rows.length > 0 ? { rows } : null\n}\n\nfunction markUserToggled(head: HTMLElement): void {\n head.setAttribute(USER_TOGGLED_ATTR, 'true')\n}\n\nfunction nearestGroupHead(element: Element): HTMLElement | null {\n const decorated = element.closest(`.${GROUP_HEAD_CLASS}`)\n return decorated instanceof HTMLElement ? decorated : null\n}\n\nfunction titleForProcessRows(rows: HTMLElement[]): string {\n const text = rows.map((row) => row.textContent ?? '').join('\\n')\n if (COMMAND_PATTERN.test(text)) return '运行了命令'\n if (SEARCH_PATTERN.test(text)) return '进行了搜索'\n return '思考过程'\n}\n\nfunction nodeElement(node: Node): Element | null {\n if (node instanceof Element) return node\n return node.parentElement\n}\n\nfunction shouldIgnore(element: HTMLElement): boolean {\n return element.closest('textarea,input,select,a,[contenteditable=\"true\"],script,style') !== null\n}\n\nfunction isInteractiveTarget(target: EventTarget | null, groupHead: HTMLElement): boolean {\n if (!(target instanceof Element)) return false\n const interactive = target.closest('button,a,input,textarea,select,[role=\"button\"],[contenteditable=\"true\"]')\n return interactive !== null && interactive !== groupHead\n}\n","const STYLE_ID = '@eddyskywalker/dsh-chatgpt-subscription/main'\n\nconst CSS = `\n.dsh-codex-page{box-sizing:border-box;color:var(--dsw-alias-label-primary);display:flex;flex-direction:column;gap:20px;max-width:780px;min-width:0;padding:2px 0 30px}\n.dsh-codex-page *{box-sizing:border-box}\n.dsh-codex-title{font-size:15px;font-weight:650;line-height:1.4;margin:0 0 5px}\n.dsh-codex-intro,.dsh-codex-muted{color:var(--dsw-alias-label-secondary);font-size:13px;line-height:1.55;margin:0}\n.dsh-codex-group{border-top:1px solid var(--dsw-alias-border-l2);min-width:0}\n.dsh-codex-grouphead{align-items:center;display:flex;gap:12px;justify-content:space-between;min-height:48px}\n.dsh-codex-grouphead h3{font-size:14px;font-weight:650;margin:0}\n.dsh-codex-row{align-items:center;border-bottom:1px solid var(--dsw-alias-border-l2);display:flex;gap:20px;justify-content:space-between;min-height:44px;padding:8px 0}\n.dsh-codex-label{color:var(--dsw-alias-label-secondary);font-size:13px;flex:0 0 auto}\n.dsh-codex-value{font-size:13px;min-width:0;overflow-wrap:anywhere;text-align:right}\n.dsh-codex-actions{display:flex;flex-wrap:wrap;gap:8px;justify-content:flex-end;padding-top:12px}\n.dsh-codex-button{background:var(--dsw-alias-bg-layer-2);border: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}\n.dsh-codex-button:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}\n.dsh-codex-button:focus-visible,.dsh-codex-link:focus-visible{outline:2px solid var(--dsw-alias-button-info-fill,#397ee8);outline-offset:2px}\n.dsh-codex-button:disabled{cursor:default;opacity:.5}\n.dsh-codex-button-primary{background:var(--dsw-alias-button-info-fill,#397ee8);border-color:transparent;color:var(--dsw-alias-button-info-label,#fff)}\n.dsh-codex-notice{background:var(--dsw-alias-bg-layer-2);border: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}\n.dsh-codex-error,.dsh-codex-warning{font-size:12px;line-height:1.5;margin:8px 0 0}\n.dsh-codex-error{color:var(--dsw-alias-label-danger,#d94b4b)}\n.dsh-codex-warning{color:var(--dsw-alias-label-warning,#c77a18)}\n.dsh-codex-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}\n.dsh-codex-link{color:var(--dsw-alias-label-link,#3278d4);display:inline-block;font-size:13px;margin-top:8px}\n.dsh-codex-models{display:flex;flex-wrap:wrap;gap:6px;padding-top:12px}\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}\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}\n.dsh-codex-quota-title{align-items:center;display:flex;font-size:13px;gap:8px;justify-content:space-between}\n.dsh-codex-quota-title span{color:var(--dsw-alias-label-tertiary);font-size:11px;text-transform:uppercase}\n.dsh-codex-meter-wrap{margin-top:13px}\n.dsh-codex-meter-label,.dsh-codex-meter-meta{display:flex;gap:10px;justify-content:space-between}\n.dsh-codex-meter-label{font-size:12px;margin-bottom:6px}\n.dsh-codex-meter-meta{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:1.45;margin-top:6px}\n.dsh-codex-meter{background:var(--dsw-alias-bg-layer-1,rgba(127,127,127,.15));border-radius:999px;height:7px;overflow:hidden;width:100%}\n.dsh-codex-meter>span{background:var(--dsw-alias-button-info-fill,#397ee8);border-radius:inherit;display:block;height:100%;max-width:100%;min-width:0;transition:width .25s ease}\n.dsh-codex-meter-warning>span{background:var(--dsw-alias-label-warning,#d58a24)}\n.dsh-codex-meter-danger>span{background:var(--dsw-alias-label-danger,#d94b4b)}\n.dsh-codex-empty{border: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}\n.dsh-codex-timestamp{color:var(--dsw-alias-label-tertiary);font-size:11px;margin:10px 0 0;text-align:right}\n.dsh-codex-skeleton{display:grid;gap:9px;padding-top:10px}\n.dsh-codex-skeleton span{animation:dsh-codex-pulse 1.4s ease-in-out infinite;background:var(--dsw-alias-bg-layer-2);border-radius:5px;height:42px}\n.dsh-codex-skeleton span:nth-child(2){animation-delay:.12s}.dsh-codex-skeleton span:nth-child(3){animation-delay:.24s}\n.dsh-codex-sr{height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;clip:rect(0 0 0 0);white-space:nowrap}\n.dsh-codex-process-group-head{border-radius:6px;cursor:pointer;transition:background-color .15s ease,opacity .15s ease}\n.dsh-codex-process-group-head:hover{background:color-mix(in srgb,var(--dsw-alias-bg-layer-2,rgba(127,127,127,.18)) 72%,transparent)}\n.dsh-codex-process-group-head:focus-visible{outline:2px solid var(--dsw-alias-button-info-fill,#397ee8);outline-offset:2px}\n.dsh-codex-process-group-head.dsh-codex-process-group-collapsed{align-items:center!important;color:transparent!important;display:flex!important;font-size:0!important;line-height:28px!important;max-height:28px!important;min-height:28px!important;overflow:hidden!important;opacity:.78}\n.dsh-codex-process-group-head.dsh-codex-process-group-collapsed>*{display:none!important}\n.dsh-codex-process-group-head.dsh-codex-process-group-collapsed::before{color:var(--dsw-alias-label-secondary);content:\"▸ \" attr(data-dsh-codex-process-title);display:block;font-size:13px;line-height:28px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.dsh-codex-process-group-hidden{display:none!important}\n@keyframes dsh-codex-pulse{0%,100%{opacity:.55}50%{opacity:1}}\n@media(max-width:560px){.dsh-codex-row{align-items:flex-start;flex-direction:column;gap:3px}.dsh-codex-value{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}}\n@media(prefers-reduced-motion:reduce){.dsh-codex-meter>span,.dsh-codex-process-group-head{transition:none}.dsh-codex-skeleton span{animation:none}}\n`\n\nexport function installStyles(): () => void {\n if (document.querySelector(`style[data-plugin-css=\"${STYLE_ID}\"]`) !== null) return () => undefined\n const element = document.createElement('style')\n element.dataset.plugin = '@eddyskywalker/dsh-chatgpt-subscription'\n element.dataset.pluginCss = STYLE_ID\n element.textContent = CSS\n document.head.appendChild(element)\n return () => element.remove()\n}\n","import type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-settings/client'\nimport type {} from '@deepseek-ai/dsh-client-locale/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-slots'\nimport { CodexSubscriptionSection } from './CodexSubscriptionSection.tsx'\nimport { dictionaries, NS, type LocaleKey } from './locales.ts'\nimport { installProcessFolding } from './process-folding.ts'\nimport { installStyles } from './styles.ts'\n\ndeclare module '@deepseek-ai/dsh-client-ui-slots' {\n interface LocaleNamespaceMap {\n 'dsh-chatgpt-subscription': LocaleKey\n }\n}\n\nexport const inject = ['slots', 'locale']\n\nexport function apply(ctx: ClientContext): void {\n ctx.effect(() => ctx.locale.register(NS, dictionaries), 'dsh-chatgpt-subscription: dictionaries')\n ctx.effect(() => installStyles(), 'dsh-chatgpt-subscription: styles')\n ctx.effect(() => installProcessFolding(), 'dsh-chatgpt-subscription: process folding')\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}\n"],"mappings":"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"}
1
+ {"version":3,"file":"client.js","names":[],"sources":["../src/compat.ts","../src/client/api.ts","../src/client/CodexSubscriptionSection.tsx","../src/client/locales.ts","../src/client/process-folding.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\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_USAGE_URL = 'https://chatgpt.com/backend-api/wham/usage' as const\nexport const CODEX_ORIGINATOR = 'opencode' 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 { ROUTE_PREFIX } from '../compat.ts'\nimport type {\n ApiEnvelope,\n LoginEventDto,\n LoginStartDto,\n PluginStatusDto,\n QuotaStatusDto,\n ConnectionTestDto,\n} from '../shared/contracts.ts'\n\nexport class SubscriptionApi {\n status(): Promise<PluginStatusDto> {\n return request<PluginStatusDto>(`${ROUTE_PREFIX}/status`)\n }\n\n startLogin(): Promise<LoginStartDto> {\n return post<LoginStartDto>(`${ROUTE_PREFIX}/login/start`, {})\n }\n\n cancelLogin(loginId: string): Promise<{ cancelled: boolean }> {\n return post(`${ROUTE_PREFIX}/login/cancel`, { loginId })\n }\n\n logout(): Promise<{ authenticated: false }> {\n return post(`${ROUTE_PREFIX}/logout`, {})\n }\n\n refresh(): Promise<PluginStatusDto> {\n return post(`${ROUTE_PREFIX}/token/refresh`, {})\n }\n\n refreshQuota(): Promise<QuotaStatusDto> {\n return post(`${ROUTE_PREFIX}/quota/refresh`, {})\n }\n\n testConnection(): Promise<ConnectionTestDto> {\n return post(`${ROUTE_PREFIX}/connection/test`, {})\n }\n\n events(loginId: string): EventSource {\n return new EventSource(`${ROUTE_PREFIX}/login/events?loginId=${encodeURIComponent(loginId)}`)\n }\n}\n\nasync function post<T>(url: string, body: Record<string, unknown>): Promise<T> {\n return request<T>(url, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(body),\n })\n}\n\nasync function request<T>(url: string, init?: RequestInit): Promise<T> {\n const response = await fetch(url, { ...init, credentials: 'same-origin' })\n const envelope = await response.json() as ApiEnvelope<T>\n if (!response.ok || !envelope.ok) {\n throw new Error(envelope.ok ? `Request failed (${response.status})` : envelope.error.message)\n }\n return envelope.value\n}\n\nexport function parseLoginEvent(event: MessageEvent<string>): LoginEventDto | null {\n try {\n const value = JSON.parse(event.data) as LoginEventDto\n return typeof value === 'object' && value !== null && typeof value.type === 'string' ? value : null\n } catch {\n return null\n }\n}\n","import { useCallback, useEffect, useRef, useState } from 'react'\nimport type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { PluginStatusDto, QuotaBucketDto, QuotaWindowDto } from '../shared/contracts.ts'\nimport { SubscriptionApi, parseLoginEvent } from './api.ts'\nimport { NS } from './locales.ts'\n\ntype Props = PropsRuntime<'settings.section'> & PropsLocale<typeof NS>\ntype BusyAction = 'login' | 'token' | 'quota' | 'test' | 'logout' | null\ntype Translate = Props['t']\n\nconst MODELS = ['gpt-5.6-sol', 'gpt-5.6-terra', 'gpt-5.6-luna', 'gpt-5.5', 'gpt-5.4', 'gpt-5.4-mini', 'gpt-5.2']\n\nexport function CodexSubscriptionSection({ t }: Props): React.JSX.Element {\n const apiRef = useRef(new SubscriptionApi())\n const eventSourceRef = useRef<EventSource | null>(null)\n const [status, setStatus] = useState<PluginStatusDto | null>(null)\n const [busy, setBusy] = useState<BusyAction>(null)\n const [error, setError] = useState<string | null>(null)\n const [authUrl, setAuthUrl] = useState<string | null>(null)\n const [popupBlocked, setPopupBlocked] = useState(false)\n const [connection, setConnection] = useState<{ latencyMs: number; checkedAt: number } | null>(null)\n\n const load = useCallback(async (quiet = false) => {\n if (!quiet) setError(null)\n try {\n const next = await apiRef.current.status()\n setStatus(next)\n if (next.error !== undefined) setError(next.error.message)\n } catch (cause) {\n if (!quiet) setError(messageOf(cause))\n }\n }, [])\n\n useEffect(() => {\n void load()\n const refreshWhenVisible = (): void => {\n if (document.visibilityState === 'visible') void load(true)\n }\n document.addEventListener('visibilitychange', refreshWhenVisible)\n const timer = window.setInterval(refreshWhenVisible, 60_000)\n return () => {\n window.clearInterval(timer)\n document.removeEventListener('visibilitychange', refreshWhenVisible)\n eventSourceRef.current?.close()\n }\n }, [load])\n\n const watchLogin = useCallback((loginId: string) => {\n eventSourceRef.current?.close()\n const source = apiRef.current.events(loginId)\n eventSourceRef.current = source\n const finish = async (message?: string): Promise<void> => {\n source.close()\n eventSourceRef.current = null\n setBusy(null)\n setAuthUrl(null)\n if (message !== undefined) setError(message)\n // Preserve the terminal OAuth error while refreshing the account DTO.\n await load(true)\n }\n source.addEventListener('completed', (event) => {\n const parsed = parseLoginEvent(event as MessageEvent<string>)\n if (parsed?.type === 'completed') void finish()\n })\n source.addEventListener('cancelled', () => void finish())\n source.addEventListener('failed', (event) => {\n const parsed = parseLoginEvent(event as MessageEvent<string>)\n void finish(parsed?.type === 'failed' ? parsed.error.message : 'ChatGPT sign-in failed.')\n })\n }, [load])\n\n useEffect(() => {\n const loginId = status?.login.active ? status.login.loginId : null\n if (loginId !== null && loginId !== undefined && eventSourceRef.current === null) watchLogin(loginId)\n }, [status?.login.active, status?.login.loginId, watchLogin])\n\n const startLogin = async (): Promise<void> => {\n setBusy('login')\n setError(null)\n setPopupBlocked(false)\n const popup = window.open('about:blank', 'dsh-chatgpt-oauth', 'popup,width=560,height=760')\n try {\n const login = await apiRef.current.startLogin()\n setAuthUrl(login.authUrl)\n if (popup === null) setPopupBlocked(true)\n else popup.location.replace(login.authUrl)\n watchLogin(login.loginId)\n await load(true)\n } catch (cause) {\n popup?.close()\n setBusy(null)\n setError(messageOf(cause))\n }\n }\n\n const cancelLogin = async (): Promise<void> => {\n const loginId = status?.login.loginId\n if (loginId === null || loginId === undefined) return\n setBusy('login')\n try {\n await apiRef.current.cancelLogin(loginId)\n eventSourceRef.current?.close()\n eventSourceRef.current = null\n setAuthUrl(null)\n await load()\n } catch (cause) {\n setError(messageOf(cause))\n } finally {\n setBusy(null)\n }\n }\n\n const refreshToken = async (): Promise<void> => run('token', async () => {\n setStatus(await apiRef.current.refresh())\n })\n\n const refreshQuota = async (): Promise<void> => run('quota', async () => {\n const quota = await apiRef.current.refreshQuota()\n setStatus((current) => current === null ? current : { ...current, quota })\n })\n\n const testConnection = async (): Promise<void> => run('test', async () => {\n const result = await apiRef.current.testConnection()\n setConnection({ latencyMs: result.latencyMs, checkedAt: result.checkedAt })\n })\n\n const logout = async (): Promise<void> => run('logout', async () => {\n await apiRef.current.logout()\n eventSourceRef.current?.close()\n eventSourceRef.current = null\n setAuthUrl(null)\n setConnection(null)\n await load()\n })\n\n const run = async (action: Exclude<BusyAction, null>, task: () => Promise<void>): Promise<void> => {\n setBusy(action)\n setError(null)\n try {\n await task()\n } catch (cause) {\n setError(messageOf(cause))\n } finally {\n setBusy(null)\n }\n }\n\n const account = status?.account\n return <section className=\"dsh-codex-page\" aria-labelledby=\"dsh-codex-title\">\n <header>\n <h2 id=\"dsh-codex-title\" className=\"dsh-codex-title\">{t('title')}</h2>\n <p className=\"dsh-codex-intro\">{t('intro')}</p>\n </header>\n\n {error !== null ? <div className=\"dsh-codex-errorbar\" role=\"alert\">\n <span>{error}</span>\n {status === null ? <Button disabled={busy !== null} onClick={() => load()}>{t('retry')}</Button> : null}\n </div> : null}\n\n {status === null && error === null ? <Skeleton label={t('loading')} /> : <>\n <Section title={t('account')}>\n <InfoRow label={status?.authenticated ? t('signedIn') : t('signedOut')} value={account?.email ?? '—'} />\n {status?.authenticated ? <>\n <InfoRow label={t('plan')} value={account?.planType ?? t('unknown')} />\n <InfoRow label={t('accountId')} value={account?.accountIdSuffix ?? '—'} />\n <InfoRow label={t('expires')} value={formatDate(account?.tokenExpiresAt)} />\n </> : null}\n <InfoRow label={t('storage')} value={t('storageValue')} />\n <p className=\"dsh-codex-notice\">{t('securityNotice')}</p>\n {status?.login.active ? <p className=\"dsh-codex-muted\" role=\"status\">{t('pending')}</p> : null}\n {popupBlocked ? <p className=\"dsh-codex-error\">{t('popupBlocked')}</p> : null}\n {authUrl !== null ? <a className=\"dsh-codex-link\" href={authUrl} target=\"_blank\" rel=\"noreferrer\">{t('continueLogin')}</a> : null}\n <div className=\"dsh-codex-actions\">\n {status?.login.active\n ? <Button disabled={busy !== null} onClick={cancelLogin}>{t('cancel')}</Button>\n : <Button primary disabled={busy !== null} onClick={startLogin}>{status?.authenticated ? t('signInAgain') : t('signIn')}</Button>}\n {status?.authenticated ? <>\n <Button disabled={busy !== null} onClick={refreshToken}>{t('refreshToken')}</Button>\n <Button disabled={busy !== null} onClick={logout}>{t('signOut')}</Button>\n </> : null}\n </div>\n </Section>\n\n <Section title={t('connection')}>\n <InfoRow label={t('provider')} value=\"Codex(ChatGPT 订阅) · codex-chatgpt\" />\n <InfoRow label={t('connectionState')} value={connection === null ? t('untested') : t('connected')} />\n {connection !== null ? <InfoRow label={t('latency')} value={`${connection.latencyMs} ms · ${formatDate(connection.checkedAt)}`} /> : null}\n <div className=\"dsh-codex-models\" aria-label={t('models')}>\n {MODELS.map((model) => <code key={model}>{model}</code>)}\n </div>\n <div className=\"dsh-codex-actions\">\n <Button disabled={!status?.authenticated || busy !== null} onClick={testConnection}>{busy === 'test' ? t('testing') : t('testConnection')}</Button>\n </div>\n </Section>\n\n <Section title={t('quota')} aside={<Button disabled={!status?.authenticated || busy !== null} onClick={refreshQuota}>{busy === 'quota' ? t('refreshing') : t('refreshQuota')}</Button>}>\n <p className=\"dsh-codex-muted\">{t('quotaIntro')}</p>\n {status?.quota.state === 'signed-out' ? <p className=\"dsh-codex-empty\">{t('quotaSignedOut')}</p> : null}\n {status?.quota.buckets.map((bucket) => <QuotaBucket key={bucket.id} bucket={bucket} t={t} />)}\n {status?.quota.state === 'empty' ? <p className=\"dsh-codex-empty\">{t('noQuota')}</p> : null}\n {status?.quota.stale ? <p className=\"dsh-codex-warning\" role=\"status\">{t('stale')}</p> : null}\n {status?.quota.error ? <p className=\"dsh-codex-error\" role=\"alert\">{status.quota.error.message}</p> : null}\n {status?.quota.fetchedAt ? <p className=\"dsh-codex-timestamp\">{t('updated')}: {formatDate(status.quota.fetchedAt)}</p> : null}\n </Section>\n </>}\n\n <span className=\"dsh-codex-sr\" aria-live=\"polite\">{busy === null ? '' : busy}</span>\n </section>\n}\n\nfunction Section({ title, aside, children }: { title: string; aside?: React.ReactNode; children: React.ReactNode }): React.JSX.Element {\n return <section className=\"dsh-codex-group\">\n <div className=\"dsh-codex-grouphead\"><h3>{title}</h3>{aside}</div>\n {children}\n </section>\n}\n\nfunction Button({ primary = false, disabled, onClick, children }: { primary?: boolean; disabled?: boolean; onClick: () => void | Promise<void>; children: React.ReactNode }): React.JSX.Element {\n return <button className={`dsh-codex-button${primary ? ' dsh-codex-button-primary' : ''}`} type=\"button\" disabled={disabled} onClick={() => void onClick()}>{children}</button>\n}\n\nfunction InfoRow({ label, value }: { label: string; value: string }): React.JSX.Element {\n return <div className=\"dsh-codex-row\"><span className=\"dsh-codex-label\">{label}</span><span className=\"dsh-codex-value\">{value}</span></div>\n}\n\nfunction QuotaBucket({ bucket, t }: { bucket: QuotaBucketDto; t: Translate }): React.JSX.Element {\n return <article className=\"dsh-codex-quota-card\">\n <div className=\"dsh-codex-quota-title\"><strong>{bucket.name}</strong>{bucket.planType ? <span>{bucket.planType}</span> : null}</div>\n {bucket.primary ? <QuotaBar label={windowLabel(bucket.primary.windowDurationMins, t)} window={bucket.primary} t={t} /> : null}\n {bucket.secondary ? <QuotaBar label={windowLabel(bucket.secondary.windowDurationMins, t)} window={bucket.secondary} t={t} /> : null}\n </article>\n}\n\nexport function QuotaBar({ label, window, t }: { label: string; window: QuotaWindowDto; t: Translate }): React.JSX.Element {\n const percent = window.usedPercent\n const level = percent >= 95 ? 'danger' : percent >= 80 ? 'warning' : 'normal'\n const remaining = Math.max(0, 100 - percent)\n return <div className=\"dsh-codex-meter-wrap\">\n <div className=\"dsh-codex-meter-label\"><span>{label}</span><strong>{formatPercent(percent)}</strong></div>\n <div className={`dsh-codex-meter dsh-codex-meter-${level}`} role=\"progressbar\" aria-label={`${label}: ${formatPercent(percent)} ${t('used')}`} aria-valuemin={0} aria-valuemax={100} aria-valuenow={percent}>\n <span style={{ width: `${percent}%` }} />\n </div>\n <div className=\"dsh-codex-meter-meta\">\n <span>{percent >= 100 ? `${t('exhausted')} · ${formatPercent(remaining)} ${t('remaining')}` : `${formatPercent(percent)} ${t('used')} · ${formatPercent(remaining)} ${t('remaining')}`}</span>\n <span>{window.resetsAt === null ? '—' : `${t('resets')}: ${formatReset(window.resetsAt)}`}</span>\n </div>\n </div>\n}\n\nfunction Skeleton({ label }: { label: string }): React.JSX.Element {\n return <div className=\"dsh-codex-skeleton\" role=\"status\" aria-label={label}><span /><span /></div>\n}\n\nexport function windowLabel(minutes: number | null, t: Translate): string {\n if (minutes === null) return t('limitWindow')\n const [value, unit]: [number, Intl.NumberFormatOptions['unit']] = minutes >= 1440 && minutes % 1440 === 0\n ? [minutes / 1440, 'day']\n : minutes >= 60 && minutes % 60 === 0\n ? [minutes / 60, 'hour']\n : [Math.round(minutes), 'minute']\n return `${new Intl.NumberFormat(undefined, { style: 'unit', unit, unitDisplay: 'long' }).format(value)} ${t('limitWindow')}`\n}\n\nfunction formatPercent(value: number): string {\n return `${new Intl.NumberFormat(undefined, { maximumFractionDigits: 1 }).format(value)}%`\n}\n\nfunction formatDate(seconds: number | undefined): string {\n if (seconds === undefined) return '—'\n return new Intl.DateTimeFormat(undefined, { dateStyle: 'medium', timeStyle: 'short' }).format(seconds * 1000)\n}\n\nexport function formatReset(seconds: number): string {\n const absolute = formatDate(seconds)\n const diff = seconds * 1000 - Date.now()\n const abs = Math.abs(diff)\n const [amount, unit]: [number, Intl.RelativeTimeFormatUnit] = abs >= 86_400_000\n ? [Math.round(diff / 86_400_000), 'day']\n : abs >= 3_600_000\n ? [Math.round(diff / 3_600_000), 'hour']\n : [Math.round(diff / 60_000), 'minute']\n return `${absolute} (${new Intl.RelativeTimeFormat(undefined, { numeric: 'auto' }).format(amount, unit)})`\n}\n\nfunction messageOf(error: unknown): string {\n return error instanceof Error ? error.message : String(error)\n}\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 storageValue: 'Windows DPAPI(当前用户加密)',\n securityNotice: '令牌仅保存在 Host 端的 DPAPI 加密文件中,不会进入浏览器、settings.yaml 或日志。',\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 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 exhausted: '额度已用尽',\n resets: '重置',\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 storageValue: 'Windows DPAPI (current-user encrypted)',\n securityNotice: 'Tokens stay in a Host-side DPAPI-encrypted file and never enter the browser, settings.yaml, or logs.',\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 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 exhausted: 'Quota exhausted',\n resets: 'Resets',\n retry: 'Retry',\n unknown: 'Unknown',\n}\n\nexport type LocaleKey = keyof typeof zh\nexport const dictionaries = { zh, en }\n","const ROW_CLASS = 'dsh-codex-process-row'\r\nconst GROUP_HEAD_CLASS = 'dsh-codex-process-group-head'\r\nconst GROUP_COLLAPSED_CLASS = 'dsh-codex-process-group-collapsed'\r\nconst GROUP_HIDDEN_CLASS = 'dsh-codex-process-group-hidden'\r\nconst USER_TOGGLED_ATTR = 'data-dsh-codex-process-user-toggled'\r\nconst TITLE_ATTR = 'data-dsh-codex-process-title'\r\nconst TITLE = 'Click to expand or collapse process details'\r\nconst DEFAULT_AUTO_COLLAPSE_MS = 350\r\nconst MAX_PROCESS_LABELS_PER_ROW = 3\r\nconst MAX_SCAN_ROOTS_PER_FRAME = 80\r\nconst MAX_TEXT_SAMPLE = 20_000\r\nconst PROCESS_CANDIDATE_SELECTOR = 'article,section,li,div,p,span,button,h1,h2,h3,h4,h5,h6,[role=\"button\"],[role=\"listitem\"]'\r\nconst PROCESS_PREFIX_PATTERN = '(?:上下文注入|Think|Search|Code|代码|Pwsh|PowerShell|Bash|Shell|Read|Glob|Grep|Web(?:\\\\s+Search)?|Tool|工具|思考)'\r\nconst COMMAND_PATTERN = /(?:Code|代码|Pwsh|PowerShell|Bash|Shell|Read|Glob|Grep|Tool|工具)/i\r\nconst SEARCH_PATTERN = /(?:Search|Web\\s+Search|搜索)/i\r\nconst PROCESS_PREFIX_RE = new RegExp(`^\\\\s*(?:[•●◦▪▫·#-]\\\\s*)?${PROCESS_PREFIX_PATTERN}\\\\s*(?:[·::-]|$)`, 'i')\r\nconst PROCESS_LINE_RE = new RegExp(`(?:^|\\\\n)\\\\s*(?:[•●◦▪▫·#-]\\\\s*)?${PROCESS_PREFIX_PATTERN}\\\\s*(?:[·::-]|$)`, 'gi')\r\n\r\nexport interface ProcessFoldingOptions {\r\n autoCollapseMs?: number\r\n}\r\n\r\ninterface GroupState {\r\n rows: HTMLElement[]\r\n click: (event: MouseEvent) => void\r\n keydown: (event: KeyboardEvent) => void\r\n timer: ReturnType<typeof setTimeout> | null\r\n}\r\n\r\ninterface PreviousGroupState {\r\n collapsed: boolean\r\n userToggled: boolean\r\n}\r\n\r\nexport function installProcessFolding(options: ProcessFoldingOptions = {}): () => void {\r\n if (typeof document === 'undefined') return () => undefined\r\n if (document.body === null) {\r\n let dispose: () => void = () => undefined\r\n let started = false\r\n const start = () => {\r\n if (started) return\r\n started = true\r\n dispose = installProcessFolding(options)\r\n }\r\n document.addEventListener('DOMContentLoaded', start, { once: true })\r\n return () => {\r\n document.removeEventListener('DOMContentLoaded', start)\r\n dispose()\r\n }\r\n }\r\n\r\n const autoCollapseMs = options.autoCollapseMs ?? DEFAULT_AUTO_COLLAPSE_MS\r\n const groups = new Map<HTMLElement, GroupState>()\r\n const pending = new Set<Element>()\r\n let frame: number | null = null\r\n\r\n const scheduleFlush = () => {\r\n if (frame !== null) return\r\n frame = requestAnimationFrame(() => {\r\n frame = null\r\n flush()\r\n })\r\n }\r\n\r\n const queue = (element: Element | null) => {\r\n if (element === null || !element.isConnected) return\r\n pending.add(element)\r\n scheduleFlush()\r\n }\r\n\r\n const scheduleAutoCollapse = (head: HTMLElement) => {\r\n const state = groups.get(head)\r\n if (state === undefined || head.hasAttribute(USER_TOGGLED_ATTR)) return\r\n if (state.timer !== null) clearTimeout(state.timer)\r\n state.timer = setTimeout(() => {\r\n state.timer = null\r\n if (head.isConnected && !head.hasAttribute(USER_TOGGLED_ATTR)) setGroupCollapsed(head, true)\r\n }, autoCollapseMs)\r\n }\r\n\r\n const syncGroup = (rows: HTMLElement[], previous: PreviousGroupState | undefined) => {\r\n const head = rows[0]\r\n const title = titleForProcessRows(rows)\r\n const click = (event: MouseEvent) => {\r\n if (isInteractiveTarget(event.target, head)) return\r\n markUserToggled(head)\r\n setGroupCollapsed(head, !head.classList.contains(GROUP_COLLAPSED_CLASS))\r\n }\r\n const keydown = (event: KeyboardEvent) => {\r\n if (event.key !== 'Enter' && event.key !== ' ') return\r\n event.preventDefault()\r\n markUserToggled(head)\r\n setGroupCollapsed(head, !head.classList.contains(GROUP_COLLAPSED_CLASS))\r\n }\r\n\r\n groups.set(head, { rows, click, keydown, timer: null })\r\n for (const row of rows) row.classList.add(ROW_CLASS)\r\n head.classList.add(GROUP_HEAD_CLASS)\r\n if (!head.hasAttribute('tabindex')) head.tabIndex = 0\r\n head.setAttribute('aria-expanded', String(!(previous?.collapsed ?? false)))\r\n head.setAttribute(TITLE_ATTR, title)\r\n head.title ||= TITLE\r\n if (previous?.userToggled === true) head.setAttribute(USER_TOGGLED_ATTR, 'true')\r\n head.addEventListener('click', click)\r\n head.addEventListener('keydown', keydown)\r\n setGroupCollapsed(head, previous?.collapsed ?? false)\r\n scheduleAutoCollapse(head)\r\n }\r\n\r\n const rebuildParentGroups = (parent: Element) => {\r\n const previous = new Map<HTMLElement, PreviousGroupState>()\r\n for (const [head, state] of groups) {\r\n if (head.parentElement !== parent) continue\r\n previous.set(head, {\r\n collapsed: head.classList.contains(GROUP_COLLAPSED_CLASS),\r\n userToggled: head.hasAttribute(USER_TOGGLED_ATTR),\r\n })\r\n cleanupGroup(head, state)\r\n groups.delete(head)\r\n }\r\n\r\n let rows: HTMLElement[] = []\r\n const flushRows = () => {\r\n if (rows.length > 0) syncGroup(rows, previous.get(rows[0]))\r\n rows = []\r\n }\r\n\r\n for (const child of Array.from(parent.children)) {\r\n if (child instanceof HTMLElement && isProcessRow(child)) {\r\n rows.push(child)\r\n } else {\r\n flushRows()\r\n }\r\n }\r\n flushRows()\r\n }\r\n\r\n const flush = () => {\r\n const parents = new Set<Element>()\r\n let scanned = 0\r\n for (const root of Array.from(pending)) {\r\n pending.delete(root)\r\n if (!root.isConnected) continue\r\n for (const row of findProcessRows(root)) {\r\n if (row.parentElement !== null) parents.add(row.parentElement)\r\n }\r\n const grouped = nearestGroupHead(root)\r\n if (grouped !== null && grouped.parentElement !== null) parents.add(grouped.parentElement)\r\n scanned++\r\n if (scanned >= MAX_SCAN_ROOTS_PER_FRAME && pending.size > 0) {\r\n scheduleFlush()\r\n break\r\n }\r\n }\r\n for (const parent of parents) rebuildParentGroups(parent)\r\n }\r\n\r\n const observer = new MutationObserver((mutations) => {\r\n for (const mutation of mutations) {\r\n if (mutation.type === 'characterData') {\r\n queue(nodeElement(mutation.target)?.closest(PROCESS_CANDIDATE_SELECTOR) ?? nodeElement(mutation.target))\r\n continue\r\n }\r\n for (const node of mutation.addedNodes) queue(nodeElement(node))\r\n }\r\n })\r\n observer.observe(document.body, { childList: true, characterData: true, subtree: true })\r\n queue(document.body)\r\n\r\n return () => {\r\n observer.disconnect()\r\n if (frame !== null) cancelAnimationFrame(frame)\r\n pending.clear()\r\n for (const [head, state] of groups) cleanupGroup(head, state)\r\n groups.clear()\r\n }\r\n}\r\n\r\nfunction cleanupGroup(head: HTMLElement, state: GroupState): void {\r\n if (state.timer !== null) clearTimeout(state.timer)\r\n head.removeEventListener('click', state.click)\r\n head.removeEventListener('keydown', state.keydown)\r\n for (const row of state.rows) row.classList.remove(ROW_CLASS, GROUP_HIDDEN_CLASS)\r\n head.classList.remove(GROUP_HEAD_CLASS, GROUP_COLLAPSED_CLASS)\r\n head.removeAttribute('aria-expanded')\r\n head.removeAttribute(USER_TOGGLED_ATTR)\r\n head.removeAttribute(TITLE_ATTR)\r\n if (head.title === TITLE) head.removeAttribute('title')\r\n}\r\n\r\nfunction findProcessRows(root: Element): HTMLElement[] {\r\n const rows: HTMLElement[] = []\r\n if (root instanceof HTMLElement && isProcessRow(root)) pushProcessRow(rows, root)\r\n for (const element of root.querySelectorAll(PROCESS_CANDIDATE_SELECTOR)) {\r\n if (element instanceof HTMLElement && isProcessRow(element)) pushProcessRow(rows, element)\r\n }\r\n return rows\r\n}\r\n\r\nfunction pushProcessRow(rows: HTMLElement[], row: HTMLElement): void {\r\n if (rows.some((existing) => existing.contains(row))) return\r\n rows.push(row)\r\n}\r\n\r\nfunction isProcessRow(element: HTMLElement): boolean {\r\n if (element.closest('.dsh-codex-page') !== null || shouldIgnore(element)) return false\r\n const raw = (element.textContent ?? '').slice(0, MAX_TEXT_SAMPLE)\r\n const normalized = raw.replace(/\\s+/g, ' ').trim()\r\n if (!PROCESS_PREFIX_RE.test(normalized)) return false\r\n const stats = processTextStats(raw)\r\n if (stats.processLabels === 0 || stats.processLabels > MAX_PROCESS_LABELS_PER_ROW) return false\r\n return !(element.children.length > 0 && stats.hasNonProcessLine)\r\n}\r\n\r\nfunction processTextStats(text: string): { processLabels: number; hasNonProcessLine: boolean } {\r\n PROCESS_LINE_RE.lastIndex = 0\r\n let processLabels = 0\r\n while (PROCESS_LINE_RE.exec(text) !== null) processLabels++\r\n const hasNonProcessLine = text.split(/\\r?\\n/)\r\n .map((line) => line.replace(/\\s+/g, ' ').trim())\r\n .some((line) => line !== '' && !PROCESS_PREFIX_RE.test(line))\r\n return { processLabels, hasNonProcessLine }\r\n}\r\n\r\nfunction setGroupCollapsed(head: HTMLElement, collapsed: boolean): void {\r\n const state = findCurrentGroupState(head)\r\n if (state === null) return\r\n head.classList.toggle(GROUP_COLLAPSED_CLASS, collapsed)\r\n head.setAttribute('aria-expanded', String(!collapsed))\r\n for (const row of state.rows.slice(1)) row.classList.toggle(GROUP_HIDDEN_CLASS, collapsed)\r\n}\r\n\r\nfunction findCurrentGroupState(head: HTMLElement): { rows: HTMLElement[] } | null {\r\n const rows: HTMLElement[] = [head]\r\n let sibling = head.nextElementSibling\r\n while (sibling instanceof HTMLElement && isProcessRow(sibling)) {\r\n rows.push(sibling)\r\n sibling = sibling.nextElementSibling\r\n }\r\n return rows.length > 0 ? { rows } : null\r\n}\r\n\r\nfunction markUserToggled(head: HTMLElement): void {\r\n head.setAttribute(USER_TOGGLED_ATTR, 'true')\r\n}\r\n\r\nfunction nearestGroupHead(element: Element): HTMLElement | null {\r\n const decorated = element.closest(`.${GROUP_HEAD_CLASS}`)\r\n return decorated instanceof HTMLElement ? decorated : null\r\n}\r\n\r\nfunction titleForProcessRows(rows: HTMLElement[]): string {\r\n const text = rows.map((row) => row.textContent ?? '').join('\\n')\r\n if (COMMAND_PATTERN.test(text)) return '运行了命令'\r\n if (SEARCH_PATTERN.test(text)) return '进行了搜索'\r\n return '思考过程'\r\n}\r\n\r\nfunction nodeElement(node: Node): Element | null {\r\n if (node instanceof Element) return node\r\n return node.parentElement\r\n}\r\n\r\nfunction shouldIgnore(element: HTMLElement): boolean {\r\n return element.closest('textarea,input,select,a,[contenteditable=\"true\"],script,style') !== null\r\n}\r\n\r\nfunction isInteractiveTarget(target: EventTarget | null, groupHead: HTMLElement): boolean {\r\n if (!(target instanceof Element)) return false\r\n const interactive = target.closest('button,a,input,textarea,select,[role=\"button\"],[contenteditable=\"true\"]')\r\n return interactive !== null && interactive !== groupHead\r\n}\r\n","const STYLE_ID = '@eddyskywalker/dsh-chatgpt-subscription/main'\n\nconst CSS = `\n.dsh-codex-page{box-sizing:border-box;color:var(--dsw-alias-label-primary);display:flex;flex-direction:column;gap:20px;max-width:780px;min-width:0;padding:2px 0 30px}\n.dsh-codex-page *{box-sizing:border-box}\n.dsh-codex-title{font-size:15px;font-weight:650;line-height:1.4;margin:0 0 5px}\n.dsh-codex-intro,.dsh-codex-muted{color:var(--dsw-alias-label-secondary);font-size:13px;line-height:1.55;margin:0}\n.dsh-codex-group{border-top:1px solid var(--dsw-alias-border-l2);min-width:0}\n.dsh-codex-grouphead{align-items:center;display:flex;gap:12px;justify-content:space-between;min-height:48px}\n.dsh-codex-grouphead h3{font-size:14px;font-weight:650;margin:0}\n.dsh-codex-row{align-items:center;border-bottom:1px solid var(--dsw-alias-border-l2);display:flex;gap:20px;justify-content:space-between;min-height:44px;padding:8px 0}\n.dsh-codex-label{color:var(--dsw-alias-label-secondary);font-size:13px;flex:0 0 auto}\n.dsh-codex-value{font-size:13px;min-width:0;overflow-wrap:anywhere;text-align:right}\n.dsh-codex-actions{display:flex;flex-wrap:wrap;gap:8px;justify-content:flex-end;padding-top:12px}\n.dsh-codex-button{background:var(--dsw-alias-bg-layer-2);border: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}\n.dsh-codex-button:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}\n.dsh-codex-button:focus-visible,.dsh-codex-link:focus-visible{outline:2px solid var(--dsw-alias-button-info-fill,#397ee8);outline-offset:2px}\n.dsh-codex-button:disabled{cursor:default;opacity:.5}\n.dsh-codex-button-primary{background:var(--dsw-alias-button-info-fill,#397ee8);border-color:transparent;color:var(--dsw-alias-button-info-label,#fff)}\n.dsh-codex-notice{background:var(--dsw-alias-bg-layer-2);border: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}\n.dsh-codex-error,.dsh-codex-warning{font-size:12px;line-height:1.5;margin:8px 0 0}\n.dsh-codex-error{color:var(--dsw-alias-label-danger,#d94b4b)}\n.dsh-codex-warning{color:var(--dsw-alias-label-warning,#c77a18)}\n.dsh-codex-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}\n.dsh-codex-link{color:var(--dsw-alias-label-link,#3278d4);display:inline-block;font-size:13px;margin-top:8px}\n.dsh-codex-models{display:flex;flex-wrap:wrap;gap:6px;padding-top:12px}\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}\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}\n.dsh-codex-quota-title{align-items:center;display:flex;font-size:13px;gap:8px;justify-content:space-between}\n.dsh-codex-quota-title span{color:var(--dsw-alias-label-tertiary);font-size:11px;text-transform:uppercase}\n.dsh-codex-meter-wrap{margin-top:13px}\n.dsh-codex-meter-label,.dsh-codex-meter-meta{display:flex;gap:10px;justify-content:space-between}\n.dsh-codex-meter-label{font-size:12px;margin-bottom:6px}\n.dsh-codex-meter-meta{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:1.45;margin-top:6px}\n.dsh-codex-meter{background:var(--dsw-alias-bg-layer-1,rgba(127,127,127,.15));border-radius:999px;height:7px;overflow:hidden;width:100%}\n.dsh-codex-meter>span{background:var(--dsw-alias-button-info-fill,#397ee8);border-radius:inherit;display:block;height:100%;max-width:100%;min-width:0;transition:width .25s ease}\n.dsh-codex-meter-warning>span{background:var(--dsw-alias-label-warning,#d58a24)}\n.dsh-codex-meter-danger>span{background:var(--dsw-alias-label-danger,#d94b4b)}\n.dsh-codex-empty{border: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}\n.dsh-codex-timestamp{color:var(--dsw-alias-label-tertiary);font-size:11px;margin:10px 0 0;text-align:right}\n.dsh-codex-skeleton{display:grid;gap:9px;padding-top:10px}\n.dsh-codex-skeleton span{animation:dsh-codex-pulse 1.4s ease-in-out infinite;background:var(--dsw-alias-bg-layer-2);border-radius:5px;height:42px}\n.dsh-codex-skeleton span:nth-child(2){animation-delay:.12s}.dsh-codex-skeleton span:nth-child(3){animation-delay:.24s}\n.dsh-codex-sr{height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;clip:rect(0 0 0 0);white-space:nowrap}\n.dsh-codex-process-group-head{border-radius:6px;cursor:pointer;transition:background-color .15s ease,opacity .15s ease}\n.dsh-codex-process-group-head:hover{background:color-mix(in srgb,var(--dsw-alias-bg-layer-2,rgba(127,127,127,.18)) 72%,transparent)}\n.dsh-codex-process-group-head:focus-visible{outline:2px solid var(--dsw-alias-button-info-fill,#397ee8);outline-offset:2px}\n.dsh-codex-process-group-head.dsh-codex-process-group-collapsed{align-items:center!important;color:transparent!important;display:flex!important;font-size:0!important;line-height:28px!important;max-height:28px!important;min-height:28px!important;overflow:hidden!important;opacity:.78}\n.dsh-codex-process-group-head.dsh-codex-process-group-collapsed>*{display:none!important}\n.dsh-codex-process-group-head.dsh-codex-process-group-collapsed::before{color:var(--dsw-alias-label-secondary);content:\"▸ \" attr(data-dsh-codex-process-title);display:block;font-size:13px;line-height:28px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.dsh-codex-process-group-hidden{display:none!important}\n@keyframes dsh-codex-pulse{0%,100%{opacity:.55}50%{opacity:1}}\n@media(max-width:560px){.dsh-codex-row{align-items:flex-start;flex-direction:column;gap:3px}.dsh-codex-value{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}}\n@media(prefers-reduced-motion:reduce){.dsh-codex-meter>span,.dsh-codex-process-group-head{transition:none}.dsh-codex-skeleton span{animation:none}}\n`\n\nexport function installStyles(): () => void {\n if (document.querySelector(`style[data-plugin-css=\"${STYLE_ID}\"]`) !== null) return () => undefined\n const element = document.createElement('style')\n element.dataset.plugin = '@eddyskywalker/dsh-chatgpt-subscription'\n element.dataset.pluginCss = STYLE_ID\n element.textContent = CSS\n document.head.appendChild(element)\n return () => element.remove()\n}\n","import type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-settings/client'\nimport type {} from '@deepseek-ai/dsh-client-locale/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-slots'\nimport { CodexSubscriptionSection } from './CodexSubscriptionSection.tsx'\nimport { dictionaries, NS, type LocaleKey } from './locales.ts'\nimport { installProcessFolding } from './process-folding.ts'\nimport { installStyles } from './styles.ts'\n\ndeclare module '@deepseek-ai/dsh-client-ui-slots' {\n interface LocaleNamespaceMap {\n 'dsh-chatgpt-subscription': LocaleKey\n }\n}\n\nexport const inject = ['slots', 'locale']\n\nexport function apply(ctx: ClientContext): void {\n ctx.effect(() => ctx.locale.register(NS, dictionaries), 'dsh-chatgpt-subscription: dictionaries')\n ctx.effect(() => installStyles(), 'dsh-chatgpt-subscription: styles')\n ctx.effect(() => installProcessFolding(), 'dsh-chatgpt-subscription: process folding')\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}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"process-folding.d.ts","sourceRoot":"","sources":["../../../src/client/process-folding.ts"],"names":[],"mappings":"AAmBA,MAAM,WAAW,qBAAqB;IACpC,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB;AAcD,wBAAgB,qBAAqB,CAAC,OAAO,GAAE,qBAA0B,GAAG,MAAM,IAAI,CA8IrF"}
1
+ {"version":3,"file":"process-folding.d.ts","sourceRoot":"","sources":["../../../src/client/process-folding.ts"],"names":[],"mappings":"AAkBA,MAAM,WAAW,qBAAqB;IACpC,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB;AAcD,wBAAgB,qBAAqB,CAAC,OAAO,GAAE,qBAA0B,GAAG,MAAM,IAAI,CA8IrF"}
package/package.json CHANGED
@@ -1,105 +1,105 @@
1
- {
2
- "name": "@eddyskywalker/dsh-chatgpt-subscription",
3
- "version": "0.1.4",
4
- "description": "DSH provider plugin for Codex access through a ChatGPT subscription.",
5
- "author": {
6
- "name": "eddyskywalker",
7
- "url": "https://www.npmjs.com/~eddyskywalker"
8
- },
9
- "repository": {
10
- "type": "git",
11
- "url": "git+https://github.com/Aa728848/dsh-chatgpt-subscription.git"
12
- },
13
- "homepage": "https://github.com/Aa728848/dsh-chatgpt-subscription#readme",
14
- "bugs": {
15
- "url": "https://github.com/Aa728848/dsh-chatgpt-subscription/issues"
16
- },
17
- "keywords": [
18
- "dsh-plugin",
19
- "dsh",
20
- "deepseek-harness",
21
- "chatgpt",
22
- "codex",
23
- "openai",
24
- "provider"
25
- ],
26
- "type": "module",
27
- "publishConfig": {
28
- "access": "public",
29
- "tag": "latest"
30
- },
31
- "main": "lib/index.js",
32
- "types": "lib/types/index.d.ts",
33
- "exports": {
34
- ".": {
35
- "types": "./lib/types/index.d.ts",
36
- "default": "./lib/index.js"
37
- },
38
- "./client": {
39
- "types": "./lib/types/client/index.d.ts",
40
- "default": "./lib/client.js"
41
- },
42
- "./package.json": "./package.json"
43
- },
44
- "dsh": {
45
- "bundle": {
46
- "patch": "./cordis.patch.yml"
47
- },
48
- "client": {
49
- "inject": [
50
- "@deepseek-ai/dsh-client-runtime",
51
- "@deepseek-ai/dsh-client-locale",
52
- "@deepseek-ai/dsh-client-ui-slots",
53
- "@deepseek-ai/dsh-client-ui-settings"
54
- ],
55
- "platform": "web"
56
- }
57
- },
58
- "peerDependencies": {
59
- "@deepseek-ai/cordis": "^4.0.1",
60
- "@deepseek-ai/dsh-attachment": "^0.1.0-rc.6",
61
- "@deepseek-ai/dsh-client-locale": "^0.1.0-rc.6",
62
- "@deepseek-ai/dsh-client-runtime": "^0.1.0-rc.6",
63
- "@deepseek-ai/dsh-client-ui-settings": "^0.1.0-rc.6",
64
- "@deepseek-ai/dsh-client-ui-slots": "^0.1.0-rc.6",
65
- "@deepseek-ai/dsh-host-webserver": "^0.1.0-rc.6",
66
- "@deepseek-ai/dsh-llm": "^0.1.0-rc.6",
67
- "react": "^18.2.0"
68
- },
69
- "devDependencies": {
70
- "@deepseek-ai/cordis": "^4.0.1",
71
- "@deepseek-ai/dsh-attachment": "^0.1.0-rc.6",
72
- "@deepseek-ai/dsh-client-locale": "^0.1.0-rc.6",
73
- "@deepseek-ai/dsh-client-runtime": "^0.1.0-rc.6",
74
- "@deepseek-ai/dsh-client-ui-settings": "^0.1.0-rc.6",
75
- "@deepseek-ai/dsh-client-ui-slots": "^0.1.0-rc.6",
76
- "@deepseek-ai/dsh-host-webserver": "^0.1.0-rc.6",
77
- "@deepseek-ai/dsh-llm": "^0.1.0-rc.6",
78
- "@types/node": "^22.20.0",
79
- "@types/react": "~18.3.1",
80
- "@types/react-dom": "^18.3.5",
81
- "jsdom": "29.1.1",
82
- "react": "^18.3.1",
83
- "react-dom": "^18.3.1",
84
- "tsdown": "0.22.2",
85
- "typescript": "~5.7.2",
86
- "vitest": "^4.1.8"
87
- },
88
- "files": [
89
- "lib/index.js",
90
- "lib/client.js",
91
- "lib/client.js.map",
92
- "lib/types/**/*.d.ts",
93
- "lib/types/**/*.d.ts.map",
94
- "cordis.patch.yml",
95
- "README.md",
96
- "CHANGELOG.md"
97
- ],
98
- "license": "MIT",
99
- "scripts": {
100
- "build": "tsc -b && tsdown",
101
- "prepack": "npm run build",
102
- "test": "vitest run",
103
- "typecheck": "tsc -b --pretty false"
104
- }
105
- }
1
+ {
2
+ "name": "@eddyskywalker/dsh-chatgpt-subscription",
3
+ "version": "0.1.5",
4
+ "description": "DSH provider plugin for Codex access through a ChatGPT subscription.",
5
+ "author": {
6
+ "name": "eddyskywalker",
7
+ "url": "https://www.npmjs.com/~eddyskywalker"
8
+ },
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git+https://github.com/Aa728848/dsh-chatgpt-subscription.git"
12
+ },
13
+ "homepage": "https://github.com/Aa728848/dsh-chatgpt-subscription#readme",
14
+ "bugs": {
15
+ "url": "https://github.com/Aa728848/dsh-chatgpt-subscription/issues"
16
+ },
17
+ "keywords": [
18
+ "dsh-plugin",
19
+ "dsh",
20
+ "deepseek-harness",
21
+ "chatgpt",
22
+ "codex",
23
+ "openai",
24
+ "provider"
25
+ ],
26
+ "type": "module",
27
+ "publishConfig": {
28
+ "access": "public",
29
+ "tag": "latest"
30
+ },
31
+ "main": "lib/index.js",
32
+ "types": "lib/types/index.d.ts",
33
+ "exports": {
34
+ ".": {
35
+ "types": "./lib/types/index.d.ts",
36
+ "default": "./lib/index.js"
37
+ },
38
+ "./client": {
39
+ "types": "./lib/types/client/index.d.ts",
40
+ "default": "./lib/client.js"
41
+ },
42
+ "./package.json": "./package.json"
43
+ },
44
+ "dsh": {
45
+ "bundle": {
46
+ "patch": "./cordis.patch.yml"
47
+ },
48
+ "client": {
49
+ "inject": [
50
+ "@deepseek-ai/dsh-client-runtime",
51
+ "@deepseek-ai/dsh-client-locale",
52
+ "@deepseek-ai/dsh-client-ui-slots",
53
+ "@deepseek-ai/dsh-client-ui-settings"
54
+ ],
55
+ "platform": "web"
56
+ }
57
+ },
58
+ "peerDependencies": {
59
+ "@deepseek-ai/cordis": "^4.0.1",
60
+ "@deepseek-ai/dsh-attachment": "^0.1.0-rc.6",
61
+ "@deepseek-ai/dsh-client-locale": "^0.1.0-rc.6",
62
+ "@deepseek-ai/dsh-client-runtime": "^0.1.0-rc.6",
63
+ "@deepseek-ai/dsh-client-ui-settings": "^0.1.0-rc.6",
64
+ "@deepseek-ai/dsh-client-ui-slots": "^0.1.0-rc.6",
65
+ "@deepseek-ai/dsh-host-webserver": "^0.1.0-rc.6",
66
+ "@deepseek-ai/dsh-llm": "^0.1.0-rc.6",
67
+ "react": "^18.2.0"
68
+ },
69
+ "devDependencies": {
70
+ "@deepseek-ai/cordis": "^4.0.1",
71
+ "@deepseek-ai/dsh-attachment": "^0.1.0-rc.6",
72
+ "@deepseek-ai/dsh-client-locale": "^0.1.0-rc.6",
73
+ "@deepseek-ai/dsh-client-runtime": "^0.1.0-rc.6",
74
+ "@deepseek-ai/dsh-client-ui-settings": "^0.1.0-rc.6",
75
+ "@deepseek-ai/dsh-client-ui-slots": "^0.1.0-rc.6",
76
+ "@deepseek-ai/dsh-host-webserver": "^0.1.0-rc.6",
77
+ "@deepseek-ai/dsh-llm": "^0.1.0-rc.6",
78
+ "@types/node": "^22.20.0",
79
+ "@types/react": "~18.3.1",
80
+ "@types/react-dom": "^18.3.5",
81
+ "jsdom": "29.1.1",
82
+ "react": "^18.3.1",
83
+ "react-dom": "^18.3.1",
84
+ "tsdown": "0.22.2",
85
+ "typescript": "~5.7.2",
86
+ "vitest": "^4.1.8"
87
+ },
88
+ "files": [
89
+ "lib/index.js",
90
+ "lib/client.js",
91
+ "lib/client.js.map",
92
+ "lib/types/**/*.d.ts",
93
+ "lib/types/**/*.d.ts.map",
94
+ "cordis.patch.yml",
95
+ "README.md",
96
+ "CHANGELOG.md"
97
+ ],
98
+ "license": "MIT",
99
+ "scripts": {
100
+ "build": "tsc -b && tsdown",
101
+ "prepack": "npm run build",
102
+ "test": "vitest run",
103
+ "typecheck": "tsc -b --pretty false"
104
+ }
105
+ }