dsh-codex-subscription 1.6.0 → 1.7.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 +8 -4
- package/README.zh-CN.md +7 -3
- package/lib/client.js +283 -80
- package/lib/index.js +1 -1
- package/package.json +5 -4
- package/docs/assets/composer-quota-en.png +0 -0
- package/docs/assets/settings-en.png +0 -0
- package/docs/assets/settings-focus-en.png +0 -0
- package/docs/assets/settings-focus.png +0 -0
- package/docs/assets/settings.png +0 -0
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.7.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.7.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.7.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.7.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
|
@@ -49,7 +49,7 @@ DSH-Portable exposes the same standard plugin command, so the command above also
|
|
|
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
51
|
| **Subscription search** | Explicitly choose DSH default search or Codex subscription search |
|
|
52
|
-
| **Codex image generation and editing (Beta)** | Generate without references, or explicitly edit selected
|
|
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
|
|
|
55
55
|
These capabilities reuse the same local ChatGPT sign-in. Subscription routing failures stay visible and never silently switch to another paid route.
|
|
@@ -169,11 +169,15 @@ clicks are single-flight, and an uncertain network result is never retried autom
|
|
|
169
169
|
|
|
170
170
|
### Image generation and editing (Beta)
|
|
171
171
|
|
|
172
|
-
Generated images open in a DSH-native preview with zoom, fit, dimensions,
|
|
173
|
-
|
|
174
|
-
|
|
172
|
+
Generated images open in a DSH-native preview with zoom, fit, dimensions, **Download original**, and numbered region notes.
|
|
173
|
+
**Continue editing in composer** attaches exactly the image you opened and writes the region notes into the draft without
|
|
174
|
+
sending it. A new image request does not silently include earlier images. GPT Image 2 can take longer than a normal text
|
|
175
175
|
turn, and detailed text, exact composition, or repeated-character consistency may still need another pass.
|
|
176
176
|
|
|
177
|
+
<p align="center">
|
|
178
|
+
<img src="https://raw.githubusercontent.com/WSL043/dsh-codex-subscription/main/docs/assets/image-preview-annotations-en.png" width="900" alt="DSH-native generated-image preview with zoom, original download, and numbered region annotations">
|
|
179
|
+
</p>
|
|
180
|
+
|
|
177
181
|
### Composer speed
|
|
178
182
|
|
|
179
183
|
With a supported Codex model selected, open the composer's model menu to choose Standard or Fast.
|
package/README.zh-CN.md
CHANGED
|
@@ -166,9 +166,13 @@ ChatGPT 返回可用重置卡时,设置页会用紧凑的一行显示数量和
|
|
|
166
166
|
|
|
167
167
|
### 图片生成与编辑(Beta)
|
|
168
168
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
169
|
+
生成图片会在 DSH 原生查看器中打开,可缩放、适合窗口、查看尺寸、下载原图,并对具体部位添加编号标注。
|
|
170
|
+
点击“在输入框中继续编辑”时,只会附上当前打开的这一张图,并把部位标注写入草稿,不会自动发送。
|
|
171
|
+
新的图片请求不会静默带入历史图片。GPT Image 2 的耗时可能明显长于文本回复,复杂文字、精确构图和连续角色一致性也可能需要再次调整。
|
|
172
|
+
|
|
173
|
+
<p align="center">
|
|
174
|
+
<img src="https://raw.githubusercontent.com/WSL043/dsh-codex-subscription/main/docs/assets/image-preview-annotations.png" width="900" alt="DSH 原生图片预览中的缩放、原图下载与编号部位标注">
|
|
175
|
+
</p>
|
|
172
176
|
|
|
173
177
|
### 输入框速度
|
|
174
178
|
|
package/lib/client.js
CHANGED
|
@@ -28,6 +28,7 @@ window.__ModuleLoader__.load({
|
|
|
28
28
|
//#endregion
|
|
29
29
|
let react = require("react");
|
|
30
30
|
react = __toESM(react, 1);
|
|
31
|
+
let react_dom = require("react-dom");
|
|
31
32
|
let _deepseek_ai_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
32
33
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
33
34
|
//#region node_modules/.pnpm/@heroicons+react@2.2.0_react@18.3.1/node_modules/@heroicons/react/16/solid/esm/BoltIcon.js
|
|
@@ -250,8 +251,17 @@ window.__ModuleLoader__.load({
|
|
|
250
251
|
imageZoomOut: "缩小",
|
|
251
252
|
imageZoomIn: "放大",
|
|
252
253
|
imageFit: "适合窗口",
|
|
253
|
-
|
|
254
|
-
|
|
254
|
+
imageAnnotate: "标注部位",
|
|
255
|
+
imageAnnotateHint: "点击图片添加编号标注",
|
|
256
|
+
imageAnnotation: "标注 {value}",
|
|
257
|
+
imageAnnotationPlaceholder: "描述这个部位要修改什么",
|
|
258
|
+
imageEditPrompt: "描述你想怎样修改这张图",
|
|
259
|
+
imageEditDefault: "编辑这张图片。",
|
|
260
|
+
imageRegionNotes: "部位修改:",
|
|
261
|
+
imageEdit: "在输入框中继续编辑",
|
|
262
|
+
imageEditPreparing: "正在添加到输入框…",
|
|
263
|
+
imageEditFailed: "无法把图片添加到输入框。",
|
|
264
|
+
imageRemoveAnnotation: "删除标注"
|
|
255
265
|
};
|
|
256
266
|
const en = {
|
|
257
267
|
nav: "Codex",
|
|
@@ -373,8 +383,17 @@ window.__ModuleLoader__.load({
|
|
|
373
383
|
imageZoomOut: "Zoom out",
|
|
374
384
|
imageZoomIn: "Zoom in",
|
|
375
385
|
imageFit: "Fit to window",
|
|
376
|
-
|
|
377
|
-
|
|
386
|
+
imageAnnotate: "Annotate",
|
|
387
|
+
imageAnnotateHint: "Click the image to add a numbered note",
|
|
388
|
+
imageAnnotation: "Note {value}",
|
|
389
|
+
imageAnnotationPlaceholder: "Describe what should change in this area",
|
|
390
|
+
imageEditPrompt: "Describe how you want to change this image",
|
|
391
|
+
imageEditDefault: "Edit this image.",
|
|
392
|
+
imageRegionNotes: "Region changes:",
|
|
393
|
+
imageEdit: "Continue editing in composer",
|
|
394
|
+
imageEditPreparing: "Adding to composer…",
|
|
395
|
+
imageEditFailed: "Could not add the image to the composer.",
|
|
396
|
+
imageRemoveAnnotation: "Remove note"
|
|
378
397
|
};
|
|
379
398
|
const STYLE = `
|
|
380
399
|
.codexSubscription{display:flex;flex-direction:column;gap:10px;max-width:720px;color:var(--dsw-alias-label-primary);container-type:inline-size}
|
|
@@ -409,11 +428,24 @@ window.__ModuleLoader__.load({
|
|
|
409
428
|
.codexModelSelect{position:relative;min-width:0}.codexModelSelectTrigger{display:flex;align-items:center;gap:4px;min-width:0;max-width:min(360px,45cqw);height:28px;padding:0 4px 0 8px;border:0;border-radius:24px;outline:0;background:transparent;color:var(--dsw-alias-label-secondary);font-size:13px;font-weight:500;line-height:20px;cursor:pointer}.codexModelSelectTrigger:hover:not(:disabled),.codexModelSelectTrigger[aria-expanded=true]{background:var(--dsw-alias-interactive-bg-hover)}.codexModelSelectTrigger:focus-visible{box-shadow:0 0 0 2px var(--dsw-alias-border-l3)}.codexModelSelectTrigger:disabled{color:var(--dsw-alias-label-dimmed);cursor:default}.codexModelSelectBolt{display:block;flex:none;width:14px;height:14px;color:var(--dsw-alias-label-primary)}.codexModelSelectLabel{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.codexModelSelectEffort{flex:none;color:var(--dsw-alias-label-caption)}.codexModelSelectChevron{flex:none;color:var(--dsw-alias-label-caption);transition:transform 120ms}.codexModelSelectTrigger[aria-expanded=true] .codexModelSelectChevron{transform:rotate(180deg)}
|
|
410
429
|
.codexModelSelectMenu,.codexModelSelectSubmenu{position:absolute;z-index:30;box-sizing:border-box;width:max-content;min-width:min(240px,calc(100vw - 32px));max-width:min(420px,calc(100vw - 32px));max-height:min(360px,calc(100vh - 96px));padding:4px;border:1px solid var(--dsw-alias-border-inverted);border-radius:12px;background:var(--dsw-specific-menu);box-shadow:var(--dsw-shadow-lv3);color:var(--dsw-alias-label-primary);overflow:hidden}.codexModelSelectMenu{right:0;bottom:calc(100% + 8px)}.codexModelSelectSubmenu{right:calc(100% + 8px);bottom:0;min-width:min(230px,calc(100vw - 32px))}.codexModelSelectCell{display:flex;align-items:center;gap:8px;width:100%;min-width:100%;height:40px;box-sizing:border-box;padding:0 10px;border:0;border-radius:10px;background:transparent;color:inherit;font-size:14px;line-height:22px;text-align:left;cursor:pointer}.codexModelSelectCell:hover,.codexModelSelectCell:focus-visible,.codexModelSelectCell[data-open=true]{background:var(--dsw-alias-interactive-bg-hover);outline:0}.codexModelSelectCell:disabled{color:var(--dsw-alias-label-dimmed);cursor:default}.codexModelSelectCellLabel{flex:none;white-space:nowrap}.codexModelSelectCellValue{flex:auto;min-width:0;overflow:hidden;color:var(--dsw-alias-label-tertiary);text-align:right;text-overflow:ellipsis;white-space:nowrap}.codexModelSelectCellChevron{flex:none;color:var(--dsw-alias-label-tertiary)}.codexModelSelectGroups{min-height:0;max-height:352px;overflow-y:auto}.codexModelSelectGroup+.codexModelSelectGroup{margin-top:4px}.codexModelSelectGroupTitle{position:sticky;top:0;z-index:1;padding:5px 8px 3px;background:var(--dsw-specific-menu);color:var(--dsw-alias-label-tertiary);font-size:12px;font-weight:500;line-height:18px}.codexModelSelectOption{display:flex;align-items:center;gap:8px;width:100%;min-width:100%;min-height:38px;box-sizing:border-box;padding:6px 8px;border:0;border-radius:10px;outline:0;background:transparent;color:inherit;text-align:left;cursor:pointer}.codexModelSelectOption:hover:not(:disabled),.codexModelSelectOption:focus-visible{background:var(--dsw-alias-interactive-bg-hover)}.codexModelSelectOption:disabled{color:var(--dsw-alias-label-dimmed);cursor:default}.codexModelSelectOptionCopy{display:flex;flex:1;min-width:0;flex-direction:column}.codexModelSelectOptionName{overflow:hidden;color:inherit;font-size:14px;font-weight:500;line-height:20px;text-overflow:ellipsis;white-space:nowrap}.codexModelSelectOptionDescription{overflow:hidden;color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px;text-overflow:ellipsis;white-space:nowrap}.codexModelSelectCheck{display:grid;place-items:center;flex:0 0 18px;color:var(--dsw-alias-label-primary)}.codexModelSelectStatus,.codexModelSelectEmpty{padding:10px;color:var(--dsw-alias-label-tertiary);font-size:13px;line-height:20px}.codexModelSelectError,.codexModelSelectWarning{display:flex;align-items:flex-start;justify-content:space-between;gap:8px;margin-bottom:4px;padding:7px 8px;border-radius:8px;background:var(--dsw-alias-interactive-bg-hover-danger);color:var(--dsw-alias-state-error-primary);font-size:12px;line-height:18px}.codexModelSelectWarning{background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-state-warn-label)}.codexModelSelectRetry{flex:none;padding:0;border:0;background:transparent;color:inherit;font:inherit;font-weight:600;cursor:pointer}
|
|
411
430
|
.codexModelSelectMenu{overflow:visible}
|
|
412
|
-
.codexImageTool{display:flex;flex-direction:column;gap:8px;margin:4px 0;color:var(--dsw-alias-label-primary)}.codexImageToolRow{display:flex;align-items:center;min-height:24px;gap:8px;font-size:13px;line-height:20px}.codexImageToolIcon{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;color:var(--dsw-alias-label-secondary)}.codexImageToolIcon::before{content:'';width:8px;height:8px;border:1.5px solid currentColor;border-radius:3px}.codexImageTool[data-state=running] .codexImageToolIcon::before{border-radius:50%;border-right-color:transparent;animation:codexImageSpin 800ms linear infinite}.codexImageTool[data-state=error] .codexImageToolIcon::before{border-color:var(--dsw-alias-state-error-primary);background:var(--dsw-alias-state-error-primary)}.codexImageToolTitle{font-weight:500}.codexImageToolState{color:var(--dsw-alias-label-tertiary)}.codexImageToolError{margin:0 0 0 24px;font-size:12px;line-height:18px;color:var(--dsw-alias-state-error-primary)}.codexImageToolGallery{margin-left:24px}.codexGeneratedImageFrame{display:flex;align-items:center;justify-content:center;width:min(240px,100%);
|
|
431
|
+
.codexImageTool{display:flex;flex-direction:column;gap:8px;margin:4px 0;color:var(--dsw-alias-label-primary)}.codexImageToolRow{display:flex;align-items:center;min-height:24px;gap:8px;font-size:13px;line-height:20px}.codexImageToolIcon{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;color:var(--dsw-alias-label-secondary)}.codexImageToolIcon::before{content:'';width:8px;height:8px;border:1.5px solid currentColor;border-radius:3px}.codexImageTool[data-state=running] .codexImageToolIcon::before{border-radius:50%;border-right-color:transparent;animation:codexImageSpin 800ms linear infinite}.codexImageTool[data-state=error] .codexImageToolIcon::before{border-color:var(--dsw-alias-state-error-primary);background:var(--dsw-alias-state-error-primary)}.codexImageToolTitle{font-weight:500}.codexImageToolState{color:var(--dsw-alias-label-tertiary)}.codexImageToolError{margin:0 0 0 24px;font-size:12px;line-height:18px;color:var(--dsw-alias-state-error-primary)}.codexImageToolGallery{margin-left:24px}.codexGeneratedImageFrame{display:flex;align-items:center;justify-content:center;width:min(240px,100%);height:240px;padding:0;overflow:hidden;border:1px solid var(--dsw-alias-border-l2);border-radius:16px;background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-tertiary);cursor:pointer}.codexGeneratedImageFrame img{display:block;width:100%;height:100%;object-fit:cover}.codexGeneratedImageRetry{min-height:36px;padding:0 12px;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-secondary);cursor:pointer}.codexGeneratedImageModal{width:min(920px,calc(100vw - 32px));max-height:calc(100vh - 32px)}.codexGeneratedImageModalContent{min-height:0;overflow:hidden}.codexGeneratedImageViewer{display:flex;min-width:0;flex-direction:column;gap:12px}.codexGeneratedImageStage{display:grid;place-items:center;min-height:280px;max-height:calc(100vh - 260px);overflow:auto;border:1px solid var(--dsw-alias-border-l2);border-radius:12px;background:var(--dsw-alias-bg-module-platform)}.codexGeneratedImageStage img{display:block;max-width:100%;max-height:calc(100vh - 280px);object-fit:contain;transform-origin:center;transition:transform 120ms ease}.codexGeneratedImageMeta{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px}.codexGeneratedImageToolbar{display:flex;align-items:center;justify-content:space-between;gap:10px;flex-wrap:wrap}.codexGeneratedImageZoom{display:flex;align-items:center;gap:6px}.codexGeneratedImageZoomValue{min-width:44px;color:var(--dsw-alias-label-secondary);font-size:12px;text-align:center}.codexGeneratedImageDownload{display:inline-flex;align-items:center;gap:6px;min-height:32px;box-sizing:border-box;padding:0 12px;border:1px solid var(--dsw-alias-border-l2);border-radius:999px;background:transparent;color:var(--dsw-alias-label-primary);font-size:13px;text-decoration:none}.codexGeneratedImageDownload:hover{background:var(--dsw-alias-interactive-bg-hover)}.codexGeneratedImageGuidance{display:flex;flex-direction:column;gap:2px;padding-top:2px;color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px}@keyframes codexImageSpin{to{transform:rotate(360deg)}}
|
|
413
432
|
.codexImageBeta{padding:0 5px;border:1px solid var(--dsw-alias-border-l2);border-radius:999px;color:var(--dsw-alias-label-tertiary);font-size:10px;line-height:16px}
|
|
414
433
|
@container (max-width:560px){.codexSubscriptionCreditRows{grid-template-columns:1fr}}
|
|
415
434
|
@container (max-width:480px){.codexSubscriptionAccountRow,.codexSubscriptionSectionHead{align-items:flex-start;flex-direction:column}.codexSubscriptionActions{width:100%}.codexSubscriptionSearchChoices{grid-template-columns:1fr}}
|
|
416
435
|
@media(max-width:640px){.codexSubscriptionCard{padding:14px}}
|
|
436
|
+
`;
|
|
437
|
+
const IMAGE_STYLE = String.raw`
|
|
438
|
+
.codexGeneratedImageLightbox{position:fixed;inset:0;z-index:1000;display:grid;grid-template-rows:auto minmax(0,1fr) auto;background:var(--dsw-alias-bg-base,#111);color:var(--dsw-alias-label-primary);outline:0}.codexGeneratedImageTopbar{display:flex;align-items:center;justify-content:space-between;gap:20px;min-height:58px;padding:8px 14px;border-bottom:1px solid var(--dsw-alias-border-l2);background:color-mix(in srgb,var(--dsw-alias-bg-base,#111) 92%,transparent);backdrop-filter:blur(18px)}.codexGeneratedImageTopbar>div:first-child{display:flex;min-width:0;flex-direction:column}.codexGeneratedImageTopbar strong{overflow:hidden;font-size:13px;font-weight:600;line-height:20px;text-overflow:ellipsis;white-space:nowrap}.codexGeneratedImageTopbar small{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:17px}.codexGeneratedImageActions{display:flex;align-items:center;gap:6px}.codexGeneratedImageActions button,.codexGeneratedImageActions a{box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center;gap:5px;height:32px;padding:0 10px;border:1px solid transparent;border-radius:16px;background:transparent;color:var(--dsw-alias-label-primary);font:inherit;font-size:12px;text-decoration:none;cursor:pointer}.codexGeneratedImageActions button:hover,.codexGeneratedImageActions a:hover,.codexGeneratedImageActions button.is-active{background:var(--dsw-alias-interactive-bg-hover)}.codexGeneratedImageActions button:focus-visible,.codexGeneratedImageActions a:focus-visible{outline:2px solid var(--dsw-alias-border-l3);outline-offset:1px}.codexGeneratedImageActions button:disabled{opacity:.4;cursor:default}.codexGeneratedImageActions>span{min-width:38px;color:var(--dsw-alias-label-tertiary);font-size:11px;text-align:center}.codexGeneratedImageClose{font-size:20px!important}.codexGeneratedImageCanvas{position:relative;display:grid;place-items:center;min-height:0;overflow:auto;padding:24px;background:var(--dsw-alias-bg-base,#111)}.codexGeneratedImageSurface{position:relative;display:inline-flex;max-width:calc(100vw - 48px);max-height:calc(100vh - 210px);transform-origin:center;transition:transform 120ms ease}.codexGeneratedImageSurface img{display:block;max-width:100%;max-height:calc(100vh - 210px);border-radius:12px;object-fit:contain}.codexGeneratedImageCanvas.is-annotating .codexGeneratedImageSurface{cursor:crosshair}.codexGeneratedImagePin{position:absolute;display:grid;place-items:center;width:24px;height:24px;padding:0;border:2px solid white;border-radius:50%;background:var(--dsw-alias-label-primary);box-shadow:0 1px 4px rgba(0,0,0,.35);color:var(--dsw-alias-bg-base,#111);font:inherit;font-size:11px;font-weight:700;transform:translate(-50%,-50%);cursor:pointer}.codexGeneratedImagePin.is-active{background:var(--dsw-alias-state-business-primary,#3964fe);color:white}.codexGeneratedImageAnnotateHint{position:absolute;bottom:14px;left:50%;padding:6px 10px;border-radius:14px;background:color-mix(in srgb,var(--dsw-alias-bg-layer-3) 90%,transparent);box-shadow:var(--dsw-shadow-lv2);color:var(--dsw-alias-label-secondary);font-size:11px;transform:translateX(-50%)}.codexGeneratedImageEditDock{display:flex;flex-direction:column;gap:8px;padding:10px 14px 14px;border-top:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2,var(--dsw-alias-bg-base))}.codexGeneratedImagePrompt,.codexGeneratedImageAnnotation{display:flex;align-items:center;gap:8px;width:min(820px,100%);margin:0 auto}.codexGeneratedImagePrompt>*:first-child,.codexGeneratedImageAnnotation>*:nth-child(2){min-width:0;flex:1}.codexGeneratedImagePrompt button{flex:none;white-space:nowrap}.codexGeneratedImageAnnotation>span{flex:none;color:var(--dsw-alias-label-secondary);font-size:12px}.codexGeneratedImageAnnotation>button{flex:none;height:28px;padding:0 8px;border:0;border-radius:14px;background:transparent;color:var(--dsw-alias-label-tertiary);font:inherit;font-size:11px;cursor:pointer}.codexGeneratedImageAnnotation>button:hover{background:var(--dsw-alias-interactive-bg-hover)}.codexGeneratedImageEditError{width:min(820px,100%);margin:0 auto;color:var(--dsw-alias-state-error-primary);font-size:11px;line-height:17px}@media(max-width:760px){.codexGeneratedImageTopbar{align-items:flex-start;flex-direction:column}.codexGeneratedImageActions{width:100%;overflow-x:auto}.codexGeneratedImageActions>span{display:none}.codexGeneratedImageCanvas{padding:12px}.codexGeneratedImageSurface{max-width:calc(100vw - 24px);max-height:calc(100vh - 270px)}.codexGeneratedImageSurface img{max-height:calc(100vh - 270px)}.codexGeneratedImagePrompt,.codexGeneratedImageAnnotation{align-items:stretch;flex-direction:column}.codexGeneratedImagePrompt button{width:100%}}
|
|
439
|
+
`;
|
|
440
|
+
const IMAGE_LAYOUT_STYLE = String.raw`
|
|
441
|
+
.codexGeneratedImageWorkspace{display:grid;min-height:0;grid-template-columns:minmax(0,1fr)}
|
|
442
|
+
.codexGeneratedImageWorkspace.has-comments{grid-template-columns:minmax(0,1fr) 296px}
|
|
443
|
+
.codexGeneratedImageComments{display:flex;min-width:0;flex-direction:column;gap:12px;overflow:auto;padding:18px 14px;border-left:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2,var(--dsw-alias-bg-base))}
|
|
444
|
+
.codexGeneratedImageComments>header{display:flex;flex-direction:column;gap:2px}.codexGeneratedImageComments>header strong{font-size:13px;font-weight:600;line-height:20px}.codexGeneratedImageComments>header small{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:17px}
|
|
445
|
+
.codexGeneratedImageCommentList{display:flex;flex-direction:column;gap:8px}.codexGeneratedImageCommentList article{display:grid;grid-template-columns:24px minmax(0,1fr) 24px;align-items:start;gap:7px;padding:9px;border:1px solid var(--dsw-alias-border-l2);border-radius:12px;background:var(--dsw-alias-bg-layer-3)}.codexGeneratedImageCommentList article.is-active{border-color:var(--dsw-alias-state-business-primary,#3964fe)}
|
|
446
|
+
.codexGeneratedImageCommentList article>span{display:grid;place-items:center;width:22px;height:22px;border-radius:50%;background:var(--dsw-alias-label-primary);color:var(--dsw-alias-bg-base,#111);font-size:10px;font-weight:700}.codexGeneratedImageCommentList textarea{box-sizing:border-box;width:100%;min-height:64px;resize:vertical;border:0;outline:0;background:transparent;color:var(--dsw-alias-label-primary);font:inherit;font-size:12px;line-height:18px}.codexGeneratedImageCommentList textarea::placeholder{color:var(--dsw-alias-label-dimmed)}
|
|
447
|
+
.codexGeneratedImageCommentList article>button{display:grid;place-items:center;width:22px;height:22px;padding:0;border:0;border-radius:50%;background:transparent;color:var(--dsw-alias-label-tertiary);font:inherit;font-size:17px;cursor:pointer}.codexGeneratedImageCommentList article>button:hover{background:var(--dsw-alias-interactive-bg-hover)}
|
|
448
|
+
@media(max-width:760px){.codexGeneratedImageWorkspace.has-comments{grid-template-columns:minmax(0,1fr);grid-template-rows:minmax(0,1fr) minmax(118px,34vh)}.codexGeneratedImageComments{border-top:1px solid var(--dsw-alias-border-l2);border-left:0;padding:10px 12px}}
|
|
417
449
|
`;
|
|
418
450
|
const unwrap = (response) => {
|
|
419
451
|
if (!response?.ok) throw new Error(response?.error?.message ?? "Codex RPC failed");
|
|
@@ -443,13 +475,28 @@ window.__ModuleLoader__.load({
|
|
|
443
475
|
return cleaned.toLowerCase().endsWith(".png") ? cleaned : `${cleaned}.png`;
|
|
444
476
|
};
|
|
445
477
|
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`;
|
|
446
|
-
function
|
|
478
|
+
function editDraft(prompt, annotations, t) {
|
|
479
|
+
const notes = annotations.map((annotation, index) => ({
|
|
480
|
+
number: index + 1,
|
|
481
|
+
note: annotation.note.trim()
|
|
482
|
+
})).filter((annotation) => annotation.note !== "").map((annotation) => String(annotation.number) + ". " + annotation.note);
|
|
483
|
+
const base = prompt.trim() === "" ? t("imageEditDefault") : prompt.trim();
|
|
484
|
+
return notes.length === 0 ? base : base + "\n\n" + t("imageRegionNotes") + "\n" + notes.join("\n");
|
|
485
|
+
}
|
|
486
|
+
function CodexGeneratedImage({ attachment, loadImage, attachForEdit, t }) {
|
|
447
487
|
const [attempt, setAttempt] = (0, react.useState)(0);
|
|
448
488
|
const [error, setError] = (0, react.useState)(false);
|
|
449
489
|
const [open, setOpen] = (0, react.useState)(false);
|
|
450
490
|
const [src, setSrc] = (0, react.useState)();
|
|
451
491
|
const [zoom, setZoom] = (0, react.useState)(1);
|
|
492
|
+
const [annotationMode, setAnnotationMode] = (0, react.useState)(false);
|
|
493
|
+
const [annotations, setAnnotations] = (0, react.useState)([]);
|
|
494
|
+
const [selectedAnnotation, setSelectedAnnotation] = (0, react.useState)();
|
|
495
|
+
const [prompt, setPrompt] = (0, react.useState)("");
|
|
496
|
+
const [editBusy, setEditBusy] = (0, react.useState)(false);
|
|
497
|
+
const [editError, setEditError] = (0, react.useState)(false);
|
|
452
498
|
const triggerRef = (0, react.useRef)(null);
|
|
499
|
+
const dialogRef = (0, react.useRef)(null);
|
|
453
500
|
(0, react.useEffect)(() => {
|
|
454
501
|
let live = true;
|
|
455
502
|
setError(false);
|
|
@@ -471,15 +518,224 @@ window.__ModuleLoader__.load({
|
|
|
471
518
|
setOpen(false);
|
|
472
519
|
window.requestAnimationFrame(() => triggerRef.current?.focus());
|
|
473
520
|
};
|
|
521
|
+
(0, react.useEffect)(() => {
|
|
522
|
+
if (!open) return void 0;
|
|
523
|
+
const previousOverflow = document.body.style.overflow;
|
|
524
|
+
document.body.style.overflow = "hidden";
|
|
525
|
+
dialogRef.current?.focus();
|
|
526
|
+
const keydown = (event) => {
|
|
527
|
+
if (event.key === "Escape") {
|
|
528
|
+
event.preventDefault();
|
|
529
|
+
close();
|
|
530
|
+
return;
|
|
531
|
+
}
|
|
532
|
+
if (event.key === "Tab") {
|
|
533
|
+
const focusable = [...dialogRef.current.querySelectorAll("button:not(:disabled),a[href],input:not(:disabled),textarea:not(:disabled),[tabindex]:not([tabindex=\"-1\"])")];
|
|
534
|
+
if (focusable.length === 0) return;
|
|
535
|
+
const first = focusable[0];
|
|
536
|
+
const last = focusable.at(-1);
|
|
537
|
+
if (event.shiftKey && document.activeElement === first) {
|
|
538
|
+
event.preventDefault();
|
|
539
|
+
last.focus();
|
|
540
|
+
} else if (!event.shiftKey && document.activeElement === last) {
|
|
541
|
+
event.preventDefault();
|
|
542
|
+
first.focus();
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
};
|
|
546
|
+
document.addEventListener("keydown", keydown);
|
|
547
|
+
return () => {
|
|
548
|
+
document.body.style.overflow = previousOverflow;
|
|
549
|
+
document.removeEventListener("keydown", keydown);
|
|
550
|
+
};
|
|
551
|
+
}, [open]);
|
|
474
552
|
const label = attachment.name ?? t("imageLabel");
|
|
475
553
|
const downloadName = imageDownloadName(attachment);
|
|
476
|
-
const imageMeta =
|
|
554
|
+
const imageMeta = attachment.width + " × " + attachment.height + " · " + imageByteSize(attachment.bytes);
|
|
555
|
+
const addAnnotation = (event) => {
|
|
556
|
+
if (!annotationMode || event.target.closest(".codexGeneratedImagePin")) return;
|
|
557
|
+
const bounds = event.currentTarget.getBoundingClientRect();
|
|
558
|
+
const annotation = {
|
|
559
|
+
id: crypto.randomUUID(),
|
|
560
|
+
x: Math.max(0, Math.min(1, (event.clientX - bounds.left) / bounds.width)),
|
|
561
|
+
y: Math.max(0, Math.min(1, (event.clientY - bounds.top) / bounds.height)),
|
|
562
|
+
note: ""
|
|
563
|
+
};
|
|
564
|
+
setAnnotations((value) => [...value, annotation]);
|
|
565
|
+
setSelectedAnnotation(annotation.id);
|
|
566
|
+
};
|
|
567
|
+
const continueEditing = async () => {
|
|
568
|
+
if (editBusy || src === void 0) return;
|
|
569
|
+
setEditBusy(true);
|
|
570
|
+
setEditError(false);
|
|
571
|
+
try {
|
|
572
|
+
await attachForEdit(src, downloadName, editDraft(prompt, annotations, t));
|
|
573
|
+
close();
|
|
574
|
+
} catch {
|
|
575
|
+
setEditError(true);
|
|
576
|
+
} finally {
|
|
577
|
+
setEditBusy(false);
|
|
578
|
+
}
|
|
579
|
+
};
|
|
477
580
|
if (error) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
478
581
|
type: "button",
|
|
479
582
|
className: "codexGeneratedImageRetry",
|
|
480
583
|
onClick: () => setAttempt((value) => value + 1),
|
|
481
584
|
children: t("imageLoadFailed")
|
|
482
585
|
});
|
|
586
|
+
const lightbox = !open || src === void 0 ? null : (0, react_dom.createPortal)(/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
587
|
+
ref: dialogRef,
|
|
588
|
+
className: "codexGeneratedImageLightbox",
|
|
589
|
+
role: "dialog",
|
|
590
|
+
"aria-modal": "true",
|
|
591
|
+
"aria-label": t("imagePreview"),
|
|
592
|
+
tabIndex: -1,
|
|
593
|
+
children: [
|
|
594
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("header", {
|
|
595
|
+
className: "codexGeneratedImageTopbar",
|
|
596
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: label }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("small", { children: imageMeta })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
597
|
+
className: "codexGeneratedImageActions",
|
|
598
|
+
children: [
|
|
599
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
600
|
+
type: "button",
|
|
601
|
+
className: annotationMode ? "is-active" : "",
|
|
602
|
+
"aria-pressed": annotationMode,
|
|
603
|
+
onClick: () => setAnnotationMode((value) => !value),
|
|
604
|
+
children: t("imageAnnotate")
|
|
605
|
+
}),
|
|
606
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
607
|
+
type: "button",
|
|
608
|
+
"aria-label": t("imageZoomOut"),
|
|
609
|
+
disabled: zoom <= .5,
|
|
610
|
+
onClick: () => setZoom((value) => Math.max(.5, value - .25)),
|
|
611
|
+
children: "−"
|
|
612
|
+
}),
|
|
613
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [Math.round(zoom * 100), "%"] }),
|
|
614
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
615
|
+
type: "button",
|
|
616
|
+
"aria-label": t("imageZoomIn"),
|
|
617
|
+
disabled: zoom >= 3,
|
|
618
|
+
onClick: () => setZoom((value) => Math.min(3, value + .25)),
|
|
619
|
+
children: "+"
|
|
620
|
+
}),
|
|
621
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
622
|
+
type: "button",
|
|
623
|
+
onClick: () => setZoom(1),
|
|
624
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconFullscreenOutline16, { "aria-hidden": "true" }), t("imageFit")]
|
|
625
|
+
}),
|
|
626
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("a", {
|
|
627
|
+
href: src,
|
|
628
|
+
download: downloadName,
|
|
629
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconDownloadOutline16, { "aria-hidden": "true" }), t("imageDownload")]
|
|
630
|
+
}),
|
|
631
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
632
|
+
type: "button",
|
|
633
|
+
className: "codexGeneratedImageClose",
|
|
634
|
+
"aria-label": t("imageClosePreview"),
|
|
635
|
+
onClick: close,
|
|
636
|
+
children: "×"
|
|
637
|
+
})
|
|
638
|
+
]
|
|
639
|
+
})]
|
|
640
|
+
}),
|
|
641
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
642
|
+
className: "codexGeneratedImageWorkspace " + (annotationMode || annotations.length > 0 ? "has-comments" : ""),
|
|
643
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("main", {
|
|
644
|
+
className: "codexGeneratedImageCanvas " + (annotationMode ? "is-annotating" : ""),
|
|
645
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
646
|
+
className: "codexGeneratedImageSurface",
|
|
647
|
+
onClick: addAnnotation,
|
|
648
|
+
style: { transform: "scale(" + zoom + ")" },
|
|
649
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
|
|
650
|
+
src,
|
|
651
|
+
alt: label
|
|
652
|
+
}), annotations.map((annotation, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
653
|
+
type: "button",
|
|
654
|
+
className: "codexGeneratedImagePin " + (annotation.id === selectedAnnotation ? "is-active" : ""),
|
|
655
|
+
"aria-label": fill(t("imageAnnotation"), { value: index + 1 }),
|
|
656
|
+
style: {
|
|
657
|
+
left: annotation.x * 100 + "%",
|
|
658
|
+
top: annotation.y * 100 + "%"
|
|
659
|
+
},
|
|
660
|
+
onClick: (event) => {
|
|
661
|
+
event.stopPropagation();
|
|
662
|
+
setSelectedAnnotation(annotation.id);
|
|
663
|
+
},
|
|
664
|
+
children: index + 1
|
|
665
|
+
}, annotation.id))]
|
|
666
|
+
}), annotationMode ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
667
|
+
className: "codexGeneratedImageAnnotateHint",
|
|
668
|
+
children: t("imageAnnotateHint")
|
|
669
|
+
}) : null]
|
|
670
|
+
}), annotationMode || annotations.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("aside", {
|
|
671
|
+
className: "codexGeneratedImageComments",
|
|
672
|
+
"aria-label": t("imageAnnotate"),
|
|
673
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("header", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: t("imageAnnotate") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("small", { children: t("imageAnnotateHint") })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
674
|
+
className: "codexGeneratedImageCommentList",
|
|
675
|
+
children: annotations.map((annotation, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("article", {
|
|
676
|
+
className: annotation.id === selectedAnnotation ? "is-active" : "",
|
|
677
|
+
onClick: () => setSelectedAnnotation(annotation.id),
|
|
678
|
+
children: [
|
|
679
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: index + 1 }),
|
|
680
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", {
|
|
681
|
+
value: annotation.note,
|
|
682
|
+
rows: 3,
|
|
683
|
+
"aria-label": fill(t("imageAnnotation"), { value: index + 1 }),
|
|
684
|
+
placeholder: t("imageAnnotationPlaceholder"),
|
|
685
|
+
onFocus: () => setSelectedAnnotation(annotation.id),
|
|
686
|
+
onChange: (event) => {
|
|
687
|
+
const note = event.target.value;
|
|
688
|
+
setAnnotations((value) => value.map((item) => item.id === annotation.id ? {
|
|
689
|
+
...item,
|
|
690
|
+
note
|
|
691
|
+
} : item));
|
|
692
|
+
}
|
|
693
|
+
}),
|
|
694
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
695
|
+
type: "button",
|
|
696
|
+
"aria-label": t("imageRemoveAnnotation"),
|
|
697
|
+
onClick: (event) => {
|
|
698
|
+
event.stopPropagation();
|
|
699
|
+
setAnnotations((value) => value.filter((item) => item.id !== annotation.id));
|
|
700
|
+
if (selectedAnnotation === annotation.id) setSelectedAnnotation(void 0);
|
|
701
|
+
},
|
|
702
|
+
children: "×"
|
|
703
|
+
})
|
|
704
|
+
]
|
|
705
|
+
}, annotation.id))
|
|
706
|
+
})]
|
|
707
|
+
}) : null]
|
|
708
|
+
}),
|
|
709
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("footer", {
|
|
710
|
+
className: "codexGeneratedImageEditDock",
|
|
711
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
712
|
+
className: "codexGeneratedImagePrompt",
|
|
713
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Input, {
|
|
714
|
+
value: prompt,
|
|
715
|
+
placeholder: t("imageEditPrompt"),
|
|
716
|
+
onChange: (event) => setPrompt(event.target.value),
|
|
717
|
+
onKeyDown: (event) => {
|
|
718
|
+
if (event.key === "Enter" && !event.shiftKey) {
|
|
719
|
+
event.preventDefault();
|
|
720
|
+
continueEditing();
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
724
|
+
type: "button",
|
|
725
|
+
disabled: editBusy,
|
|
726
|
+
onClick: () => {
|
|
727
|
+
continueEditing();
|
|
728
|
+
},
|
|
729
|
+
children: editBusy ? t("imageEditPreparing") : t("imageEdit")
|
|
730
|
+
})]
|
|
731
|
+
}), editError ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
732
|
+
className: "codexGeneratedImageEditError",
|
|
733
|
+
role: "alert",
|
|
734
|
+
children: t("imageEditFailed")
|
|
735
|
+
}) : null]
|
|
736
|
+
})
|
|
737
|
+
]
|
|
738
|
+
}), document.body);
|
|
483
739
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
484
740
|
ref: triggerRef,
|
|
485
741
|
type: "button",
|
|
@@ -496,78 +752,9 @@ window.__ModuleLoader__.load({
|
|
|
496
752
|
src,
|
|
497
753
|
alt: label
|
|
498
754
|
})
|
|
499
|
-
}),
|
|
500
|
-
open,
|
|
501
|
-
onClose: close,
|
|
502
|
-
title: t("imagePreview"),
|
|
503
|
-
closeLabel: t("imageClosePreview"),
|
|
504
|
-
className: "codexGeneratedImageModal",
|
|
505
|
-
contentClassName: "codexGeneratedImageModalContent",
|
|
506
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
507
|
-
className: "codexGeneratedImageViewer",
|
|
508
|
-
children: [
|
|
509
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
510
|
-
className: "codexGeneratedImageStage",
|
|
511
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
|
|
512
|
-
src,
|
|
513
|
-
alt: label,
|
|
514
|
-
style: { transform: `scale(${zoom})` }
|
|
515
|
-
})
|
|
516
|
-
}),
|
|
517
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
518
|
-
className: "codexGeneratedImageMeta",
|
|
519
|
-
children: imageMeta
|
|
520
|
-
}),
|
|
521
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
522
|
-
className: "codexGeneratedImageToolbar",
|
|
523
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
524
|
-
className: "codexGeneratedImageZoom",
|
|
525
|
-
children: [
|
|
526
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
527
|
-
type: "button",
|
|
528
|
-
variant: "outline",
|
|
529
|
-
"aria-label": t("imageZoomOut"),
|
|
530
|
-
title: t("imageZoomOut"),
|
|
531
|
-
disabled: zoom <= .5,
|
|
532
|
-
onClick: () => setZoom((value) => Math.max(.5, value - .25)),
|
|
533
|
-
children: "−"
|
|
534
|
-
}),
|
|
535
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
536
|
-
className: "codexGeneratedImageZoomValue",
|
|
537
|
-
children: [Math.round(zoom * 100), "%"]
|
|
538
|
-
}),
|
|
539
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
540
|
-
type: "button",
|
|
541
|
-
variant: "outline",
|
|
542
|
-
"aria-label": t("imageZoomIn"),
|
|
543
|
-
title: t("imageZoomIn"),
|
|
544
|
-
disabled: zoom >= 3,
|
|
545
|
-
onClick: () => setZoom((value) => Math.min(3, value + .25)),
|
|
546
|
-
children: "+"
|
|
547
|
-
}),
|
|
548
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
549
|
-
type: "button",
|
|
550
|
-
variant: "outline",
|
|
551
|
-
onClick: () => setZoom(1),
|
|
552
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconFullscreenOutline16, { "aria-hidden": "true" }), t("imageFit")]
|
|
553
|
-
})
|
|
554
|
-
]
|
|
555
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("a", {
|
|
556
|
-
className: "codexGeneratedImageDownload",
|
|
557
|
-
href: src,
|
|
558
|
-
download: downloadName,
|
|
559
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconDownloadOutline16, { "aria-hidden": "true" }), t("imageDownload")]
|
|
560
|
-
})]
|
|
561
|
-
}),
|
|
562
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
563
|
-
className: "codexGeneratedImageGuidance",
|
|
564
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("imageRefineHint") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("imageNewHint") })]
|
|
565
|
-
})
|
|
566
|
-
]
|
|
567
|
-
})
|
|
568
|
-
})] });
|
|
755
|
+
}), lightbox] });
|
|
569
756
|
}
|
|
570
|
-
function CodexImageToolRow({ block, loadImage, t }) {
|
|
757
|
+
function CodexImageToolRow({ block, loadImage, attachForEdit, t }) {
|
|
571
758
|
const settled = block?.kind === "tool-result";
|
|
572
759
|
const image = settled ? block.content.find((item) => item?.type === "image" && item.attachment !== void 0) : void 0;
|
|
573
760
|
const failed = settled && block.isError === true;
|
|
@@ -604,6 +791,7 @@ window.__ModuleLoader__.load({
|
|
|
604
791
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CodexGeneratedImage, {
|
|
605
792
|
attachment: image.attachment,
|
|
606
793
|
loadImage,
|
|
794
|
+
attachForEdit,
|
|
607
795
|
t
|
|
608
796
|
})
|
|
609
797
|
}),
|
|
@@ -1868,7 +2056,7 @@ window.__ModuleLoader__.load({
|
|
|
1868
2056
|
ctx.effect(() => {
|
|
1869
2057
|
const tag = document.createElement("style");
|
|
1870
2058
|
tag.dataset.plugin = "dsh-codex-subscription";
|
|
1871
|
-
tag.textContent = STYLE;
|
|
2059
|
+
tag.textContent = STYLE + IMAGE_STYLE + IMAGE_LAYOUT_STYLE;
|
|
1872
2060
|
document.head.append(tag);
|
|
1873
2061
|
return () => tag.remove();
|
|
1874
2062
|
}, "codex-subscription: style");
|
|
@@ -1935,7 +2123,22 @@ window.__ModuleLoader__.load({
|
|
|
1935
2123
|
locale: NS,
|
|
1936
2124
|
inject: (sessionId) => ({
|
|
1937
2125
|
t,
|
|
1938
|
-
loadImage: (attachment) => conversation.resolveImage(sessionId, attachment)
|
|
2126
|
+
loadImage: (attachment) => conversation.resolveImage(sessionId, attachment),
|
|
2127
|
+
attachForEdit: async (src, filename, draft) => {
|
|
2128
|
+
const actx = sessions.scope(sessionId);
|
|
2129
|
+
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");
|
|
2130
|
+
const response = await fetch(src);
|
|
2131
|
+
if (!response.ok) throw new Error("Could not read generated image");
|
|
2132
|
+
const blob = await response.blob();
|
|
2133
|
+
const created = conversation.createDraftImages([new File([blob], filename, { type: blob.type || "image/png" })]);
|
|
2134
|
+
const input = conversation.input.for(actx);
|
|
2135
|
+
if (!input.addImages(created.map((item) => item.id))) {
|
|
2136
|
+
conversation.releaseDraftImages(created);
|
|
2137
|
+
throw new Error("The composer is busy");
|
|
2138
|
+
}
|
|
2139
|
+
sessions.open(sessionId);
|
|
2140
|
+
input.setDraft(draft);
|
|
2141
|
+
}
|
|
1939
2142
|
})
|
|
1940
2143
|
}, CodexImageToolRow));
|
|
1941
2144
|
}
|
package/lib/index.js
CHANGED
|
@@ -504,7 +504,7 @@ function openaiCodexSubscriptionProvider({ resolveSpeedMode = () => void 0 } = {
|
|
|
504
504
|
}
|
|
505
505
|
//#endregion
|
|
506
506
|
//#region src/version.js
|
|
507
|
-
const PACKAGE_VERSION = "1.
|
|
507
|
+
const PACKAGE_VERSION = "1.7.0";
|
|
508
508
|
const USER_AGENT = `dsh-codex-subscription/${PACKAGE_VERSION}`;
|
|
509
509
|
//#endregion
|
|
510
510
|
//#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.7.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",
|
|
@@ -20,8 +20,7 @@
|
|
|
20
20
|
"compatibility.json",
|
|
21
21
|
"LICENSE",
|
|
22
22
|
"SECURITY.md",
|
|
23
|
-
"THIRD_PARTY_NOTICES.md"
|
|
24
|
-
"docs/assets/*.png"
|
|
23
|
+
"THIRD_PARTY_NOTICES.md"
|
|
25
24
|
],
|
|
26
25
|
"dsh": {
|
|
27
26
|
"bundle": {
|
|
@@ -95,7 +94,8 @@
|
|
|
95
94
|
"@deepseek-ai/dsh-web": "0.1.0-rc.6 || 0.1.0-rc.7 || 0.1.0-rc.8 || 0.1.1-rc.1 || 0.1.1-rc.2",
|
|
96
95
|
"@deepseek-ai/schemastery": "3.18.1",
|
|
97
96
|
"@earendil-works/pi-ai": "0.82.1",
|
|
98
|
-
"react": "^18.2.0"
|
|
97
|
+
"react": "^18.2.0",
|
|
98
|
+
"react-dom": "^18.2.0"
|
|
99
99
|
},
|
|
100
100
|
"devDependencies": {
|
|
101
101
|
"@deepseek-ai/cordis": "4.0.1",
|
|
@@ -119,6 +119,7 @@
|
|
|
119
119
|
"@earendil-works/pi-ai": "0.82.1",
|
|
120
120
|
"@heroicons/react": "2.2.0",
|
|
121
121
|
"react": "18.3.1",
|
|
122
|
+
"react-dom": "18.3.1",
|
|
122
123
|
"tsdown": "0.22.2"
|
|
123
124
|
},
|
|
124
125
|
"scripts": {
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/docs/assets/settings.png
DELETED
|
Binary file
|