dsh-connect-workbuddy 4.6.3 → 4.6.5
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 +39 -0
- package/docs/WINDOWS.md +7 -1
- package/lib/bin.js +1 -1
- package/lib/client.js +5 -1
- package/lib/{host-heartbeat-BnaHx2f6.js → host-heartbeat-BpqT3LJe.js} +47 -5
- package/lib/index.js +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,44 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 4.6.5 (2026-10-16)
|
|
4
|
+
|
|
5
|
+
> 版本号是 **patch**:两处诊断正确性修复,没有接口或配置变更。
|
|
6
|
+
|
|
7
|
+
### Fixes
|
|
8
|
+
|
|
9
|
+
- **国际版 App 探测不到:可执行文件候选缺了 `WorkBuddyAI.exe` 与 `WorkBuddyAI` 目录(issue #68)**
|
|
10
|
+
- **症状**:只装了国际版的机器上,插件拿不到密钥 payload 的**来源** → 凭据读不出 → 界面显示成「属于另一个地区」。而报告者实测国际版装在 **`%LOCALAPPDATA%\Programs\WorkBuddyAI\WorkBuddyAI.exe`** —— **目录名与二进制名都和国内版不同**,`workbuddyAppExecutableCandidates()` 的 win32 分支两个都没覆盖。
|
|
11
|
+
- **为什么这类漏探特别难查**:它的失败形态**不是「找不到可执行文件」**,而是「凭据读不出」,最后被下游渲染成区域问题。探针少一个候选与「用户没装 App」在界面上长得一样。
|
|
12
|
+
- **改了什么**:新增 `WINDOWS_APP_EXECUTABLE_NAMES`(`WorkBuddy.exe` / `WorkBuddyAI.exe`)与 `WINDOWS_APP_SUBDIRECTORIES`(`Programs\WorkBuddy` / `WorkBuddy` / `Programs\WorkBuddyAI` / `WorkBuddyAI`),候选按「三个 base × 四个目录 × 两个二进制」笛卡尔积生成(16 个,原先是 4 个)。**目录与二进制不做配对假设**:观察到的是 `WorkBuddyAI\WorkBuddyAI.exe`,但一个 miss 在这里是不可见的,所以两种拼法都试。
|
|
13
|
+
- **`normalizeRegistryExecutable()` 同步放宽**:它是另一处按文件名判断的地方,也必须认国际版 —— 否则注册表里指向国际版二进制的 `DisplayIcon` 会被当成「别的产品的二进制」拒掉。**这个值是会被启动的**,所以只加白名单里的两个名字,不是「任何 exe 都收」。
|
|
14
|
+
- **守卫**:`tests/at-rest.spec.ts` 新增 2 例并把原先断言候选数为 `4` 的那条改成断言**乘积**(`3 × 4 × 2`)—— 用乘积而不是常量,是为了让「少掉一个维度」这种编辑无法靠集合变小而静默通过。新增例子断言国际版路径在内、国内版仍在且在它之前;另一条断言注册表校验接受两种二进制、且**仍拒绝** `uninstall.exe` 与 `WorkBuddy.exe.bak`。**变异验证**:① 去掉 `WorkBuddyAI.exe` → 红 3 例;② 去掉 `WorkBuddyAI` 目录 → 红 2 例;③ 注册表校验不再限制文件名 → 红 2 例。
|
|
15
|
+
- **证据档位**:报告的路径来自报告者的真机(属 A 档观察);**本仓库无法在真机上复现**(无一等 Windows 机器在手),所以这条修复的依据是 A 档观察 + 本仓库的形态断言,未在真机复核 —— 按 `docs/WINDOWS.md` §2 的口径,其「国际版路径命中」仍是 **C 档(约定推导)**,待 Windows 用户回报后升格。
|
|
16
|
+
|
|
17
|
+
- **「另一个地区」把「解密失败」盖住了:优先级顺序把更具体的诊断吃掉(issue #68)**
|
|
18
|
+
- **症状**:凭据**解密失败**时,卡片显示的是「找到了你的 WorkBuddy 登录信息,但它**属于另一个地区的标签页**」。报告者据此去切 tab,**而切 tab 永远救不了解密失败** —— 两个区域都读不出来,密钥推导才是问题。
|
|
19
|
+
- **根因**:`signedOutNotice()` 里 `wrong-region` **先于** `encrypted` 判定,而这两者**不是互斥的,它们会同时出现**,且同时出现是**常态**:`diagnose()` 会探测**两个区域**的文件,于是一台装了**两个 WorkBuddy 版本**的机器上,新版的文件解密失败(`encrypted`),旧版的文件仍能解开、只是属于另一个区域(`wrong-region`)。先判 `wrong-region` 的后果是:只要有一个可解的兄弟文件,headline 就永远说「切 tab」,把真正的阻塞压在下面。
|
|
20
|
+
- **改了什么**:把 `encrypted` 提到 `wrong-region` **之前**。判据不是「哪个更常见」,而是「**哪个是硬阻塞**」—— 另一个标签页上有可读的登录是一条更便宜的修法,但前提是**有登录可读**。诚实地说:原先的顺序把用户推向唯一不可能起作用的动作,而这**正是这个函数存在的理由**,只是两个原因的位置对调了。
|
|
21
|
+
- **反向那一半也保住了**:没有 `encrypted` 时,`wrong-region` 仍然胜出(新增一条测试钉住),否则就是用一个错 headline 换另一个。
|
|
22
|
+
- **守卫**:`tests/searched-paths.spec.ts` 新增 2 例 —— ① 两者共存时 `encrypted` 胜出,且**断言渲染出的字符串**里不含「切换到上方对应标签页」(文案才是用户看到的东西);② 无阻塞时 `wrong-region` 仍胜出。**变异验证**:把顺序恢复成 `wrong-region` 先判 → 红 1 例。
|
|
23
|
+
|
|
24
|
+
## 4.6.4 (2026-10-16)
|
|
25
|
+
|
|
26
|
+
> 版本号是 **patch**:只动开发脚本与测试,**不改插件运行时行为**。
|
|
27
|
+
|
|
28
|
+
### Fixes
|
|
29
|
+
|
|
30
|
+
- **`probe-region-token-accounting.mjs` 补上 `tool-result` 与高熵类 —— 这正是 #59 那个「预测不出上游数字」缺口的关键一格(issue #59)**
|
|
31
|
+
- **为什么补**:本仓库的探针原先只有 `prose` / `code` / `json` 三档。而一份真实长会话的 body 构成(`WORKBUDDY_BODY_REPORT` 抓下来的 35 个真实请求)是 **`tool-result` 占 47% 字符**,是三档里**一档都没覆盖**的内容类别。用三档去预测,结论是「上游报的数比最贵档还高 28%」,看起来像发现了新机制;而把实测的 `tool-result` 系数(**455.5 tok/1k**,跨区域 455.5 vs 455.6)代回去,**缺口从 28% 收到约 1%**。**缺的是系数表的一行,不是新机制。**
|
|
32
|
+
- **新增的 `--kind`**:`base64`(实测 2.50× 于 `code`)、`hex`(2.04×)、`ansi`(1.92×)、`proc`(1.63×)、`tool-result`。报告者的实测显示**高熵内容是长会话里最贵的一类**,而 base64 恰是 `code` 的 2.5 倍 —— 老表把 `code` 当成天花板,因此系统性低估。
|
|
33
|
+
- **生成器必须是确定性的**:两个区域要收到**逐字节相同**的填充文本,否则测出来的比值是在量生成器而不是量网关。故不读时钟、不读随机源、不读文件系统;用固定种子的 32 位 LCG。**这一点由测试直接断言源码文本**(`Math.random` / `Date.now` / `new Date` / `fs` 调用一律不得出现),因为行为断言只能证明「这次恰好相同」。
|
|
34
|
+
- **★ 写测试时抓到一个真缺陷**:初版生成器是 `(state >>> 8) % alphabet.length` —— 只取 LCG 状态的 log2(L) 位,**在 L=64 时每 16384 字符就重复一次**,于是 65536 字符的填充里同一段 16 KiB 出现四次。**短周期正是这个类存在要避免的「可压缩」**:一个能看出重复的分词器会少收 token,于是实测水位被**低估**,而这正是原始 #59 现象的形状。修法是在取模前先做两轮 xorshift-multiply 混合(实测 12 万字符内无周期)。
|
|
35
|
+
- **采样规则**(写进模块注释):**不得只取日志开头**。报告者实测同一类真实 `tool-result` 文本,取开头 12k 字符得 322.6 tok/1k,全时段均匀采样得 455.5 —— **差 41%**。填充文本不仅要跨区域逐字节相同,还要与真实分布同构,否则量到的是一类内容的系数、却被当作整份历史用。
|
|
36
|
+
- **`tool-result` 刻意不走 `entropy()`**:逐字符打散模板会产出没有任何工具会发出的文本,而这个类的**全部意义就在于内容形状**(标识符、花括号、引号键、路径、对齐数字)真实。它的变化来自「每轮以递进的偏移重复模板」,因此同样没有短周期。
|
|
37
|
+
- **守卫**:新增 `tests/probe-fillers.spec.ts`,8 例 —— ① 十个 `语言:类别` 组合都存在;② 每次生成逐字节相同;③ **源码文本里不得出现随机源或时钟**;④ **不得有 64 / 1024 / 16384 的周期**(这一条就是抓到上面那个真缺陷的那条);⑤ `tool-result` 仍像 tool-result(含 `export function` / `"path"` / `await fs.readFile`,且中文版确实是中文);⑥ `ansi` 是**真的控制字节** `<ESC>[31m`,不是字面的 `\u001B` 六字符;⑦ 结构化类别里不得出现 `NaN`;⑧ 每个填充长度都超过默认 `--chars=12000`。
|
|
38
|
+
- **第 ⑦ 条的取法有讲究,写在测试注释里**:`NaN` 只查 `ansi` / `proc` / `tool-result` 三类 —— 它们是**格式化**出来的(`\u001B[3${n}m`、`.padStart`),出现 `NaN` 必是缺陷;而 base64 / hex 是从字母表里取的,字母表本身含 `N`、`a`、`N`,子串会以约 64³ 分之一的概率偶然出现。初版断言查了全部类别,**是错的**(会在无关的地方随机转红)—— 这是我写完立刻遇到并改掉的。
|
|
39
|
+
- **变异验证(5 个变异,全部转红,各自只打中应打中的用例)**:① 去掉取模前的混合(重现 16384 周期)→ 红 1 例;② 顺序循环字母表(64 周期)→ 红 1 例;③ 改用 `Math.random` → 红 1 例;④ `ansi` 退化成字面 `\u001B` → 红 1 例;⑤ `tool-result` 逐字符打散成乱码 → 红 1 例。
|
|
40
|
+
- **来源**:本条的补类与采样规则由 issue #59 的报告者提出并附实测数据(`tool-result` 455.5、高熵四档、尺寸梯度 12k→500k),本仓库按其建议固化。**探针脚本不随包发布**(`files` 白名单不含 `scripts/`),所以这一版与已安装插件的行为无关。
|
|
41
|
+
|
|
3
42
|
## 4.6.3 (2026-10-16)
|
|
4
43
|
|
|
5
44
|
> 版本号是 **patch**:没有接口、配置或界面变更,但它修的是一个**所有国际版模型全部不可用**的缺陷。
|
package/docs/WINDOWS.md
CHANGED
|
@@ -40,9 +40,15 @@ Windows 在本项目里不是「顺带能跑」的平台,而是**有专属分
|
|
|
40
40
|
|
|
41
41
|
| 档位 | 含义 | 实例 |
|
|
42
42
|
| --- | --- | --- |
|
|
43
|
-
| **A 真机取证** | 在真实 Windows 上取得,可作为最终判据 | ①
|
|
43
|
+
| **A 真机取证** | 在真实 Windows 上取得,可作为最终判据 | ① 真实 Windows 安装(2026-09-26)里 `workbuddy-desktop.info` 的 `nickname` / `phoneNumber` / `accessToken` 信封**观察到 `keyId=9127dea1b44020a7`**;② issue #13 报告的 `E:\WorkBuddy\WorkBuddy.exe`;③ **§1-5 的控制台闪窗**(见下方专门说明);④ §1-1 凭据目录与 §1-2 可执行文件候选在真机上命中(`doctor` 全绿,见 §7 记录) |
|
|
44
44
|
| **B CI 实测** | `windows-latest` 上跑过,覆盖跨平台正确性 | 套件全绿;`tests/auth.spec.ts` 的 `win32` 分支断言(注入 `platform`/`home`/`env`,**任何主机上都能跑**) |
|
|
45
45
|
| **C 约定推导** | 按平台约定写出 + 单元测试钉住,**未在真机逐项验证** | 四个凭据/可执行文件候选路径中**未在本机命中的那些**(见 §7 记录:本机只命中了 `%LOCALAPPDATA%\Programs\WorkBuddy` 与 `%LOCALAPPDATA%\...\auth`,其余候选仍属 C 档) |
|
|
46
|
+
|
|
47
|
+
> **2026-10-16 更正(issue #68 逼出来的)**:上面 ① 此前写作「`tests/at-rest.spec.ts` 里**固定向量** `keyId=9127dea1b44020a7`」,并把该测试当作这条观察的守卫。**那个说法是错的**:观察本身成立(§7 的记录也独立记着它),但**推导出该 keyId 的那把 secret 从未被留存**,所以测试只能断言 16 位十六进制**形态**,无法复现该值 —— 它此前并未真正钉住这个向量,而文档把它读成了「已钉住」。
|
|
48
|
+
>
|
|
49
|
+
> 现已把测试改名为「derives a 16-hex-char id, which is the shape the real envelopes carry」并在注释里写明它不证明什么;**推导规则**(哈希 base64 串而非解码字节、取 `sha256(key)` 前 16 位十六进制)由它上面的两条测试真正钉住 —— 那两条才是否证得动的。
|
|
50
|
+
>
|
|
51
|
+
> 若要真正钉住这个向量,需要**连同推导它的一把 secret 一起取样**(或至少记录 `sha256(secret)` 的输入形式);在那之前,① 仍是**观察记录**,不是**回归守卫**。登记在此,免得下一个人再把它当成守卫。
|
|
46
52
|
| **D 未验证** | 无任何上述支撑 | —— |
|
|
47
53
|
|
|
48
54
|
### A 档取证:§1-5 的控制台闪窗(2026-09-26,Windows 11 22621)
|
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-BpqT3LJe.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
|
@@ -3652,11 +3652,15 @@ window.__ModuleLoader__.load({
|
|
|
3652
3652
|
* is precisely the action that cannot work when the credential exists but is
|
|
3653
3653
|
* encrypted. Leaving it in the collapsed list meant the headline contradicted
|
|
3654
3654
|
* the detail below it — and the headline is the only part most users read.
|
|
3655
|
+
*
|
|
3656
|
+
* `encrypted` outranks `wrong-region` as well, which is a change (issue #68):
|
|
3657
|
+
* the two are not alternatives, they co-occur, and when they do the unreadable
|
|
3658
|
+
* key is the blocker. See the note in {@link signedOutNotice}.
|
|
3655
3659
|
*/
|
|
3656
3660
|
function signedOutNotice(input) {
|
|
3657
3661
|
if (input.selectionLost) return { key: "row.selectionLostMessage" };
|
|
3658
|
-
if (input.searched.some((item) => item.reason === "wrong-region")) return { key: "row.signedOutWrongRegion" };
|
|
3659
3662
|
if (input.searched.some((item) => item.reason === "encrypted")) return { key: "row.signedOutEncrypted" };
|
|
3663
|
+
if (input.searched.some((item) => item.reason === "wrong-region")) return { key: "row.signedOutWrongRegion" };
|
|
3660
3664
|
if (input.searched.length > 0) return { key: "row.signedOutHint" };
|
|
3661
3665
|
return input.message === void 0 ? { key: "row.signedOutHint" } : {
|
|
3662
3666
|
key: "row.signedOutHint",
|
|
@@ -335,8 +335,41 @@ const SYMMETRIC_SCHEME = "sym-v1";
|
|
|
335
335
|
const WORKBUDDY_APP_EXECUTABLE_ENV = "WORKBUDDY_APP_EXECUTABLE";
|
|
336
336
|
/** How long the app is given to answer with its key payload. */
|
|
337
337
|
const KEY_FETCH_TIMEOUT_MS = 1e4;
|
|
338
|
-
/**
|
|
339
|
-
|
|
338
|
+
/**
|
|
339
|
+
* File names the WorkBuddy desktop executable goes by on Windows.
|
|
340
|
+
*
|
|
341
|
+
* `WorkBuddy.exe` is the domestic build. The international build ships as
|
|
342
|
+
* **`WorkBuddyAI.exe` under a `WorkBuddyAI` directory** (issue #68), and the
|
|
343
|
+
* probe list below carries no candidate that matched it — so a machine with only
|
|
344
|
+
* the international app installed could not find the key payload's source and
|
|
345
|
+
* reported the credentials as unreadable, which the UI then described as a
|
|
346
|
+
* wrong-region sign-in.
|
|
347
|
+
*
|
|
348
|
+
* Kept as a LIST rather than a second constant because the same name test is
|
|
349
|
+
* used in two places that must agree: the directory joiners below, and the
|
|
350
|
+
* registry-value validator (`normalizeRegistryExecutable`), which must accept a
|
|
351
|
+
* `DisplayIcon` pointing at either binary. The first entry is the canonical one
|
|
352
|
+
* used when a directory is known to hold the domestic build.
|
|
353
|
+
*/
|
|
354
|
+
const APP_EXECUTABLE_NAMES = ["WorkBuddy.exe", "WorkBuddyAI.exe"];
|
|
355
|
+
/** The canonical executable name; the rest of {@link APP_EXECUTABLE_NAMES}. */
|
|
356
|
+
const APP_EXECUTABLE_NAME = APP_EXECUTABLE_NAMES[0];
|
|
357
|
+
/**
|
|
358
|
+
* Windows install directories the desktop app is observed to use, in probe
|
|
359
|
+
* order, relative to a base such as `%LOCALAPPDATA%` or `%ProgramFiles%`.
|
|
360
|
+
*
|
|
361
|
+
* `Programs\WorkBuddy` is the common per-user layout; `WorkBuddy` is the flatter
|
|
362
|
+
* one some installers produce. The `WorkBuddyAI` pair is the international
|
|
363
|
+
* build's layout (issue #68) — both spellings are carried because the directory
|
|
364
|
+
* and the binary were observed to agree, but a future build could pair either
|
|
365
|
+
* way, and a miss here is invisible (it surfaces as "unreadable credentials").
|
|
366
|
+
*/
|
|
367
|
+
const WINDOWS_APP_SUBDIRECTORIES = [
|
|
368
|
+
["Programs", "WorkBuddy"],
|
|
369
|
+
["WorkBuddy"],
|
|
370
|
+
["Programs", "WorkBuddyAI"],
|
|
371
|
+
["WorkBuddyAI"]
|
|
372
|
+
];
|
|
340
373
|
/**
|
|
341
374
|
* macOS bundles the desktop app may be installed as, in probe order.
|
|
342
375
|
*
|
|
@@ -581,7 +614,8 @@ function normalizeRegistryExecutable(value) {
|
|
|
581
614
|
if (unquoted === void 0 || unquoted === "") return void 0;
|
|
582
615
|
const withoutIndex = unquoted.replace(/,\s*-?\d+\s*$/u, "");
|
|
583
616
|
if (withoutIndex === "") return void 0;
|
|
584
|
-
|
|
617
|
+
const base = win32.basename(withoutIndex).toLowerCase();
|
|
618
|
+
if (!APP_EXECUTABLE_NAMES.some((name) => name.toLowerCase() === base)) return void 0;
|
|
585
619
|
return withoutIndex;
|
|
586
620
|
}
|
|
587
621
|
/**
|
|
@@ -653,7 +687,15 @@ function workbuddyAppExecutableCandidates(platform = process.platform, home = ho
|
|
|
653
687
|
const local = env["LOCALAPPDATA"]?.trim();
|
|
654
688
|
const programFiles = env["ProgramFiles"]?.trim();
|
|
655
689
|
const programFilesX86 = env["ProgramFiles(x86)"]?.trim();
|
|
656
|
-
|
|
690
|
+
const bases = [
|
|
691
|
+
local === void 0 || local === "" ? void 0 : local,
|
|
692
|
+
programFiles === void 0 || programFiles === "" ? void 0 : programFiles,
|
|
693
|
+
programFilesX86 === void 0 || programFilesX86 === "" ? void 0 : programFilesX86
|
|
694
|
+
];
|
|
695
|
+
for (const base of bases) {
|
|
696
|
+
if (base === void 0) continue;
|
|
697
|
+
for (const subdirectory of WINDOWS_APP_SUBDIRECTORIES) for (const name of APP_EXECUTABLE_NAMES) candidates.push(win32.join(base, ...subdirectory, name));
|
|
698
|
+
}
|
|
657
699
|
} else if (platform === "darwin") for (const name of MACOS_APP_BUNDLE_NAMES) candidates.push(readBundleExecutable(join("/Applications", name)), readBundleExecutable(join(home, "Applications", name)));
|
|
658
700
|
return candidates.filter((candidate) => candidate !== void 0 && candidate !== "");
|
|
659
701
|
}
|
|
@@ -3907,7 +3949,7 @@ function generationOf(version) {
|
|
|
3907
3949
|
//#endregion
|
|
3908
3950
|
//#region src/version.ts
|
|
3909
3951
|
/** The npm package version this build was produced from. */
|
|
3910
|
-
const WORKBUDDY_CONNECT_VERSION = "4.6.
|
|
3952
|
+
const WORKBUDDY_CONNECT_VERSION = "4.6.5";
|
|
3911
3953
|
//#endregion
|
|
3912
3954
|
//#region src/host-heartbeat.ts
|
|
3913
3955
|
/**
|
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-BpqT3LJe.js";
|
|
2
2
|
import z from "@deepseek-ai/schemastery";
|
|
3
3
|
import { appendFile, mkdir, readFile } 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.6.
|
|
5
|
+
"version": "4.6.5",
|
|
6
6
|
"author": "dingminhua",
|
|
7
7
|
"copyright": "Copyright (c) 2026 LaoDing",
|
|
8
8
|
"license": "MIT",
|