dsh-connect-workbuddy 2.0.12 → 2.0.13

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,5 +1,21 @@
1
1
  # Changelog
2
2
 
3
+ ## 2.0.13 (Unreleased)
4
+
5
+ ### Bug Fixes
6
+
7
+ - **上下文预算(或任何 regions/accounts 字段)保存失败:`settings mutate … must contain only JSON-compatible data (found a function at $.ops[0].value.get)`**(用户实报)。这是把「易失标记一生效」那条缺陷(2.0.12 修的)的**另一条受害者路径**补上了。
8
+
9
+ - **根因**:`__save` 端点(卡片保存的 Host 兜底路径)在合并时直接读取 `row.value[field]`,而 `row.value` 是 settings 服务解析后的 config——某 volatile 字段(`regions` / `accounts`)在那里是一个 `{ get(): T }` **活引用**。`{ ...这种对象 }` 展开后变成 `{ get: <函数> }`,于是 `settings.mutate` 的严格 JSON 兼容校验拒绝它,报 `found a function at $.ops[0].value.get`。保存**完全失败**(不是静默失败,而是直接报错),因为真实保存流程里 `scope.set()` 被判为未落盘后回退到了这个端点。
10
+ - **修法**:`__save` 在合并前先 `unwrapVolatileDeep(row.value?.[field])` 把活引用剥净,让 `mutate` 收到的 payload 只含 JSON 兼容数据。`unwrapVolatileDeep` 是 2.0.12 为 `installSection` 引入的同一 helper,这里复用。
11
+ - **回归测试**(`tests/web-status.spec.ts`):构造一个 resolved config 含 `{ get() }` 活引用的 settings 服务,经真实 `__save` 路由请求,断言 `mutate` 收到的是一个能通过 JSON 往返的 payload(无函数),且上下文预算字段完好。**变异验证**:把 `unwrapVolatileDeep` 那行去掉,该用例立即变红。
12
+
13
+ > 说明:`__save` 会先把 `row.value[field]` 解包、再用「浅展开 + incoming 覆盖」合并到该字段。对单 region 写入(本次场景)足够;若日后要一次写多个 region 槽位,应改为深合并——届时再扩。
14
+
15
+ ### Tests
16
+
17
+ - 331 → 332(新增 1 例:live-reference 配置下的 `__save` 保存回归)。
18
+
3
19
  ## 2.0.12 (2026-09-23)
4
20
 
5
21
  ### Features
package/lib/bin.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { O as workbuddyOwnAuthPath, T as legacyWorkbuddyOwnAuthPath, W as findWorkbuddyAppExecutable, _ as WorkBuddyCredentialStore, a as readHostHeartbeat, b as defaultDesktopAuthCandidates, c as WORKBUDDY_CONNECT_VERSION, g as WORKBUDDY_AUTH_FILE_ENV, j as WorkBuddyUpstreamClient, l as FALLBACK_WORKBUDDY_MODELS, o as workbuddyHostHeartbeatPath, r as isHeartbeatProcessAlive, u as FALLBACK_WORKBUDDY_MODELS_GLOBAL, x as defaultDesktopAuthDirs, z as WORKBUDDY_APP_EXECUTABLE_ENV } from "./host-heartbeat-ChtMu37E.js";
2
+ import { O as workbuddyOwnAuthPath, T as legacyWorkbuddyOwnAuthPath, W as findWorkbuddyAppExecutable, _ as WorkBuddyCredentialStore, a as readHostHeartbeat, b as defaultDesktopAuthCandidates, c as WORKBUDDY_CONNECT_VERSION, g as WORKBUDDY_AUTH_FILE_ENV, j as WorkBuddyUpstreamClient, l as FALLBACK_WORKBUDDY_MODELS, o as workbuddyHostHeartbeatPath, r as isHeartbeatProcessAlive, u as FALLBACK_WORKBUDDY_MODELS_GLOBAL, x as defaultDesktopAuthDirs, z as WORKBUDDY_APP_EXECUTABLE_ENV } from "./host-heartbeat-FxHiaIn-.js";
3
3
  import { realpathSync } from "node:fs";
4
4
  import { fileURLToPath } from "node:url";
5
5
  //#region src/bin.ts
@@ -2208,7 +2208,7 @@ var WorkBuddyCatalog = class {
2208
2208
  //#endregion
2209
2209
  //#region src/version.ts
2210
2210
  /** The npm package version this build was produced from. */
2211
- const WORKBUDDY_CONNECT_VERSION = "2.0.12";
2211
+ const WORKBUDDY_CONNECT_VERSION = "2.0.13";
2212
2212
  //#endregion
2213
2213
  //#region src/host-heartbeat.ts
2214
2214
  /**
package/lib/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { A as WorkBuddyCredentialRejectedError, B as clearAtRestKeyCache, C as hasEncryptedCredentialFields, D as workbuddyAccountId, E as parseWorkBuddyAuth, F as parseReasoning, G as isEncryptedFieldWrapper, H as deriveAtRestKeyId, I as parseUpstreamModel, J as macosNestedAppBundles, K as isWorkbuddyBundle, L as prepareChatBody, M as classifyUpstreamError, N as isCredentialRejectedError, O as workbuddyOwnAuthPath, P as parseCreditMultiplier, R as regionOf, S as defaultDesktopAuthPath, T as legacyWorkbuddyOwnAuthPath, U as fetchAtRestKeyPayload, V as deriveAtRestKey, W as findWorkbuddyAppExecutable, X as readAtRestKey, Y as openEncryptedField, Z as workbuddyAppExecutableCandidates, _ as WorkBuddyCredentialStore, a as readHostHeartbeat, b as defaultDesktopAuthCandidates, c as WORKBUDDY_CONNECT_VERSION, d as WorkBuddyCatalog, f as deriveCatalog, g as WORKBUDDY_AUTH_FILE_ENV, h as WORKBUDDY_AUTH_FILENAME, i as processStartTimeMs, j as WorkBuddyUpstreamClient, k as CREDENTIAL_REJECTED_CODE, l as FALLBACK_WORKBUDDY_MODELS, m as ENCRYPTED_CREDENTIAL_CODE, n as clearHostHeartbeat, o as workbuddyHostHeartbeatPath, p as fallbackModelsFor, q as macosBundleExecutable, r as isHeartbeatProcessAlive, s as writeHostHeartbeat, t as WORKBUDDY_HOST_HEARTBEAT_FILENAME, u as FALLBACK_WORKBUDDY_MODELS_GLOBAL, v as WorkBuddyEncryptedCredentialError, w as isEncryptedCredentialError, x as defaultDesktopAuthDirs, y as authFileName, z as WORKBUDDY_APP_EXECUTABLE_ENV } from "./host-heartbeat-ChtMu37E.js";
1
+ import { A as WorkBuddyCredentialRejectedError, B as clearAtRestKeyCache, C as hasEncryptedCredentialFields, D as workbuddyAccountId, E as parseWorkBuddyAuth, F as parseReasoning, G as isEncryptedFieldWrapper, H as deriveAtRestKeyId, I as parseUpstreamModel, J as macosNestedAppBundles, K as isWorkbuddyBundle, L as prepareChatBody, M as classifyUpstreamError, N as isCredentialRejectedError, O as workbuddyOwnAuthPath, P as parseCreditMultiplier, R as regionOf, S as defaultDesktopAuthPath, T as legacyWorkbuddyOwnAuthPath, U as fetchAtRestKeyPayload, V as deriveAtRestKey, W as findWorkbuddyAppExecutable, X as readAtRestKey, Y as openEncryptedField, Z as workbuddyAppExecutableCandidates, _ as WorkBuddyCredentialStore, a as readHostHeartbeat, b as defaultDesktopAuthCandidates, c as WORKBUDDY_CONNECT_VERSION, d as WorkBuddyCatalog, f as deriveCatalog, g as WORKBUDDY_AUTH_FILE_ENV, h as WORKBUDDY_AUTH_FILENAME, i as processStartTimeMs, j as WorkBuddyUpstreamClient, k as CREDENTIAL_REJECTED_CODE, l as FALLBACK_WORKBUDDY_MODELS, m as ENCRYPTED_CREDENTIAL_CODE, n as clearHostHeartbeat, o as workbuddyHostHeartbeatPath, p as fallbackModelsFor, q as macosBundleExecutable, r as isHeartbeatProcessAlive, s as writeHostHeartbeat, t as WORKBUDDY_HOST_HEARTBEAT_FILENAME, u as FALLBACK_WORKBUDDY_MODELS_GLOBAL, v as WorkBuddyEncryptedCredentialError, w as isEncryptedCredentialError, x as defaultDesktopAuthDirs, y as authFileName, z as WORKBUDDY_APP_EXECUTABLE_ENV } from "./host-heartbeat-FxHiaIn-.js";
2
2
  import z from "@deepseek-ai/schemastery";
3
3
  import { randomBytes, timingSafeEqual } from "node:crypto";
4
4
  import { createProvider } from "@earendil-works/pi-ai";
@@ -916,7 +916,7 @@ function registerWorkBuddyStatusRoute(ctx, deps) {
916
916
  if (field !== "regions" && field !== "accounts") return json(res, 400, { error: "field must be regions or accounts" });
917
917
  const row = settings.describe().find((r) => String(r.ns).includes("workbuddy"));
918
918
  if (row === void 0) return json(res, 503, { error: "workbuddy namespace missing from describe()" });
919
- const current = row.value?.[field] ?? {};
919
+ const current = unwrapVolatileDeep(row.value?.[field] ?? {});
920
920
  const incoming = body.value ?? {};
921
921
  const merged = {
922
922
  ...current,
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": "2.0.12",
5
+ "version": "2.0.13",
6
6
  "author": "dingminhua",
7
7
  "copyright": "Copyright (c) 2026 LaoDing",
8
8
  "license": "MIT",