dsh-connect-workbuddy 1.0.0

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/index.d.ts ADDED
@@ -0,0 +1,651 @@
1
+ import z from "@deepseek-ai/schemastery";
2
+ import { PiAiAdapter } from "@deepseek-ai/dsh-llm-pi-ai";
3
+ import { Context } from "@deepseek-ai/cordis";
4
+ import { AttachmentStore } from "@deepseek-ai/dsh-attachment";
5
+ //#region src/auth.d.ts
6
+ /** Normalized WorkBuddy credential, timestamps in epoch milliseconds. */
7
+ interface WorkBuddyCredential {
8
+ accessToken: string;
9
+ refreshToken: string;
10
+ expiresAtMs: number;
11
+ refreshExpiresAtMs?: number;
12
+ domain: string;
13
+ uid: string;
14
+ enterpriseId?: string;
15
+ nickname?: string;
16
+ uin?: string;
17
+ /** Which auth file this came from; refreshes are always `dsh`. */
18
+ source: 'desktop' | 'dsh';
19
+ /** Absolute path of the auth file this credential was read from. */
20
+ filePath: string;
21
+ }
22
+ /** Read-only sign-in summary for status and doctor output. */
23
+ interface WorkBuddyAuthStatus {
24
+ state: 'signed-in' | 'signed-out';
25
+ expiresAtMs?: number;
26
+ refreshExpiresAtMs?: number;
27
+ nickname?: string;
28
+ domain?: string;
29
+ source?: 'desktop' | 'dsh';
30
+ }
31
+ /** Constructor options; only {@link refresh} is required. */
32
+ interface WorkBuddyStoreOptions {
33
+ /** Explicit desktop auth-file path, overriding env and platform defaults. */
34
+ desktopPath?: string;
35
+ /** Explicit plugin-owned copy path, defaulting under `$DSH_HOME`. */
36
+ ownPath?: string;
37
+ /**
38
+ * Auth directories to scan, overriding the platform defaults. Injectable so
39
+ * the multi-account scan is testable without touching a real machine.
40
+ */
41
+ authDirs?: readonly string[];
42
+ /** Performs the upstream token refresh. */
43
+ refresh: (credential: WorkBuddyCredential) => Promise<WorkBuddyRefreshOutcome>;
44
+ /** Refresh this long before actual expiry; default five minutes. */
45
+ refreshMarginMs?: number;
46
+ }
47
+ /** One selectable local account, token-free. */
48
+ interface WorkBuddyAccountChoice {
49
+ /** Stable id derived from `uin` (or `uid` when uin is absent). */
50
+ id: string;
51
+ accountName: string;
52
+ uin?: string;
53
+ domain: string;
54
+ source: 'desktop' | 'dsh';
55
+ tokenExpiresAtMs: number;
56
+ /** The auth file this account was read from; newest is preferred. */
57
+ filePath: string;
58
+ selected: boolean;
59
+ }
60
+ /** Basename of the plugin-owned credential copy inside the Harness home. */
61
+ declare const WORKBUDDY_AUTH_FILENAME = ".workbuddy-auth.json";
62
+ /** Env variable that overrides the desktop auth-file location. */
63
+ declare const WORKBUDDY_AUTH_FILE_ENV = "WORKBUDDY_AUTH_FILE";
64
+ /** Plugin-owned copy path inside the Harness home. */
65
+ declare function workbuddyOwnAuthPath(): string;
66
+ /**
67
+ * Platform-default directories holding the WorkBuddy desktop app's auth file.
68
+ *
69
+ * Windows and Linux prefer the OS-issued env location and fall back to the
70
+ * home-derived convention when it is unset, so a redirected profile (OneDrive
71
+ * folder backup, enterprise policy) still resolves. macOS has no equivalent
72
+ * env variable; the single Application Support path is used as-is.
73
+ *
74
+ * `platform`, `home`, and `env` are injectable so the platform branches are
75
+ * testable on any host without touching a real machine.
76
+ */
77
+ declare function defaultDesktopAuthDirs(platform?: NodeJS.Platform, home?: string, env?: NodeJS.ProcessEnv): string[];
78
+ /** The live auth file's platform candidates, in probe order. */
79
+ declare function defaultDesktopAuthCandidates(): string[];
80
+ /** First platform-default candidate; see {@link defaultDesktopAuthCandidates}. */
81
+ declare function defaultDesktopAuthPath(): string | undefined;
82
+ /**
83
+ * Parse a WorkBuddy auth document in either on-disk shape: the plugin OAuth
84
+ * nested form `{"auth":{...},"account":{...}}` and the flat panel form.
85
+ * Returns undefined when the document carries no access token.
86
+ */
87
+ declare function parseWorkBuddyAuth(text: string, filePath: string): WorkBuddyCredential | undefined;
88
+ /**
89
+ * Filename of a path regardless of the host separator: Windows paths use `\`
90
+ * and this helper must keep working when a Windows path is compared on a
91
+ * POSIX host (e.g. tests injecting a Windows-style auth dir).
92
+ */
93
+ declare function authFileName(path: string): string;
94
+ /**
95
+ * Stable account id. `uin` is the billing identity the upstream keys on and
96
+ * survives across re-login; `uid` is the fallback for documents without one.
97
+ */
98
+ declare function workbuddyAccountId(credential: Pick<WorkBuddyCredential, 'uin' | 'uid' | 'nickname'>): string;
99
+ /**
100
+ * Read-only credential store with demand-driven refresh and multi-account
101
+ * discovery.
102
+ *
103
+ * Refresh policy: refresh only when the access token is inside the margin
104
+ * (or already expired), keep the refreshed credential in the plugin-owned
105
+ * copy, and never write the desktop app's files. A failed refresh still
106
+ * returns a not-yet-expired token so an unreachable refresh endpoint does
107
+ * not take down a working session.
108
+ */
109
+ declare class WorkBuddyCredentialStore {
110
+ private readonly refresh;
111
+ private readonly refreshMarginMs;
112
+ private readonly ownPath;
113
+ private readonly authDirs;
114
+ private desktopPathOverride;
115
+ private accountId;
116
+ /** Account ids with usable credit, tried first when nothing is selected. */
117
+ private preferIds;
118
+ private inflight;
119
+ constructor(options: WorkBuddyStoreOptions);
120
+ /** Repoint the desktop file or directory; applies on the next read. */
121
+ setDesktopPath(path: string | undefined): void;
122
+ /** Select an account by id; tokens stay outside settings. */
123
+ selectAccount(accountId: string | undefined): void;
124
+ /** Selected account id, for diagnostics and route assembly. */
125
+ 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
+ /** The auth-file path candidates, in probe order. */
133
+ private resolveDesktopCandidates;
134
+ /** The resolved desktop auth-file path, for diagnostics. */
135
+ desktopAuthPath(): string | undefined;
136
+ /** The plugin-owned copy path, for diagnostics. */
137
+ ownAuthPath(): string;
138
+ /**
139
+ * Every auth file to scan: the live file plus the timestamped backups
140
+ * WorkBuddy leaves beside it.
141
+ *
142
+ * An explicitly configured path pins the *directory*: its siblings are
143
+ * still scanned, because a user who points the plugin at their auth file
144
+ * expects account switching to work the same way it does on the default
145
+ * path. Only the file ordering changes.
146
+ *
147
+ * A corrupt or signed-out file must never hide the others, so each read is
148
+ * independent and failures are skipped rather than propagated.
149
+ */
150
+ private candidateFiles;
151
+ /** Timestamped siblings of one auth file, newest first by filename. */
152
+ private backupsBeside;
153
+ /**
154
+ * Read every local credential, deduplicated by account id. Files are
155
+ * probed newest-first, so the first entry for an account is its freshest.
156
+ */
157
+ private readAll;
158
+ /**
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.
162
+ */
163
+ private preferred;
164
+ /** Token-free account list for the plugin card. */
165
+ accounts(): Promise<WorkBuddyAccountChoice[]>;
166
+ /** The freshest stored credential for the current selection, no refresh. */
167
+ current(): Promise<WorkBuddyCredential | undefined>;
168
+ /** The credential to send upstream: {@link current}, refreshed on demand. */
169
+ resolve(): Promise<WorkBuddyCredential>;
170
+ /** Read-only sign-in summary; never refreshes and never throws. */
171
+ status(): Promise<WorkBuddyAuthStatus>;
172
+ /** Remove the plugin-owned copy; the desktop files are untouched. */
173
+ logout(): Promise<void>;
174
+ private needsRefresh;
175
+ private refreshNow;
176
+ private saveOwn;
177
+ private readOwn;
178
+ /** Whether any candidate file exists as a regular file; diagnostics only. */
179
+ desktopFilePresent(): Promise<boolean>;
180
+ }
181
+ //#endregion
182
+ //#region src/upstream.d.ts
183
+ /** WorkBuddy region selected by the credential's login domain. */
184
+ type WorkBuddyRegion = 'cn' | 'global';
185
+ /** Upstream failure classes the shim maps onto distinct HTTP answers. */
186
+ type UpstreamErrorKind = 'hard_credit' | 'soft_rate' | 'session_dead' | 'not_found' | 'server' | 'client';
187
+ /** Reasoning capability as the upstream catalog declares it. */
188
+ interface WorkBuddyReasoning {
189
+ supportedEfforts?: readonly string[];
190
+ defaultEffort?: string;
191
+ canDisableThinking?: boolean;
192
+ }
193
+ /** One CLI-usable model, carrying everything the plugin card displays. */
194
+ interface WorkBuddyUpstreamModel {
195
+ id: string;
196
+ name: string;
197
+ contextWindow: number;
198
+ maxTokens: number;
199
+ /** Credit multiplier parsed from the upstream `credits` string. */
200
+ creditMultiplier?: number;
201
+ /**
202
+ * Image-input support decided by the user's explicit selection (imageModelIds),
203
+ * not inferred from the upstream `supportsImages`/`disabledMultimodal` flags,
204
+ * which proved insufficiently reliable. See `catalog.ts` / `index.ts`.
205
+ */
206
+ multimodal?: boolean;
207
+ reasoning?: WorkBuddyReasoning;
208
+ descriptionZh?: string;
209
+ descriptionEn?: string;
210
+ supportsToolCall?: boolean;
211
+ }
212
+ /** One billing package and its remaining credit, already aggregated. */
213
+ /** One billing package as the upstream returns it, dates already parsed. */
214
+ interface WorkBuddyCreditPackage {
215
+ packageName: string;
216
+ remain: number;
217
+ size: number;
218
+ /** CapacityType 4: refreshed every cycle and never expires. */
219
+ monthly: boolean;
220
+ /** Next cycle start (the monthly refresh point); only on monthly packages. */
221
+ refreshAtMs?: number;
222
+ /** One-off expiry; the package disappears from the account at this time. */
223
+ expiresAtMs?: number;
224
+ }
225
+ /** Aggregated credit answer for one credential. */
226
+ interface WorkBuddyCredits {
227
+ total: number;
228
+ packages: readonly WorkBuddyCreditPackage[];
229
+ /** Credits expiring within 3 days across every package. */
230
+ expiringSoon: number;
231
+ /** When the nearest package expires, in ms. */
232
+ nearestExpiryMs?: number;
233
+ }
234
+ /** Daily check-in activity state. */
235
+ interface WorkBuddyCheckinStatus {
236
+ active: boolean;
237
+ todayCheckedIn: boolean;
238
+ streakDays: number;
239
+ dailyCredit: number;
240
+ todayCredit: number;
241
+ isStreakDay: boolean;
242
+ nextStreakDay: number;
243
+ streakBonusDays: number;
244
+ streakBonusCredit: number;
245
+ claimButtonText?: string;
246
+ }
247
+ /** Daily check-in claim result. */
248
+ interface WorkBuddyCheckinClaim {
249
+ credit: number;
250
+ streakDays: number;
251
+ isStreakDay: boolean;
252
+ }
253
+ /** Token refresh answer; fields the upstream omits stay absent. */
254
+ interface WorkBuddyRefreshOutcome {
255
+ accessToken: string;
256
+ refreshToken?: string;
257
+ expiresInSec?: number;
258
+ domain?: string;
259
+ }
260
+ /** Chat answer: either a live SSE response or a classified failure. */
261
+ type WorkBuddyChatResult = {
262
+ ok: true;
263
+ response: Response;
264
+ } | {
265
+ ok: false;
266
+ status: number;
267
+ kind: UpstreamErrorKind;
268
+ message: string;
269
+ };
270
+ /** Classify an upstream failure from its HTTP status and body excerpt. */
271
+ declare function classifyUpstreamError(status: number, body: string): UpstreamErrorKind;
272
+ /** Region for a login domain; an empty domain means CN (matching upstream tooling). */
273
+ declare function regionOf(domain: string): WorkBuddyRegion;
274
+ /**
275
+ * Normalize an OpenAI chat-completions body for the WorkBuddy upstream:
276
+ * force `stream: true` (the upstream rejects non-streaming) and flatten
277
+ * `tool_choice` (the upstream's field is a string; object forms return 400).
278
+ */
279
+ declare function prepareChatBody(source: string): string;
280
+ /**
281
+ * Parse the upstream's `credits` string into a multiplier.
282
+ *
283
+ * Observed forms: `"x0.79 credits"`, `"x0.05"`, `"x0.00 credits"`,
284
+ * and absent. Unparsable values yield undefined rather than a guess — the
285
+ * card simply omits the rate instead of displaying a fabricated one.
286
+ */
287
+ declare function parseCreditMultiplier(value: unknown): number | undefined;
288
+ /** Parse the upstream's `reasoning` object; unknown shapes degrade to `{}`. */
289
+ declare function parseReasoning(value: unknown): WorkBuddyReasoning | undefined;
290
+ /** Parse one catalog entry; entries without usable token limits are dropped. */
291
+ declare function parseUpstreamModel(value: unknown): WorkBuddyUpstreamModel | undefined;
292
+ /**
293
+ * Upstream HTTP client. One instance serves the whole plugin; requests take
294
+ * the credential explicitly so token refreshes apply on the next call.
295
+ */
296
+ declare class WorkBuddyUpstreamClient {
297
+ /** POST the chat endpoint; a successful answer is the raw SSE response. */
298
+ chatStream(credential: WorkBuddyCredential, bodyJson: string, signal?: AbortSignal): Promise<WorkBuddyChatResult>;
299
+ /** POST the token-refresh endpoint; the caller merges the outcome. */
300
+ refreshToken(credential: WorkBuddyCredential): Promise<WorkBuddyRefreshOutcome>;
301
+ /**
302
+ * GET the personal model catalog and keep the `cli` agent's models only,
303
+ * preserving the capability fields the plugin card displays.
304
+ */
305
+ fetchModels(credential: WorkBuddyCredential, signal?: AbortSignal): Promise<readonly WorkBuddyUpstreamModel[]>;
306
+ /** Query today's check-in status without changing account state. */
307
+ fetchCheckinStatus(credential: WorkBuddyCredential): Promise<WorkBuddyCheckinStatus>;
308
+ /** Claim today's check-in reward. The browser route guards this mutation. */
309
+ claimDailyCheckin(credential: WorkBuddyCredential): Promise<WorkBuddyCheckinClaim>;
310
+ /**
311
+ * POST the billing endpoint for the remaining credit, keeping every package
312
+ * separate: the card groups monthly-cycle packages itself and lists the
313
+ * nearest-expiring one-off packages, so aggregation here would lose the
314
+ * dates it needs.
315
+ */
316
+ fetchCredits(credential: WorkBuddyCredential): Promise<WorkBuddyCredits>;
317
+ }
318
+ //#endregion
319
+ //#region src/catalog.d.ts
320
+ /** One model entry the adapter exposes. */
321
+ type WorkBuddyModelInfo = WorkBuddyUpstreamModel;
322
+ /**
323
+ * Static CLI models captured from the CN endpoint (2026-08-30). The upstream
324
+ * refresh replaces this list at startup; it exists so the provider registers
325
+ * with a usable catalog even while the first fetch is in flight or offline.
326
+ */
327
+ declare const FALLBACK_WORKBUDDY_MODELS: readonly WorkBuddyModelInfo[];
328
+ /**
329
+ * Derive the runtime catalog from the last-refreshed directory plus the
330
+ * user's selection. This is the single source of truth for what DSH exposes,
331
+ * so saving only the selection is enough to rebuild it after a restart.
332
+ *
333
+ * An empty selection falls back to the whole directory: a plugin that has
334
+ * never been configured must still serve models rather than nothing.
335
+ */
336
+ type WorkBuddyContextBudget = number;
337
+ declare function deriveCatalog(catalog: readonly WorkBuddyModelInfo[], enabled: ReadonlySet<string>, budgets?: Readonly<Record<string, WorkBuddyContextBudget | undefined>>): WorkBuddyModelInfo[];
338
+ /** Mutable catalog shared by the shim's `/v1/models` and the adapter. */
339
+ declare class WorkBuddyCatalog {
340
+ private models;
341
+ /** Current entries; the fallback list until the upstream answer lands. */
342
+ current(): readonly WorkBuddyModelInfo[];
343
+ /** Replace the list; callers invalidate their adapter snapshot after this. */
344
+ set(models: readonly WorkBuddyModelInfo[]): void;
345
+ }
346
+ //#endregion
347
+ //#region src/shim.d.ts
348
+ /** Minimal logger surface the plugin context already provides. */
349
+ interface ShimLogger {
350
+ warn(...args: unknown[]): void;
351
+ error(...args: unknown[]): void;
352
+ }
353
+ /** What the plugin needs from a running shim. */
354
+ interface WorkBuddyShim {
355
+ /** Resolves once the listener is up; rejects if listening failed. */
356
+ ready: Promise<void>;
357
+ /** The shim origin, e.g. `http://127.0.0.1:39271`; valid after ready. */
358
+ baseUrl(): string;
359
+ /**
360
+ * The per-process shared secret the plugin's own client must carry as
361
+ * `Authorization: Bearer <token>`. Lives only in memory; the adapter
362
+ * resolves this instead of the upstream access token, because the shim
363
+ * resolves the real credential itself via the store.
364
+ */
365
+ token(): string;
366
+ /** Stop serving and destroy open connections. */
367
+ close(): Promise<void>;
368
+ }
369
+ /** Constructor dependencies. */
370
+ interface WorkBuddyShimOptions {
371
+ store: WorkBuddyCredentialStore;
372
+ client: Pick<WorkBuddyUpstreamClient, 'chatStream'>;
373
+ catalog: WorkBuddyCatalog;
374
+ logger?: ShimLogger;
375
+ }
376
+ /**
377
+ * Start the loopback endpoint. Requests must carry the shim's shared secret;
378
+ * the loopback bind alone is not a trust boundary.
379
+ */
380
+ declare function createWorkBuddyShim(options: WorkBuddyShimOptions): WorkBuddyShim;
381
+ //#endregion
382
+ //#region src/adapter.d.ts
383
+ /** Provider route this bundle owns. */
384
+ declare const WORKBUDDY_PROVIDER = "workbuddy";
385
+ /** Provider idle ceiling while one stream read is outstanding. */
386
+ declare const WORKBUDDY_STREAM_IDLE_TIMEOUT_MS = 300000;
387
+ /** Constructor dependencies. */
388
+ interface WorkBuddyAdapterOptions {
389
+ shim: WorkBuddyShim;
390
+ store: WorkBuddyCredentialStore;
391
+ catalog: WorkBuddyCatalog;
392
+ /** Resolve the durable attachment service at request time, when present. */
393
+ resolveAttachments?: () => AttachmentStore | undefined;
394
+ }
395
+ /** What {@link createWorkBuddyAdapter} hands back. */
396
+ interface WorkBuddyAdapter {
397
+ adapter: PiAiAdapter;
398
+ /** Rebuild the adapter's provider snapshot; call after a catalog update. */
399
+ invalidate: () => void;
400
+ }
401
+ declare const THINKING_LEVELS: readonly ["minimal", "low", "medium", "high", "xhigh", "max"];
402
+ type WorkBuddyThinkingLevel = typeof THINKING_LEVELS[number];
403
+ type WorkBuddyThinkingLevelMap = Partial<Record<'off' | WorkBuddyThinkingLevel, string | null>>;
404
+ /** pi-ai input modalities: images only when WorkBuddy advertises them. */
405
+ declare function workBuddyModelInput(info: WorkBuddyModelInfo): ('text' | 'image')[];
406
+ /** Map only levels advertised by WorkBuddy; undeclared DSH levels stay unavailable. */
407
+ declare function workBuddyThinkingLevelMap(info: WorkBuddyModelInfo): WorkBuddyThinkingLevelMap | undefined;
408
+ /**
409
+ * Assemble the adapter. The provider's `getModels` reads the live catalog,
410
+ * and every model's `baseUrl` is re-resolved per read so the shim's
411
+ * ephemeral port applies from the first snapshot after startup.
412
+ */
413
+ declare function createWorkBuddyAdapter(options: WorkBuddyAdapterOptions): WorkBuddyAdapter;
414
+ //#endregion
415
+ //#region src/host-heartbeat.d.ts
416
+ /**
417
+ * Host-side heartbeat: a small JSON file written under `$DSH_HOME` once the
418
+ * `workbuddy` provider is registered. The status CLI reads it to report
419
+ * whether the host bundle is alive, independent of the browser card.
420
+ *
421
+ * 参考:corrinehu/dsh-workbuddy-connect(MIT,Copyright (c) 2026 Corrine Hu)
422
+ * — 该机制由其设计:浏览器端无法写文件,其健康只能靠 console.error 上报,
423
+ * 因此由宿主写心跳文件,缺失即代表宿主从未启动;崩溃后的陈旧心跳
424
+ * 通过 PID 存活检查识别。
425
+ * 改动:无。机制本身已完备,原样沿用。
426
+ *
427
+ * @module dsh-connect-workbuddy/host-heartbeat
428
+ */
429
+ /** Basename of the host heartbeat file inside the Harness home. */
430
+ declare const WORKBUDDY_HOST_HEARTBEAT_FILENAME = ".workbuddy-host-heartbeat.json";
431
+ /** Current on-disk heartbeat format; readers reject others. */
432
+ declare const HEARTBEAT_FORMAT_VERSION = 1;
433
+ /** On-disk shape of the heartbeat. */
434
+ interface WorkBuddyHostHeartbeat {
435
+ version: typeof HEARTBEAT_FORMAT_VERSION;
436
+ package: 'dsh-connect-workbuddy';
437
+ pluginVersion: string;
438
+ /** Epoch milliseconds when the host registered the provider. */
439
+ registeredAt: number;
440
+ /** Host process PID, to distinguish a stale heartbeat after a crash. */
441
+ pid: number;
442
+ }
443
+ /** Absolute path of the host heartbeat file. */
444
+ declare function workbuddyHostHeartbeatPath(): string;
445
+ /**
446
+ * Process start time in epoch milliseconds; undefined when unavailable.
447
+ *
448
+ * POSIX reads `ps -o lstart=`; Windows has no such command, so the creation
449
+ * time is taken from PowerShell's `Get-Process` StartTime, emitted as UTC ISO
450
+ * 8601 so `Date.parse` understands it without locale assumptions. Absent or
451
+ * unqueryable processes (other users' processes) degrade to undefined.
452
+ */
453
+ declare function processStartTimeMs(pid: number): number | undefined;
454
+ /**
455
+ * Whether the recorded host process still matches the heartbeat's PID.
456
+ *
457
+ * A PID can be reused after a crash, so the recorded start time is compared
458
+ * against the live process: a different start time means a different process.
459
+ */
460
+ declare function isHeartbeatProcessAlive(heartbeat: WorkBuddyHostHeartbeat): boolean;
461
+ /** Read the heartbeat; absent or unparsable files report undefined. */
462
+ declare function readHostHeartbeat(): Promise<WorkBuddyHostHeartbeat | undefined>;
463
+ /** Write the heartbeat for the current process. */
464
+ declare function writeHostHeartbeat(): Promise<void>;
465
+ /** Remove the heartbeat; called when the plugin is disposed. */
466
+ declare function clearHostHeartbeat(): Promise<void>;
467
+ //#endregion
468
+ //#region src/version.d.ts
469
+ /**
470
+ * Package version, injected at build time by `tsdown.config.ts`.
471
+ *
472
+ * 参考:corrinehu/dsh-workbuddy-connect(MIT)— 版本由构建期 define 注入,
473
+ * 而非运行时读 package.json(发布包只含 lib/,不含 package.json 的
474
+ * 可解析路径)。沿用该做法。
475
+ *
476
+ * @module dsh-connect-workbuddy/version
477
+ */
478
+ /** The npm package version this build was produced from. */
479
+ declare const WORKBUDDY_CONNECT_VERSION: string;
480
+ //#endregion
481
+ //#region src/status-paths.d.ts
482
+ /**
483
+ * Node-free constants and types shared by the Host and browser halves.
484
+ *
485
+ * 参考:dingminhua/dsh-connect-trae(MIT,Copyright (c) 2026 LaoDing)
486
+ * — 「3 条同源只读路由(usage / models:refresh / accounts:refresh)+ 一份
487
+ * 与浏览器共享的 node-free 类型定义」的 host↔client 桥梁形态来自该项目
488
+ * (其 `status-paths.ts` 亦如此,并注明沿用
489
+ * corrinehu/dsh-workbuddy-connect 的 status-route 模式)。
490
+ * 改动:路由路径改用本插件 id;类型字段按 WorkBuddy 上游实际给出的能力
491
+ * (积分倍率、多模态、推理档位)调整,不保留 trae 的 1M 变体字段。
492
+ *
493
+ * @module dsh-connect-workbuddy/status-paths
494
+ */
495
+ /** Plugin-owned usage endpoint consumed by its browser half. */
496
+ declare const WORKBUDDY_USAGE_PATH = "/plugins/dsh-connect-workbuddy/usage";
497
+ /** Plugin-owned live model refresh endpoint. */
498
+ declare const WORKBUDDY_MODELS_REFRESH_PATH = "/plugins/dsh-connect-workbuddy/models/refresh";
499
+ /** Plugin-owned local account rescan endpoint. */
500
+ declare const WORKBUDDY_ACCOUNTS_REFRESH_PATH = "/plugins/dsh-connect-workbuddy/accounts/refresh";
501
+ /** Plugin-owned daily check-in action endpoint. */
502
+ declare const WORKBUDDY_CHECKIN_PATH = "/plugins/dsh-connect-workbuddy/checkin";
503
+ /** One credit package as the upstream returns it, node-free. */
504
+ interface WorkBuddyWebCreditPackage {
505
+ packageName: string;
506
+ remain: number;
507
+ size: number;
508
+ /** CapacityType 4: refreshed every cycle and never expires. */
509
+ monthly: boolean;
510
+ /** Next cycle start (the monthly refresh point) in ms; only on monthly packages. */
511
+ cycleRefreshMs?: number;
512
+ /** One-off expiry in ms; the package disappears from the account then. */
513
+ expiresAtMs?: number;
514
+ }
515
+ /** Aggregated credit answer rendered by the plugin card. */
516
+ interface WorkBuddyWebCredits {
517
+ total: number;
518
+ packages: readonly WorkBuddyWebCreditPackage[];
519
+ /** Credits expiring within 3 days across every package. */
520
+ expiringSoon: number;
521
+ /** When the nearest package expires, in ms. */
522
+ nearestExpiryMs?: number;
523
+ }
524
+ /** Daily check-in state rendered below total remaining credits. */
525
+ interface WorkBuddyWebCheckin {
526
+ active: boolean;
527
+ todayCheckedIn: boolean;
528
+ streakDays: number;
529
+ dailyCredit: number;
530
+ todayCredit: number;
531
+ isStreakDay: boolean;
532
+ nextStreakDay: number;
533
+ streakBonusDays: number;
534
+ streakBonusCredit: number;
535
+ claimButtonText?: string;
536
+ }
537
+ /** Editable WorkBuddy model row rendered by the plugin-owned settings card. */
538
+ interface WorkBuddyWebModel {
539
+ id: string;
540
+ name: string;
541
+ /** Effective DSH context after applying the saved local budget. */
542
+ contextWindow: number;
543
+ /** Native maximum advertised by WorkBuddy; models above 200K expose 200K/max. */
544
+ nativeContextWindow: number;
545
+ maxTokens: number;
546
+ creditMultiplier?: number;
547
+ multimodal?: boolean;
548
+ reasoning?: {
549
+ supportedEfforts?: readonly string[];
550
+ defaultEffort?: string;
551
+ };
552
+ description?: string;
553
+ }
554
+ /** One selectable local account, token-free. */
555
+ interface WorkBuddyWebAccount {
556
+ id: string;
557
+ accountName: string;
558
+ uin?: string;
559
+ domain: string;
560
+ source: 'desktop' | 'dsh';
561
+ tokenExpiresAtMs: number;
562
+ selected: boolean;
563
+ }
564
+ type WorkBuddyWebPackage = WorkBuddyWebCreditPackage;
565
+ /** The JSON document the plugin card renders. */
566
+ type WorkBuddyWebUsage = {
567
+ status: 'signed-out';
568
+ accounts: readonly WorkBuddyWebAccount[];
569
+ message?: string;
570
+ } | {
571
+ status: 'signed-in';
572
+ accountId: string;
573
+ accountName: string;
574
+ uin?: string;
575
+ domain?: string;
576
+ source?: 'desktop' | 'dsh';
577
+ tokenExpiresAtMs: number;
578
+ accounts: readonly WorkBuddyWebAccount[];
579
+ models: readonly WorkBuddyWebModel[];
580
+ enabledModelIds: readonly string[];
581
+ imageModelIds: readonly string[];
582
+ credits?: WorkBuddyWebCredits;
583
+ creditsError?: string;
584
+ checkin?: WorkBuddyWebCheckin;
585
+ checkinError?: string;
586
+ } | {
587
+ status: 'error';
588
+ message: string;
589
+ };
590
+ //#endregion
591
+ //#region src/web-status.d.ts
592
+ /** Constructor dependencies. */
593
+ interface WorkBuddyStatusRouteOptions {
594
+ store: WorkBuddyCredentialStore;
595
+ client: Pick<WorkBuddyUpstreamClient, 'fetchCredits' | 'fetchCheckinStatus' | 'claimDailyCheckin'>;
596
+ /** The last-refreshed model directory (unfiltered) for card display. */
597
+ displayModels(): readonly WorkBuddyModelInfo[];
598
+ /** The user's selection, stored as model ids. */
599
+ enabledModelIds(): readonly string[];
600
+ /** Model ids the user opted into image input. */
601
+ imageModelIds(): readonly string[];
602
+ /** Saved local DSH context budgets by model id. */
603
+ contextBudgets(): Readonly<Record<string, number | undefined>>;
604
+ /** Re-read the live catalog from the upstream. */
605
+ discoverModels?(signal?: AbortSignal): Promise<readonly WorkBuddyModelInfo[]>;
606
+ }
607
+ /**
608
+ * Assemble the card's usage document. Sign-in state is read-only; credit is a
609
+ * live billing answer whose failure degrades to `creditsError` rather than
610
+ * failing the whole document.
611
+ */
612
+ declare function workBuddyWebStatus(deps: WorkBuddyStatusRouteOptions): Promise<WorkBuddyWebUsage>;
613
+ /**
614
+ * Mount the read-only routes on a context where `webServer` is available.
615
+ * The caller uses `ctx.inject(['webServer'], ...)`, so Desktop startup order
616
+ * cannot make this registration disappear.
617
+ */
618
+ declare function registerWorkBuddyStatusRoute(ctx: Context, deps: WorkBuddyStatusRouteOptions): void;
619
+ //#endregion
620
+ //#region src/index.d.ts
621
+ /** Stable Cordis plugin name. */
622
+ declare const name = "dsh-connect-workbuddy";
623
+ /** The model registry required before the provider can register. */
624
+ declare const inject: string[];
625
+ /** Settings namespace for the plugin configuration card. */
626
+ declare const WORKBUDDY_SETTINGS_NS: import("@deepseek-ai/dsh-settings").SettingsNamespace;
627
+ /** Plugin configuration. */
628
+ interface Config {
629
+ /** Explicit WorkBuddy desktop auth-file path, overriding env and platform defaults. */
630
+ authFile?: string;
631
+ /** Stable local account selector; tokens remain outside settings. */
632
+ accountId?: string;
633
+ /** The last-refreshed model directory; what the plugin card displays. */
634
+ lastCatalog?: WorkBuddyModelInfo[];
635
+ /** The user's selection, as model ids. */
636
+ enabledModelIds?: string[];
637
+ /** Model ids the user explicitly opted into image input. */
638
+ imageModelIds?: string[];
639
+ /** Local DSH context budget per model; models above 200K default to 200K. */
640
+ contextBudgets?: Record<string, WorkBuddyContextBudget>;
641
+ }
642
+ declare const Config: z<Config>;
643
+ /**
644
+ * Start the loopback endpoint, register the `workbuddy` provider, and
645
+ * refresh the model catalog from the upstream once credentials allow it.
646
+ * The static fallback catalog serves from the first moment, so an offline
647
+ * upstream never leaves the provider empty.
648
+ */
649
+ declare function apply(ctx: Context, config: Config): void;
650
+ //#endregion
651
+ export { Config, FALLBACK_WORKBUDDY_MODELS, type UpstreamErrorKind, WORKBUDDY_ACCOUNTS_REFRESH_PATH, WORKBUDDY_AUTH_FILENAME, WORKBUDDY_AUTH_FILE_ENV, WORKBUDDY_CHECKIN_PATH, WORKBUDDY_CONNECT_VERSION, WORKBUDDY_HOST_HEARTBEAT_FILENAME, WORKBUDDY_MODELS_REFRESH_PATH, WORKBUDDY_PROVIDER, WORKBUDDY_SETTINGS_NS, WORKBUDDY_STREAM_IDLE_TIMEOUT_MS, WORKBUDDY_USAGE_PATH, type WorkBuddyAccountChoice, type WorkBuddyAdapter, type WorkBuddyAuthStatus, WorkBuddyCatalog, type WorkBuddyChatResult, type WorkBuddyCredential, WorkBuddyCredentialStore, type WorkBuddyCreditPackage, type WorkBuddyCredits, type WorkBuddyHostHeartbeat, type WorkBuddyModelInfo, type WorkBuddyReasoning, type WorkBuddyRefreshOutcome, type WorkBuddyShim, type WorkBuddyStatusRouteOptions, type WorkBuddyStoreOptions, WorkBuddyUpstreamClient, type WorkBuddyUpstreamModel, type WorkBuddyWebAccount, type WorkBuddyWebCheckin, type WorkBuddyWebCredits, type WorkBuddyWebModel, type WorkBuddyWebPackage, type WorkBuddyWebUsage, apply, authFileName, classifyUpstreamError, clearHostHeartbeat, createWorkBuddyAdapter, createWorkBuddyShim, defaultDesktopAuthCandidates, defaultDesktopAuthDirs, defaultDesktopAuthPath, deriveCatalog, inject, isHeartbeatProcessAlive, name, parseCreditMultiplier, parseReasoning, parseUpstreamModel, parseWorkBuddyAuth, prepareChatBody, processStartTimeMs, readHostHeartbeat, regionOf, registerWorkBuddyStatusRoute, workBuddyModelInput, workBuddyThinkingLevelMap, workBuddyWebStatus, workbuddyAccountId, workbuddyHostHeartbeatPath, workbuddyOwnAuthPath, writeHostHeartbeat };