dsh-connect-workbuddy 1.0.0 → 1.0.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 CHANGED
@@ -1,6 +1,16 @@
1
1
  # Changelog
2
2
 
3
- ## Unreleased
3
+ ## 1.0.1 (2026-08-30)
4
+
5
+ ### Fixes
6
+
7
+ - 账号选择改为严格绑定用户显式选择:删除启动时按积分自动挑选账号的逻辑,未选号时跟随 App 当前登录(live 文件);账号失效时不再静默切换到其他账号,而是报「未登录」让用户重新选择,避免账单落到用户未选择的账号上。
8
+
9
+ ### Docs
10
+
11
+ - `docs/DESIGN.md` 对齐当前进度:图片输入改为手动勾选说明;补充 `reasoning.effort`(固定档位)形态与推理强度两态已知问题;积分展示补充月度周期套餐与每日签到;scripts 探针数量更新。
12
+ - README 与 README.en.md 功能特性更新:图片输入改为按模型手动勾选。
13
+ - 新增 `docs/reasoning-investigation.md`:记录推理强度调查结论(上游两态数据、DSH 链路、实测档位、待决策修复方向)。仅记录,未改代码。
4
14
 
5
15
  ## 1.0.0 (2026-08-30)
6
16
 
package/README.en.md CHANGED
@@ -22,7 +22,7 @@ A [DeepSeek Harness (DSH)](https://github.com/deepseek-ai/deepseek-harness) bund
22
22
  ## Features
23
23
 
24
24
  - **WorkBuddy model provider** — registers locally signed-in WorkBuddy models as the `workbuddy` provider (e.g. `GLM-5.3`, `DeepSeek-V4-Pro`, `Kimi-K3`, `MiniMax-M3`, `Hy3`).
25
- - **Model management** — refresh the full catalog from upstream and enable or disable each model individually; refresh is a draft operation that only takes effect on save. Upstream also reports credit multiplier, context/output limits, reasoning efforts, and multimodal capability.
25
+ - **Model management** — refresh the full catalog from upstream and enable or disable each model individually; refresh is a draft operation that only takes effect on save. Upstream also reports credit multiplier, context/output limits, and reasoning efforts; image input is opted in per model manually (off by default).
26
26
  - **Local account switching** — discovers the multiple sign-in credentials WorkBuddy's desktop app leaves behind and lets you switch between them. Tokens are never written to DSH settings.
27
27
  - **Read-only credits overview** — remaining credit aggregated per package, plus each model's credit multiplier. Queries consume no credits.
28
28
  - **Multi-candidate credential paths** — probes the platform defaults for macOS / Windows / Linux in turn, overridable by environment variable or directly in the card.
package/README.md CHANGED
@@ -28,7 +28,7 @@
28
28
  ## 功能特性
29
29
 
30
30
  - **WorkBuddy 模型接入** —— 把本机登录的 WorkBuddy 模型注册为 DSH 的 `workbuddy` provider,模型选择器出现 `GLM-5.3`、`DeepSeek-V4-Pro`、`Kimi-K3`、`MiniMax-M3`、`Hy3` 等。
31
- - **模型管理** —— 从上游刷新完整模型目录,逐项勾选启用或禁用;刷新是草稿操作,点保存才生效。上游同时给出积分倍率、上下文/输出上限、推理档位与多模态能力。
31
+ - **模型管理** —— 从上游刷新完整模型目录,逐项勾选启用或禁用;刷新是草稿操作,点保存才生效。上游同时给出积分倍率、上下文/输出上限与推理档位;图片输入按模型手动勾选(默认不勾选)。
32
32
  - **本机账号切换** —— 自动发现 WorkBuddy 桌面端留下的多个登录凭据,可切换账号;Token 不写入 DSH 设置。
33
33
  - **只读积分概览** —— 按套餐聚合展示剩余积分,并列出每个模型的积分倍率。查询不消耗积分。
34
34
  - **凭据路径多候选** —— macOS / Windows / Linux 逐一探测默认位置,也支持环境变量与卡片内直接指定。
package/lib/bin.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { C as defaultDesktopAuthCandidates, O as workbuddyOwnAuthPath, a as readHostHeartbeat, b as WORKBUDDY_AUTH_FILE_ENV, c as WORKBUDDY_CONNECT_VERSION, g as FALLBACK_WORKBUDDY_MODELS, l as WorkBuddyUpstreamClient, o as workbuddyHostHeartbeatPath, r as isHeartbeatProcessAlive, w as defaultDesktopAuthDirs, x as WorkBuddyCredentialStore } from "./host-heartbeat-DHfQtrSf.js";
2
+ import { C as defaultDesktopAuthCandidates, O as workbuddyOwnAuthPath, a as readHostHeartbeat, b as WORKBUDDY_AUTH_FILE_ENV, c as WORKBUDDY_CONNECT_VERSION, g as FALLBACK_WORKBUDDY_MODELS, l as WorkBuddyUpstreamClient, o as workbuddyHostHeartbeatPath, r as isHeartbeatProcessAlive, w as defaultDesktopAuthDirs, x as WorkBuddyCredentialStore } from "./host-heartbeat-Be1hox2i.js";
3
3
  import { realpathSync } from "node:fs";
4
4
  import { fileURLToPath } from "node:url";
5
5
  //#region src/bin.ts
@@ -15,10 +15,10 @@ import { execFileSync } from "node:child_process";
15
15
  * 未过期则继续沿用旧 token。这些机制已在该项目验证,此处沿用。
16
16
  * 改动:原版只解析单个 `workbuddy-desktop.info`。WorkBuddy 桌面端在
17
17
  * 同一 auth 目录留下带时间戳的备份文件(`workbuddy-desktop.<stamp>.info`),
18
- * 实测这些文件各自持有不同账号的可用凭据(本机 6 个文件 → 2 个账号,
19
- * 均能通过上游鉴权,但积分分别为 1875 与 0)。本实现改为扫描整个
20
- * auth 目录,按 uin 去重为多个可选账号,并默认优先有可用积分的账号。
21
- * 跟随 App 当前登录仍是默认行为,切换账号是显式选项。
18
+ * 实测这些文件各自持有不同账号的可用凭据(本机 6 个文件 → 2 个账号)。
19
+ * 本实现改为扫描整个 auth 目录,按 uin 去重为多个可选账号。跟随 App
20
+ * 当前登录(live 文件)仍是默认行为;用户显式选择的账号被严格绑定,
21
+ * 不因积分多少而切换,失效时也不会静默改选其他账号。
22
22
  *
23
23
  * @module dsh-connect-workbuddy/auth
24
24
  */
@@ -209,8 +209,6 @@ var WorkBuddyCredentialStore = class {
209
209
  authDirs;
210
210
  desktopPathOverride;
211
211
  accountId;
212
- /** Account ids with usable credit, tried first when nothing is selected. */
213
- preferIds = [];
214
212
  inflight;
215
213
  constructor(options) {
216
214
  this.refresh = options.refresh;
@@ -233,15 +231,6 @@ var WorkBuddyCredentialStore = class {
233
231
  selectedAccountId() {
234
232
  return this.accountId;
235
233
  }
236
- /**
237
- * Preferred account ordering used when no account is explicitly selected.
238
- * An account with zero credit fails every chat request, so accounts with
239
- * usable credit must win the default.
240
- */
241
- setPreferAccountIds(ids) {
242
- this.preferIds = [...ids];
243
- this.inflight = void 0;
244
- }
245
234
  /** The auth-file path candidates, in probe order. */
246
235
  resolveDesktopCandidates() {
247
236
  const fromEnv = process.env[WORKBUDDY_AUTH_FILE_ENV];
@@ -322,16 +311,14 @@ var WorkBuddyCredentialStore = class {
322
311
  return [...byId.values()];
323
312
  }
324
313
  /**
325
- * Preferred account first, else the live sign-in, else the freshest
326
- * credential. Following the app's current sign-in is the documented default
327
- * behaviour; the backups exist so the user can switch explicitly.
314
+ * Default when no account is explicitly selected: the live sign-in, else the
315
+ * freshest credential. Following the app's current sign-in is the documented
316
+ * default behaviour; the backups exist so the user can switch explicitly.
317
+ * This is NOT credit-seeking — it never reorders accounts to find one with
318
+ * remaining credit.
328
319
  */
329
320
  preferred(credentials) {
330
321
  if (credentials.length === 0) return void 0;
331
- for (const id of this.preferIds) {
332
- const match = credentials.find((credential) => workbuddyAccountId(credential) === id);
333
- if (match !== void 0) return match;
334
- }
335
322
  return credentials.reduce((best, credential) => {
336
323
  if (fileRank(credential.filePath) < fileRank(best.filePath)) return credential;
337
324
  if (fileRank(credential.filePath) === fileRank(best.filePath) && credential.expiresAtMs > best.expiresAtMs) return credential;
@@ -362,7 +349,7 @@ var WorkBuddyCredentialStore = class {
362
349
  async current() {
363
350
  const credentials = await this.readAll();
364
351
  if (this.accountId === void 0) return this.preferred(credentials);
365
- return credentials.find((credential) => workbuddyAccountId(credential) === this.accountId) ?? this.preferred(credentials);
352
+ return credentials.find((credential) => workbuddyAccountId(credential) === this.accountId);
366
353
  }
367
354
  /** The credential to send upstream: {@link current}, refreshed on demand. */
368
355
  async resolve() {
@@ -1009,7 +996,7 @@ var WorkBuddyUpstreamClient = class {
1009
996
  //#endregion
1010
997
  //#region src/version.ts
1011
998
  /** The npm package version this build was produced from. */
1012
- const WORKBUDDY_CONNECT_VERSION = "1.0.0";
999
+ const WORKBUDDY_CONNECT_VERSION = "1.0.1";
1013
1000
  //#endregion
1014
1001
  //#region src/host-heartbeat.ts
1015
1002
  /**
package/lib/index.d.ts CHANGED
@@ -113,8 +113,6 @@ declare class WorkBuddyCredentialStore {
113
113
  private readonly authDirs;
114
114
  private desktopPathOverride;
115
115
  private accountId;
116
- /** Account ids with usable credit, tried first when nothing is selected. */
117
- private preferIds;
118
116
  private inflight;
119
117
  constructor(options: WorkBuddyStoreOptions);
120
118
  /** Repoint the desktop file or directory; applies on the next read. */
@@ -123,12 +121,6 @@ declare class WorkBuddyCredentialStore {
123
121
  selectAccount(accountId: string | undefined): void;
124
122
  /** Selected account id, for diagnostics and route assembly. */
125
123
  selectedAccountId(): string | undefined;
126
- /**
127
- * Preferred account ordering used when no account is explicitly selected.
128
- * An account with zero credit fails every chat request, so accounts with
129
- * usable credit must win the default.
130
- */
131
- setPreferAccountIds(ids: readonly string[]): void;
132
124
  /** The auth-file path candidates, in probe order. */
133
125
  private resolveDesktopCandidates;
134
126
  /** The resolved desktop auth-file path, for diagnostics. */
@@ -156,9 +148,11 @@ declare class WorkBuddyCredentialStore {
156
148
  */
157
149
  private readAll;
158
150
  /**
159
- * Preferred account first, else the live sign-in, else the freshest
160
- * credential. Following the app's current sign-in is the documented default
161
- * behaviour; the backups exist so the user can switch explicitly.
151
+ * Default when no account is explicitly selected: the live sign-in, else the
152
+ * freshest credential. Following the app's current sign-in is the documented
153
+ * default behaviour; the backups exist so the user can switch explicitly.
154
+ * This is NOT credit-seeking — it never reorders accounts to find one with
155
+ * remaining credit.
162
156
  */
163
157
  private preferred;
164
158
  /** Token-free account list for the plugin card. */
package/lib/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { C as defaultDesktopAuthCandidates, D as workbuddyAccountId, E as parseWorkBuddyAuth, O as workbuddyOwnAuthPath, S as authFileName, T as defaultDesktopAuthPath, _ as WorkBuddyCatalog, a as readHostHeartbeat, b as WORKBUDDY_AUTH_FILE_ENV, c as WORKBUDDY_CONNECT_VERSION, d as parseCreditMultiplier, f as parseReasoning, g as FALLBACK_WORKBUDDY_MODELS, h as regionOf, i as processStartTimeMs, l as WorkBuddyUpstreamClient, m as prepareChatBody, n as clearHostHeartbeat, o as workbuddyHostHeartbeatPath, p as parseUpstreamModel, r as isHeartbeatProcessAlive, s as writeHostHeartbeat, t as WORKBUDDY_HOST_HEARTBEAT_FILENAME, u as classifyUpstreamError, v as deriveCatalog, w as defaultDesktopAuthDirs, x as WorkBuddyCredentialStore, y as WORKBUDDY_AUTH_FILENAME } from "./host-heartbeat-DHfQtrSf.js";
1
+ import { C as defaultDesktopAuthCandidates, D as workbuddyAccountId, E as parseWorkBuddyAuth, O as workbuddyOwnAuthPath, S as authFileName, T as defaultDesktopAuthPath, _ as WorkBuddyCatalog, a as readHostHeartbeat, b as WORKBUDDY_AUTH_FILE_ENV, c as WORKBUDDY_CONNECT_VERSION, d as parseCreditMultiplier, f as parseReasoning, g as FALLBACK_WORKBUDDY_MODELS, h as regionOf, i as processStartTimeMs, l as WorkBuddyUpstreamClient, m as prepareChatBody, n as clearHostHeartbeat, o as workbuddyHostHeartbeatPath, p as parseUpstreamModel, r as isHeartbeatProcessAlive, s as writeHostHeartbeat, t as WORKBUDDY_HOST_HEARTBEAT_FILENAME, u as classifyUpstreamError, v as deriveCatalog, w as defaultDesktopAuthDirs, x as WorkBuddyCredentialStore, y as WORKBUDDY_AUTH_FILENAME } from "./host-heartbeat-Be1hox2i.js";
2
2
  import z from "@deepseek-ai/schemastery";
3
3
  import { installSettingsSection, settingsNamespace } from "@deepseek-ai/dsh-settings";
4
4
  import { randomBytes, timingSafeEqual } from "node:crypto";
@@ -688,33 +688,6 @@ function apply(ctx, config) {
688
688
  shim.close();
689
689
  clearHostHeartbeat();
690
690
  });
691
- /**
692
- * Prefer an account with usable credit. Every account yields the same
693
- * catalog, but an account at zero credit fails each chat request, so the
694
- * default must not land there.
695
- */
696
- const selectPreferredCreditAccount = async () => {
697
- try {
698
- const accounts = await store.accounts();
699
- const scored = [];
700
- for (const account of accounts) try {
701
- store.selectAccount(account.id);
702
- const credential = await store.resolve();
703
- const credits = await client.fetchCredits(credential);
704
- scored.push({
705
- id: account.id,
706
- credits: credits.total
707
- });
708
- } catch (error) {
709
- ctx.logger.warn(`dsh-connect-workbuddy: account ${account.id} unavailable for default selection`, error);
710
- }
711
- scored.sort((a, b) => b.credits - a.credits);
712
- store.setPreferAccountIds(scored.filter((item) => item.credits > 0).map((item) => item.id));
713
- store.selectAccount(current().accountId);
714
- } catch (error) {
715
- ctx.logger.warn("dsh-connect-workbuddy: default account selection failed; continuing", error);
716
- }
717
- };
718
691
  shim.ready.then(async () => {
719
692
  if (stopped) return;
720
693
  let invalidate;
@@ -770,7 +743,6 @@ function apply(ctx, config) {
770
743
  ctx.logger.error("dsh-connect-workbuddy: provider registration failed", error);
771
744
  return;
772
745
  }
773
- await selectPreferredCreditAccount();
774
746
  if (stopped) return;
775
747
  (async () => {
776
748
  try {
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "dsh-connect-workbuddy",
3
3
  "displayName": "DSH Connect WorkBuddy",
4
4
  "description": "Connect locally signed-in WorkBuddy models to DeepSeek Harness with a read-only credits overview and model management.",
5
- "version": "1.0.0",
5
+ "version": "1.0.1",
6
6
  "author": "dingminhua",
7
7
  "copyright": "Copyright (c) 2026 LaoDing",
8
8
  "license": "MIT",