dsh-connect-workbuddy 4.8.0 → 4.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -0
- package/README.en.md +1 -1
- package/README.md +1 -1
- package/lib/bin.js +1 -1
- package/lib/client.js +216 -102
- package/lib/{host-heartbeat--S6JVSci.js → host-heartbeat-BfAvb1_d.js} +1 -1
- package/lib/index.js +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 4.8.1 (2026-10-18)
|
|
4
|
+
|
|
5
|
+
> 版本号是 **patch**:只改卡片界面的样式与排版,不改请求、响应、计费或任何配置项。发往上游的请求体与本版之前逐字节相同。
|
|
6
|
+
|
|
7
|
+
### Changes
|
|
8
|
+
|
|
9
|
+
- **积分读数区重排为「偏好行」,样式与排版对齐 dsh-connect-trae**
|
|
10
|
+
- **原来错在哪**:这个区块在卡片上换过三个位置 —— 先是 tab 栏下两个并排的复选框(读起来像**一个**共享设置),再被塞进「账号池」标题行(与标题、当前账号徽章挤在同一条基线,最宽的下拉框把徽章推到卡片最右缘,读起来像下拉框的标签),最后成了带独立标题的小节(`justify-content:space-between` 又把每句话劈成「左边缘的标签 + 右边缘的控件」,中间隔着半张卡的空隙)。三次都是**归属**问题,不是间距问题。
|
|
11
|
+
- **现在的形状**(与参考实现逐条一致):一块**没有标题的偏好行组**,直接挂在 tab 块下面 —— 一个复选框 + 标题 + 其下一行说明,然后**缩进 25px**(15px 方框 + 10px 行距)的「显示位置」行,标签与下拉框相邻、从左侧打包,行内没有任何元素被拉伸到边缘。
|
|
12
|
+
- **顺带修掉一个真漏洞**:这个区块此前通过 `AccountPool` 的 `headerExtra` 插槽渲染,而 `AccountPool` 在宿主不报告账号池状态时**整段返回 null** —— 开关会跟着一起消失,用户在那个宿主上**根本没有**打开读数的入口,唯一的线索是一行读数不见了。现在它渲染在 `AccountPool` 之外,与该区块是否存在无关。`headerExtra` 这个插槽已从 `AccountPool` 整个删除,不只是不再传。
|
|
13
|
+
- **文案随之改为「说明」而非「复述」**:主开关的标题由区域相关(「对话框显示 WB CN 积分」)改为区域无关的「在输入框工具栏显示积分读数」—— 它现在带一行自己的说明,且紧邻的下拉框就叫「输入框工具栏」,旧标题会与它重复。新增两段说明:开关下面那句讲**读数是什么**,下拉框下面那句讲**选位置是什么意思**;主开关关闭时后者换成一句点名原因和做法的提示,而不是留一个灰框让用户猜。
|
|
14
|
+
- **勾选框交回平台**:区域卡里的勾选框曾用 `appearance:none` 手绘(15px 方块、3px 圆角、两条旋转边框拼的勾)。参考实现没有手绘 —— 它只写 `accent-color`,方框的尺寸/圆角/勾形全由平台决定。截图实测:2x 屏上那个方块是 26 设备像素 = **13 CSS px**,正是引擎自带复选框的默认尺寸,不是任何人写下的数字。已改为与参考实现相同的两条声明,手绘规则全部删除。
|
|
15
|
+
- **下拉框退回原生外观**:曾手绘成白底细边 + 两条渐变拼的箭头(照一张**浅色**设置页截图),在深色卡片里成了唯一自带填充/边框/箭头的元素,读起来像贴进段落里的一个表单控件。现在用原生控件 + 一条细边,尺寸由它自己的两个选项决定,不再有 `min-width:132px` 这个为「与徽章共享标题行」而设的地板。
|
|
16
|
+
- **README**(中英同步):关掉读数的那句话改为新标签,并补上「显示位置」这一行的说明。
|
|
17
|
+
|
|
3
18
|
## 4.8.0 (2026-10-18)
|
|
4
19
|
|
|
5
20
|
> 版本号是 **minor**:这不是只改内部的 patch —— 它**会改动会话历史**。跨区/跨窗口切换后原本必然卡死的那一类会话,本版能把上下文折回去继续用。没有溢出时行为完全不变。
|
package/README.en.md
CHANGED
|
@@ -29,7 +29,7 @@ A [DeepSeek Harness (DSH)](https://github.com/deepseek-ai/deepseek-harness) bund
|
|
|
29
29
|
|
|
30
30
|
**Two things to know.** ① **It really does spend credits** — one measured probe reported `credit` 0.02 (a refused one 429s and costs almost nothing). So testing is **manual and per-model only**: there is deliberately no “Test selected” batch button, because sweeping the whole list from one click is an uncontrolled spend — and the Host enforces the same rule, **accepting a single model only** and refusing multi-model requests. ② The upstream advertises a 1M context yet throttles far below it, and the plugin advertises each model's **native** window to DSH (no longer clamped to 200K as of 3.5.0), so DSH compacts very late — hitting the throttle in a long session follows directly from that. To make DSH compact sooner, set a “DSH context budget” cap on the model's row (200K / 500K / the model's native window).
|
|
31
31
|
- **Local account switching** — discovers the multiple sign-in credentials WorkBuddy's desktop app leaves behind and lets you switch per region. Tokens are never written to DSH settings.
|
|
32
|
-
- **Credit readout in the composer toolbar (follows the selected model, per region)** — a clickable readout sits at the left of the composer toolbar (e.g. `WB CN · 1,072`) and **switches region automatically with the model this session is using**: pick a WB CN model and it shows the domestic balance, pick a WB AI model and it shows the international one; with any other provider's model it does not appear at all. It refreshes every 5 minutes and can also be refreshed by hand. Clicking it opens a panel: a **table of balances per account**, where clicking a row switches to that account (the same setting the card's account picker writes), and an account that cannot serve right now is **labelled in its row** (e.g. rate-limited, out of credits) using the same wording as the account-pool table. The per-account figures are fetched only while the panel is open, so the 5-minute background refresh never multiplies by the account count. To turn a side off, untick “Show
|
|
32
|
+
- **Credit readout in the composer toolbar (follows the selected model, per region)** — a clickable readout sits at the left of the composer toolbar (e.g. `WB CN · 1,072`) and **switches region automatically with the model this session is using**: pick a WB CN model and it shows the domestic balance, pick a WB AI model and it shows the international one; with any other provider's model it does not appear at all. It refreshes every 5 minutes and can also be refreshed by hand. Clicking it opens a panel: a **table of balances per account**, where clicking a row switches to that account (the same setting the card's account picker writes), and an account that cannot serve right now is **labelled in its row** (e.g. rate-limited, out of credits) using the same wording as the account-pool table. The per-account figures are fetched only while the panel is open, so the 5-minute background refresh never multiplies by the account count. To turn a side off, untick “Show credits in the composer toolbar” under that region's tab on the card; while a region's provider is switched off, the readout disappears and its switch is disabled. The same block carries a “Position” line: by default the readout sits in the composer toolbar (the row with the model picker); choosing “below the input box” moves it to the turn/step/token stats row instead — useful when another plugin has taken the toolbar seat.
|
|
33
33
|
|
|
34
34
|
<img src="docs/assets/dsh-connect-workbuddy-composer-credits.png" width="360" alt="Composer credit panel: a per-account balance table for the domestic region, with a refresh button and a last-refreshed time" />
|
|
35
35
|
- **Account pool: batch actions across several accounts, plus automatic failover** — tick the accounts you want into a pool and you get **one-click check-in for every account**, **one-click testing of every account against a model you choose** (defaulting to the region's zero-multiplier free model), and with **Enable the account pool** switched on, **automatic failover**: a request that fails upstream is retried against the pool's other usable accounts, in order, until one serves it or none is left. Membership starts **empty and is an explicit opt-in**: "signed in on this machine" is not the same as "spend this account's credits and claim its rewards". The pool's **ranking decides who serves every request** (usable first, then expiring-credits-first, higher credits, freshest credential), and on a failure the next usable member is tried. It **never writes back your saved selection** — switch the pool off and your own account applies again immediately. **The switch only decides whether the PLUGIN chooses** — with it off, the plugin stops picking and switching accounts for you, but check-in and testing stay available (they are manual actions). Testing reuses the model rows' real-volume probe, so it **does cost real credits**; **automatic check-in is deliberately not offered** — a check-in claims real rewards, so it only ever runs when you press the button. See [Account pool](#account-pool).
|
package/README.md
CHANGED
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
|
|
37
37
|
**两点需要知道**:① **它真的花钱**——实测一次报 `credit` 0.02(被限流时直接 429,几乎不花)。因此**只能按单个模型手工点**,没有「测试已勾选」这类批量按钮:一次覆盖整个列表就是一次不可控支出(服务端也据此**只接受单个模型**,多模型请求会被拒)。② 上游虽宣称 1M 上下文,但节流线远低于此;插件按模型的**原生窗口**向 DSH 宣称(3.5.0 起不再默认压到 200K),所以 DSH 很晚才压缩对话——长会话撞限流是这条机制的直接结果。想让 DSH 更早压缩,就在模型行上手动设一个「DSH 上下文预算」上限(可选 200K / 500K / 模型原生窗口)。
|
|
38
38
|
- **本机账号切换** —— 自动发现 WorkBuddy 桌面端留下的多个登录凭据,可按区域切换账号;Token 不写入 DSH 设置。
|
|
39
|
-
- **对话输入框积分读数(国内版 / 国际版自动切换)** —— 对话输入框左侧工具栏常驻一行可点击的读数(如 `WB CN · 1,072`),**按本会话当前选中的模型自动切换区域**:选中 WB CN 的模型就显示国内版余额,选中 WB AI 的模型就显示国际版余额;用其它 provider 的模型时该读数完全不出现。每 5 分钟自动刷新,也可点开手动刷新。点击读数弹出面板:**按账号列出的余额表格**,点某一行即可切换到该账号(与卡片上的账号选择是同一个设置);**当前不能用的账号会在行内标出原因**(如「被限流」「积分耗尽」),标注口径与账号池表格一致。面板里的余额只在打开时才去查,因此不会让 5 分钟的后台刷新按账号数翻倍。要关掉某一边,就在卡片对应区域的 tab
|
|
39
|
+
- **对话输入框积分读数(国内版 / 国际版自动切换)** —— 对话输入框左侧工具栏常驻一行可点击的读数(如 `WB CN · 1,072`),**按本会话当前选中的模型自动切换区域**:选中 WB CN 的模型就显示国内版余额,选中 WB AI 的模型就显示国际版余额;用其它 provider 的模型时该读数完全不出现。每 5 分钟自动刷新,也可点开手动刷新。点击读数弹出面板:**按账号列出的余额表格**,点某一行即可切换到该账号(与卡片上的账号选择是同一个设置);**当前不能用的账号会在行内标出原因**(如「被限流」「积分耗尽」),标注口径与账号池表格一致。面板里的余额只在打开时才去查,因此不会让 5 分钟的后台刷新按账号数翻倍。要关掉某一边,就在卡片对应区域的 tab 下取消勾选「在输入框工具栏显示积分读数」;该区域的供应商被关闭时,读数不显示、开关也置灰。同一个开关下面还有「显示位置」这一行:默认在输入框工具栏(与模型选择同一行),改成「输入框下方」后读数落到轮次/步数/token 统计那一行——装了别的插件把工具栏座位占掉时用得上。
|
|
40
40
|
|
|
41
41
|
<img src="docs/assets/dsh-connect-workbuddy-composer-credits.png" width="360" alt="对话输入框积分面板:国内版账号余额表格、刷新积分按钮与最近刷新时间" />
|
|
42
42
|
- **账号池:多账号批量操作与自动换号** —— 把要用的账号勾进池子,即可**一键签到所有账号**、**一键测试所有账号 × 你指定的模型**(默认挑该区域倍率为 0 的免费模型);开启**启用账号池**即同时打开**自动换号**——某个请求在上游失败时,插件会依次用池内其他可用账号重试,直到有一个接手、或全部不可用为止,然后才把错误报给你。成员**默认一个都不含**、必须显式勾选(「本机有登录」不等于「要拿它去签到和花积分」);**开启后由池子的排序决定每一次请求用谁**(可用优先,其次快过期先花、积分高、凭据更新的);失败时依次用池内其他可用账号重试。排序**从不写回你保存的选择**——关掉开关,你选定的账号立刻完全生效。只有请求本身不合法(HTTP 400)不换号:同一个请求体换谁都是 400,重试只会白等。**这个开关只管「插件要不要自己决定」**:关掉它,插件不再替你选账号、也不再替你换号,但**签到与测试仍然可用**(它们是手动动作)。测试走的是与模型行同一套真实体积探测,因此**有真实成本**;**不提供自动签到**——签到会真实领取奖励,只在你点按钮时执行。详见[账号池](#账号池)。
|
package/lib/bin.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { C as defaultDesktopAuthDirs, F as WorkBuddyUpstreamClient, K as WORKBUDDY_APP_EXECUTABLE_ENV, O as legacyWorkbuddyOwnAuthPath, Q as findWorkbuddyAppExecutableWithSource, S as defaultDesktopAuthCandidates, a as readHostHeartbeat, c as WORKBUDDY_CONNECT_VERSION, d as FALLBACK_WORKBUDDY_MODELS_GLOBAL, j as workbuddyOwnAuthPath, l as piAiRuntimeInfo, o as workbuddyHostHeartbeatPath, ot as hostPeersInfo, r as isHeartbeatProcessAlive, u as FALLBACK_WORKBUDDY_MODELS, v as WORKBUDDY_AUTH_FILE_ENV, y as WorkBuddyCredentialStore } from "./host-heartbeat
|
|
2
|
+
import { C as defaultDesktopAuthDirs, F as WorkBuddyUpstreamClient, K as WORKBUDDY_APP_EXECUTABLE_ENV, O as legacyWorkbuddyOwnAuthPath, Q as findWorkbuddyAppExecutableWithSource, S as defaultDesktopAuthCandidates, a as readHostHeartbeat, c as WORKBUDDY_CONNECT_VERSION, d as FALLBACK_WORKBUDDY_MODELS_GLOBAL, j as workbuddyOwnAuthPath, l as piAiRuntimeInfo, o as workbuddyHostHeartbeatPath, ot as hostPeersInfo, r as isHeartbeatProcessAlive, u as FALLBACK_WORKBUDDY_MODELS, v as WORKBUDDY_AUTH_FILE_ENV, y as WorkBuddyCredentialStore } from "./host-heartbeat-BfAvb1_d.js";
|
|
3
3
|
import { realpathSync } from "node:fs";
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
5
|
//#region src/bin.ts
|
package/lib/client.js
CHANGED
|
@@ -1403,7 +1403,7 @@ window.__ModuleLoader__.load({
|
|
|
1403
1403
|
* section implying the feature exists.
|
|
1404
1404
|
*/
|
|
1405
1405
|
function AccountPool(props) {
|
|
1406
|
-
const { t, region, pool, settingsScope, siblingBusy, onBusyChange, onSaved, onRefresh, onRescan, rescanning, onSelectAccount, selectingAccount, accountTools
|
|
1406
|
+
const { t, region, pool, settingsScope, siblingBusy, onBusyChange, onSaved, onRefresh, onRescan, rescanning, onSelectAccount, selectingAccount, accountTools } = props;
|
|
1407
1407
|
const [draft, setDraft] = (0, react.useState)(null);
|
|
1408
1408
|
const [saving, setSaving] = (0, react.useState)(false);
|
|
1409
1409
|
const [saveError, setSaveError] = (0, react.useState)(void 0);
|
|
@@ -1863,7 +1863,7 @@ window.__ModuleLoader__.load({
|
|
|
1863
1863
|
visible: true,
|
|
1864
1864
|
message: t("row.poolSaving"),
|
|
1865
1865
|
hint: t("row.veilHintList")
|
|
1866
|
-
}) : null, (0, react.createElement)("div", { className: "dsm-workbuddy-pool-head" }, (0, react.createElement)("h3", { className: "dsm-workbuddy-pool-title" }, t("row.poolTitle")),
|
|
1866
|
+
}) : null, (0, react.createElement)("div", { className: "dsm-workbuddy-pool-head" }, (0, react.createElement)("h3", { className: "dsm-workbuddy-pool-title" }, t("row.poolTitle")), currentName === void 0 ? null : (0, react.createElement)("span", { className: "dsm-workbuddy-pool-current-badge" }, t("row.poolCurrentHeader", { account: currentName }))), !poolRunning && onSelectAccount !== void 0 && pool.accounts.length > 0 ? (0, react.createElement)("div", { className: "dsm-workbuddy-pool-set" }, (0, react.createElement)("span", { className: "dsm-workbuddy-pool-set-copy" }, (0, react.createElement)("b", null, t("row.poolManualAccountLabel")), (0, react.createElement)("span", null, t("row.poolManualAccountHint"))), (0, react.createElement)("span", { className: "dsm-workbuddy-pool-set-ctl" }, (0, react.createElement)("select", {
|
|
1867
1867
|
className: "dsm-workbuddy-pool-select dsm-workbuddy-pool-account-select",
|
|
1868
1868
|
value: currentAccount?.accountId ?? "",
|
|
1869
1869
|
disabled: selectingAccount === true,
|
|
@@ -3047,33 +3047,105 @@ window.__ModuleLoader__.load({
|
|
|
3047
3047
|
.dsm-btn-primary{background:var(--dsw-alias-label-primary);color:var(--dsw-alias-bg-layer-3)}
|
|
3048
3048
|
.dsm-btn-primary:hover:not(:disabled){opacity:.9}
|
|
3049
3049
|
.dsm-workbuddy-usage{display:flex;flex-direction:column;gap:16px;margin:0;padding:16px 0 4px}
|
|
3050
|
-
|
|
3051
|
-
|
|
3050
|
+
/* The provider bar: one CARD per region, side by side.
|
|
3051
|
+
*
|
|
3052
|
+
* COPIED FROM dsh-connect-trae, rule for rule, because an approximation of it
|
|
3053
|
+
* read as a different component. An earlier revision marked the selected card
|
|
3054
|
+
* with 1px border PLUS an inset 1.5px hairline in the contrast colour, and
|
|
3055
|
+
* that is 2.5 CSS px of near-black on a 2x display — five device pixels of
|
|
3056
|
+
* frame against the reference's one. What the reference does instead:
|
|
3057
|
+
*
|
|
3058
|
+
* - selected = the accent COLOUR on the same 1px border, plus a slightly
|
|
3059
|
+
* darker fill. The LIGHTNESS carries the state, not the thickness.
|
|
3060
|
+
* - the switch is separated from the label by a hairline RULE inside the
|
|
3061
|
+
* card (border-left in border-l1), not by dead space. That rule is what
|
|
3062
|
+
* makes the switch read as a second control in the same box rather than
|
|
3063
|
+
* as a floating square at the card's right edge.
|
|
3064
|
+
* - the cell owns its padding (8px 12px) and the tab button has none, so
|
|
3065
|
+
* the label's text sits at a predictable inset no matter how the button's
|
|
3066
|
+
* focus ring draws.
|
|
3067
|
+
* - 10px corner radius, matching the reference's card shape.
|
|
3068
|
+
*
|
|
3069
|
+
* The row stays what it was semantically: role="tablist" with one button per
|
|
3070
|
+
* region, and the checkbox inside each card is a SEPARATE control (switch this
|
|
3071
|
+
* provider on/off) — never merged into the tab action. Both regions can be on
|
|
3072
|
+
* at once, so this must not become a radio group just because the cards look
|
|
3073
|
+
* like one.
|
|
3074
|
+
*
|
|
3075
|
+
* The checkbox is the PLATFORM'S OWN, styled only with accent-color — the
|
|
3076
|
+
* same three declarations the reference card has, no more. An earlier revision
|
|
3077
|
+
* drew it here (appearance:none, 15px square, 3px radius, a tick made of two
|
|
3078
|
+
* rotated borders) on the theory that pinning the geometry would match the
|
|
3079
|
+
* reference across platforms. It did not: the reference does not draw it, so
|
|
3080
|
+
* the drawn box was a second, invented control sitting in the same row as the
|
|
3081
|
+
* real one. Measured against the screenshot, its box is 26 device px on a 2x
|
|
3082
|
+
* display — 13 CSS px, which is the engine's own default size, not a number
|
|
3083
|
+
* anyone wrote down.
|
|
3084
|
+
*
|
|
3085
|
+
* accent-color hands size, radius and tick glyph to the platform. That is the
|
|
3086
|
+
* point: the box then follows the reader's OS and theme, which is what makes
|
|
3087
|
+
* it read as a checkbox rather than as a painted square. */
|
|
3088
|
+
.dsm-workbuddy-tabs{display:flex;gap:8px;align-items:stretch}
|
|
3089
|
+
.dsm-workbuddy-tab-cell{display:flex;align-items:center;gap:4px;flex:1;min-width:0;padding:8px 12px;border:1px solid var(--dsw-alias-border-l2,#3a3d45);border-radius:10px;background:var(--dsw-alias-bg-layer-3,#2a2c33);transition:border-color .15s,background .15s}
|
|
3090
|
+
.dsm-workbuddy-tab-cell:hover{border-color:var(--dsw-alias-label-dimmed,#777)}
|
|
3091
|
+
.dsm-workbuddy-tab-cell:has(.dsm-workbuddy-tab-active){border-color:var(--dsw-alias-brand-primary,#5686fe);background:var(--dsw-alias-bg-layer-2,#232529)}
|
|
3092
|
+
.dsm-workbuddy-tab{appearance:none;font:inherit;cursor:pointer;flex:1;min-width:0;border:0;border-radius:7px;padding:0;color:var(--dsw-alias-label-tertiary,#999);font-size:13px;font-weight:600;line-height:20px;text-align:left;background:transparent;transition:color .15s;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
|
3052
3093
|
.dsm-workbuddy-tab:hover:not(:disabled):not(.dsm-workbuddy-tab-active){color:var(--dsw-alias-label-primary,#e6e6e6)}
|
|
3053
3094
|
.dsm-workbuddy-tab:focus-visible{outline:2px solid var(--dsw-alias-brand-primary,#5686fe);outline-offset:1px}
|
|
3054
|
-
.dsm-workbuddy-tab-active{color:var(--dsw-alias-label-primary,#e6e6e6)
|
|
3055
|
-
.dsm-workbuddy-tab-dot{display:inline-block;width:7px;height:7px;border-radius:50%;margin-right:
|
|
3056
|
-
.
|
|
3057
|
-
|
|
3095
|
+
.dsm-workbuddy-tab-active{color:var(--dsw-alias-label-primary,#e6e6e6)}
|
|
3096
|
+
.dsm-workbuddy-tab-dot{display:inline-block;width:7px;height:7px;border-radius:50%;margin-right:7px;vertical-align:baseline}
|
|
3097
|
+
/* The hairline rule between the label and the switch. The auto left margin is
|
|
3098
|
+
what pushes the switch to the card's right edge; without it the rule would
|
|
3099
|
+
sit tight against the text. */
|
|
3100
|
+
.dsm-workbuddy-tab-switch{display:inline-flex;align-items:center;flex:none;margin-left:auto;padding-left:10px;border-left:1px solid var(--dsw-alias-border-l1,rgba(127,127,127,.24));cursor:pointer}
|
|
3058
3101
|
.dsm-workbuddy-tab-switch input{margin:0;cursor:pointer;accent-color:var(--dsw-alias-brand-primary,#5686fe)}
|
|
3059
|
-
.dsm-workbuddy-tab-switch input:disabled{
|
|
3060
|
-
/*
|
|
3061
|
-
the
|
|
3062
|
-
|
|
3063
|
-
|
|
3064
|
-
|
|
3065
|
-
|
|
3066
|
-
.
|
|
3067
|
-
|
|
3068
|
-
|
|
3069
|
-
|
|
3070
|
-
|
|
3071
|
-
|
|
3072
|
-
|
|
3073
|
-
|
|
3074
|
-
|
|
3075
|
-
|
|
3076
|
-
|
|
3102
|
+
.dsm-workbuddy-tab-switch input:disabled{cursor:default}
|
|
3103
|
+
/* PREFERENCE LINES: a checkbox on a line that commits on the click, packed from
|
|
3104
|
+
the LEFT — the shape the reference card uses for this exact block.
|
|
3105
|
+
*
|
|
3106
|
+
* They belong to the TAB block above and carry no heading of their own, because
|
|
3107
|
+
* both switches describe THIS tab. Earlier revisions gave them a headed section,
|
|
3108
|
+
* which meant a second 「积分」 heading one line under the tab hint; the reference
|
|
3109
|
+
* card never had one either.
|
|
3110
|
+
*
|
|
3111
|
+
* The picker used to sit at the row's far edge, pushed there by
|
|
3112
|
+
* justify-content:space-between. That split one sentence into two objects with
|
|
3113
|
+
* half a card of empty space between them, and left the reader to guess which
|
|
3114
|
+
* label the control belonged to. Here nothing in a row stretches: the words ask
|
|
3115
|
+
* the question and the control answers right beside them.
|
|
3116
|
+
*
|
|
3117
|
+
* align-items:flex-start, not center: the hint wraps to two lines at narrow
|
|
3118
|
+
* widths, and centring would float the checkbox against the middle of it.
|
|
3119
|
+
*
|
|
3120
|
+
* No horizontal inset: the reference card pads this block by the same 2px its
|
|
3121
|
+
* tab hint carries, so box and caption share one left edge. THIS card's tab hint
|
|
3122
|
+
* (the dsm-workbuddy-models-summary class) has no side padding, so copying the
|
|
3123
|
+
* reference's 2px would leave the two edges 2px apart — a difference too small
|
|
3124
|
+
* to name and just big enough to look unaligned. */
|
|
3125
|
+
.dsm-workbuddy-prefs{display:flex;flex-direction:column;gap:14px;padding:2px 0 0}
|
|
3126
|
+
.dsm-workbuddy-pref{display:flex;align-items:flex-start;gap:10px;font-size:13px;line-height:18px;color:var(--dsw-alias-label-secondary,#c6c9d0);cursor:pointer}
|
|
3127
|
+
/* The platform's own checkbox, themed only with accent-color. A hand-drawn box
|
|
3128
|
+
was tried on this card and reverted: brand-primary resolves to the host's
|
|
3129
|
+
CONTRAST colour, so a ticked box painted itself as a heavy black pill — the
|
|
3130
|
+
loudest object in a section made of plain 13px text. */
|
|
3131
|
+
.dsm-workbuddy-pref input{flex:none;cursor:pointer;accent-color:var(--dsw-alias-brand-primary,#5686fe)}
|
|
3132
|
+
.dsm-workbuddy-pref-check{inline-size:15px;block-size:15px;margin:3px 0 0}
|
|
3133
|
+
.dsm-workbuddy-pref input:disabled{cursor:default}
|
|
3134
|
+
.dsm-workbuddy-pref:has(input:disabled){opacity:.6;cursor:default}
|
|
3135
|
+
/* The NAME and what it does are TWO lines, not one wrapped blob: first what the
|
|
3136
|
+
switch does, then what it means. Running them together is what made this
|
|
3137
|
+
block read as a wall of text. */
|
|
3138
|
+
.dsm-workbuddy-pref-copy{display:flex;flex-direction:column;gap:3px;min-width:0}
|
|
3139
|
+
.dsm-workbuddy-pref-label{font-weight:500;color:var(--dsw-alias-label-primary,#e6e6e6)}
|
|
3140
|
+
/* The picker's own line: indented by the checkbox's width plus the row gap
|
|
3141
|
+
(15px + 10px), so its label starts on the same left edge as the checkbox
|
|
3142
|
+
labels above it rather than under their boxes. */
|
|
3143
|
+
.dsm-workbuddy-pref-indent{padding-left:25px}
|
|
3144
|
+
/* Name then control, packed left — 显示位置 [输入框工具栏] — so the row reads as
|
|
3145
|
+
one sentence instead of a text column facing a control column. */
|
|
3146
|
+
.dsm-workbuddy-pref-lead{display:flex;align-items:center;justify-content:flex-start;gap:10px;min-width:0}
|
|
3147
|
+
.dsm-workbuddy-pref-lead .dsm-workbuddy-pref-label{flex:none}
|
|
3148
|
+
.dsm-workbuddy-pref-hint{color:var(--dsw-alias-label-tertiary,#999);font-size:12px;line-height:17px}
|
|
3077
3149
|
/* The supplement to the host's fixed quota sentence (issue #63). The plugin no
|
|
3078
3150
|
longer claims the host's shell.quota-notice chain seat, so this no longer
|
|
3079
3151
|
paints into shell.overlay — that seat is the reason the previous build's
|
|
@@ -3084,11 +3156,34 @@ window.__ModuleLoader__.load({
|
|
|
3084
3156
|
The body is one step quieter than the text it follows. */
|
|
3085
3157
|
.dsm-workbuddy-quota-notice{display:inline}
|
|
3086
3158
|
.dsm-workbuddy-quota-notice-body{color:var(--dsw-alias-label-tertiary,#8b8f98);font-size:12px}
|
|
3087
|
-
|
|
3088
|
-
|
|
3089
|
-
|
|
3090
|
-
|
|
3091
|
-
|
|
3159
|
+
/* The seat picker is the PLATFORM's select, sized by its own two options rather
|
|
3160
|
+
* than stretched: the control answers one short question and sits beside the
|
|
3161
|
+
* words that ask it.
|
|
3162
|
+
*
|
|
3163
|
+
* This was drawn by hand for one revision — appearance:none, a layer-2 panel and
|
|
3164
|
+
* a chevron built from two rotated gradients — copying a reference screenshot's
|
|
3165
|
+
* white field. That does not survive the trip: the screenshot was a LIGHT
|
|
3166
|
+
* settings page, this card is dark, and the drawn field ended up the only
|
|
3167
|
+
* element here with its own fill, border and arrow, so it read as a form control
|
|
3168
|
+
* pasted into a paragraph. The reference card's own dark build uses the native
|
|
3169
|
+
* control with a hairline border, which is what this rule is.
|
|
3170
|
+
*
|
|
3171
|
+
* Sized by content, not by a min-width: it used to carry min-width:132px so it
|
|
3172
|
+
* could share a heading row with the account badge, and that floor is now the
|
|
3173
|
+
* reason a two-word option would still leave a gap after the word it answers. */
|
|
3174
|
+
.dsm-workbuddy-credit-position{flex:none;max-width:none;margin-top:0;padding:3px 8px;border:1px solid var(--dsw-alias-border-l2,#3a3d45);border-radius:7px;background:var(--dsw-alias-bg-layer-3,#2a2c33);color:var(--dsw-alias-label-primary,#e6e6e6);font:inherit;font-size:12px;line-height:16px;cursor:pointer}
|
|
3175
|
+
.dsm-workbuddy-credit-position:hover:not(:disabled){border-color:var(--dsw-alias-label-dimmed,#777)}
|
|
3176
|
+
.dsm-workbuddy-credit-position:focus-visible{outline:2px solid var(--dsw-alias-brand-primary,#5686fe);outline-offset:1px}
|
|
3177
|
+
.dsm-workbuddy-credit-position:disabled{opacity:.5;cursor:default}
|
|
3178
|
+
/* A card whose provider is switched OFF dims its LABEL AND DOT. The checkbox
|
|
3179
|
+
* beside them must stay at full strength, because that checkbox is the only
|
|
3180
|
+
* way to switch the region back on — dimming it would grey out the control
|
|
3181
|
+
* that fixes the state it is reporting. Its own disabled rule still dims it
|
|
3182
|
+
* when writes are unavailable, which is a different condition and reads as a
|
|
3183
|
+
* different thing.
|
|
3184
|
+
*
|
|
3185
|
+
* That is also what the reference card does: it marks the off state on the
|
|
3186
|
+
* tab button and leaves the switch live. */
|
|
3092
3187
|
.dsm-workbuddy-tab-off{opacity:.55}
|
|
3093
3188
|
/* Re-detection keeps a copy in the signed-out branch (that branch is where
|
|
3094
3189
|
"I just signed in over there" applies), so it needs its own placement: the
|
|
@@ -3187,14 +3282,19 @@ window.__ModuleLoader__.load({
|
|
|
3187
3282
|
|
|
3188
3283
|
/* ---- Account pool ---- */
|
|
3189
3284
|
.dsm-workbuddy-pool{display:flex;flex-direction:column;gap:12px;margin:0;padding:16px 0 4px;border-top:1px solid var(--dsw-alias-border-l2,#36373b)}
|
|
3190
|
-
/*
|
|
3191
|
-
|
|
3192
|
-
|
|
3193
|
-
|
|
3194
|
-
|
|
3195
|
-
|
|
3285
|
+
/* The block's heading: title on the left, serving-account badge on the right.
|
|
3286
|
+
*
|
|
3287
|
+
* It used to hold a THIRD child — the credit-readout switch, slotted in between
|
|
3288
|
+
* the title and the badge by the card. A control that configures something else
|
|
3289
|
+
* spent several revisions sitting inside this block's title, and it forced the
|
|
3290
|
+
* row onto a shared baseline with a picker whose width shoved the badge to the
|
|
3291
|
+
* far edge. The switch now has its own section above; what is left is the one
|
|
3292
|
+
* thing that is genuinely this block's title row.
|
|
3293
|
+
*
|
|
3294
|
+
* The badge is pushed right with margin-left:auto rather than the row using
|
|
3295
|
+
* space-between, so it stays on the right edge even if a future change adds a
|
|
3296
|
+
* child or removes one. */
|
|
3196
3297
|
.dsm-workbuddy-pool-head{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
|
|
3197
|
-
.dsm-workbuddy-pool-head-extra{display:inline-flex;align-items:center}
|
|
3198
3298
|
.dsm-workbuddy-pool-current-badge{margin-left:auto;padding:2px 10px;border-radius:999px;background:rgba(86,134,254,.16);color:var(--dsw-alias-brand-primary,#5686fe);font-size:12px;font-weight:600;line-height:18px;white-space:nowrap}
|
|
3199
3299
|
/* Sits under the header block, before the batch buttons: account discovery is
|
|
3200
3300
|
the first step of using the pool, so it reads above the actions it enables. */
|
|
@@ -4614,39 +4714,6 @@ window.__ModuleLoader__.load({
|
|
|
4614
4714
|
}))
|
|
4615
4715
|
})] });
|
|
4616
4716
|
/**
|
|
4617
|
-
* Sidebar credit line switch — ONE control, for the ACTIVE tab's region only.
|
|
4618
|
-
*
|
|
4619
|
-
* The two regions are independent providers with independent accounts, so
|
|
4620
|
-
* each tab owns its own switch and they are never shown as a pair: this one
|
|
4621
|
-
* writes `regions.<activeRegion>.showCreditsInMainUi`, which decides only
|
|
4622
|
-
* whether THAT region's line appears in the sidebar. That matches how every
|
|
4623
|
-
* other control in this card is scoped to the selected tab (account, pool,
|
|
4624
|
-
* model list), and it means a CN-only user is never shown a switch for an
|
|
4625
|
-
* account they do not have. An earlier revision rendered both boxes side by
|
|
4626
|
-
* side under the tab bar regardless of the active tab; that read as one
|
|
4627
|
-
* shared setting and was replaced.
|
|
4628
|
-
*
|
|
4629
|
-
* RENDERED BESIDE THE POOL HEADING, not on its own row. It used to occupy a
|
|
4630
|
-
* full line of vertical space for a single checkbox; the pool heading already
|
|
4631
|
-
* had a title-left / badge-right row, so the control fits there without the
|
|
4632
|
-
* block growing. It is handed to `AccountPool` as a ready-made node purely so
|
|
4633
|
-
* the two can share a flex row — the write path, the disabled rules and the
|
|
4634
|
-
* serialization against the card's other region writers all stay here, where
|
|
4635
|
-
* the settings scope and the save state live.
|
|
4636
|
-
*/
|
|
4637
|
-
const creditsSwitch = /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
4638
|
-
className: "dsm-workbuddy-credits-switch",
|
|
4639
|
-
title: activeRegion === "cn" ? t("row.showCreditsCnHint") : t("row.showCreditsGlobalHint"),
|
|
4640
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
4641
|
-
type: "checkbox",
|
|
4642
|
-
checked: activeRegionOn ? creditsShownOn(activeRegion) : false,
|
|
4643
|
-
disabled: !activeRegionOn || togglingCredits === activeRegion || !canWrite || saving || poolBusy,
|
|
4644
|
-
onChange: (event) => {
|
|
4645
|
-
toggleCredits(activeRegion, event.target.checked);
|
|
4646
|
-
}
|
|
4647
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: activeRegion === "cn" ? t("row.showCreditsCn") : t("row.showCreditsGlobal") })]
|
|
4648
|
-
});
|
|
4649
|
-
/**
|
|
4650
4717
|
* WHERE the readout sits — a two-way choice, active tab's region only
|
|
4651
4718
|
* (issue #62).
|
|
4652
4719
|
*
|
|
@@ -4654,31 +4721,76 @@ window.__ModuleLoader__.load({
|
|
|
4654
4721
|
* question together ("show it, and where"), and because a user only reaches
|
|
4655
4722
|
* for this when the default seat is unavailable — typically after installing
|
|
4656
4723
|
* another plugin that occupies the composer row. Rendered as a `<select>`
|
|
4657
|
-
* rather than a pair of radios so it stays one compact row
|
|
4658
|
-
*
|
|
4724
|
+
* rather than a pair of radios so it stays one compact row.
|
|
4725
|
+
*
|
|
4726
|
+
* LABEL LEFT, CONTROL RIGHT — the reverse of the first draft, which put the
|
|
4727
|
+
* select first. Under an always-visible caption the label is what the eye
|
|
4728
|
+
* scans for ("显示位置"), so it leads and the value follows; leading with the
|
|
4729
|
+
* control made it read as a second checkbox whose box happened to be a
|
|
4730
|
+
* dropdown. It also matches the reference settings screen, where the option
|
|
4731
|
+
* name sits left of its picker.
|
|
4659
4732
|
*
|
|
4660
4733
|
* Disabled with the region, exactly like the switch: a region that is off has
|
|
4661
4734
|
* no readout to place.
|
|
4662
4735
|
*/
|
|
4663
|
-
const creditPositionPicker = /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("
|
|
4664
|
-
className: "dsm-workbuddy-credit-position
|
|
4665
|
-
|
|
4666
|
-
|
|
4667
|
-
|
|
4668
|
-
|
|
4669
|
-
|
|
4670
|
-
|
|
4671
|
-
|
|
4672
|
-
|
|
4673
|
-
|
|
4674
|
-
|
|
4675
|
-
|
|
4676
|
-
|
|
4677
|
-
|
|
4678
|
-
|
|
4679
|
-
|
|
4736
|
+
const creditPositionPicker = /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
|
|
4737
|
+
className: "dsm-workbuddy-credit-position",
|
|
4738
|
+
value: activeRegionOn ? creditPositionOn(activeRegion) : "composer",
|
|
4739
|
+
disabled: !activeRegionOn || togglingCredits === activeRegion || !canWrite || saving || poolBusy,
|
|
4740
|
+
"aria-label": t("row.creditPositionAria", { region: activeRegion === "cn" ? t("row.tabCn") : t("row.tabGlobal") }),
|
|
4741
|
+
onChange: (event) => {
|
|
4742
|
+
changeCreditPosition(activeRegion, event.currentTarget.value === "stats" ? "stats" : "composer");
|
|
4743
|
+
},
|
|
4744
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
4745
|
+
value: "composer",
|
|
4746
|
+
children: t("row.creditPositionComposer")
|
|
4747
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
4748
|
+
value: "stats",
|
|
4749
|
+
children: t("row.creditPositionStats")
|
|
4750
|
+
})]
|
|
4751
|
+
});
|
|
4752
|
+
const creditPositionCaption = t("row.creditPositionHintInline");
|
|
4753
|
+
const creditPositionDisabledCaption = t("row.creditPositionDisabledHint");
|
|
4754
|
+
const creditPreferences = /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4755
|
+
className: "dsm-workbuddy-prefs",
|
|
4756
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
4757
|
+
className: "dsm-workbuddy-pref",
|
|
4758
|
+
title: activeRegion === "cn" ? t("row.showCreditsCnHint") : t("row.showCreditsGlobalHint"),
|
|
4759
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
4760
|
+
type: "checkbox",
|
|
4761
|
+
className: "dsm-workbuddy-pref-check",
|
|
4762
|
+
checked: activeRegionOn ? creditsShownOn(activeRegion) : false,
|
|
4763
|
+
disabled: !activeRegionOn || togglingCredits === activeRegion || !canWrite || saving || poolBusy,
|
|
4764
|
+
onChange: (event) => {
|
|
4765
|
+
toggleCredits(activeRegion, event.target.checked);
|
|
4766
|
+
}
|
|
4767
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
4768
|
+
className: "dsm-workbuddy-pref-copy",
|
|
4769
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
4770
|
+
className: "dsm-workbuddy-pref-label",
|
|
4771
|
+
children: activeRegion === "cn" ? t("row.showCreditsCn") : t("row.showCreditsGlobal")
|
|
4772
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
4773
|
+
className: "dsm-workbuddy-pref-hint",
|
|
4774
|
+
children: t("row.showCreditsHintInline")
|
|
4775
|
+
})]
|
|
4680
4776
|
})]
|
|
4681
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("
|
|
4777
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
4778
|
+
className: "dsm-workbuddy-pref dsm-workbuddy-pref-indent",
|
|
4779
|
+
title: t("row.creditPositionHint"),
|
|
4780
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
4781
|
+
className: "dsm-workbuddy-pref-copy",
|
|
4782
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
4783
|
+
className: "dsm-workbuddy-pref-lead",
|
|
4784
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
4785
|
+
className: "dsm-workbuddy-pref-label",
|
|
4786
|
+
children: t("row.creditPositionLabel")
|
|
4787
|
+
}), creditPositionPicker]
|
|
4788
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
4789
|
+
className: "dsm-workbuddy-pref-hint",
|
|
4790
|
+
children: activeRegionOn ? creditPositionCaption : creditPositionDisabledCaption
|
|
4791
|
+
})]
|
|
4792
|
+
})
|
|
4793
|
+
})]
|
|
4682
4794
|
});
|
|
4683
4795
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
|
|
4684
4796
|
className: `dsm-plugin-card${open ? " dsm-plugin-card-open" : ""}`,
|
|
@@ -4768,6 +4880,7 @@ window.__ModuleLoader__.load({
|
|
|
4768
4880
|
className: "dsm-workbuddy-tab-off-notice",
|
|
4769
4881
|
children: t("row.tabOffNotice")
|
|
4770
4882
|
}) : null,
|
|
4883
|
+
creditPreferences,
|
|
4771
4884
|
status.status === "error" || status.status === "signed-in" && status.creditsError !== void 0 ? status.status === "signed-in" && status.credentialRejected === true ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
4772
4885
|
className: "dsm-workbuddy-usage-hint",
|
|
4773
4886
|
children: t("row.reloginHint")
|
|
@@ -4824,16 +4937,11 @@ window.__ModuleLoader__.load({
|
|
|
4824
4937
|
},
|
|
4825
4938
|
selectingAccount: switchingAccount,
|
|
4826
4939
|
accountTools,
|
|
4827
|
-
...status.pool === void 0 ? {} : { headerExtra: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [creditsSwitch, creditPositionPicker] }) },
|
|
4828
4940
|
siblingBusy: saving || togglingRegion !== void 0,
|
|
4829
4941
|
onBusyChange: setPoolBusy,
|
|
4830
4942
|
onSaved: async () => await refreshUsage(activeRegion) !== void 0,
|
|
4831
4943
|
onRefresh: () => refreshUsage(activeRegion)
|
|
4832
4944
|
}),
|
|
4833
|
-
status.pool === void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4834
|
-
className: "dsm-workbuddy-credits-switch-row",
|
|
4835
|
-
children: [creditsSwitch, creditPositionPicker]
|
|
4836
|
-
}) : null,
|
|
4837
4945
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("section", {
|
|
4838
4946
|
className: "dsm-workbuddy-models",
|
|
4839
4947
|
"aria-label": t("row.modelsTitle"),
|
|
@@ -6188,13 +6296,16 @@ window.__ModuleLoader__.load({
|
|
|
6188
6296
|
"row.poolRowRemoved": "{accountName}: hidden from the list. 「Detect accounts again」 re-adds it; the desktop app stays signed in.",
|
|
6189
6297
|
"row.poolRowRemoving": "Removing the account…",
|
|
6190
6298
|
"row.poolRowRemoveDesktopOnly": "{accountName}: hidden from the list — this account comes from the desktop app's own sign-in, which is left untouched. 「Detect accounts again」 re-adds it.",
|
|
6191
|
-
"row.showCreditsCn": "
|
|
6192
|
-
"row.showCreditsGlobal": "
|
|
6299
|
+
"row.showCreditsCn": "Show credits in the composer toolbar",
|
|
6300
|
+
"row.showCreditsGlobal": "Show credits in the composer toolbar",
|
|
6193
6301
|
"row.showCreditsCnHint": "Show the domestic (WB CN) credit balance in the composer toolbar, but only while this session uses a WB CN model. Click it for per-account balances and a manual refresh (refreshes by itself every 5 minutes).",
|
|
6194
|
-
"row.creditPositionLabel": "
|
|
6302
|
+
"row.creditPositionLabel": "Position",
|
|
6195
6303
|
"row.creditPositionComposer": "composer toolbar",
|
|
6196
6304
|
"row.creditPositionStats": "below the input box",
|
|
6197
6305
|
"row.creditPositionAria": "Credit readout position for {region}",
|
|
6306
|
+
"row.creditPositionHintInline": "Where the readout sits. \"composer toolbar\" is the default — the row with the model picker.",
|
|
6307
|
+
"row.creditPositionDisabledHint": "Unavailable while the switch above is off: tick \"Show credits in the composer toolbar\" first.",
|
|
6308
|
+
"row.showCreditsHintInline": "The balance for the account currently serving this tab. Click for per-account balances; it also refreshes every 5 minutes.",
|
|
6198
6309
|
"quotaNotice.fallbackHead": "The quota for this request is exhausted",
|
|
6199
6310
|
"quotaNotice.supplement": " (some models also have a daily limit that is unrelated to your credits)",
|
|
6200
6311
|
"row.creditPositionHint": "Where the credit readout sits. \"composer toolbar\" is the default (the row with the model picker). Choose \"below the input box\" — the row carrying the round / step / token statistics — if another plugin occupies the composer toolbar and the readout does not appear.",
|
|
@@ -6473,13 +6584,16 @@ window.__ModuleLoader__.load({
|
|
|
6473
6584
|
"row.poolRowRemoved": "{accountName}:已从列表中隐藏。点「重新检测账号」会重新加入,桌面 App 的登录不受影响。",
|
|
6474
6585
|
"row.poolRowRemoving": "正在删除账号…",
|
|
6475
6586
|
"row.poolRowRemoveDesktopOnly": "{accountName}:已从列表中隐藏——这个账号来自桌面 App 自己的登录,该登录未被改动。点「重新检测账号」会重新加入。",
|
|
6476
|
-
"row.showCreditsCn": "
|
|
6477
|
-
"row.showCreditsGlobal": "
|
|
6587
|
+
"row.showCreditsCn": "在输入框工具栏显示积分读数",
|
|
6588
|
+
"row.showCreditsGlobal": "在输入框工具栏显示积分读数",
|
|
6478
6589
|
"row.showCreditsCnHint": "在对话输入框工具栏显示国内版(WB CN)剩余积分,仅当本会话使用 WB CN 模型时出现。点击可看各账号余额并手动刷新(每 5 分钟也会自动刷新)。",
|
|
6479
|
-
"row.creditPositionLabel": "
|
|
6590
|
+
"row.creditPositionLabel": "显示位置",
|
|
6480
6591
|
"row.creditPositionComposer": "输入框工具栏",
|
|
6481
6592
|
"row.creditPositionStats": "输入框下方",
|
|
6482
6593
|
"row.creditPositionAria": "{region} 的积分显示位置",
|
|
6594
|
+
"row.creditPositionHintInline": "读数显示在哪里。「输入框工具栏」是默认位置,与模型选择同一行。",
|
|
6595
|
+
"row.creditPositionDisabledHint": "主开关关闭时不可调整:先勾选上方「在输入框工具栏显示积分读数」。",
|
|
6596
|
+
"row.showCreditsHintInline": "当前为本 tab 服务的那个账号的余额。点一下能看各账号明细,另外每 5 分钟自动刷新一次。",
|
|
6483
6597
|
"quotaNotice.fallbackHead": "当前请求的额度已用尽",
|
|
6484
6598
|
"quotaNotice.supplement": "(部分模型另有每日额度,与积分无关)",
|
|
6485
6599
|
"row.creditPositionHint": "积分显示在哪里。「输入框工具栏」是默认位置(与模型选择同一行)。如果装了别的插件后读数不显示,改成「输入框下方」—— 那是「轮次 / 步数 / token」统计所在的那一行。",
|
|
@@ -3957,7 +3957,7 @@ function generationOf(version) {
|
|
|
3957
3957
|
//#endregion
|
|
3958
3958
|
//#region src/version.ts
|
|
3959
3959
|
/** The npm package version this build was produced from. */
|
|
3960
|
-
const WORKBUDDY_CONNECT_VERSION = "4.8.
|
|
3960
|
+
const WORKBUDDY_CONNECT_VERSION = "4.8.1";
|
|
3961
3961
|
//#endregion
|
|
3962
3962
|
//#region src/host-heartbeat.ts
|
|
3963
3963
|
/**
|
package/lib/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as isEncryptedFieldWrapper, A as workbuddyAccountId, B as modelIdOfBody, C as defaultDesktopAuthDirs, D as isVaultAccountId, E as isEncryptedCredentialError, F as WorkBuddyUpstreamClient, G as regionOf, H as parseReasoning, I as classifyUpstreamError, J as deriveAtRestKey, K as WORKBUDDY_APP_EXECUTABLE_ENV, L as declaredTools, M as CREDENTIAL_REJECTED_CODE, N as WORKBUDDY_FALLBACK_SYSTEM_PROMPT, O as legacyWorkbuddyOwnAuthPath, P as WorkBuddyCredentialRejectedError, R as isCredentialRejectedError, S as defaultDesktopAuthCandidates, T as hasEncryptedCredentialFields, U as parseUpstreamModel, V as parseCreditMultiplier, W as prepareChatBody, X as fetchAtRestKeyPayload, Y as deriveAtRestKeyId, Z as findWorkbuddyAppExecutable, _ as WORKBUDDY_AUTH_FILENAME, a as readHostHeartbeat, at as workbuddyAppExecutableCandidates, b as WorkBuddyEncryptedCredentialError, c as WORKBUDDY_CONNECT_VERSION, ct as withFileLock, d as FALLBACK_WORKBUDDY_MODELS_GLOBAL, et as isWorkbuddyBundle, f as WorkBuddyCatalog, g as ENCRYPTED_CREDENTIAL_CODE, h as fallbackModelsFor, i as processStartTimeMs, it as readAtRestKey, j as workbuddyOwnAuthPath, k as parseWorkBuddyAuth, l as piAiRuntimeInfo, lt as writeFileAtomic, m as deriveCatalog, n as clearHostHeartbeat, nt as macosNestedAppBundles, o as workbuddyHostHeartbeatPath, p as applyContextBudgets, q as clearAtRestKeyCache, r as isHeartbeatProcessAlive, rt as openEncryptedField, s as writeHostHeartbeat, st as resolveDshHome, t as WORKBUDDY_HOST_HEARTBEAT_FILENAME, tt as macosBundleExecutable, u as FALLBACK_WORKBUDDY_MODELS, v as WORKBUDDY_AUTH_FILE_ENV, w as defaultDesktopAuthPath, x as authFileName, y as WorkBuddyCredentialStore, z as knownRegionOf } from "./host-heartbeat
|
|
1
|
+
import { $ as isEncryptedFieldWrapper, A as workbuddyAccountId, B as modelIdOfBody, C as defaultDesktopAuthDirs, D as isVaultAccountId, E as isEncryptedCredentialError, F as WorkBuddyUpstreamClient, G as regionOf, H as parseReasoning, I as classifyUpstreamError, J as deriveAtRestKey, K as WORKBUDDY_APP_EXECUTABLE_ENV, L as declaredTools, M as CREDENTIAL_REJECTED_CODE, N as WORKBUDDY_FALLBACK_SYSTEM_PROMPT, O as legacyWorkbuddyOwnAuthPath, P as WorkBuddyCredentialRejectedError, R as isCredentialRejectedError, S as defaultDesktopAuthCandidates, T as hasEncryptedCredentialFields, U as parseUpstreamModel, V as parseCreditMultiplier, W as prepareChatBody, X as fetchAtRestKeyPayload, Y as deriveAtRestKeyId, Z as findWorkbuddyAppExecutable, _ as WORKBUDDY_AUTH_FILENAME, a as readHostHeartbeat, at as workbuddyAppExecutableCandidates, b as WorkBuddyEncryptedCredentialError, c as WORKBUDDY_CONNECT_VERSION, ct as withFileLock, d as FALLBACK_WORKBUDDY_MODELS_GLOBAL, et as isWorkbuddyBundle, f as WorkBuddyCatalog, g as ENCRYPTED_CREDENTIAL_CODE, h as fallbackModelsFor, i as processStartTimeMs, it as readAtRestKey, j as workbuddyOwnAuthPath, k as parseWorkBuddyAuth, l as piAiRuntimeInfo, lt as writeFileAtomic, m as deriveCatalog, n as clearHostHeartbeat, nt as macosNestedAppBundles, o as workbuddyHostHeartbeatPath, p as applyContextBudgets, q as clearAtRestKeyCache, r as isHeartbeatProcessAlive, rt as openEncryptedField, s as writeHostHeartbeat, st as resolveDshHome, t as WORKBUDDY_HOST_HEARTBEAT_FILENAME, tt as macosBundleExecutable, u as FALLBACK_WORKBUDDY_MODELS, v as WORKBUDDY_AUTH_FILE_ENV, w as defaultDesktopAuthPath, x as authFileName, y as WorkBuddyCredentialStore, z as knownRegionOf } from "./host-heartbeat-BfAvb1_d.js";
|
|
2
2
|
import z from "@deepseek-ai/schemastery";
|
|
3
3
|
import { appendFile, mkdir, readFile, writeFile } from "node:fs/promises";
|
|
4
4
|
import { randomBytes, randomUUID, timingSafeEqual } from "node:crypto";
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "dsh-connect-workbuddy",
|
|
3
3
|
"displayName": "DSH Connect WorkBuddy",
|
|
4
4
|
"description": "把本机登录的 WorkBuddy 模型接入 DeepSeek Harness,并提供只读的积分概览与模型管理。",
|
|
5
|
-
"version": "4.8.
|
|
5
|
+
"version": "4.8.1",
|
|
6
6
|
"author": "dingminhua",
|
|
7
7
|
"copyright": "Copyright (c) 2026 LaoDing",
|
|
8
8
|
"license": "MIT",
|