dsh-codex-subscription 1.11.3 → 1.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/AGENTS.md CHANGED
@@ -6,7 +6,7 @@ Use this guide when a user asks an Agent to install, update, verify, or remove
6
6
  ## Safety
7
7
 
8
8
  - Confirm the target DSH installation and profile. Use `web` only when it is the user's target.
9
- - Use the exact `1.11.3` package below; do not install a moving branch.
9
+ - Use the exact `1.12.0` package below; do not install a moving branch.
10
10
  - Never print OAuth credentials, account IDs, authorization callbacks, or credential-store contents.
11
11
  - Preserve the DSH profile, unrelated plugins, sessions, and saved sign-in.
12
12
  - Do not start, stop, or restart DSH without explicit permission.
@@ -34,13 +34,13 @@ For an official DSH installation run through npm, keep the complete `npx` prefix
34
34
  run command does not create a global `dsh` command:
35
35
 
36
36
  ```sh
37
- npx -y @deepseek-ai/dsh@0.1.1-rc.2 plugin --profile web add dsh-codex-subscription@1.11.3
37
+ npx -y @deepseek-ai/dsh@0.1.1-rc.2 plugin --profile web add dsh-codex-subscription@1.12.0
38
38
  ```
39
39
 
40
40
  With an existing global `dsh` command:
41
41
 
42
42
  ```sh
43
- dsh plugin --profile web add dsh-codex-subscription@1.11.3
43
+ dsh plugin --profile web add dsh-codex-subscription@1.12.0
44
44
  ```
45
45
 
46
46
  Use the same `add` command to update or repair. This is the complete package-changing operation.
@@ -58,7 +58,7 @@ dsh --profile web --dump-config
58
58
 
59
59
  For the official npm route, run the same checks with `npx -y @deepseek-ai/dsh@0.1.1-rc.2` in place of `dsh`.
60
60
 
61
- 1. `dsh-codex-subscription` version `1.11.3` appears exactly once.
61
+ 1. `dsh-codex-subscription` version `1.12.0` appears exactly once.
62
62
  2. `codex-subscription` appears exactly once in the composed config.
63
63
  3. No unrelated plugin or profile was changed and DSH was not restarted.
64
64
 
package/README.en.md CHANGED
@@ -133,7 +133,7 @@ Restart DSH manually after installation, then:
133
133
 
134
134
  ## Features
135
135
 
136
- - ChatGPT OAuth sign-in with credentials kept on the host;
136
+ - ChatGPT OAuth sign-in with credentials kept on the host; manually add, switch, and remove accounts without automatic rotation or quota pooling;
137
137
  - Codex models and Beta image generation/editing directly inside DSH conversations;
138
138
  - A clear global choice between DSH default search and Codex subscription search; it applies to every model and session rather than following the selected model;
139
139
  - Actual backend-provided quota, reset time, and freshness;
@@ -153,7 +153,7 @@ The plugin can follow an existing HTTPS proxy from the process environment or op
153
153
  <img src="https://raw.githubusercontent.com/WSL043/dsh-codex-subscription/main/docs/assets/composer-quota-en.png" width="800" alt="Codex quota inside the composer">
154
154
  </p>
155
155
 
156
- Choose Off, Percent, Progress bar, or Beta Runway in Settings. The compact display appears only for a selected Codex model. Runway is opt-in and estimates the current pace only from official remaining-percentage observations kept in local runtime memory; it stays quiet with insufficient evidence and recalibrates after a reset, account change, or disable.
156
+ Choose Off, Percent, Progress bar, or Beta Runway in Settings. The compact display appears only for a selected Codex model. Runway is opt-in and estimates pace only from official remaining-percentage observations. It needs at least three samples; sustained high use usually produces a range in 5–10 minutes, while low use takes longer or reports a stable state. Non-sensitive observations from the last 24 hours are kept locally so calibration can continue after restart; a quota reset, account switch, or disabling the feature starts a new calibration period.
157
157
  Standard Codex uses the lowest remaining window returned by the service; Spark uses its independent quota. The plugin does not hard-code a
158
158
  “5-hour + weekly” layout or invent Credits and spending caps that the service did not return.
159
159
 
package/README.md CHANGED
@@ -134,7 +134,7 @@ dsh --profile web --dump-config
134
134
 
135
135
  ## 功能
136
136
 
137
- - ChatGPT OAuth 登录,凭据保留在本机;
137
+ - ChatGPT OAuth 登录,凭据保留在本机;可手动添加、切换和移除多个账号,不会自动轮换或合并额度;
138
138
  - Codex 模型和 Beta 图片生成与编辑直接出现在 DSH 会话中;
139
139
  - 搜索来源是全局设置,可在 DSH 默认搜索与 Codex 订阅搜索之间切换;它对所有模型和会话生效,不会随当前模型自动切换;
140
140
  - 设置页显示服务端返回的额度、重置时间和更新时间;
@@ -154,7 +154,7 @@ dsh --profile web --dump-config
154
154
  <img src="https://raw.githubusercontent.com/WSL043/dsh-codex-subscription/main/docs/assets/composer-quota.png" width="800" alt="中文 DSH 输入框内的 Codex 剩余额度进度条">
155
155
  </p>
156
156
 
157
- 可在设置中选择关闭、百分比、进度条或 Beta 续航预测;紧凑额度只在选择 Codex 模型时显示。续航预测仅在用户主动选择后,根据本机运行内存中观察到的官方剩余百分比估算当前消耗速度;样本不足时保持安静,额度重置、登录变化或关闭功能后会重新校准。普通 Codex 使用服务端返回窗口中剩余最少的一项,
157
+ 可在设置中选择关闭、百分比、进度条或 Beta 续航预测;紧凑额度只在选择 Codex 模型时显示。续航预测仅在用户主动选择后,根据官方剩余百分比估算当前消耗速度。它至少需要 3 个样本;持续高消耗时通常 5–10 分钟即可给出范围,消耗较低时会延长观察或显示稳定。最近 24 小时的无敏感信息观测会保存在本机,重启后可以继续校准;额度重置、账号切换或关闭功能会开启新的校准周期。普通 Codex 使用服务端返回窗口中剩余最少的一项,
158
158
  Spark 使用独立额度。插件不会写死“5 小时 + 每周”,也不会虚构服务端没有返回的 Credits 或消费上限。
159
159
 
160
160
  ### 安全使用额度重置
@@ -8,6 +8,7 @@
8
8
  "0.1.1-rc.2"
9
9
  ],
10
10
  "previews": [
11
- "0.1.2-alpha.2"
11
+ "0.1.2-alpha.2",
12
+ "0.1.2-alpha.3"
12
13
  ]
13
14
  }
package/lib/client.js CHANGED
@@ -245,6 +245,13 @@ window.__ModuleLoader__.load({
245
245
  browserLogin: "浏览器登录",
246
246
  deviceLogin: "设备代码登录",
247
247
  logout: "退出登录",
248
+ addAccount: "添加账号",
249
+ accountLabel: "账号名称",
250
+ switchAccount: "切换",
251
+ removeAccount: "移除",
252
+ removeConfirm: "确认移除",
253
+ removeCancel: "保留",
254
+ signOutAll: "退出全部账号",
248
255
  cancel: "取消",
249
256
  submit: "提交授权码",
250
257
  openLogin: "打开登录页",
@@ -329,7 +336,7 @@ window.__ModuleLoader__.load({
329
336
  quickQuotaBar: "进度条",
330
337
  quickQuotaForecast: "续航预测",
331
338
  quickQuotaBeta: "Beta",
332
- quickQuotaForecastHint: "至少观察 30 分钟且额度变化 1% 后显示;重启 DSH 后重新校准。",
339
+ quickQuotaForecastHint: "按消耗速度自适应校准;高消耗通常 5–10 分钟可估算,低消耗会显示用量稳定。进度会在本机保留。",
333
340
  contextTitle: "上下文窗口",
334
341
  contextStandard: "标准",
335
342
  contextStandardHint: "使用模型目录默认值;官方 Agent 预设会自动管理上下文。",
@@ -421,6 +428,13 @@ window.__ModuleLoader__.load({
421
428
  browserLogin: "Browser sign-in",
422
429
  deviceLogin: "Device-code sign-in",
423
430
  logout: "Sign out",
431
+ addAccount: "Add account",
432
+ accountLabel: "Account name",
433
+ switchAccount: "Switch",
434
+ removeAccount: "Remove",
435
+ removeConfirm: "Confirm remove",
436
+ removeCancel: "Keep",
437
+ signOutAll: "Sign out all",
424
438
  cancel: "Cancel",
425
439
  submit: "Submit authorization code",
426
440
  openLogin: "Open sign-in page",
@@ -505,7 +519,7 @@ window.__ModuleLoader__.load({
505
519
  quickQuotaBar: "Progress bar",
506
520
  quickQuotaForecast: "Runway",
507
521
  quickQuotaBeta: "Beta",
508
- quickQuotaForecastHint: "Appears after at least 30 minutes and a 1% quota change; restarting DSH recalibrates it.",
522
+ quickQuotaForecastHint: "Calibrates to actual consumption: high use is usually estimated in 5–10 minutes, while low use is shown as stable. Progress is kept locally.",
509
523
  contextTitle: "Context window",
510
524
  contextStandard: "Standard",
511
525
  contextStandardHint: "Use the model catalog default; official agent presets manage context automatically.",
@@ -602,6 +616,7 @@ window.__ModuleLoader__.load({
602
616
  .codexSubscriptionSwitch{position:relative;flex:0 0 auto;width:32px;height:18px;padding:0;border:1px solid var(--dsw-alias-border-l3);border-radius:999px;background:var(--dsw-alias-bg-module-platform);cursor:pointer}.codexSubscriptionSwitch:disabled{cursor:not-allowed;opacity:.5}.codexSubscriptionSwitch[aria-checked=true]{background:var(--dsw-alias-label-secondary);border-color:var(--dsw-alias-label-secondary)}.codexSubscriptionSwitchKnob{position:absolute;top:2px;left:2px;width:12px;height:12px;border-radius:50%;background:var(--dsw-alias-bg-layer-1);transition:transform 120ms var(--ds-ease-in-out)}.codexSubscriptionSwitch[aria-checked=true] .codexSubscriptionSwitchKnob{transform:translateX(14px)}
603
617
  .codexSubscriptionSearch{display:flex;flex-direction:column;gap:7px}.codexSubscriptionSearchChoices{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:6px}.codexSubscriptionSearchChoice{display:grid;grid-template-columns:14px minmax(0,1fr);align-items:center;column-gap:8px;min-width:0;border:1px solid var(--dsw-alias-border-l2);border-radius:10px;background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-primary);padding:9px 10px;text-align:left;cursor:pointer}.codexSubscriptionSearchChoice:has(input:disabled){cursor:not-allowed;opacity:.5}.codexSubscriptionSearchChoice:has(input:checked){border-color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-2)}.codexSubscriptionSearchChoice:has(input:focus-visible){outline:2px solid var(--dsw-alias-border-l3);outline-offset:2px}.codexSubscriptionSearchInput{width:14px;height:14px;margin:0;accent-color:var(--dsw-alias-label-primary);cursor:inherit}.codexSubscriptionSearchCopy{display:block;min-width:0;pointer-events:none}.codexSubscriptionSearchCopy strong,.codexSubscriptionSearchCopy span{display:block}.codexSubscriptionSearchCopy strong{font-size:12px;line-height:18px;font-weight:500;color:var(--dsw-alias-label-secondary)}.codexSubscriptionSearchChoice:has(input:checked) strong{color:var(--dsw-alias-label-primary)}.codexSubscriptionSearchCopy span{font-size:11px;line-height:16px;color:var(--dsw-alias-label-tertiary)}.codexSubscriptionDivider{height:1px;background:var(--dsw-alias-border-l2)}
604
618
  .codexSubscriptionAccountRow,.codexSubscriptionSectionHead{display:flex;align-items:center;justify-content:space-between;gap:12px}.codexSubscriptionStatus{display:flex;align-items:center;gap:8px;font-size:14px;line-height:22px;font-weight:500}
619
+ .codexSubscriptionAccounts{display:flex;flex-direction:column;border-top:1px solid var(--dsw-alias-border-l2)}.codexSubscriptionAccount{display:flex;align-items:center;justify-content:space-between;gap:10px;min-height:42px;border-bottom:1px solid var(--dsw-alias-border-l2);font-size:13px}.codexSubscriptionAccount:last-child{border-bottom:0}.codexSubscriptionAccount[data-active=true]>span{font-weight:600}.codexSubscriptionFlow label{display:flex;flex-direction:column;gap:6px;font-size:12px;color:var(--dsw-alias-label-secondary)}
605
620
  .codexSubscriptionDot{width:8px;height:8px;border-radius:50%;background:var(--dsw-alias-label-dimmed)}.codexSubscriptionDot[data-state=connected]{background:var(--dsw-alias-state-success-primary)}.codexSubscriptionDot[data-state=disconnected]{background:var(--dsw-alias-state-error-primary)}
606
621
  .codexSubscriptionActions{display:flex;align-items:center;gap:8px;flex-wrap:wrap}.codexSubscriptionFlow{display:flex;flex-direction:column;gap:10px;padding:12px 14px;border-radius:10px;background:var(--dsw-alias-bg-module-platform)}
607
622
  .codexSubscriptionFlow p{font-size:13px;line-height:20px;color:var(--dsw-alias-label-secondary)}.codexSubscriptionCode{width:max-content;max-width:100%;font:600 16px/22px ui-monospace,SFMono-Regular,Consolas,monospace;letter-spacing:.08em;overflow-wrap:anywhere}
@@ -1873,6 +1888,9 @@ window.__ModuleLoader__.load({
1873
1888
  function AccountCard({ rpc, t, account, setAccount, onSignedOut }) {
1874
1889
  const [flow, setFlow] = (0, react.useState)();
1875
1890
  const [manualCode, setManualCode] = (0, react.useState)("");
1891
+ const [adding, setAdding] = (0, react.useState)(false);
1892
+ const [accountLabel, setAccountLabel] = (0, react.useState)("");
1893
+ const [removeId, setRemoveId] = (0, react.useState)();
1876
1894
  const [busy, setBusy] = (0, react.useState)(false);
1877
1895
  const [error, setError] = (0, react.useState)();
1878
1896
  const call = (endpoint, payload = {}) => rpc.call(CHANNEL, endpoint, payload).then(unwrap);
@@ -1883,35 +1901,52 @@ window.__ModuleLoader__.load({
1883
1901
  "cancelled"
1884
1902
  ].includes(flow.phase)) return void 0;
1885
1903
  const timer = window.setInterval(() => {
1886
- readLoginProgress({
1904
+ (adding ? call("login/status", { id: flow.id }).then(async (nextFlow) => ({
1905
+ flow: nextFlow,
1906
+ account: nextFlow.phase === "authenticated" ? await call("status") : void 0
1907
+ })) : readLoginProgress({
1887
1908
  flow,
1888
1909
  readFlow: () => call("login/status", { id: flow.id }),
1889
1910
  readAccount: () => call("status")
1890
- }).then((next) => {
1911
+ })).then((next) => {
1891
1912
  setFlow(next.flow);
1892
1913
  setError(void 0);
1893
1914
  if (next.account !== void 0) {
1894
1915
  setAccount(next.account);
1916
+ onSignedOut();
1917
+ setAdding(false);
1918
+ setAccountLabel("");
1919
+ setFlow(void 0);
1895
1920
  notifyQuickQuota();
1896
1921
  }
1897
1922
  }).catch(() => setError(t("failed")));
1898
1923
  }, 800);
1899
1924
  return () => window.clearInterval(timer);
1900
- }, [flow?.id, flow?.phase]);
1901
- const begin = (method) => {
1925
+ }, [
1926
+ flow?.id,
1927
+ flow?.phase,
1928
+ adding
1929
+ ]);
1930
+ const begin = (method, label) => {
1902
1931
  setFlow(void 0);
1903
1932
  setBusy(true);
1904
1933
  setError(void 0);
1905
1934
  call("login/start", {
1906
1935
  method,
1907
- openExternal: true
1936
+ openExternal: true,
1937
+ ...label === void 0 ? {} : { label }
1908
1938
  }).then(setFlow).catch(() => setError(t("failed"))).finally(() => setBusy(false));
1909
1939
  };
1910
1940
  const cancel = () => {
1911
1941
  if (flow?.id === void 0) return;
1912
1942
  setBusy(true);
1913
1943
  call("login/cancel", { id: flow.id }).then((next) => {
1914
- setFlow(next);
1944
+ setFlow(adding ? void 0 : next);
1945
+ if (adding) {
1946
+ setAdding(false);
1947
+ setAccountLabel("");
1948
+ }
1949
+ if (adding) return void 0;
1915
1950
  return call("status").then((account) => {
1916
1951
  if (account.authenticated === true) {
1917
1952
  setAccount(account);
@@ -1948,8 +1983,38 @@ window.__ModuleLoader__.load({
1948
1983
  notifyQuickQuota();
1949
1984
  }).catch(() => setError(t("failed"))).finally(() => setBusy(false));
1950
1985
  };
1986
+ const selectAccount = (id) => {
1987
+ setBusy(true);
1988
+ setError(void 0);
1989
+ call("account/select", { id }).then((next) => {
1990
+ setAccount(next);
1991
+ onSignedOut();
1992
+ notifyQuickQuota();
1993
+ }).catch(() => setError(t("failed"))).finally(() => setBusy(false));
1994
+ };
1995
+ const removeAccount = (id) => {
1996
+ if (removeId !== id) {
1997
+ setRemoveId(id);
1998
+ return;
1999
+ }
2000
+ setBusy(true);
2001
+ setError(void 0);
2002
+ call("account/remove", { id }).then((next) => {
2003
+ setAccount(next);
2004
+ setRemoveId(void 0);
2005
+ onSignedOut();
2006
+ notifyQuickQuota();
2007
+ }).catch(() => setError(t("failed"))).finally(() => setBusy(false));
2008
+ };
1951
2009
  const signedIn = account?.authenticated === true;
1952
2010
  const accountReady = account !== void 0;
2011
+ const accounts = account?.accounts ?? [];
2012
+ const activeAccount = accounts.find((candidate) => candidate.active);
2013
+ const loginVisible = flow !== void 0 && ![
2014
+ "authenticated",
2015
+ "failed",
2016
+ "cancelled"
2017
+ ].includes(flow.phase);
1953
2018
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1954
2019
  className: "codexSubscriptionCard",
1955
2020
  children: [
@@ -1963,16 +2028,26 @@ window.__ModuleLoader__.load({
1963
2028
  className: "codexSubscriptionDot",
1964
2029
  "data-state": accountReady ? signedIn ? "connected" : "disconnected" : "loading",
1965
2030
  "aria-hidden": "true"
1966
- }), accountReady ? signedIn ? t("connected") : t("disconnected") : t("accountLoading")]
2031
+ }), accountReady ? signedIn ? activeAccount?.label ?? t("connected") : t("disconnected") : t("accountLoading")]
1967
2032
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1968
2033
  className: "codexSubscriptionActions",
1969
- children: signedIn ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
2034
+ children: signedIn ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
1970
2035
  type: "button",
1971
2036
  variant: "outline",
1972
- disabled: busy,
2037
+ disabled: busy || loginVisible,
2038
+ onClick: () => {
2039
+ setFlow(void 0);
2040
+ setAdding(true);
2041
+ setAccountLabel(`Account ${accounts.length + 1}`);
2042
+ },
2043
+ children: t("addAccount")
2044
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
2045
+ type: "button",
2046
+ variant: "outline",
2047
+ disabled: busy || loginVisible,
1973
2048
  onClick: logout,
1974
- children: t("logout")
1975
- }) : accountReady && (flow === void 0 || ["failed", "cancelled"].includes(flow.phase)) ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
2049
+ children: t("signOutAll")
2050
+ })] }) : accountReady && (flow === void 0 || ["failed", "cancelled"].includes(flow.phase)) ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
1976
2051
  type: "button",
1977
2052
  variant: "primary",
1978
2053
  disabled: busy,
@@ -1987,7 +2062,77 @@ window.__ModuleLoader__.load({
1987
2062
  })] }) : null
1988
2063
  })]
1989
2064
  }),
1990
- !signedIn && flow?.phase === "waiting_device" ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2065
+ signedIn && accounts.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2066
+ className: "codexSubscriptionAccounts",
2067
+ children: accounts.map((candidate) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2068
+ className: "codexSubscriptionAccount",
2069
+ "data-active": candidate.active,
2070
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: candidate.label }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2071
+ className: "codexSubscriptionActions",
2072
+ children: [
2073
+ candidate.active ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
2074
+ type: "button",
2075
+ variant: "outline",
2076
+ disabled: busy || loginVisible,
2077
+ onClick: () => selectAccount(candidate.id),
2078
+ children: t("switchAccount")
2079
+ }),
2080
+ accounts.length > 1 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
2081
+ type: "button",
2082
+ variant: "outline",
2083
+ disabled: busy || loginVisible,
2084
+ onClick: () => removeAccount(candidate.id),
2085
+ children: removeId === candidate.id ? t("removeConfirm") : t("removeAccount")
2086
+ }) : null,
2087
+ removeId === candidate.id ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
2088
+ type: "button",
2089
+ variant: "outline",
2090
+ disabled: busy,
2091
+ onClick: () => setRemoveId(void 0),
2092
+ children: t("removeCancel")
2093
+ }) : null
2094
+ ]
2095
+ })]
2096
+ }, candidate.id))
2097
+ }) : null,
2098
+ signedIn && adding && flow === void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2099
+ className: "codexSubscriptionFlow",
2100
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", { children: [t("accountLabel"), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Input, {
2101
+ className: "codexSubscriptionInput",
2102
+ value: accountLabel,
2103
+ maxLength: 48,
2104
+ onChange: (event) => setAccountLabel(event.currentTarget.value)
2105
+ })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2106
+ className: "codexSubscriptionActions",
2107
+ children: [
2108
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
2109
+ type: "button",
2110
+ variant: "primary",
2111
+ disabled: busy || accountLabel.trim() === "",
2112
+ onClick: () => begin("browser", accountLabel.trim()),
2113
+ children: t("browserLogin")
2114
+ }),
2115
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
2116
+ type: "button",
2117
+ variant: "outline",
2118
+ disabled: busy || accountLabel.trim() === "",
2119
+ onClick: () => begin("device_code", accountLabel.trim()),
2120
+ children: t("deviceLogin")
2121
+ }),
2122
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
2123
+ type: "button",
2124
+ variant: "outline",
2125
+ disabled: busy,
2126
+ onClick: () => {
2127
+ setAdding(false);
2128
+ setAccountLabel("");
2129
+ },
2130
+ children: t("cancel")
2131
+ })
2132
+ ]
2133
+ })]
2134
+ }) : null,
2135
+ flow?.phase === "waiting_device" ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1991
2136
  className: "codexSubscriptionFlow",
1992
2137
  children: [
1993
2138
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: t("deviceHint") }),
@@ -2004,7 +2149,7 @@ window.__ModuleLoader__.load({
2004
2149
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: t("waiting") })
2005
2150
  ]
2006
2151
  }) : null,
2007
- !signedIn && flow?.phase === "waiting_input" ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("form", {
2152
+ flow?.phase === "waiting_input" ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("form", {
2008
2153
  className: "codexSubscriptionFlow",
2009
2154
  onSubmit: submit,
2010
2155
  children: [
@@ -2033,7 +2178,7 @@ window.__ModuleLoader__.load({
2033
2178
  })
2034
2179
  ]
2035
2180
  }) : null,
2036
- !signedIn && flow !== void 0 && ["starting", "waiting_browser"].includes(flow.phase) ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2181
+ flow !== void 0 && ["starting", "waiting_browser"].includes(flow.phase) ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2037
2182
  className: "codexSubscriptionFlow",
2038
2183
  children: [
2039
2184
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: t("waiting") }),