dsh-workbuddy-connect 0.2.1 → 0.2.3

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/README.en.md CHANGED
@@ -22,23 +22,41 @@ Expand the card to see the account, token validity, and remaining credit.
22
22
 
23
23
  Prerequisite: the WorkBuddy desktop app is installed and signed in (the plugin reuses the app's sign-in state and follows account switches automatically).
24
24
 
25
+ The plugin runs under all three DSH interfaces: **Web**, **Desktop**, and **TUI**. Pick the install command that matches the profile you use.
26
+
25
27
  ```sh
26
- # npm (recommended; ships prebuilt artifacts)
28
+ # Web (recommended; ships prebuilt artifacts)
27
29
  dsh plugin --profile web add dsh-workbuddy-connect
30
+ dsh web
28
31
 
29
- # or install from the GitHub source
32
+ # or install the Web version from the GitHub source
30
33
  dsh plugin --profile web add github:corrinehu/dsh-workbuddy-connect
31
-
32
34
  dsh web
33
35
  ```
34
36
 
37
+ ```sh
38
+ # Desktop (the DSH Desktop app)
39
+ dsh plugin --profile desktop add dsh-workbuddy-connect
40
+ dsh --profile desktop
41
+ ```
42
+
43
+ ```sh
44
+ # TUI (terminal UI)
45
+ dsh plugin --profile dsh-tui add dsh-workbuddy-connect
46
+ dsh --profile dsh-tui
47
+ ```
48
+
49
+ > Note: the `dsh-tui` profile requires pnpm 11 to install packages (a different pnpm on PATH fails with `ERR_PNPM_UNEXPECTED_STORE` — use `npx pnpm@11`); verified on dsh `0.1.1-rc.2`.
50
+
51
+ After installing, switch to a WorkBuddy model in the model picker of the interface you chose. On Web, the settings card (Settings → Plugins → DSH WorkBuddy Connect) shows the account, token validity, and remaining credit; on TUI, configure `authFile` in `/settings`.
52
+
35
53
  ## CLI
36
54
 
37
- `dsh plugin --profile web exec dsh-workbuddy-connect status`: sign-in state and remaining credit (`--json` for machine-readable output; `doctor` for diagnostics and `logout` for credential cleanup are also available).
55
+ `dsh plugin --profile <web|desktop|dsh-tui> exec dsh-workbuddy-connect status`: sign-in state and remaining credit (`--json` for machine-readable output; `doctor` for diagnostics and `logout` for credential cleanup are also available).
38
56
 
39
57
  ## Known limitations
40
58
 
41
- - Verified on macOS with the DSH Web profile (`0.1.1-rc.2`+, Node 22+). The default credential paths on Windows / Linux are unverified — point the `WORKBUDDY_AUTH_FILE` environment variable at the actual location if needed.
59
+ - Verified on macOS with the DSH Web / Desktop / TUI profile (`0.1.1-rc.2`+, Node 22+). The default credential paths on Windows / Linux are unverified — point the `WORKBUDDY_AUTH_FILE` environment variable at the actual location if needed.
42
60
  - Relies on WorkBuddy client interfaces (not a public API); the plugin may need updates as WorkBuddy changes.
43
61
 
44
62
  ## Disclaimer
package/README.md CHANGED
@@ -28,23 +28,41 @@
28
28
 
29
29
  前置:已安装并登录 WorkBuddy 桌面 App(插件复用 App 的登录状态,账号切换自动跟随)。
30
30
 
31
+ 插件在三种 DSH 界面下均可运行:**Web**、**Desktop**、**TUI**。根据你使用的 profile 选对应命令安装。
32
+
31
33
  ```sh
32
- # npm(推荐,自带预构建产物)
34
+ # Web(推荐,自带预构建产物)
33
35
  dsh plugin --profile web add dsh-workbuddy-connect
36
+ dsh web
34
37
 
35
- # 或从 GitHub 源码安装
38
+ # 或从 GitHub 源码安装 Web 版
36
39
  dsh plugin --profile web add github:corrinehu/dsh-workbuddy-connect
37
-
38
40
  dsh web
39
41
  ```
40
42
 
43
+ ```sh
44
+ # Desktop(DSH Desktop 桌面版)
45
+ dsh plugin --profile desktop add dsh-workbuddy-connect
46
+ dsh --profile desktop
47
+ ```
48
+
49
+ ```sh
50
+ # TUI(终端界面)
51
+ dsh plugin --profile dsh-tui add dsh-workbuddy-connect
52
+ dsh --profile dsh-tui
53
+ ```
54
+
55
+ > 提示:`dsh-tui` profile 需用 pnpm 11 安装(PATH 里是其他版本会报 `ERR_PNPM_UNEXPECTED_STORE`,用 `npx pnpm@11` 即可);已验证 dsh `0.1.1-rc.2`。
56
+
57
+ 安装后,在对应界面的模型选择器里切换到 WorkBuddy 模型即可使用;Web 下设置卡片(设置 → 插件 → DSH WorkBuddy Connect)可查看账号信息、令牌有效期与剩余积分,TUI 下可在 `/settings` 里配置 `authFile`。
58
+
41
59
  ## 命令行
42
60
 
43
- `dsh plugin --profile web exec dsh-workbuddy-connect status`:登录状态与剩余积分(`--json` 输出机器可读格式;另有 `doctor` 诊断、`logout` 清理凭据)。
61
+ `dsh plugin --profile <web|desktop|dsh-tui> exec dsh-workbuddy-connect status`:登录状态与剩余积分(`--json` 输出机器可读格式;另有 `doctor` 诊断、`logout` 清理凭据)。
44
62
 
45
63
  ## 已知限制
46
64
 
47
- - 在 macOS 与 DSH Web profile(`0.1.1-rc.2`+、Node 22+)下验证通过;Windows / Linux 的凭据默认路径未经验证,必要时可通过环境变量 `WORKBUDDY_AUTH_FILE` 指定实际位置。
65
+ - 在 macOS 的 DSH Web / Desktop / TUI profile(`0.1.1-rc.2`+、Node 22+)下验证通过;Windows / Linux 的凭据默认路径未经验证,必要时可通过环境变量 `WORKBUDDY_AUTH_FILE` 指定实际位置。
48
66
  - 依赖 WorkBuddy 客户端接口(非官方开放 API),WorkBuddy 更新后插件可能需要随之调整。
49
67
 
50
68
  ## 免责声明
package/lib/bin.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { _ as WorkBuddyCredentialStore, a as readHostHeartbeat, b as workbuddyOwnAuthPath, c as WORKBUDDY_CONNECT_VERSION, l as WorkBuddyUpstreamClient, o as workbuddyHostHeartbeatPath, p as FALLBACK_WORKBUDDY_MODELS, r as isHeartbeatProcessAlive } from "./host-heartbeat-DehQgrb9.js";
2
+ import { _ as WorkBuddyCredentialStore, a as readHostHeartbeat, c as WORKBUDDY_CONNECT_VERSION, l as WorkBuddyUpstreamClient, o as workbuddyHostHeartbeatPath, p as FALLBACK_WORKBUDDY_MODELS, r as isHeartbeatProcessAlive, x as workbuddyOwnAuthPath } from "./host-heartbeat-C80jXKyk.js";
3
3
  import { realpathSync } from "node:fs";
4
4
  import { fileURLToPath } from "node:url";
5
5
  //#region src/bin.ts
@@ -24,12 +24,22 @@ const OWN_FORMAT_VERSION = 1;
24
24
  function workbuddyOwnAuthPath() {
25
25
  return join(resolveDshHome(), WORKBUDDY_AUTH_FILENAME);
26
26
  }
27
- /** Platform default for the WorkBuddy desktop app's auth file. */
28
- function defaultDesktopAuthPath() {
27
+ /**
28
+ * Platform-default candidates for the WorkBuddy desktop app's auth file, in
29
+ * probe order. Windows probes both AppData roots: current builds write under
30
+ * `%LOCALAPPDATA%` (Local), older ones under `%APPDATA%` (Roaming). macOS and
31
+ * Linux have a single well-known location.
32
+ */
33
+ function defaultDesktopAuthCandidates() {
29
34
  const home = homedir();
30
- if (process.platform === "darwin") return join(home, "Library", "Application Support", "CodeBuddyExtension", "Data", "Public", "auth", "workbuddy-desktop.info");
31
- if (process.platform === "win32") return join(home, "AppData", "Roaming", "CodeBuddyExtension", "Data", "Public", "auth", "workbuddy-desktop.info");
32
- if (process.platform === "linux") return join(home, ".config", "CodeBuddyExtension", "Data", "Public", "auth", "workbuddy-desktop.info");
35
+ if (process.platform === "darwin") return [join(home, "Library", "Application Support", "CodeBuddyExtension", "Data", "Public", "auth", "workbuddy-desktop.info")];
36
+ if (process.platform === "win32") return [join(home, "AppData", "Local", "CodeBuddyExtension", "Data", "Public", "auth", "workbuddy-desktop.info"), join(home, "AppData", "Roaming", "CodeBuddyExtension", "Data", "Public", "auth", "workbuddy-desktop.info")];
37
+ if (process.platform === "linux") return [join(home, ".config", "CodeBuddyExtension", "Data", "Public", "auth", "workbuddy-desktop.info")];
38
+ return [];
39
+ }
40
+ /** First platform-default candidate; see {@link defaultDesktopAuthCandidates}. */
41
+ function defaultDesktopAuthPath() {
42
+ return defaultDesktopAuthCandidates()[0];
33
43
  }
34
44
  /** Normalize an expiry that may arrive in seconds or milliseconds. */
35
45
  function expiryToMs(value) {
@@ -133,11 +143,17 @@ var WorkBuddyCredentialStore = class {
133
143
  }
134
144
  /**
135
145
  * Configuration precedence for the desktop file: the plugin's configured
136
- * path, then the environment variable, then the platform default.
146
+ * path, then the environment variable, then the platform defaults. An
147
+ * explicit path is used verbatim; the defaults are a probe order.
137
148
  */
138
- resolveDesktopPath() {
149
+ resolveDesktopCandidates() {
139
150
  const fromEnv = process.env[WORKBUDDY_AUTH_FILE_ENV];
140
- return this.desktopPathOverride ?? (fromEnv !== void 0 && fromEnv.trim() !== "" ? fromEnv : void 0) ?? defaultDesktopAuthPath();
151
+ const explicit = this.desktopPathOverride ?? (fromEnv !== void 0 && fromEnv.trim() !== "" ? fromEnv : void 0);
152
+ if (explicit !== void 0) return [explicit];
153
+ return defaultDesktopAuthCandidates();
154
+ }
155
+ resolveDesktopPath() {
156
+ return this.resolveDesktopCandidates()[0];
141
157
  }
142
158
  /**
143
159
  * Repoint the desktop file; a settings change applies on the next read.
@@ -167,7 +183,8 @@ var WorkBuddyCredentialStore = class {
167
183
  async resolve() {
168
184
  const credential = await this.current();
169
185
  if (credential === void 0) {
170
- const desktop = this.resolveDesktopPath() ?? "(no desktop path on this platform)";
186
+ const candidates = this.resolveDesktopCandidates();
187
+ const desktop = candidates.length > 0 ? candidates.join(" or ") : "(no desktop path on this platform)";
171
188
  throw new Error(`workbuddy: no signed-in WorkBuddy account found; sign in once in the WorkBuddy desktop app (expected ${desktop} or WORKBUDDY_AUTH_FILE), or refresh an existing session`);
172
189
  }
173
190
  if (!this.needsRefresh(credential)) return credential;
@@ -232,14 +249,17 @@ var WorkBuddyCredentialStore = class {
232
249
  });
233
250
  });
234
251
  }
252
+ /**
253
+ * Read the first desktop candidate that exists. Only an absent file
254
+ * (ENOENT) falls through to the next candidate; a file that is present
255
+ * but unparsable is authoritative for its slot, so a stale older-version
256
+ * file never silently wins over a broken newer one.
257
+ */
235
258
  async readDesktop() {
236
- const desktopPath = this.resolveDesktopPath();
237
- if (desktopPath === void 0) return void 0;
238
- try {
259
+ for (const desktopPath of this.resolveDesktopCandidates()) try {
239
260
  return parseWorkBuddyAuth(await readFile(desktopPath, "utf8"));
240
261
  } catch (error) {
241
- if (isENOENT(error)) return void 0;
242
- throw error;
262
+ if (!isENOENT(error)) throw error;
243
263
  }
244
264
  }
245
265
  async readOwn() {
@@ -250,15 +270,12 @@ var WorkBuddyCredentialStore = class {
250
270
  return;
251
271
  }
252
272
  }
253
- /** Whether the desktop file exists and is a regular file; diagnostics only. */
273
+ /** Whether any desktop-file candidate exists as a regular file; diagnostics only. */
254
274
  async desktopFilePresent() {
255
- const desktopPath = this.resolveDesktopPath();
256
- if (desktopPath === void 0) return false;
257
- try {
258
- return (await stat(desktopPath)).isFile();
259
- } catch {
260
- return false;
261
- }
275
+ for (const desktopPath of this.resolveDesktopCandidates()) try {
276
+ if ((await stat(desktopPath)).isFile()) return true;
277
+ } catch {}
278
+ return false;
262
279
  }
263
280
  };
264
281
  //#endregion
@@ -684,7 +701,7 @@ var WorkBuddyUpstreamClient = class {
684
701
  };
685
702
  //#endregion
686
703
  //#region src/version.ts
687
- const WORKBUDDY_CONNECT_VERSION = "0.2.1";
704
+ const WORKBUDDY_CONNECT_VERSION = "0.2.3";
688
705
  //#endregion
689
706
  //#region src/host-heartbeat.ts
690
707
  /**
@@ -827,4 +844,4 @@ function isHeartbeatProcessAlive(heartbeat) {
827
844
  return startAtMs <= heartbeat.registeredAt;
828
845
  }
829
846
  //#endregion
830
- export { WorkBuddyCredentialStore as _, readHostHeartbeat as a, workbuddyOwnAuthPath as b, WORKBUDDY_CONNECT_VERSION as c, prepareChatBody as d, regionOf as f, WORKBUDDY_AUTH_FILE_ENV as g, WORKBUDDY_AUTH_FILENAME as h, processStartTimeMs as i, WorkBuddyUpstreamClient as l, WorkBuddyCatalog as m, clearHostHeartbeat as n, workbuddyHostHeartbeatPath as o, FALLBACK_WORKBUDDY_MODELS as p, isHeartbeatProcessAlive as r, writeHostHeartbeat as s, WORKBUDDY_HOST_HEARTBEAT_FILENAME as t, classifyUpstreamError as u, defaultDesktopAuthPath as v, parseWorkBuddyAuth as y };
847
+ export { WorkBuddyCredentialStore as _, readHostHeartbeat as a, parseWorkBuddyAuth as b, WORKBUDDY_CONNECT_VERSION as c, prepareChatBody as d, regionOf as f, WORKBUDDY_AUTH_FILE_ENV as g, WORKBUDDY_AUTH_FILENAME as h, processStartTimeMs as i, WorkBuddyUpstreamClient as l, WorkBuddyCatalog as m, clearHostHeartbeat as n, workbuddyHostHeartbeatPath as o, FALLBACK_WORKBUDDY_MODELS as p, isHeartbeatProcessAlive as r, writeHostHeartbeat as s, WORKBUDDY_HOST_HEARTBEAT_FILENAME as t, classifyUpstreamError as u, defaultDesktopAuthCandidates as v, workbuddyOwnAuthPath as x, defaultDesktopAuthPath as y };
package/lib/index.d.ts CHANGED
@@ -107,7 +107,14 @@ declare const WORKBUDDY_AUTH_FILENAME = ".workbuddy-auth.json";
107
107
  declare const WORKBUDDY_AUTH_FILE_ENV = "WORKBUDDY_AUTH_FILE";
108
108
  /** Plugin-owned copy path inside the Harness home. */
109
109
  declare function workbuddyOwnAuthPath(): string;
110
- /** Platform default for the WorkBuddy desktop app's auth file. */
110
+ /**
111
+ * Platform-default candidates for the WorkBuddy desktop app's auth file, in
112
+ * probe order. Windows probes both AppData roots: current builds write under
113
+ * `%LOCALAPPDATA%` (Local), older ones under `%APPDATA%` (Roaming). macOS and
114
+ * Linux have a single well-known location.
115
+ */
116
+ declare function defaultDesktopAuthCandidates(): string[];
117
+ /** First platform-default candidate; see {@link defaultDesktopAuthCandidates}. */
111
118
  declare function defaultDesktopAuthPath(): string | undefined;
112
119
  /**
113
120
  * Parse a WorkBuddy auth document in either on-disk shape: the plugin OAuth
@@ -133,8 +140,10 @@ declare class WorkBuddyCredentialStore {
133
140
  constructor(options: WorkBuddyStoreOptions);
134
141
  /**
135
142
  * Configuration precedence for the desktop file: the plugin's configured
136
- * path, then the environment variable, then the platform default.
143
+ * path, then the environment variable, then the platform defaults. An
144
+ * explicit path is used verbatim; the defaults are a probe order.
137
145
  */
146
+ private resolveDesktopCandidates;
138
147
  private resolveDesktopPath;
139
148
  /**
140
149
  * Repoint the desktop file; a settings change applies on the next read.
@@ -158,9 +167,15 @@ declare class WorkBuddyCredentialStore {
158
167
  private needsRefresh;
159
168
  private refreshNow;
160
169
  private saveOwn;
170
+ /**
171
+ * Read the first desktop candidate that exists. Only an absent file
172
+ * (ENOENT) falls through to the next candidate; a file that is present
173
+ * but unparsable is authoritative for its slot, so a stale older-version
174
+ * file never silently wins over a broken newer one.
175
+ */
161
176
  private readDesktop;
162
177
  private readOwn;
163
- /** Whether the desktop file exists and is a regular file; diagnostics only. */
178
+ /** Whether any desktop-file candidate exists as a regular file; diagnostics only. */
164
179
  desktopFilePresent(): Promise<boolean>;
165
180
  }
166
181
  //#endregion
@@ -329,4 +344,4 @@ declare const Config: z<Config>;
329
344
  */
330
345
  declare function apply(ctx: Context, config: Config): void;
331
346
  //#endregion
332
- export { Config, FALLBACK_WORKBUDDY_MODELS, type UpstreamErrorKind, WORKBUDDY_AUTH_FILENAME, WORKBUDDY_AUTH_FILE_ENV, WORKBUDDY_HOST_HEARTBEAT_FILENAME, WORKBUDDY_PROVIDER, WORKBUDDY_SETTINGS_NS, WORKBUDDY_STREAM_IDLE_TIMEOUT_MS, type WorkBuddyAdapter, type WorkBuddyAuthStatus, WorkBuddyCatalog, type WorkBuddyChatResult, type WorkBuddyCredential, WorkBuddyCredentialStore, type WorkBuddyCredits, type WorkBuddyHostHeartbeat, type WorkBuddyModelInfo, type WorkBuddyRefreshOutcome, type WorkBuddyShim, WorkBuddyUpstreamClient, type WorkBuddyUpstreamModel, apply, classifyUpstreamError, clearHostHeartbeat, createWorkBuddyAdapter, createWorkBuddyShim, defaultDesktopAuthPath, inject, isHeartbeatProcessAlive, name, parseWorkBuddyAuth, prepareChatBody, processStartTimeMs, readHostHeartbeat, regionOf, workbuddyHostHeartbeatPath, workbuddyOwnAuthPath };
347
+ export { Config, FALLBACK_WORKBUDDY_MODELS, type UpstreamErrorKind, WORKBUDDY_AUTH_FILENAME, WORKBUDDY_AUTH_FILE_ENV, WORKBUDDY_HOST_HEARTBEAT_FILENAME, WORKBUDDY_PROVIDER, WORKBUDDY_SETTINGS_NS, WORKBUDDY_STREAM_IDLE_TIMEOUT_MS, type WorkBuddyAdapter, type WorkBuddyAuthStatus, WorkBuddyCatalog, type WorkBuddyChatResult, type WorkBuddyCredential, WorkBuddyCredentialStore, type WorkBuddyCredits, type WorkBuddyHostHeartbeat, type WorkBuddyModelInfo, type WorkBuddyRefreshOutcome, type WorkBuddyShim, WorkBuddyUpstreamClient, type WorkBuddyUpstreamModel, apply, classifyUpstreamError, clearHostHeartbeat, createWorkBuddyAdapter, createWorkBuddyShim, defaultDesktopAuthCandidates, defaultDesktopAuthPath, inject, isHeartbeatProcessAlive, name, parseWorkBuddyAuth, prepareChatBody, processStartTimeMs, readHostHeartbeat, regionOf, workbuddyHostHeartbeatPath, workbuddyOwnAuthPath };
package/lib/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { _ as WorkBuddyCredentialStore, a as readHostHeartbeat, b as workbuddyOwnAuthPath, d as prepareChatBody, f as regionOf, g as WORKBUDDY_AUTH_FILE_ENV, h as WORKBUDDY_AUTH_FILENAME, i as processStartTimeMs, l as WorkBuddyUpstreamClient, m as WorkBuddyCatalog, n as clearHostHeartbeat, o as workbuddyHostHeartbeatPath, p as FALLBACK_WORKBUDDY_MODELS, r as isHeartbeatProcessAlive, s as writeHostHeartbeat, t as WORKBUDDY_HOST_HEARTBEAT_FILENAME, u as classifyUpstreamError, v as defaultDesktopAuthPath, y as parseWorkBuddyAuth } from "./host-heartbeat-DehQgrb9.js";
1
+ import { _ as WorkBuddyCredentialStore, a as readHostHeartbeat, b as parseWorkBuddyAuth, d as prepareChatBody, f as regionOf, g as WORKBUDDY_AUTH_FILE_ENV, h as WORKBUDDY_AUTH_FILENAME, i as processStartTimeMs, l as WorkBuddyUpstreamClient, m as WorkBuddyCatalog, n as clearHostHeartbeat, o as workbuddyHostHeartbeatPath, p as FALLBACK_WORKBUDDY_MODELS, r as isHeartbeatProcessAlive, s as writeHostHeartbeat, t as WORKBUDDY_HOST_HEARTBEAT_FILENAME, u as classifyUpstreamError, v as defaultDesktopAuthCandidates, x as workbuddyOwnAuthPath, y as defaultDesktopAuthPath } from "./host-heartbeat-C80jXKyk.js";
2
2
  import z from "@deepseek-ai/schemastery";
3
3
  import { installSettingsSection, settingsNamespace } from "@deepseek-ai/dsh-settings";
4
4
  import { createProvider } from "@earendil-works/pi-ai";
@@ -553,4 +553,4 @@ function apply(ctx, config) {
553
553
  });
554
554
  }
555
555
  //#endregion
556
- export { Config, FALLBACK_WORKBUDDY_MODELS, WORKBUDDY_AUTH_FILENAME, WORKBUDDY_AUTH_FILE_ENV, WORKBUDDY_HOST_HEARTBEAT_FILENAME, WORKBUDDY_PROVIDER, WORKBUDDY_SETTINGS_NS, WORKBUDDY_STREAM_IDLE_TIMEOUT_MS, WorkBuddyCatalog, WorkBuddyCredentialStore, WorkBuddyUpstreamClient, apply, classifyUpstreamError, clearHostHeartbeat, createWorkBuddyAdapter, createWorkBuddyShim, defaultDesktopAuthPath, inject, isHeartbeatProcessAlive, name, parseWorkBuddyAuth, prepareChatBody, processStartTimeMs, readHostHeartbeat, regionOf, workbuddyHostHeartbeatPath, workbuddyOwnAuthPath };
556
+ export { Config, FALLBACK_WORKBUDDY_MODELS, WORKBUDDY_AUTH_FILENAME, WORKBUDDY_AUTH_FILE_ENV, WORKBUDDY_HOST_HEARTBEAT_FILENAME, WORKBUDDY_PROVIDER, WORKBUDDY_SETTINGS_NS, WORKBUDDY_STREAM_IDLE_TIMEOUT_MS, WorkBuddyCatalog, WorkBuddyCredentialStore, WorkBuddyUpstreamClient, apply, classifyUpstreamError, clearHostHeartbeat, createWorkBuddyAdapter, createWorkBuddyShim, defaultDesktopAuthCandidates, defaultDesktopAuthPath, inject, isHeartbeatProcessAlive, name, parseWorkBuddyAuth, prepareChatBody, processStartTimeMs, readHostHeartbeat, regionOf, workbuddyHostHeartbeatPath, workbuddyOwnAuthPath };
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "dsh-workbuddy-connect",
3
3
  "displayName": "DSH WorkBuddy Connect",
4
4
  "description": "将 WorkBuddy 桌面 App 包含的模型自动接入 DeepSeek Harness — bring WorkBuddy desktop app models into DeepSeek Harness with zero configuration.",
5
- "version": "0.2.1",
5
+ "version": "0.2.3",
6
6
  "author": "corrinehu",
7
7
  "keywords": [
8
8
  "dsh-plugin",
@@ -21,6 +21,7 @@
21
21
  "dsh-workbuddy-connect": "lib/bin.js"
22
22
  },
23
23
  "scripts": {
24
+ "prepack": "npm run build",
24
25
  "build": "tsdown",
25
26
  "test": "vitest run",
26
27
  "typecheck": "tsc -p tsconfig.json && tsc -p tsconfig.client.json",
@@ -99,4 +100,4 @@
99
100
  "typescript": "^5.9.3",
100
101
  "vitest": "^4.1.8"
101
102
  }
102
- }
103
+ }