dsh-workbuddy-connect 0.2.1 → 0.2.2

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/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-CYxNM1p2.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
@@ -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-CYxNM1p2.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.2",
6
6
  "author": "corrinehu",
7
7
  "keywords": [
8
8
  "dsh-plugin",