dsh-packycode-api 1.2.3 → 1.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/README.en.md +2 -2
- package/README.md +2 -2
- package/lib/client.js +156 -36
- package/package.json +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.2.4
|
|
4
|
+
|
|
5
|
+
- Added the current image key's remaining quota immediately after the Create image shortcut. Hovering or focusing it shows the key label, account name, remaining/used/total quota and update time. It shares the shortcut's visibility, refreshes every minute while mounted and after image-setting/key changes, and marks stale or failed reads without confusing them with zero credit. Real React lifecycle regressions cover provider switches, image availability, disabled/missing keys and late responses.
|
|
6
|
+
- Removed the redundant "Separate image key" badge from the image settings header.
|
|
7
|
+
- Image/account quota totals now use total remaining plus total used, as requested, rather than depending on the optional periodic `quota_limit` field. Non-resetting image keys therefore show their total even when no period cap is set. Per-key quota figures and progress bars use the same calculation. Missing balance components remain unknown, and unlimited keys retain their unlimited display.
|
|
8
|
+
- Validation, 2026-10-15: 397 tests, both rebuilt bundles and the versioned tarball. Browser verification with real React and DSH 0.2.0-rc.2 composer CSS confirmed the balance sits to the right of Create image, the hover/focus details show the current key's quota, and provider switches, the image setting and the host's hidden toolbar hide both controls together. A read-only live image-key quota projection also confirmed the no-period-cap shape; no image generation was needed for these UI changes.
|
|
9
|
+
|
|
3
10
|
## 1.2.3
|
|
4
11
|
|
|
5
12
|
- Fixed ordinary reference-only image edits failing with `PackyCode image mask must be a PNG smaller than 4 MB` when a model also fills the optional mask field with the same JPEG/WebP reference. Native `maskImage` and CLI `maskId` now explicitly accept `null`; the field descriptions distinguish sketch refinement from using an actual mask. Only an identical reference already resolved by the host as non-PNG is treated as a redundant non-mask. Reference bytes, edit endpoint, model and quality stay intact; real PNG masks and all distinct mask references still undergo format, size and dimension checks. Invalid mask-format errors now explain how to request editing without a mask. Added native and authenticated MCP regressions without paid calls.
|
package/README.en.md
CHANGED
|
@@ -51,7 +51,7 @@ Open the desktop application's **Plugins** page, click **Add plugin**, and enter
|
|
|
51
51
|
dsh-packycode-api
|
|
52
52
|
```
|
|
53
53
|
|
|
54
|
-
Choose the **official** install source, then click **Install**. To pin a version, enter `dsh-packycode-api@1.2.
|
|
54
|
+
Choose the **official** install source, then click **Install**. To pin a version, enter `dsh-packycode-api@1.2.4`.
|
|
55
55
|
|
|
56
56
|
A **first install requires no DSH restart**: open **Settings → PackyCode** and add a key immediately. When updating an already loaded older version, follow the restart guidance in the **Plugin version** card.
|
|
57
57
|
|
|
@@ -70,7 +70,7 @@ Choose a model from the `PackyCode` group. `deepseek-flash`, `gpt-6.1-sol`, `gpt
|
|
|
70
70
|
|
|
71
71
|
The **Plugins** page shows the installed state and version, and is also where you enable, disable, or uninstall.
|
|
72
72
|
|
|
73
|
-
**For non-desktop profiles only:** `dsh plugin --profile <name> add dsh-packycode-api@1.2.
|
|
73
|
+
**For non-desktop profiles only:** `dsh plugin --profile <name> add dsh-packycode-api@1.2.4`. Do not use it for `desktop` — the CLI refuses it (`profile "desktop" is managed exclusively by the Electron application`).
|
|
74
74
|
|
|
75
75
|
For a local checkout, keep the `link:` prefix: `dsh plugin --profile <name> add link:/path/to/dsh-packycode-api`. **Do not pass a bare path or `file:`** — that install copies the whole checkout, `node_modules` included, into the profile, where it then shadows the packages the DSH installation itself provides and the plugin looks uninstalled; see the FAQ. If you already installed that way, uninstall first and reinstall as above.
|
|
76
76
|
|
package/README.md
CHANGED
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
dsh-packycode-api
|
|
52
52
|
```
|
|
53
53
|
|
|
54
|
-
在**安装源**中选择**官方源**,然后点击**安装**。需要固定版本时填入 `dsh-packycode-api@1.2.
|
|
54
|
+
在**安装源**中选择**官方源**,然后点击**安装**。需要固定版本时填入 `dsh-packycode-api@1.2.4`。
|
|
55
55
|
|
|
56
56
|
首次安装后**无需重启 DSH**,可直接打开**设置 → PackyCode** 添加 Key。更新已加载的旧版时,按「插件版本」卡片的重启提示操作。
|
|
57
57
|
|
|
@@ -70,7 +70,7 @@ dsh-packycode-api
|
|
|
70
70
|
|
|
71
71
|
桌面应用的**插件**页可以看到已安装状态与版本,也可以在那里启用、停用或卸载。
|
|
72
72
|
|
|
73
|
-
**仅用于非 desktop profile:** `dsh plugin --profile <name> add dsh-packycode-api@1.2.
|
|
73
|
+
**仅用于非 desktop profile:** `dsh plugin --profile <name> add dsh-packycode-api@1.2.4`。不要对 `desktop` 使用它 —— CLI 会直接拒绝(`profile "desktop" is managed exclusively by the Electron application`)。
|
|
74
74
|
|
|
75
75
|
本地开发要加 `link:` 前缀:`dsh plugin --profile <name> add link:/path/to/dsh-packycode-api`。**不要直接写路径(或 `file:`)** —— 那样的安装会把整个仓库目录(连同 `node_modules`)复制进 profile,之后它会在 profile 内部挡住 DSH 自带的包,插件看起来像没装,见「常见问题」。已经那样装过的话,先卸载再按上面的方式重装。
|
|
76
76
|
|
package/lib/client.js
CHANGED
|
@@ -40,9 +40,11 @@ window.__ModuleLoader__.load({
|
|
|
40
40
|
intro: "填入 PackyCode(PackyAPI)的 API Key 即可使用内置模型路由。多个 Key 按顺序使用:额度用尽或失效时自动切到下一个;某个 Key 的分组用不了所选模型时,自动改用分组合适的 Key。",
|
|
41
41
|
accountsTitle: "账户与 Key",
|
|
42
42
|
imagesTitle: "图片生成与编辑",
|
|
43
|
-
imagesSeparateKey: "独立图片 Key",
|
|
44
43
|
imagesBalanceLoading: "正在读取图片 Key 余额…",
|
|
45
44
|
imagesBalanceFailed: "图片余额读取失败",
|
|
45
|
+
imagesComposerLabel: "图片剩余额度",
|
|
46
|
+
imagesBalanceKey: "当前图片 Key",
|
|
47
|
+
imagesBalanceReadAt: "更新于 {time}",
|
|
46
48
|
imagesBalanceHint: "仅汇总图片 Key 的额度,每分钟自动更新;也可手动刷新。与对话 Key 的余额分开统计。",
|
|
47
49
|
imagesIntro: "使用独立图片 Key 调用 PackyCode 图片接口。生成新图或上传图片后描述修改要求;图片模型独立于对话模型。原始 PNG 保存在本机,聊天中显示图片预览。",
|
|
48
50
|
imagesEnabled: "图片生成与编辑",
|
|
@@ -215,9 +217,11 @@ window.__ModuleLoader__.load({
|
|
|
215
217
|
intro: "Paste a PackyCode (PackyAPI) API key to use the built-in model route. Keys are used in order: an exhausted or rejected key hands over to the next one, and a key whose groups cannot reach the selected model is passed over for one whose groups can.",
|
|
216
218
|
accountsTitle: "Accounts and keys",
|
|
217
219
|
imagesTitle: "Image generation and editing",
|
|
218
|
-
imagesSeparateKey: "Separate image key",
|
|
219
220
|
imagesBalanceLoading: "Reading image key balances…",
|
|
220
221
|
imagesBalanceFailed: "Could not read image balances",
|
|
222
|
+
imagesComposerLabel: "Image balance",
|
|
223
|
+
imagesBalanceKey: "Current image key",
|
|
224
|
+
imagesBalanceReadAt: "Updated at {time}",
|
|
221
225
|
imagesBalanceHint: "Only image key quotas are counted here. Updates every minute, or use Refresh. Conversation key balances are separate.",
|
|
222
226
|
imagesIntro: "Use a dedicated image key with PackyCode’s Images API. Describe a new image or attach images with editing instructions. The image engine is independent of the conversation model. Original PNGs are saved locally and previews appear in chat.",
|
|
223
227
|
imagesEnabled: "Generate and edit images",
|
|
@@ -409,6 +413,11 @@ window.__ModuleLoader__.load({
|
|
|
409
413
|
.pkc-input:disabled{opacity:.5}
|
|
410
414
|
.pkc-image-choice{flex:none;width:100%;max-width:300px;cursor:pointer}
|
|
411
415
|
.pkc-image-shortcut{display:inline-flex;align-items:center;gap:8px}
|
|
416
|
+
.pkc-image-balance{position:relative;display:inline-flex;align-items:center}
|
|
417
|
+
.pkc-image-balance-value{cursor:help;border-radius:var(--dsw-radius-xs,4px)}
|
|
418
|
+
.pkc-image-balance-value:focus-visible{outline:1px solid var(--dsw-alias-state-business-primary);outline-offset:2px}
|
|
419
|
+
.pkc-image-balance-tooltip{position:absolute;bottom:calc(100% + 8px);left:0;z-index:100;box-sizing:border-box;width:max-content;max-width:min(320px,calc(100vw - 32px));padding:10px 12px;border:.5px solid var(--dsw-alias-border-l3);border-radius:var(--dsw-radius-md,12px);background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary);box-shadow:var(--dsw-shadow-lv1);font-size:12px;line-height:20px;white-space:pre-line;overflow-wrap:anywhere;visibility:hidden;opacity:0;pointer-events:none}
|
|
420
|
+
.pkc-image-balance:hover>.pkc-image-balance-tooltip,.pkc-image-balance:focus-within>.pkc-image-balance-tooltip{visibility:visible;opacity:1}
|
|
412
421
|
.pkc-image-result,.pkc-image-chat{display:flex;flex-direction:column;gap:10px;padding:8px 0}
|
|
413
422
|
.pkc-generated-image{display:grid;place-items:center;align-self:flex-start;max-width:100%;width:320px;min-height:80px;padding:0;overflow:hidden;border:.5px solid var(--dsw-alias-border-l3);border-radius:var(--dsw-radius-md,12px);background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-secondary);cursor:zoom-in}
|
|
414
423
|
.pkc-generated-image img{display:block;max-width:100%;max-height:480px;object-fit:contain}
|
|
@@ -576,11 +585,19 @@ window.__ModuleLoader__.load({
|
|
|
576
585
|
* @module dsh-packycode-api/totals
|
|
577
586
|
*/
|
|
578
587
|
const amount = (value) => typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
588
|
+
/** Displayed key quota is remaining plus used, independent of a period cap. */
|
|
589
|
+
function quotaTotalUsd(usage) {
|
|
590
|
+
if (usage?.unlimitedQuota === true) return void 0;
|
|
591
|
+
const remaining = amount(usage?.availableUsd);
|
|
592
|
+
const used = amount(usage?.usedUsd);
|
|
593
|
+
if (remaining === void 0 || used === void 0) return void 0;
|
|
594
|
+
return amount(Number((remaining + used).toFixed(6)));
|
|
595
|
+
}
|
|
579
596
|
/**
|
|
580
597
|
* Add up the balance rows the host returned.
|
|
581
598
|
* @param rows - the `keys` array of a balance projection.
|
|
582
599
|
* @returns summed amounts plus the conditions that make a sum incomplete:
|
|
583
|
-
* keys whose read failed, and keys with
|
|
600
|
+
* keys whose read failed, and keys with unlimited quota.
|
|
584
601
|
*/
|
|
585
602
|
function sumBalances(rows) {
|
|
586
603
|
const total = {
|
|
@@ -606,11 +623,10 @@ window.__ModuleLoader__.load({
|
|
|
606
623
|
}
|
|
607
624
|
const remaining = amount(usage.availableUsd);
|
|
608
625
|
const used = amount(usage.usedUsd);
|
|
609
|
-
const limit = amount(usage.limitUsd);
|
|
610
626
|
if (remaining !== void 0) total.remainingUsd += remaining;
|
|
611
627
|
if (used !== void 0) total.usedUsd += used;
|
|
612
|
-
if (limit !== void 0) total.limitUsd += limit;
|
|
613
628
|
}
|
|
629
|
+
total.limitUsd = Number((total.remainingUsd + total.usedUsd).toFixed(6));
|
|
614
630
|
return total;
|
|
615
631
|
}
|
|
616
632
|
//#endregion
|
|
@@ -647,13 +663,14 @@ window.__ModuleLoader__.load({
|
|
|
647
663
|
/** The same quota presentation for conversation and image credential records. */
|
|
648
664
|
function KeyBalance({ row, t }) {
|
|
649
665
|
const usage = row?.usage;
|
|
666
|
+
const totalUsd = quotaTotalUsd(usage);
|
|
650
667
|
const figures = [
|
|
651
668
|
usage?.unlimitedQuota === true ? [t("keyRemaining"), t("keyUnlimited")] : usage?.availableUsd === void 0 ? void 0 : [t("keyRemaining"), formatUsd(usage.availableUsd)],
|
|
652
669
|
usage?.usedUsd === void 0 ? void 0 : [t("keyUsed"), formatUsd(usage.usedUsd)],
|
|
653
|
-
|
|
670
|
+
totalUsd === void 0 ? void 0 : [t("accountLimit"), formatUsd(totalUsd)]
|
|
654
671
|
].filter(Boolean);
|
|
655
672
|
const meta = [usage?.name === void 0 ? t("keyNameUnknown") : `${t("keyName")} ${usage.name}`, RESET_KEYS[usage?.resetPeriod] === void 0 ? void 0 : t(RESET_KEYS[usage.resetPeriod])].filter(Boolean).join(" · ");
|
|
656
|
-
const share = usage?.unlimitedQuota !== true &&
|
|
673
|
+
const share = usage?.unlimitedQuota !== true && totalUsd > 0 && typeof usage.availableUsd === "number" ? Math.max(0, Math.min(1, usage.availableUsd / totalUsd)) : void 0;
|
|
657
674
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
658
675
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
659
676
|
className: "pkc-meta",
|
|
@@ -716,7 +733,7 @@ window.__ModuleLoader__.load({
|
|
|
716
733
|
children: t("totalLimit")
|
|
717
734
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
718
735
|
className: "pkc-stat-value",
|
|
719
|
-
children: totals.unlimited > 0 ? t("keyUnlimited") : known("
|
|
736
|
+
children: totals.unlimited > 0 ? t("keyUnlimited") : known("availableUsd") && known("usedUsd") ? formatUsd(totals.limitUsd) : "—"
|
|
720
737
|
})]
|
|
721
738
|
})
|
|
722
739
|
]
|
|
@@ -726,6 +743,103 @@ window.__ModuleLoader__.load({
|
|
|
726
743
|
})] });
|
|
727
744
|
}
|
|
728
745
|
//#endregion
|
|
746
|
+
//#region src/client-image-balance.jsx
|
|
747
|
+
/** Mirror the host's next-usable image key using only its public balance rows. */
|
|
748
|
+
function currentImageKey(balance) {
|
|
749
|
+
const keys = balance?.keys ?? [];
|
|
750
|
+
const start = Math.max(0, keys.findIndex((row) => row.id === balance.activeId));
|
|
751
|
+
for (let offset = 0; offset < keys.length; offset += 1) {
|
|
752
|
+
const row = keys[(start + offset) % keys.length];
|
|
753
|
+
if (row.disabled !== true) return row;
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
/** Mounted inside the visible Create image shortcut, so its timer shares that lifetime. */
|
|
757
|
+
function ImageShortcutBalance({ call, t }) {
|
|
758
|
+
const [view, setView] = react.useState({ loading: true });
|
|
759
|
+
const refresh = react.useRef(() => {});
|
|
760
|
+
const tooltipId = react.useId();
|
|
761
|
+
react.useEffect(() => {
|
|
762
|
+
let live = true, generation = 0, pending = false;
|
|
763
|
+
const read = async (force = false, reset = false) => {
|
|
764
|
+
if (!live || pending && !force) return;
|
|
765
|
+
const current = ++generation;
|
|
766
|
+
pending = true;
|
|
767
|
+
setView((previous) => reset ? { loading: true } : {
|
|
768
|
+
...previous,
|
|
769
|
+
loading: true
|
|
770
|
+
});
|
|
771
|
+
try {
|
|
772
|
+
const balance = await call("images/balance", { force });
|
|
773
|
+
if (live && current === generation) setView({
|
|
774
|
+
balance,
|
|
775
|
+
loading: false
|
|
776
|
+
});
|
|
777
|
+
} catch {
|
|
778
|
+
if (live && current === generation) setView((previous) => ({
|
|
779
|
+
...previous,
|
|
780
|
+
loading: false,
|
|
781
|
+
failed: true
|
|
782
|
+
}));
|
|
783
|
+
} finally {
|
|
784
|
+
if (current === generation) pending = false;
|
|
785
|
+
}
|
|
786
|
+
};
|
|
787
|
+
refresh.current = read;
|
|
788
|
+
read();
|
|
789
|
+
const changed = () => {
|
|
790
|
+
read(true, true);
|
|
791
|
+
};
|
|
792
|
+
const timer = window.setInterval(() => {
|
|
793
|
+
read();
|
|
794
|
+
}, 6e4);
|
|
795
|
+
window.addEventListener("packycode-images-updated", changed);
|
|
796
|
+
return () => {
|
|
797
|
+
live = false;
|
|
798
|
+
generation += 1;
|
|
799
|
+
refresh.current = () => {};
|
|
800
|
+
window.clearInterval(timer);
|
|
801
|
+
window.removeEventListener("packycode-images-updated", changed);
|
|
802
|
+
};
|
|
803
|
+
}, [call]);
|
|
804
|
+
const row = currentImageKey(view.balance);
|
|
805
|
+
const usage = row?.usage;
|
|
806
|
+
const unlimited = usage?.unlimitedQuota === true;
|
|
807
|
+
const remaining = unlimited ? t("keyUnlimited") : formatUsd(usage?.availableUsd);
|
|
808
|
+
const stale = usage !== void 0 && (view.failed || row.stale !== void 0);
|
|
809
|
+
const display = remaining ?? (view.loading ? "…" : "—");
|
|
810
|
+
const details = [
|
|
811
|
+
t("imagesComposerLabel"),
|
|
812
|
+
row?.label ? `${t("imagesBalanceKey")}: ${row.label}` : void 0,
|
|
813
|
+
usage?.name ? `${t("keyName")}: ${usage.name}` : void 0,
|
|
814
|
+
`${t("keyRemaining")}: ${remaining ?? "—"}`,
|
|
815
|
+
`${t("keyUsed")}: ${formatUsd(usage?.usedUsd) ?? "—"}`,
|
|
816
|
+
`${t("accountLimit")}: ${unlimited ? t("keyUnlimited") : formatUsd(quotaTotalUsd(usage)) ?? "—"}`,
|
|
817
|
+
stale ? fill(t("composerStale"), { time: readTime(row.stale?.fetchedAt ?? view.balance?.fetchedAt) }) : view.failed || row?.error ? t("imagesBalanceFailed") : view.loading ? t("imagesBalanceLoading") : view.balance?.fetchedAt === void 0 ? void 0 : fill(t("imagesBalanceReadAt"), { time: readTime(view.balance.fetchedAt) })
|
|
818
|
+
].filter(Boolean).join("\n");
|
|
819
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
820
|
+
className: "pkc-image-balance",
|
|
821
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
822
|
+
className: "pkc-composer pkc-image-balance-value",
|
|
823
|
+
role: "status",
|
|
824
|
+
tabIndex: 0,
|
|
825
|
+
"aria-label": `${t("imagesComposerLabel")}: ${stale ? "≈" : ""}${display}`,
|
|
826
|
+
"aria-describedby": tooltipId,
|
|
827
|
+
onMouseEnter: () => {
|
|
828
|
+
refresh.current();
|
|
829
|
+
},
|
|
830
|
+
onFocus: () => {
|
|
831
|
+
refresh.current();
|
|
832
|
+
},
|
|
833
|
+
children: stale ? `≈${display}` : display
|
|
834
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
835
|
+
className: "pkc-image-balance-tooltip",
|
|
836
|
+
id: tooltipId,
|
|
837
|
+
role: "tooltip",
|
|
838
|
+
children: details
|
|
839
|
+
})]
|
|
840
|
+
});
|
|
841
|
+
}
|
|
842
|
+
//#endregion
|
|
729
843
|
//#region src/client-images.jsx
|
|
730
844
|
const imageModelLabel = (id) => id.replace("gpt-image-", "GPT Image ").replace("-flare", " Flare").replace("-sunburst", " Sunburst");
|
|
731
845
|
/** Only projections come back from the host; the password draft is cleared on success. */
|
|
@@ -804,13 +918,9 @@ window.__ModuleLoader__.load({
|
|
|
804
918
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
|
|
805
919
|
className: "pkc-title",
|
|
806
920
|
children: t("imagesTitle")
|
|
807
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.
|
|
921
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
808
922
|
className: "pkc-actions",
|
|
809
|
-
children:
|
|
810
|
-
className: "pkc-chip",
|
|
811
|
-
"data-tone": "neutral",
|
|
812
|
-
children: t("imagesSeparateKey")
|
|
813
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
923
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
814
924
|
className: "pkc-btn",
|
|
815
925
|
type: "button",
|
|
816
926
|
disabled: busy || balanceLoading,
|
|
@@ -818,7 +928,7 @@ window.__ModuleLoader__.load({
|
|
|
818
928
|
readBalance(true);
|
|
819
929
|
},
|
|
820
930
|
children: balanceLoading ? t("refreshing") : t("refresh")
|
|
821
|
-
})
|
|
931
|
+
})
|
|
822
932
|
})]
|
|
823
933
|
}),
|
|
824
934
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
@@ -1028,11 +1138,14 @@ window.__ModuleLoader__.load({
|
|
|
1028
1138
|
const [error, setError] = react.useState();
|
|
1029
1139
|
react.useEffect(() => {
|
|
1030
1140
|
let live = true;
|
|
1141
|
+
let generation = 0;
|
|
1031
1142
|
const refresh = () => {
|
|
1032
|
-
if (active)
|
|
1033
|
-
|
|
1143
|
+
if (!active) return;
|
|
1144
|
+
const current = ++generation;
|
|
1145
|
+
call("images/status").then((value) => {
|
|
1146
|
+
if (live && current === generation) setReady(value.imageEnabled && value.available && value.keys.some((key) => !key.disabled));
|
|
1034
1147
|
}).catch(() => {
|
|
1035
|
-
if (live) setReady(false);
|
|
1148
|
+
if (live && current === generation) setReady(false);
|
|
1036
1149
|
});
|
|
1037
1150
|
};
|
|
1038
1151
|
setReady(false);
|
|
@@ -1046,24 +1159,31 @@ window.__ModuleLoader__.load({
|
|
|
1046
1159
|
if (!active || !ready) return null;
|
|
1047
1160
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
1048
1161
|
className: "pkc-image-shortcut",
|
|
1049
|
-
children: [
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1162
|
+
children: [
|
|
1163
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1164
|
+
className: "pkc-btn",
|
|
1165
|
+
type: "button",
|
|
1166
|
+
title: t("imagesShortcutHint"),
|
|
1167
|
+
onClick: () => {
|
|
1168
|
+
try {
|
|
1169
|
+
prepare(t("imagesDraft"));
|
|
1170
|
+
setError(void 0);
|
|
1171
|
+
} catch {
|
|
1172
|
+
setError(t("imagesDraftBusy"));
|
|
1173
|
+
}
|
|
1174
|
+
},
|
|
1175
|
+
children: t("imagesCreate")
|
|
1176
|
+
}),
|
|
1177
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ImageShortcutBalance, {
|
|
1178
|
+
call,
|
|
1179
|
+
t
|
|
1180
|
+
}),
|
|
1181
|
+
error && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1182
|
+
className: "pkc-error",
|
|
1183
|
+
role: "alert",
|
|
1184
|
+
children: error
|
|
1185
|
+
})
|
|
1186
|
+
]
|
|
1067
1187
|
});
|
|
1068
1188
|
}
|
|
1069
1189
|
function GeneratedImage({ attachment, loadImage, openImage, t }) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-packycode-api",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.4",
|
|
4
4
|
"description": "Use PackyCode API keys in DeepSeek Harness with multi-protocol models, image generation and editing, separate key rings, and balance display",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./lib/index.js",
|
|
@@ -100,6 +100,7 @@
|
|
|
100
100
|
"packycode-host-v020-fixture": "file:tests/fixtures/host-v020",
|
|
101
101
|
"react": "18.3.1",
|
|
102
102
|
"react-dom": "18.3.1",
|
|
103
|
+
"react-test-renderer": "18.3.1",
|
|
103
104
|
"tsdown": "0.22.2",
|
|
104
105
|
"yaml": "2.9.1"
|
|
105
106
|
},
|