dsh-codex-subscription 1.8.0 → 1.9.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 +4 -4
- package/README.md +5 -10
- package/README.zh-CN.md +5 -10
- package/lib/client.js +70 -22
- package/lib/index.js +1 -1
- package/package.json +1 -1
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.
|
|
9
|
+
- Use the exact `1.9.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.
|
|
37
|
+
npx -y @deepseek-ai/dsh@0.1.1-rc.2 plugin --profile web add dsh-codex-subscription@1.9.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.
|
|
43
|
+
dsh plugin --profile web add dsh-codex-subscription@1.9.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.
|
|
61
|
+
1. `dsh-codex-subscription` version `1.9.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.md
CHANGED
|
@@ -48,7 +48,7 @@ DSH-Portable exposes the same standard plugin command, so the command above also
|
|
|
48
48
|
| **Visible quota** | Keep backend-provided standard Codex, Spark, and other limits separate |
|
|
49
49
|
| **Composer quota** | Choose a compact percentage, progress bar, or no inline quota display |
|
|
50
50
|
| **Safe quota reset** | See the next expiry and deliberately try a reset with a cooldown and acknowledgement |
|
|
51
|
-
| **Subscription search** | Explicitly
|
|
51
|
+
| **Subscription search** | Explicitly route search globally through DSH default search or the signed-in Codex subscription |
|
|
52
52
|
| **Codex image generation and editing (Beta)** | Generate without references, or explicitly edit one selected image; preview, zoom, annotate regions, download the original, and continue in the same composer |
|
|
53
53
|
| **Fast mode** | Switch between Standard and Fast directly in the composer |
|
|
54
54
|
| **Model-aware context** | Keep catalog defaults, use each model's supported extended window, or enter a full numeric token limit for each model |
|
|
@@ -58,21 +58,16 @@ These capabilities reuse the same local ChatGPT sign-in. Subscription routing fa
|
|
|
58
58
|
## Product screen
|
|
59
59
|
|
|
60
60
|
<p align="center">
|
|
61
|
-
<img src="https://raw.githubusercontent.com/WSL043/dsh-codex-subscription/main/docs/assets/settings-
|
|
61
|
+
<img src="https://raw.githubusercontent.com/WSL043/dsh-codex-subscription/main/docs/assets/context-settings-en.png" width="820" alt="Current Codex subscription settings in DeepSeek Harness with search, model-aware context, composer quota, and support diagnostics">
|
|
62
62
|
</p>
|
|
63
63
|
|
|
64
|
-
|
|
65
|
-
<summary>View the complete settings screen</summary>
|
|
66
|
-
|
|
67
|
-

|
|
68
|
-
|
|
69
|
-
</details>
|
|
64
|
+
Captured from the installed official DeepSeek Harness `0.1.1-rc.2` product with the current plugin build.
|
|
70
65
|
|
|
71
66
|
## Prepare DSH
|
|
72
67
|
|
|
73
68
|
This plugin is currently compatible through DeepSeek Harness `0.1.1-rc.2` and requires a ChatGPT account that currently has Codex access.
|
|
74
69
|
|
|
75
|
-
- Do not want to configure Node.js? Use [DSH-Portable](https://github.com/WSL043/DSH-Portable), a community desktop distribution
|
|
70
|
+
- Do not want to configure Node.js? Use [DSH-Portable](https://github.com/WSL043/DSH-Portable), a community portable desktop distribution for Windows, macOS, and Linux.
|
|
76
71
|
- Prefer the official route? Follow the [DeepSeek Harness run guide](https://github.com/deepseek-ai/deepseek-harness#run).
|
|
77
72
|
|
|
78
73
|
## Install
|
|
@@ -142,7 +137,7 @@ Restart DSH manually after installation, then:
|
|
|
142
137
|
|
|
143
138
|
- ChatGPT OAuth sign-in with credentials kept on the host;
|
|
144
139
|
- Codex models and Beta image generation/editing directly inside DSH conversations;
|
|
145
|
-
- A clear choice between DSH default search and Codex subscription search;
|
|
140
|
+
- 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;
|
|
146
141
|
- Actual backend-provided quota, reset time, and freshness;
|
|
147
142
|
- Separate standard Codex, Codex-Spark, Credits, and other independent limits;
|
|
148
143
|
- Visible quota-reset count and earliest expiry, with deliberate early redemption, layered confirmation, and no automatic retry;
|
package/README.zh-CN.md
CHANGED
|
@@ -49,7 +49,7 @@ DSH-Portable 也提供相同的标准插件命令,因此同样使用上面的
|
|
|
49
49
|
| **额度可见** | 普通 Codex、Spark 等服务端实际返回的额度分开显示 |
|
|
50
50
|
| **输入框额度** | 可选择紧凑百分比、进度条或完全关闭输入框额度显示 |
|
|
51
51
|
| **安全额度重置** | 直接查看最早到期时间,并通过冷静期和知情确认主动尝试重置 |
|
|
52
|
-
| **订阅搜索** |
|
|
52
|
+
| **订阅搜索** | 可将全部模型的搜索明确路由到 DSH 默认搜索或已登录的 Codex 订阅 |
|
|
53
53
|
| **Codex 图片生成与编辑(Beta)** | 可无参考图全新生成,也可明确选择会话图片继续编辑;支持预览、缩放和下载原图 |
|
|
54
54
|
| **高速模式** | 直接在输入框切换标准或高速,无需离开当前会话 |
|
|
55
55
|
| **模型感知上下文** | 可保留目录默认值、按模型启用扩展窗口,或为每个模型填写完整数字 Token 上限 |
|
|
@@ -59,21 +59,16 @@ DSH-Portable 也提供相同的标准插件命令,因此同样使用上面的
|
|
|
59
59
|
## 实际界面
|
|
60
60
|
|
|
61
61
|
<p align="center">
|
|
62
|
-
<img src="https://raw.githubusercontent.com/WSL043/dsh-codex-subscription/main/docs/assets/settings
|
|
62
|
+
<img src="https://raw.githubusercontent.com/WSL043/dsh-codex-subscription/main/docs/assets/context-settings.png" width="820" alt="当前 DeepSeek Harness Codex 订阅设置,包含搜索来源、模型感知上下文、输入框额度和支持诊断">
|
|
63
63
|
</p>
|
|
64
64
|
|
|
65
|
-
|
|
66
|
-
<summary>查看完整设置界面</summary>
|
|
67
|
-
|
|
68
|
-

|
|
69
|
-
|
|
70
|
-
</details>
|
|
65
|
+
图片来自已安装的官方 DeepSeek Harness `0.1.1-rc.2` 与当前插件构建。
|
|
71
66
|
|
|
72
67
|
## 准备 DSH
|
|
73
68
|
|
|
74
69
|
本插件当前适配到 DeepSeek Harness `0.1.1-rc.2`,并需要一个当前具有 Codex 使用资格的 ChatGPT 账户。
|
|
75
70
|
|
|
76
|
-
- 不想配置 Node.js:使用 [DSH-Portable](https://github.com/WSL043/DSH-Portable)
|
|
71
|
+
- 不想配置 Node.js:使用 [DSH-Portable](https://github.com/WSL043/DSH-Portable)。这是面向 Windows、macOS 和 Linux 的社区便携桌面分发;
|
|
77
72
|
- 想按官方方式运行:查看 [DeepSeek Harness 官方说明](https://github.com/deepseek-ai/deepseek-harness#run)。
|
|
78
73
|
|
|
79
74
|
## 安装
|
|
@@ -142,7 +137,7 @@ dsh --profile web --dump-config
|
|
|
142
137
|
|
|
143
138
|
- ChatGPT OAuth 登录,凭据保留在本机;
|
|
144
139
|
- Codex 模型和 Beta 图片生成与编辑直接出现在 DSH 会话中;
|
|
145
|
-
- DSH 默认搜索与 Codex
|
|
140
|
+
- 搜索来源是全局设置,可在 DSH 默认搜索与 Codex 订阅搜索之间切换;它对所有模型和会话生效,不会随当前模型自动切换;
|
|
146
141
|
- 设置页显示服务端返回的额度、重置时间和更新时间;
|
|
147
142
|
- 普通 Codex、Codex-Spark、Credits 等独立额度分开显示;
|
|
148
143
|
- 显示重置卡数量与最早到期时间,也允许在额度未完全用尽时主动尝试,并经过分层确认且不会自动重试;
|
package/lib/client.js
CHANGED
|
@@ -49,6 +49,17 @@ window.__ModuleLoader__.load({
|
|
|
49
49
|
}
|
|
50
50
|
const ForwardRef = /*#__PURE__*/ react.forwardRef(BoltIcon);
|
|
51
51
|
//#endregion
|
|
52
|
+
//#region src/image-edit.js
|
|
53
|
+
function buildImageEditDraft({ prompt = "", annotations = [], translate }) {
|
|
54
|
+
if (typeof translate !== "function") throw new TypeError("translate must be a function");
|
|
55
|
+
const notes = annotations.map((annotation, index) => ({
|
|
56
|
+
number: index + 1,
|
|
57
|
+
note: typeof annotation?.note === "string" ? annotation.note.trim() : ""
|
|
58
|
+
})).filter((annotation) => annotation.note !== "").map((annotation) => String(annotation.number) + ". " + annotation.note);
|
|
59
|
+
const base = prompt.trim() === "" ? translate("imageEditDefault") : prompt.trim();
|
|
60
|
+
return notes.length === 0 ? base : base + "\n\n" + translate("imageRegionNotes") + "\n" + notes.join("\n");
|
|
61
|
+
}
|
|
62
|
+
//#endregion
|
|
52
63
|
//#region src/settings-contract.js
|
|
53
64
|
const SETTINGS_NAMESPACE = "codex-subscription";
|
|
54
65
|
const QUICK_QUOTA_MODE_FIELD = "quickQuotaMode";
|
|
@@ -212,10 +223,11 @@ window.__ModuleLoader__.load({
|
|
|
212
223
|
diagnosticsFailed: "无法生成诊断信息。",
|
|
213
224
|
feedbackOpen: "反馈问题",
|
|
214
225
|
searchTitle: "搜索来源",
|
|
226
|
+
searchScope: "此设置对所有模型和会话生效,不会随当前模型自动切换。",
|
|
215
227
|
searchDsh: "DSH 默认",
|
|
216
|
-
searchDshHint: "当前搜索服务",
|
|
228
|
+
searchDshHint: "所有模型使用 DSH 当前搜索服务",
|
|
217
229
|
searchCodex: "Codex 订阅",
|
|
218
|
-
searchCodexHint: "ChatGPT 订阅搜索",
|
|
230
|
+
searchCodexHint: "所有模型通过已登录的 ChatGPT 订阅搜索",
|
|
219
231
|
preferenceFailed: "设置未保存。",
|
|
220
232
|
preferenceRetry: "重试",
|
|
221
233
|
usage: "订阅额度",
|
|
@@ -354,10 +366,11 @@ window.__ModuleLoader__.load({
|
|
|
354
366
|
diagnosticsFailed: "Could not create diagnostics.",
|
|
355
367
|
feedbackOpen: "Report a problem",
|
|
356
368
|
searchTitle: "Search source",
|
|
369
|
+
searchScope: "Applies to every model and session; it does not switch with the selected model.",
|
|
357
370
|
searchDsh: "DSH default",
|
|
358
|
-
searchDshHint: "
|
|
371
|
+
searchDshHint: "Use DSH's current search service for every model",
|
|
359
372
|
searchCodex: "Codex subscription",
|
|
360
|
-
searchCodexHint: "ChatGPT subscription
|
|
373
|
+
searchCodexHint: "Search through the signed-in ChatGPT subscription for every model",
|
|
361
374
|
preferenceFailed: "The setting was not saved.",
|
|
362
375
|
preferenceRetry: "Retry",
|
|
363
376
|
usage: "Subscription quota",
|
|
@@ -471,6 +484,7 @@ window.__ModuleLoader__.load({
|
|
|
471
484
|
imageRemoveAnnotation: "Remove note"
|
|
472
485
|
};
|
|
473
486
|
const STYLE = `
|
|
487
|
+
.codexSubscriptionSearchHead{display:flex;flex-direction:column;gap:1px}.codexSubscriptionSearchScope{font-size:11px;line-height:17px;color:var(--dsw-alias-label-tertiary)}
|
|
474
488
|
.codexSubscription{display:flex;flex-direction:column;gap:10px;max-width:720px;color:var(--dsw-alias-label-primary);container-type:inline-size}
|
|
475
489
|
.codexSubscription h2,.codexSubscription h3,.codexSubscription p{margin:0}.codexSubscriptionHead{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
|
|
476
490
|
.codexSubscription h2{font-size:16px;line-height:24px;font-weight:500}.codexSubscription h3{font-size:14px;line-height:22px;font-weight:500}
|
|
@@ -552,15 +566,7 @@ window.__ModuleLoader__.load({
|
|
|
552
566
|
return cleaned.toLowerCase().endsWith(".png") ? cleaned : `${cleaned}.png`;
|
|
553
567
|
};
|
|
554
568
|
const imageByteSize = (bytes) => bytes < 1024 * 1024 ? `${Math.max(.1, bytes / 1024).toLocaleString(void 0, { maximumFractionDigits: 1 })} KB` : `${(bytes / 1024 / 1024).toLocaleString(void 0, { maximumFractionDigits: 1 })} MB`;
|
|
555
|
-
function
|
|
556
|
-
const notes = annotations.map((annotation, index) => ({
|
|
557
|
-
number: index + 1,
|
|
558
|
-
note: annotation.note.trim()
|
|
559
|
-
})).filter((annotation) => annotation.note !== "").map((annotation) => String(annotation.number) + ". " + annotation.note);
|
|
560
|
-
const base = prompt.trim() === "" ? t("imageEditDefault") : prompt.trim();
|
|
561
|
-
return notes.length === 0 ? base : base + "\n\n" + t("imageRegionNotes") + "\n" + notes.join("\n");
|
|
562
|
-
}
|
|
563
|
-
function CodexGeneratedImage({ attachment, loadImage, attachForEdit, t }) {
|
|
569
|
+
function CodexGeneratedImage({ attachment, loadImage, attachForEdit, getImageViewer, t }) {
|
|
564
570
|
const [attempt, setAttempt] = (0, react.useState)(0);
|
|
565
571
|
const [error, setError] = (0, react.useState)(false);
|
|
566
572
|
const [open, setOpen] = (0, react.useState)(false);
|
|
@@ -646,7 +652,11 @@ window.__ModuleLoader__.load({
|
|
|
646
652
|
setEditBusy(true);
|
|
647
653
|
setEditError(false);
|
|
648
654
|
try {
|
|
649
|
-
await attachForEdit(src, downloadName,
|
|
655
|
+
await attachForEdit(src, downloadName, buildImageEditDraft({
|
|
656
|
+
prompt,
|
|
657
|
+
annotations,
|
|
658
|
+
translate: t
|
|
659
|
+
}));
|
|
650
660
|
close();
|
|
651
661
|
} catch {
|
|
652
662
|
setEditError(true);
|
|
@@ -654,6 +664,35 @@ window.__ModuleLoader__.load({
|
|
|
654
664
|
setEditBusy(false);
|
|
655
665
|
}
|
|
656
666
|
};
|
|
667
|
+
const openImage = () => {
|
|
668
|
+
if (src === void 0) return;
|
|
669
|
+
if ((getImageViewer?.())?.open?.({
|
|
670
|
+
items: [{
|
|
671
|
+
id: attachment.attachmentId ?? downloadName,
|
|
672
|
+
src,
|
|
673
|
+
name: label,
|
|
674
|
+
width: attachment.width,
|
|
675
|
+
height: attachment.height,
|
|
676
|
+
bytes: attachment.bytes
|
|
677
|
+
}],
|
|
678
|
+
opener: triggerRef.current,
|
|
679
|
+
source: "codex-generated",
|
|
680
|
+
annotations: true,
|
|
681
|
+
editor: {
|
|
682
|
+
label: t("imageEdit"),
|
|
683
|
+
busyLabel: t("imageEditPreparing"),
|
|
684
|
+
errorLabel: t("imageEditFailed"),
|
|
685
|
+
placeholder: t("imageEditPrompt"),
|
|
686
|
+
onSubmit: ({ prompt: nextPrompt, annotations: nextAnnotations }) => attachForEdit(src, downloadName, buildImageEditDraft({
|
|
687
|
+
prompt: nextPrompt,
|
|
688
|
+
annotations: nextAnnotations,
|
|
689
|
+
translate: t
|
|
690
|
+
}))
|
|
691
|
+
}
|
|
692
|
+
}) === true) return;
|
|
693
|
+
setZoom(1);
|
|
694
|
+
setOpen(true);
|
|
695
|
+
};
|
|
657
696
|
if (error) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
658
697
|
type: "button",
|
|
659
698
|
className: "codexGeneratedImageRetry",
|
|
@@ -819,19 +858,14 @@ window.__ModuleLoader__.load({
|
|
|
819
858
|
className: "codexGeneratedImageFrame",
|
|
820
859
|
title: t("imageOpen"),
|
|
821
860
|
"aria-label": fill(t("imageOpenNamed"), { value: label }),
|
|
822
|
-
onClick:
|
|
823
|
-
if (src !== void 0) {
|
|
824
|
-
setZoom(1);
|
|
825
|
-
setOpen(true);
|
|
826
|
-
}
|
|
827
|
-
},
|
|
861
|
+
onClick: openImage,
|
|
828
862
|
children: src === void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("imageLoading") }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
|
|
829
863
|
src,
|
|
830
864
|
alt: label
|
|
831
865
|
})
|
|
832
866
|
}), lightbox] });
|
|
833
867
|
}
|
|
834
|
-
function CodexImageToolRow({ block, loadImage, attachForEdit, t }) {
|
|
868
|
+
function CodexImageToolRow({ block, loadImage, attachForEdit, getImageViewer, t }) {
|
|
835
869
|
const settled = block?.kind === "tool-result";
|
|
836
870
|
const image = settled ? block.content.find((item) => item?.type === "image" && item.attachment !== void 0) : void 0;
|
|
837
871
|
const failed = settled && block.isError === true;
|
|
@@ -869,6 +903,7 @@ window.__ModuleLoader__.load({
|
|
|
869
903
|
attachment: image.attachment,
|
|
870
904
|
loadImage,
|
|
871
905
|
attachForEdit,
|
|
906
|
+
getImageViewer,
|
|
872
907
|
t
|
|
873
908
|
})
|
|
874
909
|
}),
|
|
@@ -1100,7 +1135,13 @@ window.__ModuleLoader__.load({
|
|
|
1100
1135
|
});
|
|
1101
1136
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1102
1137
|
className: "codexSubscriptionSearch",
|
|
1103
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.
|
|
1138
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1139
|
+
className: "codexSubscriptionSearchHead",
|
|
1140
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", { children: t("searchTitle") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1141
|
+
className: "codexSubscriptionSearchScope",
|
|
1142
|
+
children: t("searchScope")
|
|
1143
|
+
})]
|
|
1144
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1104
1145
|
className: "codexSubscriptionSearchChoices",
|
|
1105
1146
|
role: "radiogroup",
|
|
1106
1147
|
"aria-label": t("searchTitle"),
|
|
@@ -2337,6 +2378,13 @@ window.__ModuleLoader__.load({
|
|
|
2337
2378
|
inject: (sessionId) => ({
|
|
2338
2379
|
t,
|
|
2339
2380
|
loadImage: (attachment) => conversation.resolveImage(sessionId, attachment),
|
|
2381
|
+
getImageViewer: () => {
|
|
2382
|
+
try {
|
|
2383
|
+
return ctx.get("nativeImageViewer");
|
|
2384
|
+
} catch {
|
|
2385
|
+
return;
|
|
2386
|
+
}
|
|
2387
|
+
},
|
|
2340
2388
|
attachForEdit: async (src, filename, draft) => {
|
|
2341
2389
|
const actx = sessions.scope(sessionId);
|
|
2342
2390
|
if (actx === void 0 || typeof conversation.createDraftImages !== "function" || conversation.input?.for === void 0) throw new Error("This DSH version does not provide the image composer bridge");
|
package/lib/index.js
CHANGED
|
@@ -902,7 +902,7 @@ function openaiCodexSubscriptionProvider({ resolveSpeedMode = () => void 0, reso
|
|
|
902
902
|
}
|
|
903
903
|
//#endregion
|
|
904
904
|
//#region src/version.js
|
|
905
|
-
const PACKAGE_VERSION = "1.
|
|
905
|
+
const PACKAGE_VERSION = "1.9.0";
|
|
906
906
|
const USER_AGENT = `dsh-codex-subscription/${PACKAGE_VERSION}`;
|
|
907
907
|
//#endregion
|
|
908
908
|
//#region src/codex-search.js
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-codex-subscription",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.9.0",
|
|
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",
|