dsh-packycode-api 1.0.4 → 1.0.5
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 +8 -0
- package/README.en.md +10 -3
- package/README.md +10 -3
- package/lib/client.js +56 -22
- package/lib/index.js +781 -214
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.0.5
|
|
4
|
+
|
|
5
|
+
- **Balance on mainland networks.** The default balance host is now `https://www.packyapi.ai` (PackyAPI's current site). `www.packyapi.com`, the default through 1.0.4, is DNS-poisoned on mainland networks: every public resolver checked (AliDNS, DNSPod, 1.1.1.1, 8.8.8.8, even AliDNS over HTTPS) returned an unrelated foreign IP, and a direct Node fetch failed with `ECONNREFUSED`. Without a proxy every key read `fetch failed` from it, which is what a Windows user saw. With a proxy it worked, so the failure came and went. A profile that saved the old host keeps it as a fallback, but `.ai` is tried first. Verified live without a proxy: `.ai` answers in about 1.3 s.
|
|
6
|
+
- A failed balance read keeps each key's last good balance (and the last account figures), marked `stale` with the time of that read and this read's error. Settings shows a note, and the composer shows `≈US$…`. These values stay in the host process: a page refresh keeps them and a restart clears them. A transport failure now names its cause (`fetch failed (ENOTFOUND)`, `no answer within 20s`), and a 429 says the gateway is rate limiting. The composer says "余额读取失败" instead of "无可用 Key" when a usable key's read failed. The total limit shows `—` instead of "不限额度" when no key was read.
|
|
7
|
+
- **Claude Code CLI identity.** In `-p` mode the official CLI picks its identity line from whether it got appended instructions. With them, it tells the model "You are Claude Code, Anthropic's official CLI for Claude, running within the Claude Agent SDK."; without them, "You are a Claude agent, built on Anthropic's Claude Agent SDK." A delegated turn ran without them and was refused upstream with `403 Request blocked: this endpoint only accepts requests from the official Claude Code CLI`. Every run now passes `--append-system-prompt`: the delegation instructions (moved out of the prompt) or, for the `claude_code` tool, a short delegation note. This is the binary's own selection (read from its code and confirmed by capturing its request); the plugin does not rewrite the CLI's system prompt. That wording is also recognised as a client-policy refusal, explained without the bare 403, and never disables a key.
|
|
8
|
+
- **Prompt over stdin; images in CLI turns.** The CLI now reads its input from stdin instead of argv. A streaming turn sends one `stream-json` user message, the `claude_code` tool sends plain text, and stdin is closed afterwards. A Windows command line is capped near 32K characters and cannot carry an image. Images in a CLI-backed turn used to become the text `[图片]`; they are now read from the attachment store at the HTTP route's request size (2048×2048, about 1 MiB), sent as Anthropic image blocks where they appeared, and labelled with their read-only host copy. A turn carries at most 20 images and 20 MiB of base64, dropping the oldest first. An image left out, or unreadable, is described with its path instead of failing the turn. Uploaded files are named with their host copy, and structured tool results keep their text. Verified with the real CLI 2.1.295 against a local gateway: the image reached `/v1/messages` as a base64 image block.
|
|
9
|
+
- **No more silent CLI waits.** A delegated turn now opens its reasoning block with `▸ 启动 Claude Code CLI…`, shows the CLI's version and model once it is up, and shows each retry the CLI makes on its own (`↻ 网关返回 HTTP 503(server_error),CLI 自动重试 1/10,1.0 秒后`). Before, a gateway answering `503 packy_concurrency_queue_full` (账号并发排队已满) or 429 kept the CLI retrying for minutes with nothing on screen. When the retries run out, the turn says PackyCode's Claude upstream is busy and how many retries were made, keeping the gateway's words and request id. A streaming CLI that prints nothing within 2 minutes of starting is stopped and reported with its stderr tail. Verified with the real CLI against a local gateway that answers 503, both recovering after two retries and giving up.
|
|
10
|
+
|
|
3
11
|
## 1.0.4
|
|
4
12
|
|
|
5
13
|
- Settings can check for and install a newer npm release. **Update plugin** installs the exact published version into the owning profile with the host's bundled pnpm, then reads `package.json` back before reporting success. A `link:` checkout is left alone. The desktop app still needs a full restart afterwards.
|
package/README.en.md
CHANGED
|
@@ -42,7 +42,7 @@ Open the desktop application's **Plugins** page, click **Add plugin**, and enter
|
|
|
42
42
|
dsh-packycode-api
|
|
43
43
|
```
|
|
44
44
|
|
|
45
|
-
Choose the **official** install source, then click **Install**. To pin a version, enter `dsh-packycode-api@1.0.
|
|
45
|
+
Choose the **official** install source, then click **Install**. To pin a version, enter `dsh-packycode-api@1.0.5`.
|
|
46
46
|
|
|
47
47
|
Then **manually restart the desktop application**. Refreshing the page does not reload the plugin inside the Host process.
|
|
48
48
|
|
|
@@ -61,7 +61,7 @@ Choose a model from the `PackyCode` group. `deepseek-flash` and `gpt-6.1-sol` wo
|
|
|
61
61
|
|
|
62
62
|
The **Plugins** page shows the installed state and version, and is also where you enable, disable, or uninstall.
|
|
63
63
|
|
|
64
|
-
**For non-desktop profiles only:** `dsh plugin --profile <name> add dsh-packycode-api@1.0.
|
|
64
|
+
**For non-desktop profiles only:** `dsh plugin --profile <name> add dsh-packycode-api@1.0.5`. Do not use it for `desktop` — the CLI refuses it (`profile "desktop" is managed exclusively by the Electron application`).
|
|
65
65
|
|
|
66
66
|
A local checkout can be linked with `dsh plugin --profile <name> add link:/path/to/dsh-packycode-api`.
|
|
67
67
|
|
|
@@ -73,7 +73,7 @@ A profile without a browser can still use the model route. It just has no settin
|
|
|
73
73
|
|
|
74
74
|
**Switch keys.** Keys are used in the order they were added. **Use this key** selects one; **Rename** changes its label (at most 60 characters, empty names are refused); **Re-enable** puts a disabled key back after a top-up or replacement.
|
|
75
75
|
|
|
76
|
-
**Read the balance.** The settings total is the remaining, used, and limit of **the keys listed here**, not the bill for every token on the PackyCode account. A key that could not be read is left out of the total and counted in a note. The composer shows the active key's remaining balance only while a PackyCode model is selected. **Refresh** bypasses the roughly 60-second cache. The default model host is `https://cf.api.fan` and the balance host is `https://www.packyapi.
|
|
76
|
+
**Read the balance.** The settings total is the remaining, used, and limit of **the keys listed here**, not the bill for every token on the PackyCode account. A key that could not be read is left out of the total and counted in a note; a key whose read failed this time but succeeded before keeps showing its last balance with the time it was read (the composer shows it as `≈US$…`) until DSH restarts. The composer shows the active key's remaining balance only while a PackyCode model is selected. **Refresh** bypasses the roughly 60-second cache. The default model host is `https://cf.api.fan` and the balance host is `https://www.packyapi.ai`; both can be changed under **Advanced: endpoints**. The old default, `https://www.packyapi.com`, is DNS-poisoned on mainland networks and answers `fetch failed` without a proxy; even when settings still name it, `.ai` is tried first.
|
|
77
77
|
|
|
78
78
|
**Use Claude.** The **Claude Code CLI** card at the top of Settings checks this device. If the CLI is missing, **Install Claude Code CLI** runs `npm install -g @anthropic-ai/claude-code` (Node.js 18+). No DSH restart is required after that install. Windows also needs [Git for Windows](https://git-scm.com/downloads/win).
|
|
79
79
|
|
|
@@ -109,6 +109,9 @@ A model in the list does not mean the current token group allows it. When changi
|
|
|
109
109
|
- The CLI receives this plugin's endpoint and current key (`ANTHROPIC_BASE_URL` / `ANTHROPIC_AUTH_TOKEN`) and an isolated config directory, `~/.dsh/packycode-claude-cli`. Without that isolation, `env` in `~/.claude/settings.json` would override the plugin key.
|
|
110
110
|
- CLI permission follows the session by default: `read-only` stays read-only, `workspace-write` may edit, and `danger-full-access` with approval disabled may use `full`. The CLI cannot ask the DSH user for approval, so a session that still asks never gets `full`. `claudeCliMode` can pin `read-only`, `edit`, or `full`. An empty `claudeCliPath` is looked up automatically; an empty `claudeCliCwd` uses the session workspace.
|
|
111
111
|
- Thinking and tool activity (`▸ Bash`, `▸ Read`, and `✗` on failure) appear in that turn's reasoning block. They are progress, not DSH tool calls. The CLI's own tools are outside the DSH sandbox.
|
|
112
|
+
- The reasoning block opens with `▸ 启动 Claude Code CLI…` and then shows the CLI's version and model once it is up. When the gateway throttles or is busy (429, 503 `账号并发排队已满` / per-account wait queue full, and similar), the CLI retries up to 10 times on its own; each retry now shows as `↻ 网关返回 HTTP 503,CLI 自动重试 n/10` instead of looking hung. When the retries run out, the turn says PackyCode's Claude upstream is busy, not that the key is bad. A CLI that prints nothing for 2 minutes after starting is stopped and reported.
|
|
113
|
+
- The conversation and its images reach the CLI over stdin (`--input-format stream-json`), not argv: a Windows command line is length-limited and cannot carry an image. Images in the conversation are sent to Claude as images, at the HTTP route's request size (at most 2048×2048, about 1 MiB each; at most 20 images and 20 MiB per turn, dropping the oldest first). An image left out is named with its read-only local copy, which the CLI can open with Read.
|
|
114
|
+
- Every run carries `--append-system-prompt` (the delegation note). In `-p` mode the official CLI introduces itself as "You are Claude Code, Anthropic's official CLI for Claude …" when it has appended instructions and as "You are a Claude agent, built on Anthropic's Claude Agent SDK." when it has none; the latter was refused upstream as not coming from the official CLI (403 `only accepts requests from the official Claude Code CLI`). That is the official CLI's own behavior; the plugin does not rewrite its system prompt.
|
|
112
115
|
- While the session model is a Claude model, titles are generated with `claude-haiku-5-5`, read-only, in a temporary directory, instead of a full Opus turn.
|
|
113
116
|
- The `claude_code` tool can delegate one task to the local CLI while the session model is `gpt-6.1-sol` or `deepseek-flash`. The requested `mode` cannot exceed what the session preset allows.
|
|
114
117
|
- An effort level the model does not support is rejected before the request is sent. Do not edit a model's effort map casually.
|
|
@@ -127,6 +130,10 @@ A model in the list does not mean the current token group allows it. When changi
|
|
|
127
130
|
|
|
128
131
|
**The balance does not match the account bill?** Settings totals only the keys stored here, not other tokens on the same PackyCode account. A key that failed to read is noted separately and is not treated as zero.
|
|
129
132
|
|
|
133
|
+
**The balance reads `fetch failed` from `https://www.packyapi.com`?** That host, the default through 1.0.4, is DNS-poisoned on mainland networks and only answers through a proxy, so it works on and off. The default is now `https://www.packyapi.ai`. The model list is built into the plugin and never queried from PackyCode, so it is unaffected.
|
|
134
|
+
|
|
135
|
+
**A Claude model sits on "thinking" with no answer?** Read the reasoning block: `↻ 网关返回 HTTP 503/429` lines mean PackyCode's Claude upstream is queueing or throttling and the CLI is retrying. `▸ 启动 Claude Code CLI…` with no "started" line after it means the local CLI did not come up (on Windows, check Git for Windows and run `claude --version` in a terminal).
|
|
136
|
+
|
|
130
137
|
**A rate limit disabled the key?** It should not. HTTP 429 does not rotate. Exhausted quota or HTTP 401 does; after a top-up, click **Re-enable**.
|
|
131
138
|
|
|
132
139
|
**Installing from the Plugins page fails with `ERR_PNPM_MINIMUM_RELEASE_AGE_VIOLATION`?** pnpm refuses packages published less than 24 hours ago and checks the whole profile lockfile. The package it names is often another plugin that was just updated, not this one. Retry once it is 24 hours old, or add the reported `name@version` under `minimumReleaseAgeExclude` in the profile's `pnpm-workspace.yaml`. Once this plugin is installed, **Update plugin** in Settings is not subject to that check.
|
package/README.md
CHANGED
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
dsh-packycode-api
|
|
43
43
|
```
|
|
44
44
|
|
|
45
|
-
在**安装源**中选择**官方源**,然后点击**安装**。需要固定版本时填入 `dsh-packycode-api@1.0.
|
|
45
|
+
在**安装源**中选择**官方源**,然后点击**安装**。需要固定版本时填入 `dsh-packycode-api@1.0.5`。
|
|
46
46
|
|
|
47
47
|
完成后**手动重启桌面应用**。仅刷新页面不会重新加载 Host 里的插件。
|
|
48
48
|
|
|
@@ -61,7 +61,7 @@ dsh-packycode-api
|
|
|
61
61
|
|
|
62
62
|
桌面应用的**插件**页可以看到已安装状态与版本,也可以在那里启用、停用或卸载。
|
|
63
63
|
|
|
64
|
-
**仅用于非 desktop profile:** `dsh plugin --profile <name> add dsh-packycode-api@1.0.
|
|
64
|
+
**仅用于非 desktop profile:** `dsh plugin --profile <name> add dsh-packycode-api@1.0.5`。不要对 `desktop` 使用它 —— CLI 会直接拒绝(`profile "desktop" is managed exclusively by the Electron application`)。
|
|
65
65
|
|
|
66
66
|
本地开发可以用绝对路径:`dsh plugin --profile <name> add link:/path/to/dsh-packycode-api`。
|
|
67
67
|
|
|
@@ -73,7 +73,7 @@ dsh-packycode-api
|
|
|
73
73
|
|
|
74
74
|
**换 Key。** Key 按添加顺序使用。点「切到此 Key」可以指定当前 Key;「重命名」改备注(最多 60 字,不能为空);充值或更换后点「重新启用」。
|
|
75
75
|
|
|
76
|
-
**看余额。** 设置页的合计是**已列出的这些 Key** 的剩余、已用与额度,不是 PackyCode 账号下全部令牌的账单。读失败的 Key
|
|
76
|
+
**看余额。** 设置页的合计是**已列出的这些 Key** 的剩余、已用与额度,不是 PackyCode 账号下全部令牌的账单。读失败的 Key 不计入合计,并会注明个数;某个 Key 这次读失败但之前读到过,会继续显示上次的余额并注明读取时间(输入框里显示为 `≈US$…`),重启 DSH 后才清空。输入框右侧只在选中 PackyCode 模型时显示当前 Key 的剩余额度。「刷新」会跳过约 60 秒的缓存。默认模型接口是 `https://cf.api.fan`,余额接口是 `https://www.packyapi.ai`,可在「高级:接口地址」里改。旧默认值 `https://www.packyapi.com` 在国内网络下 DNS 被污染、直连会 `fetch failed`,即使设置里保存的是它,插件也会先试 `.ai`。
|
|
77
77
|
|
|
78
78
|
**用 Claude。** 设置页顶部的「Claude Code CLI」卡片会检测本机 CLI。没装时点「安装 Claude Code CLI」,本机执行 `npm install -g @anthropic-ai/claude-code`(需要 Node.js 18+)。装好后不用重启 DSH。Windows 上另外需要 [Git for Windows](https://git-scm.com/downloads/win)。
|
|
79
79
|
|
|
@@ -109,6 +109,9 @@ dsh-packycode-api
|
|
|
109
109
|
- CLI 使用插件配置的地址和当前 Key(`ANTHROPIC_BASE_URL` / `ANTHROPIC_AUTH_TOKEN`),以及独立配置目录 `~/.dsh/packycode-claude-cli`。不隔离的话,`~/.claude/settings.json` 里的 `env` 会盖掉插件 Key。
|
|
110
110
|
- CLI 权限默认跟随当前会话:`read-only` → 只读,`workspace-write` → 可编辑,`danger-full-access` 且不再审批 → `full`。CLI 不能向 DSH 弹审批,所以只要会话还要审批,就不会给它 `full`。也可把设置项 `claudeCliMode` 固定成 `read-only` / `edit` / `full`。`claudeCliPath` 留空则自动查找;`claudeCliCwd` 留空则用当前会话工作区。
|
|
111
111
|
- 思考过程和工具调用(`▸ Bash`、`▸ Read`,失败时带 `✗`)会出现在这一回合的思考区。它们是进度,不是 DSH 的工具调用。CLI 自己的工具不受 DSH 沙箱约束。
|
|
112
|
+
- 思考区第一行是「▸ 启动 Claude Code CLI…」,CLI 起来后显示版本和模型。网关限流或繁忙(429、503 `账号并发排队已满` 等)时,CLI 会自己重试最多 10 次,每次重试都会显示成 `↻ 网关返回 HTTP 503,CLI 自动重试 n/10`,不再像卡住。重试用完仍失败时,会说明是 PackyCode 的 Claude 上游繁忙,不是 Key 的问题。CLI 启动后 2 分钟内没有任何输出会被停止并报告原因。
|
|
113
|
+
- 对话记录和图片通过 stdin 交给 CLI(`--input-format stream-json`),不走命令行参数:Windows 命令行长度有上限,而且命令行带不了图片。对话里的图片会以图片形式发给 Claude(与 HTTP 路由相同的压缩规格:每张不超过 2048×2048、约 1 MiB;一回合最多 20 张、合计 20 MiB,超出时先舍弃最早的)。没随消息发出的图片会写明本机只读副本的路径,CLI 需要时可以用 Read 读取。
|
|
114
|
+
- 每次运行都带 `--append-system-prompt`(委派说明)。在 `-p` 模式下,官方 CLI 有追加说明时会以 "You are Claude Code, Anthropic's official CLI for Claude …" 自我介绍,没有时是 "You are a Claude agent, built on Anthropic's Claude Agent SDK.";后者曾被上游当成非官方 CLI 拒绝(403 `only accepts requests from the official Claude Code CLI`)。这是官方 CLI 自己的行为,插件没有改写它的系统提示词。
|
|
112
115
|
- 会话跑在 Claude 模型上时,生成标题改用 `claude-haiku-5-5`,只读、临时目录,避免为起标题跑一整轮 Opus。
|
|
113
116
|
- 另有 `claude_code` 工具:当前模型是 `gpt-6.1-sol` 或 `deepseek-flash` 时,可以把一个任务委派给本机 Claude Code。请求的 `mode` 不会超过会话权限允许的上限。
|
|
114
117
|
- 声明了模型不支持的推理档位会被 harness 在发请求前拒绝,不要随手改档位映射。
|
|
@@ -127,6 +130,10 @@ dsh-packycode-api
|
|
|
127
130
|
|
|
128
131
|
**余额对不上账号账单?** 设置页合计的是这里列出的 Key,不含同账号下没添加到本插件的其它令牌。个别 Key 读失败时会单独注明,不会被算成 0。
|
|
129
132
|
|
|
133
|
+
**余额显示 `读取失败: https://www.packyapi.com: fetch failed`?** 这是 1.0.4 及更早版本的默认余额接口在国内网络下被 DNS 污染,开了代理才能连上,所以有时正常、有时失败。新版本默认改用 `https://www.packyapi.ai`。模型列表是插件内置的,不需要向 PackyCode 查询,不受影响。
|
|
134
|
+
|
|
135
|
+
**选了 Claude 模型一直显示「深度求索中」?** 看思考区:有 `↻ 网关返回 HTTP 503/429` 说明 PackyCode 的 Claude 上游在排队或限流,CLI 正在自动重试;只有「▸ 启动 Claude Code CLI…」没有「已启动」,说明本机 CLI 没起来(Windows 上先确认装了 Git for Windows,并在终端执行 `claude --version`)。
|
|
136
|
+
|
|
130
137
|
**限速之后 Key 被停用了?** 不该发生。429 不会切换 Key。额度用尽或 401 才会停用;充值后点「重新启用」。
|
|
131
138
|
|
|
132
139
|
**插件页安装报 `ERR_PNPM_MINIMUM_RELEASE_AGE_VIOLATION`?** pnpm 默认拒绝发布不满 24 小时的包,并且会检查 profile 里的整个 lockfile。报错里点名的往往是另一个刚更新过的插件,不是本插件。等它发布满 24 小时再重试,或把报错里的 `包名@版本` 加到 profile 目录 `pnpm-workspace.yaml` 的 `minimumReleaseAgeExclude` 下。已安装本插件后,设置页的「更新插件」不受这个限制。
|
package/lib/client.js
CHANGED
|
@@ -102,6 +102,9 @@ window.__ModuleLoader__.load({
|
|
|
102
102
|
totalUsed: "合计已用",
|
|
103
103
|
totalLimit: "合计额度",
|
|
104
104
|
totalPartial: "有 {count} 个 Key 未读到余额,未计入合计。",
|
|
105
|
+
totalStale: "其中 {count} 个 Key 本次读取失败,显示的是上次读到的余额。",
|
|
106
|
+
staleNote: "上次读取于 {time},本次读取失败:{error}",
|
|
107
|
+
composerStale: "上次读取于 {time},本次读取失败",
|
|
105
108
|
accountLimit: "额度",
|
|
106
109
|
refresh: "刷新",
|
|
107
110
|
refreshing: "刷新中…",
|
|
@@ -139,6 +142,7 @@ window.__ModuleLoader__.load({
|
|
|
139
142
|
notWritable: "当前 profile 不允许写入设置,改动只在本次运行内生效。",
|
|
140
143
|
composerLabel: "PackyCode 剩余额度",
|
|
141
144
|
composerNoKey: "无可用 Key",
|
|
145
|
+
composerUnread: "余额读取失败",
|
|
142
146
|
error: "读取 PackyCode 状态失败",
|
|
143
147
|
loadFailed: "读取失败",
|
|
144
148
|
cliTitle: "Claude Code CLI",
|
|
@@ -229,6 +233,10 @@ window.__ModuleLoader__.load({
|
|
|
229
233
|
notWritable: "This profile does not allow settings writes; changes apply to this run only.",
|
|
230
234
|
composerLabel: "PackyCode remaining balance",
|
|
231
235
|
composerNoKey: "No usable key",
|
|
236
|
+
composerUnread: "Balance unavailable",
|
|
237
|
+
totalStale: "{count} of these keys failed this read and show their last read balance.",
|
|
238
|
+
staleNote: "Last read at {time}; this read failed: {error}",
|
|
239
|
+
composerStale: "last read at {time}; this read failed",
|
|
232
240
|
error: "Could not read PackyCode status",
|
|
233
241
|
loadFailed: "Read failed",
|
|
234
242
|
cliTitle: "Claude Code CLI",
|
|
@@ -341,6 +349,18 @@ window.__ModuleLoader__.load({
|
|
|
341
349
|
if (balance === void 0) return void 0;
|
|
342
350
|
return balance.keys?.find((entry) => entry.id === balance.activeId) ?? balance.keys?.[0];
|
|
343
351
|
}
|
|
352
|
+
/** The clock time of an epoch-millisecond reading, for a "last read at" note. */
|
|
353
|
+
function readTime(ms) {
|
|
354
|
+
if (typeof ms !== "number" || !Number.isFinite(ms)) return "—";
|
|
355
|
+
try {
|
|
356
|
+
return new Date(ms).toLocaleTimeString(void 0, {
|
|
357
|
+
hour: "2-digit",
|
|
358
|
+
minute: "2-digit"
|
|
359
|
+
});
|
|
360
|
+
} catch {
|
|
361
|
+
return new Date(ms).toISOString().slice(11, 16);
|
|
362
|
+
}
|
|
363
|
+
}
|
|
344
364
|
function clearMessage(error) {
|
|
345
365
|
const text = typeof error?.message === "string" && error.message.length > 0 ? error.message : String(error);
|
|
346
366
|
return text.length > 200 ? text.slice(0, 200) : text;
|
|
@@ -719,23 +739,30 @@ window.__ModuleLoader__.load({
|
|
|
719
739
|
className: "packyCodeRow",
|
|
720
740
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
721
741
|
className: "packyCodeRowMain",
|
|
722
|
-
children: [
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
742
|
+
children: [
|
|
743
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
744
|
+
className: "packyCodeRowName",
|
|
745
|
+
children: [
|
|
746
|
+
row.label,
|
|
747
|
+
row.id === status?.activeId && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
748
|
+
className: "packyCodeChip packyCodeChipActive",
|
|
749
|
+
children: t("keyActive")
|
|
750
|
+
}),
|
|
751
|
+
row.disabled && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
752
|
+
className: "packyCodeChip",
|
|
753
|
+
children: t("keyDisabled")
|
|
754
|
+
})
|
|
755
|
+
]
|
|
756
|
+
}),
|
|
757
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
758
|
+
className: "packyCodeRowMeta",
|
|
759
|
+
children: figures.length > 0 ? [tokenName, ...figures].filter(Boolean).join(" · ") : row.error === void 0 ? t("keyNoBalance") : `${t("loadFailed")}: ${row.error}`
|
|
760
|
+
}),
|
|
761
|
+
row.stale !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
762
|
+
className: "packyCodeRowMeta",
|
|
763
|
+
children: t("staleNote").replace("{time}", readTime(row.stale.fetchedAt)).replace("{error}", row.stale.error ?? "")
|
|
764
|
+
})
|
|
765
|
+
]
|
|
739
766
|
})
|
|
740
767
|
}, row.id);
|
|
741
768
|
};
|
|
@@ -806,7 +833,7 @@ window.__ModuleLoader__.load({
|
|
|
806
833
|
children: t("totalLimit")
|
|
807
834
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
808
835
|
className: "packyCodeFigureValue",
|
|
809
|
-
children: totals.counted === 0
|
|
836
|
+
children: totals.counted === 0 ? "—" : totals.unlimited > 0 ? t("keyUnlimited") : formatUsd(totals.limitUsd) ?? "—"
|
|
810
837
|
})]
|
|
811
838
|
})
|
|
812
839
|
]
|
|
@@ -814,6 +841,10 @@ window.__ModuleLoader__.load({
|
|
|
814
841
|
totals.unread > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
815
842
|
className: "packyCodeNote",
|
|
816
843
|
children: t("totalPartial").replace("{count}", String(totals.unread))
|
|
844
|
+
}),
|
|
845
|
+
rows.some((row) => row.stale !== void 0) && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
846
|
+
className: "packyCodeNote",
|
|
847
|
+
children: t("totalStale").replace("{count}", String(rows.filter((row) => row.stale !== void 0).length))
|
|
817
848
|
})
|
|
818
849
|
] })]
|
|
819
850
|
}),
|
|
@@ -1042,15 +1073,18 @@ window.__ModuleLoader__.load({
|
|
|
1042
1073
|
};
|
|
1043
1074
|
}, [call, enabled]);
|
|
1044
1075
|
if (!enabled || balance === void 0) return null;
|
|
1045
|
-
const
|
|
1046
|
-
const
|
|
1047
|
-
const
|
|
1076
|
+
const row = activeUsage(balance);
|
|
1077
|
+
const usage = row?.usage;
|
|
1078
|
+
const display = usage?.unlimitedQuota === true ? t("keyUnlimited") : formatUsd(usage?.availableUsd) ?? (row?.error === void 0 ? t("composerNoKey") : t("composerUnread"));
|
|
1079
|
+
const stale = row?.stale !== void 0 && usage !== void 0;
|
|
1080
|
+
const shown = stale ? `≈${display}` : display;
|
|
1081
|
+
const label = stale ? `${t("composerLabel")}: ${display}(${t("composerStale").replace("{time}", readTime(row.stale.fetchedAt))})` : `${t("composerLabel")}: ${display}`;
|
|
1048
1082
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1049
1083
|
className: "packyCodeComposer",
|
|
1050
1084
|
role: "status",
|
|
1051
1085
|
"aria-label": label,
|
|
1052
1086
|
title: label,
|
|
1053
|
-
children:
|
|
1087
|
+
children: shown
|
|
1054
1088
|
});
|
|
1055
1089
|
}
|
|
1056
1090
|
const inject = [
|