dsh-codex-subscription 2.1.1 → 2.1.3-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.en.md CHANGED
@@ -92,9 +92,9 @@ dsh --profile headless "Reply with only the word: ok"
92
92
  The official `npx @deepseek-ai/dsh web` command does not create a global `dsh` command. Keep the full `npx` prefix when installing the plugin:
93
93
 
94
94
  ```sh
95
- npx -y @deepseek-ai/dsh@0.1.5-rc.1 plugin --profile web add dsh-codex-subscription
96
- npx -y @deepseek-ai/dsh@0.1.5-rc.1 plugin --profile web list dsh-codex-subscription --depth 0
97
- npx -y @deepseek-ai/dsh@0.1.5-rc.1 --profile web --dump-config
95
+ npx -y @deepseek-ai/dsh@0.1.5-rc.2 plugin --profile web add dsh-codex-subscription
96
+ npx -y @deepseek-ai/dsh@0.1.5-rc.2 plugin --profile web list dsh-codex-subscription --depth 0
97
+ npx -y @deepseek-ai/dsh@0.1.5-rc.2 --profile web --dump-config
98
98
  ```
99
99
 
100
100
  </details>
@@ -277,22 +277,22 @@ These operations preserve the DSH profile, other plugins, and saved sign-in.
277
277
  ### Update and verify
278
278
 
279
279
  ```sh
280
- npx -y @deepseek-ai/dsh@0.1.5-rc.1 plugin --profile web update dsh-codex-subscription
281
- npx -y @deepseek-ai/dsh@0.1.5-rc.1 plugin --profile web list dsh-codex-subscription --depth 0
282
- npx -y @deepseek-ai/dsh@0.1.5-rc.1 --profile web --dump-config
280
+ npx -y @deepseek-ai/dsh@0.1.5-rc.2 plugin --profile web update dsh-codex-subscription
281
+ npx -y @deepseek-ai/dsh@0.1.5-rc.2 plugin --profile web list dsh-codex-subscription --depth 0
282
+ npx -y @deepseek-ai/dsh@0.1.5-rc.2 --profile web --dump-config
283
283
  ```
284
284
 
285
285
  ### Uninstall
286
286
 
287
287
  ```sh
288
- npx -y @deepseek-ai/dsh@0.1.5-rc.1 plugin --profile web remove dsh-codex-subscription
288
+ npx -y @deepseek-ai/dsh@0.1.5-rc.2 plugin --profile web remove dsh-codex-subscription
289
289
  ```
290
290
 
291
291
  </details>
292
292
 
293
293
  ## Troubleshooting
294
294
 
295
- - **`dsh` is not recognized:** the official npm route does not create a global `dsh` command; use the complete `npx -y @deepseek-ai/dsh@0.1.5-rc.1 ...` command above;
295
+ - **`dsh` is not recognized:** the official npm route does not create a global `dsh` command; use the complete `npx -y @deepseek-ai/dsh@0.1.5-rc.2 ...` command above;
296
296
  - **More than one DSH exists:** run the standard command from the intended DSH environment so that product selects the corresponding profile;
297
297
  - **Setup still fails:** confirm the command is running in the intended DSH environment. Do not delete the profile or change the system PATH to force an install.
298
298
  - **Need to report a problem:** generate a **Support diagnostics** report at the bottom of Settings, then open the [bug report form](https://github.com/WSL043/dsh-codex-subscription/issues/new?template=install-problem.yml). The report includes the OS/runtime, bounded sign-in phase, and safe request-failure categories, but excludes credentials, account identifiers, raw responses, and full logs. Paste it into the required diagnostics field; never attach sign-in URLs, authorization codes, or browser callback addresses.
package/README.md CHANGED
@@ -93,9 +93,9 @@ dsh --profile headless "只回复:ok"
93
93
  官方的 `npx @deepseek-ai/dsh web` 不会创建全局 `dsh` 命令,因此安装插件时也要保留完整的 `npx` 前缀:
94
94
 
95
95
  ```sh
96
- npx -y @deepseek-ai/dsh@0.1.5-rc.1 plugin --profile web add dsh-codex-subscription
97
- npx -y @deepseek-ai/dsh@0.1.5-rc.1 plugin --profile web list dsh-codex-subscription --depth 0
98
- npx -y @deepseek-ai/dsh@0.1.5-rc.1 --profile web --dump-config
96
+ npx -y @deepseek-ai/dsh@0.1.5-rc.2 plugin --profile web add dsh-codex-subscription
97
+ npx -y @deepseek-ai/dsh@0.1.5-rc.2 plugin --profile web list dsh-codex-subscription --depth 0
98
+ npx -y @deepseek-ai/dsh@0.1.5-rc.2 --profile web --dump-config
99
99
  ```
100
100
 
101
101
  </details>
@@ -276,22 +276,22 @@ dsh plugin --profile web remove dsh-codex-subscription
276
276
  ### 更新并检查
277
277
 
278
278
  ```sh
279
- npx -y @deepseek-ai/dsh@0.1.5-rc.1 plugin --profile web update dsh-codex-subscription
280
- npx -y @deepseek-ai/dsh@0.1.5-rc.1 plugin --profile web list dsh-codex-subscription --depth 0
281
- npx -y @deepseek-ai/dsh@0.1.5-rc.1 --profile web --dump-config
279
+ npx -y @deepseek-ai/dsh@0.1.5-rc.2 plugin --profile web update dsh-codex-subscription
280
+ npx -y @deepseek-ai/dsh@0.1.5-rc.2 plugin --profile web list dsh-codex-subscription --depth 0
281
+ npx -y @deepseek-ai/dsh@0.1.5-rc.2 --profile web --dump-config
282
282
  ```
283
283
 
284
284
  ### 卸载
285
285
 
286
286
  ```sh
287
- npx -y @deepseek-ai/dsh@0.1.5-rc.1 plugin --profile web remove dsh-codex-subscription
287
+ npx -y @deepseek-ai/dsh@0.1.5-rc.2 plugin --profile web remove dsh-codex-subscription
288
288
  ```
289
289
 
290
290
  </details>
291
291
 
292
292
  ## 常见问题
293
293
 
294
- - **`dsh` 无法识别**:官方 npm 方式本来就不会创建全局 `dsh` 命令,请使用上面的完整 `npx -y @deepseek-ai/dsh@0.1.5-rc.1 ...` 命令;
294
+ - **`dsh` 无法识别**:官方 npm 方式本来就不会创建全局 `dsh` 命令,请使用上面的完整 `npx -y @deepseek-ai/dsh@0.1.5-rc.2 ...` 命令;
295
295
  - **电脑上有多个 DSH**:请从目标 DSH 环境运行标准命令,由该产品自身选择对应 profile;
296
296
  - **安装仍然失败**:确认命令是在目标 DSH 环境中运行,不要删除 profile 或随意修改系统 PATH。
297
297
  - **需要提交问题**:在设置页底部生成“支持诊断”,然后打开[使用问题表单](https://github.com/WSL043/dsh-codex-subscription/issues/new?template=install-problem.yml)。报告包含系统/运行时、有限的登录阶段和安全的请求失败分类,但不含凭据、账号标识、原始响应或完整日志;请粘贴到必填诊断栏,且不要附上登录链接、授权码或浏览器回调地址。
@@ -1,12 +1,14 @@
1
1
  {
2
- "latestTested": "0.1.5-rc.1",
2
+ "latestTested": "0.1.5-rc.2",
3
3
  "supported": [
4
4
  "0.1.2-rc.1",
5
- "0.1.5-rc.1"
5
+ "0.1.5-rc.1",
6
+ "0.1.5-rc.2"
6
7
  ],
7
8
  "previews": [
8
9
  "0.1.5-alpha.1",
9
10
  "0.1.5-alpha.2",
10
- "0.1.6-alpha.1"
11
+ "0.1.6-alpha.1",
12
+ "0.1.6-alpha.2"
11
13
  ]
12
14
  }
package/lib/client.js CHANGED
@@ -483,6 +483,41 @@ window.__ModuleLoader__.load({
483
483
  };
484
484
  }
485
485
  //#endregion
486
+ //#region src/client-session-compat.js
487
+ async function withComposerSession(sessions, id, operation) {
488
+ const reference = typeof sessions.retain === "function" ? sessions.retain(id, { source: "controllerOperation" }) : void 0;
489
+ try {
490
+ if (reference) await reference.ready;
491
+ const context = reference ? reference.binding.ctx : sessions.scope(id);
492
+ if (!context) throw new Error("Image composer is unavailable");
493
+ return await operation(context);
494
+ } finally {
495
+ reference?.release();
496
+ }
497
+ }
498
+ function openComposerSession(sessions, workspace, id) {
499
+ if (typeof workspace?.openSession === "function") workspace.openSession(id);
500
+ else if (typeof sessions.open === "function") sessions.open(id);
501
+ else throw new Error("Session navigation is unavailable");
502
+ }
503
+ function createSessionOpeners() {
504
+ const entries = /* @__PURE__ */ new Map();
505
+ return {
506
+ register(id, callback) {
507
+ const callbacks = entries.get(id) ?? /* @__PURE__ */ new Set();
508
+ entries.set(id, callbacks);
509
+ callbacks.add(callback);
510
+ return () => {
511
+ callbacks.delete(callback);
512
+ if (!callbacks.size) entries.delete(id);
513
+ };
514
+ },
515
+ has: (id) => entries.has(id),
516
+ get: (id) => [...entries.get(id) ?? []].at(-1),
517
+ clear: () => entries.clear()
518
+ };
519
+ }
520
+ //#endregion
486
521
  //#region src/image-edit.js
487
522
  const isRecord = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
488
523
  const validCoordinate = (value) => typeof value === "number" && Number.isFinite(value) && value >= 0 && value <= 1;
@@ -645,7 +680,10 @@ window.__ModuleLoader__.load({
645
680
  loadImage,
646
681
  attempt
647
682
  ]);
648
- const item = image.attachment ?? image.preview;
683
+ const item = {
684
+ ...image.attachment ?? image.preview,
685
+ ...image.label ? { name: image.label } : {}
686
+ };
649
687
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
650
688
  type: "button",
651
689
  className: "codexImageThumb",
@@ -670,11 +708,12 @@ window.__ModuleLoader__.load({
670
708
  }) : failed ? t("accountRetry") : "…"
671
709
  });
672
710
  }
673
- function MessageImagePreviews({ images, align, ...props }) {
711
+ function MessageImagePreviews({ images, align, compact, thumbnail, ...props }) {
674
712
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
675
713
  className: "codexMessageImages",
676
714
  "data-align": align,
677
- "data-single": images.length === 1,
715
+ "data-single": images.length === 1 && !compact && !thumbnail,
716
+ "data-thumbnail": thumbnail || void 0,
678
717
  children: images.map((image, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MessageImagePreview, {
679
718
  image,
680
719
  ...props
@@ -689,6 +728,7 @@ window.__ModuleLoader__.load({
689
728
  .codexMessageImages{flex-wrap:wrap}.codexMessageImages[data-align=end]{justify-content:flex-end}
690
729
  .codexMessageImages[data-single=true] .codexImageThumb{width:240px;height:auto;max-width:100%}
691
730
  .codexMessageImages[data-single=true] img{height:auto;max-height:320px;object-fit:contain}
731
+ .codexMessageImages[data-thumbnail=true]{padding:0}.codexMessageImages[data-thumbnail=true] img{object-fit:contain}
692
732
  `;
693
733
  //#endregion
694
734
  //#region src/image-conversation-node.js
@@ -7146,7 +7186,7 @@ window.__ModuleLoader__.load({
7146
7186
  }
7147
7187
  //#endregion
7148
7188
  //#region src/version.js
7149
- const PACKAGE_VERSION = "2.1.1";
7189
+ const PACKAGE_VERSION = "2.1.3-beta.1";
7150
7190
  //#endregion
7151
7191
  //#region src/client-recovery.js
7152
7192
  async function recoveryCall(rpc, endpoint, payload = {}, timeoutMs = 1e4) {
@@ -9594,9 +9634,15 @@ window.__ModuleLoader__.load({
9594
9634
  else ctx.inject(["remote.session"], installDirectorySlots);
9595
9635
  const conversation = ctx.get("conversation");
9596
9636
  const uiConversation = ctx.get("uiConversation");
9597
- const sketchOpeners = /* @__PURE__ */ new Map();
9637
+ const sketchOpeners = createSessionOpeners();
9598
9638
  const sketchSessions = createSketchSessionRegistry();
9599
- ctx.effect(() => () => sketchSessions.dispose(), "codex-subscription: sketch sessions");
9639
+ const lifetime = new AbortController();
9640
+ ctx.effect(() => () => {
9641
+ lifetime.abort();
9642
+ imageViewer.close();
9643
+ sketchOpeners.clear();
9644
+ sketchSessions.dispose();
9645
+ }, "codex-subscription: sketch sessions");
9600
9646
  ctx.inject(["inputTriggers"], (triggerContext) => triggerContext.effect(() => triggerContext.get("inputTriggers").registerSource(createSketchTrigger({
9601
9647
  enabled: () => {
9602
9648
  const value = preference.getSnapshot();
@@ -9632,33 +9678,38 @@ window.__ModuleLoader__.load({
9632
9678
  const openSketchImage = (sessionId) => async (src, name) => {
9633
9679
  const settings = preference.getSnapshot(), open = sketchOpeners.get(sessionId);
9634
9680
  if (!settings.imageSketch || !settings.imageEditing || !open) throw Error("Sketch unavailable");
9635
- const response = await fetch(src);
9681
+ const response = await fetch(src, { signal: lifetime.signal });
9636
9682
  if (!response.ok) throw Error("Image unavailable");
9637
9683
  const blob = await response.blob();
9638
9684
  if (blob.size > 20 * 1024 * 1024) throw Error("Image too large");
9685
+ lifetime.signal.throwIfAborted();
9686
+ const liveOpen = sketchOpeners.get(sessionId);
9687
+ if (!liveOpen || !preference.getSnapshot().imageSketch || !preference.getSnapshot().imageEditing) throw Error("Sketch unavailable");
9639
9688
  imageViewer.close();
9640
- open("sketch", document.activeElement, new File([blob], name || "image.png", { type: blob.type || "image/png" }));
9689
+ liveOpen("sketch", document.activeElement, new File([blob], name || "image.png", { type: blob.type || "image/png" }));
9641
9690
  };
9642
9691
  const attachForEdit = (sessionId) => async (src, filename, draft, annotations = [], referenceName, sourceInDraft = false) => {
9643
9692
  if (!preference.getSnapshot().imageEditing) throw new Error("Image editing is disabled");
9644
- const actx = sessions.scope(sessionId);
9645
- if (actx === void 0 || conversation.input?.for === void 0) throw new Error("This DSH version does not provide the image composer bridge");
9646
- const response = await fetch(src);
9647
- if (!response.ok) throw new Error("Could not read generated image");
9648
- const blob = await response.blob();
9649
- const files = sourceInDraft ? [] : [new File([blob], filename, { type: blob.type || "image/png" })];
9650
- if (annotations.length > 0) {
9651
- const reference = await createAnnotatedImageReference(blob, annotations);
9652
- files.push(new File([reference], referenceName, { type: "image/png" }));
9653
- }
9654
- const input = conversation.input.for(actx);
9655
- if (!preference.getSnapshot().imageEditing) throw new Error("Image editing is disabled");
9656
- if (files.length) attachImageFiles(conversation, input, files, sessionId);
9657
- sessions.open(sessionId);
9658
- if (sourceInDraft && !annotations.length) return;
9659
- if (!input.state.getSnapshot().draft.trim()) input.setDraft(draft);
9660
- else if (annotations.length) if (!input.state.getSnapshot().occurrences?.length) appendImagePrompt(input, draft);
9661
- else input.notify("info", draft);
9693
+ return withComposerSession(sessions, sessionId, async (actx) => {
9694
+ if (conversation.input?.for === void 0) throw new Error("This DSH version does not provide the image composer bridge");
9695
+ const response = await fetch(src, { signal: lifetime.signal });
9696
+ if (!response.ok) throw new Error("Could not read generated image");
9697
+ const blob = await response.blob();
9698
+ const files = sourceInDraft ? [] : [new File([blob], filename, { type: blob.type || "image/png" })];
9699
+ if (annotations.length > 0) {
9700
+ const reference = await createAnnotatedImageReference(blob, annotations);
9701
+ files.push(new File([reference], referenceName, { type: "image/png" }));
9702
+ }
9703
+ lifetime.signal.throwIfAborted();
9704
+ const input = conversation.input.for(actx);
9705
+ if (!preference.getSnapshot().imageEditing) throw new Error("Image editing is disabled");
9706
+ if (files.length) attachImageFiles(conversation, input, files, sessionId);
9707
+ openComposerSession(sessions, ctx.get("uiWorkspace"), sessionId);
9708
+ if (sourceInDraft && !annotations.length) return;
9709
+ if (!input.state.getSnapshot().draft.trim()) input.setDraft(draft);
9710
+ else if (annotations.length) if (!input.state.getSnapshot().occurrences?.length) appendImagePrompt(input, draft);
9711
+ else input.notify("info", draft);
9712
+ });
9662
9713
  };
9663
9714
  const nativeAttachments = () => ctx.slots.entries("conversation.input.attachments").find((entry) => entry.component !== ComposerImagePreviews && entry.locale === "conversation" && !entry.inject && !entry.store && !entry.children);
9664
9715
  const watchNativeAttachments = (callback) => ctx.slots.subscribe("conversation.input.attachments", callback);
@@ -9706,12 +9757,7 @@ window.__ModuleLoader__.load({
9706
9757
  sessionId,
9707
9758
  rpc,
9708
9759
  sessionState: sketchSessions.get(sessionId),
9709
- registerOpen: (callback) => {
9710
- sketchOpeners.set(sessionId, callback);
9711
- return () => {
9712
- if (sketchOpeners.get(sessionId) === callback) sketchOpeners.delete(sessionId);
9713
- };
9714
- },
9760
+ registerOpen: (callback) => sketchOpeners.register(sessionId, callback),
9715
9761
  attachSketch: (blob) => {
9716
9762
  const current = preference.getSnapshot();
9717
9763
  if (!current.imageSketch || !current.imageEditing) throw new Error("Sketch editing is disabled");
package/lib/index.js CHANGED
@@ -468,6 +468,19 @@ function bodyBytes(body) {
468
468
  if (body instanceof Uint8Array) return Buffer.from(body);
469
469
  throw new TypeError("Unsupported Codex OAuth request body");
470
470
  }
471
+ function transportError(error, signal) {
472
+ if (signal?.aborted || error?.name === "AbortError" || error?.code === "ABORT_ERR") return error;
473
+ if (!/^(?:ECONNRESET|ECONNREFUSED|EPIPE|ETIMEDOUT|ENETUNREACH|EHOSTUNREACH|EAI_AGAIN|ERR_STREAM_PREMATURE_CLOSE)$/.test(error?.code ?? "")) return error;
474
+ return Object.assign(new Error(`Network transport failure (${error.code}): ${error.message}`, { cause: error }), { code: error.code });
475
+ }
476
+ function transportResponseBody(response, signal) {
477
+ const body = new PassThrough();
478
+ response.on("error", (error) => body.destroy(transportError(error, signal)));
479
+ body.on("close", () => response.destroy());
480
+ const stream = Readable.toWeb(body);
481
+ response.pipe(body);
482
+ return stream;
483
+ }
471
484
  function fetchThroughProxy(input, init, proxyUrl) {
472
485
  const target = new URL(typeof input === "string" || input instanceof URL ? input : input.url);
473
486
  const body = bodyBytes(init?.body);
@@ -489,13 +502,14 @@ function fetchThroughProxy(input, init, proxyUrl) {
489
502
  205,
490
503
  304
491
504
  ].includes(status);
492
- resolve(new Response(empty ? null : Readable.toWeb(response), {
505
+ if (empty) response.resume();
506
+ resolve(new Response(empty ? null : transportResponseBody(response, init?.signal), {
493
507
  status,
494
508
  statusText: response.statusMessage,
495
509
  headers: responseHeaders
496
510
  }));
497
511
  });
498
- request$1.on("error", reject);
512
+ request$1.on("error", (error) => reject(transportError(error, init?.signal)));
499
513
  if (body) request$1.write(body);
500
514
  request$1.end();
501
515
  });
@@ -2495,6 +2509,20 @@ function createCodexRpcHandler(coordinator, options = {}) {
2495
2509
  };
2496
2510
  }
2497
2511
  //#endregion
2512
+ //#region src/transport-failure.js
2513
+ function normalizeTransportEvent(event, signal) {
2514
+ if (signal?.aborted || event?.type !== "error" || event.reason !== "error") return event;
2515
+ const message = event.error?.errorMessage;
2516
+ if (typeof message !== "string" || !/^WebSocket closed (?:1006|1011|1012|1013)(?:\s|$)/.test(message)) return event;
2517
+ return {
2518
+ ...event,
2519
+ error: {
2520
+ ...event.error,
2521
+ errorMessage: `Network transport failure: ${message}`
2522
+ }
2523
+ };
2524
+ }
2525
+ //#endregion
2498
2526
  //#region src/pi-ai-runtime.js
2499
2527
  const FAST_SERVICE_TIER = "priority";
2500
2528
  /**
@@ -2578,13 +2606,17 @@ function openaiCodexSubscriptionProvider({ resolveSpeedMode = () => void 0, reso
2578
2606
  let prepared;
2579
2607
  const step = async (method, value) => {
2580
2608
  const request = await (prepared ??= connection?.prepare(options) ?? Promise.resolve({ options }));
2581
- return runNetwork("model", () => {
2609
+ const result = await runNetwork("model", () => {
2582
2610
  iterator ??= factory(compaction?.requestOptions(request.options) ?? request.options)[Symbol.asyncIterator]();
2583
2611
  return iterator[method]?.(value) ?? (method === "throw" ? Promise.reject(value) : Promise.resolve({
2584
2612
  done: true,
2585
2613
  value
2586
2614
  }));
2587
2615
  }, compaction?.networkOptions(request.network) ?? request.network);
2616
+ return result.done ? result : {
2617
+ ...result,
2618
+ value: normalizeTransportEvent(result.value, request.options?.signal)
2619
+ };
2588
2620
  };
2589
2621
  return {
2590
2622
  [Symbol.asyncIterator]() {
@@ -2612,7 +2644,7 @@ function openaiCodexSubscriptionProvider({ resolveSpeedMode = () => void 0, reso
2612
2644
  Object.freeze(["0.82.1", "0.85.1"]);
2613
2645
  //#endregion
2614
2646
  //#region src/version.js
2615
- const PACKAGE_VERSION = "2.1.1";
2647
+ const PACKAGE_VERSION = "2.1.3-beta.1";
2616
2648
  const USER_AGENT = `dsh-codex-subscription/${PACKAGE_VERSION}`;
2617
2649
  //#endregion
2618
2650
  //#region src/model-catalog.js
@@ -2806,7 +2838,7 @@ function createOfficialModelCatalog(options = {}) {
2806
2838
  };
2807
2839
  return Object.freeze({
2808
2840
  refresh,
2809
- getModels: (fallback) => models ?? fallback,
2841
+ getModels: (fallback) => models ?? fallback.filter((model) => model.id !== "gpt-5.3-codex-spark"),
2810
2842
  metadata: (modelId) => metadata.get(modelId),
2811
2843
  revision: () => revision,
2812
2844
  capabilityGaps: () => [...metadata.values()].filter((model) => model.unsupported && /^[a-z][a-z0-9._-]{0,79}$/u.test(model.id)).slice(0, 20).map((model) => ({
@@ -4661,7 +4693,7 @@ const publicError = (code, message) => ({
4661
4693
  details: { issues: [] }
4662
4694
  }
4663
4695
  });
4664
- function createSubscriptionRpcHandler({ authHandler, usageReader, resetCreditService, preferences, diagnosticsReader, modelCatalog, originalImages, resolveInheritedOriginal }) {
4696
+ function createSubscriptionRpcHandler({ authHandler, usageReader, resetCreditService, preferences, diagnosticsReader, modelCatalog, originalImages, resolveInheritedOriginal, closeConnections }) {
4665
4697
  return async (endpoint, payload, signal) => {
4666
4698
  if (endpoint === "image/original/chunk") try {
4667
4699
  signal.throwIfAborted();
@@ -4781,6 +4813,11 @@ function createSubscriptionRpcHandler({ authHandler, usageReader, resetCreditSer
4781
4813
  return publicError("internal", message);
4782
4814
  }
4783
4815
  const result = await authHandler(endpoint, payload, signal);
4816
+ if (result.ok === true && [
4817
+ "logout",
4818
+ "account/select",
4819
+ "account/remove"
4820
+ ].includes(endpoint)) closeConnections?.();
4784
4821
  if (endpoint === "account/remove" && result.ok === true && typeof payload?.id === "string") await usageReader.clearScope(payload.id);
4785
4822
  if (endpoint === "logout" && result.ok === true) {
4786
4823
  await usageReader.clear();
@@ -5156,6 +5193,7 @@ function apply(ctx) {
5156
5193
  modelCatalog
5157
5194
  }),
5158
5195
  modelCatalog,
5196
+ closeConnections: () => connection.dispose(),
5159
5197
  originalImages,
5160
5198
  resolveInheritedOriginal: (sessionId, assetId) => inheritedOriginalImageRef(ctx.get?.("sessions")?.get?.(sessionId), assetId)
5161
5199
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-codex-subscription",
3
- "version": "2.1.1",
3
+ "version": "2.1.3-beta.1",
4
4
  "description": "Use ChatGPT and Codex subscriptions in DeepSeek Harness with OAuth, quota, safe resets, web search, images, and Fast mode",
5
5
  "type": "module",
6
6
  "main": "./lib/index.js",
@@ -74,21 +74,21 @@
74
74
  },
75
75
  "peerDependencies": {
76
76
  "@deepseek-ai/cordis": "4.0.1 || 4.0.2",
77
- "@deepseek-ai/dsh-api-remotes": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.6-alpha.1",
78
- "@deepseek-ai/dsh-client-connection": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.6-alpha.1",
79
- "@deepseek-ai/dsh-client-locale": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.6-alpha.1",
80
- "@deepseek-ai/dsh-client-ui-conversation": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.6-alpha.1",
81
- "@deepseek-ai/dsh-client-ui-model-selection": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.6-alpha.1",
82
- "@deepseek-ai/dsh-client-ui-primitives": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.6-alpha.1",
83
- "@deepseek-ai/dsh-client-ui-settings": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.6-alpha.1",
84
- "@deepseek-ai/dsh-client-ui-slots": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.6-alpha.1",
85
- "@deepseek-ai/dsh-client-ui-tool": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.6-alpha.1",
86
- "@deepseek-ai/dsh-credentials": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.6-alpha.1",
87
- "@deepseek-ai/dsh-llm": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.6-alpha.1",
88
- "@deepseek-ai/dsh-llm-pi-ai": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.6-alpha.1",
89
- "@deepseek-ai/dsh-settings": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.6-alpha.1",
90
- "@deepseek-ai/dsh-tools": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.6-alpha.1",
91
- "@deepseek-ai/dsh-web": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.6-alpha.1",
77
+ "@deepseek-ai/dsh-api-remotes": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
78
+ "@deepseek-ai/dsh-client-connection": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
79
+ "@deepseek-ai/dsh-client-locale": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
80
+ "@deepseek-ai/dsh-client-ui-conversation": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
81
+ "@deepseek-ai/dsh-client-ui-model-selection": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
82
+ "@deepseek-ai/dsh-client-ui-primitives": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
83
+ "@deepseek-ai/dsh-client-ui-settings": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
84
+ "@deepseek-ai/dsh-client-ui-slots": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
85
+ "@deepseek-ai/dsh-client-ui-tool": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
86
+ "@deepseek-ai/dsh-credentials": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
87
+ "@deepseek-ai/dsh-llm": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
88
+ "@deepseek-ai/dsh-llm-pi-ai": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
89
+ "@deepseek-ai/dsh-settings": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
90
+ "@deepseek-ai/dsh-tools": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
91
+ "@deepseek-ai/dsh-web": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
92
92
  "@deepseek-ai/schemastery": "3.18.1 || ^3.18.2",
93
93
  "@earendil-works/pi-ai": "0.82.1 || 0.85.1",
94
94
  "react": "^18.2.0",
@@ -96,23 +96,23 @@
96
96
  },
97
97
  "devDependencies": {
98
98
  "@deepseek-ai/cordis": "4.0.2",
99
- "@deepseek-ai/dsh-api-remotes": "0.1.5-rc.1",
100
- "@deepseek-ai/dsh-client-connection": "0.1.5-rc.1",
101
- "@deepseek-ai/dsh-client-locale": "0.1.5-rc.1",
102
- "@deepseek-ai/dsh-client-ui-conversation": "0.1.5-rc.1",
103
- "@deepseek-ai/dsh-client-ui-model-selection": "0.1.5-rc.1",
104
- "@deepseek-ai/dsh-client-ui-primitives": "0.1.5-rc.1",
105
- "@deepseek-ai/dsh-client-ui-settings": "0.1.5-rc.1",
106
- "@deepseek-ai/dsh-client-ui-slots": "0.1.5-rc.1",
107
- "@deepseek-ai/dsh-client-ui-tool": "0.1.5-rc.1",
108
- "@deepseek-ai/dsh-credentials": "0.1.5-rc.1",
109
- "@deepseek-ai/dsh-invariants": "0.1.5-rc.1",
110
- "@deepseek-ai/dsh-llm": "0.1.5-rc.1",
111
- "@deepseek-ai/dsh-llm-pi-ai": "0.1.5-rc.1",
112
- "@deepseek-ai/dsh-session": "0.1.5-rc.1",
113
- "@deepseek-ai/dsh-settings": "0.1.5-rc.1",
114
- "@deepseek-ai/dsh-tools": "0.1.5-rc.1",
115
- "@deepseek-ai/dsh-web": "0.1.5-rc.1",
99
+ "@deepseek-ai/dsh-api-remotes": "0.1.5-rc.2",
100
+ "@deepseek-ai/dsh-client-connection": "0.1.5-rc.2",
101
+ "@deepseek-ai/dsh-client-locale": "0.1.5-rc.2",
102
+ "@deepseek-ai/dsh-client-ui-conversation": "0.1.5-rc.2",
103
+ "@deepseek-ai/dsh-client-ui-model-selection": "0.1.5-rc.2",
104
+ "@deepseek-ai/dsh-client-ui-primitives": "0.1.5-rc.2",
105
+ "@deepseek-ai/dsh-client-ui-settings": "0.1.5-rc.2",
106
+ "@deepseek-ai/dsh-client-ui-slots": "0.1.5-rc.2",
107
+ "@deepseek-ai/dsh-client-ui-tool": "0.1.5-rc.2",
108
+ "@deepseek-ai/dsh-credentials": "0.1.5-rc.2",
109
+ "@deepseek-ai/dsh-invariants": "0.1.5-rc.2",
110
+ "@deepseek-ai/dsh-llm": "0.1.5-rc.2",
111
+ "@deepseek-ai/dsh-llm-pi-ai": "0.1.5-rc.2",
112
+ "@deepseek-ai/dsh-session": "0.1.5-rc.2",
113
+ "@deepseek-ai/dsh-settings": "0.1.5-rc.2",
114
+ "@deepseek-ai/dsh-tools": "0.1.5-rc.2",
115
+ "@deepseek-ai/dsh-web": "0.1.5-rc.2",
116
116
  "@deepseek-ai/schemastery": "3.18.2",
117
117
  "@earendil-works/pi-ai": "0.82.1",
118
118
  "@heroicons/react": "2.2.0",