dsh-connect-workbuddy 5.2.3 → 5.3.1

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.
@@ -1684,63 +1684,6 @@ function batchModelIds(ids, size = 50) {
1684
1684
  for (let index = 0; index < unique.length; index += size) batches.push(unique.slice(index, index + size));
1685
1685
  return batches;
1686
1686
  }
1687
- /** The app's own Chinese wording, per level. `normal` and `unknown` have none. */
1688
- const BUSY_LABELS_ZH = {
1689
- idle: "空闲",
1690
- busy: "轻微拥堵",
1691
- congested: "极度拥堵",
1692
- unavailable: "不可用"
1693
- };
1694
- /** The app's own English wording, per level. */
1695
- const BUSY_LABELS_EN = {
1696
- idle: "Idle",
1697
- busy: "Slightly congested",
1698
- congested: "Extremely congested",
1699
- unavailable: "Unavailable"
1700
- };
1701
- /**
1702
- * The word this level is drawn with, or `undefined` when it is not worth drawing.
1703
- *
1704
- * `normal` returns `undefined` on purpose: the app's selector shows a busy line
1705
- * only for a level that differs from the healthy default, and a badge that reads
1706
- * "正常" on fifteen rows out of twenty is noise, not information. `unknown`
1707
- * returns `undefined` for the same reason plus one more — the plugin must not
1708
- * invent a claim the upstream never made.
1709
- */
1710
- function busyLabel(level, locale = "zh") {
1711
- return (locale === "en" ? BUSY_LABELS_EN : BUSY_LABELS_ZH)[level];
1712
- }
1713
- /**
1714
- * Suffix appended to a model's DSH-facing display name, prefixed with a middle
1715
- * dot, or `''` when the level is not worth drawing.
1716
- *
1717
- * This is the "badge to the RIGHT of the model name" the DSH model selector
1718
- * already does for its own variants (`deepseek-v4.1-flash · 1017`): DSH renders
1719
- * `name` verbatim and offers no separate badge slot to a provider, so the only
1720
- * way to put load beside the name — instead of in a second line, or inside the
1721
- * name — is to extend the name. The name stays display-only: every DSH-side join
1722
- * keys on the model ID, and `workBuddyDisplayName` is the single place that
1723
- * builds it.
1724
- *
1725
- * ONLY A LEVEL THAT ASKS FOR A DECISION IS DRAWN — `busy`, `congested`,
1726
- * `unavailable`. `idle` deliberately gets no suffix here even though it has a
1727
- * word: on the measured CN roster seven of twenty models are idle, and a picker
1728
- * whose every row carries a badge reads as decoration rather than as a warning.
1729
- * That is also how the app's own selector behaves in its compact mode, where only
1730
- * `congested` is drawn at all. The card's detail panel is where the full scale
1731
- * belongs.
1732
- */
1733
- function busyDisplaySuffix(level, locale = "zh") {
1734
- if (level === void 0 || !DRAWN_IN_PICKER.has(level)) return "";
1735
- const label = busyLabel(level, locale);
1736
- return label === void 0 ? "" : ` · ${label}`;
1737
- }
1738
- /** The levels that change a model-picking decision; see {@link busyDisplaySuffix}. */
1739
- const DRAWN_IN_PICKER = /* @__PURE__ */ new Set([
1740
- "busy",
1741
- "congested",
1742
- "unavailable"
1743
- ]);
1744
1687
  /**
1745
1688
  * Attach each model's level to its catalog entry.
1746
1689
  *
@@ -5861,7 +5804,7 @@ function generationOf(version) {
5861
5804
  //#endregion
5862
5805
  //#region src/version.ts
5863
5806
  /** The npm package version this build was produced from. */
5864
- const WORKBUDDY_CONNECT_VERSION = "5.2.3";
5807
+ const WORKBUDDY_CONNECT_VERSION = "5.3.1";
5865
5808
  //#endregion
5866
5809
  //#region src/host-heartbeat.ts
5867
5810
  /**
@@ -6019,4 +5962,4 @@ async function clearHostHeartbeat() {
6019
5962
  await rm(workbuddyHostHeartbeatPath(), { force: true });
6020
5963
  }
6021
5964
  //#endregion
6022
- export { regionOf as $, parseWorkBuddyAuth as A, workbuddyAppExecutableCandidates as At, forceNeutralHead as B, defaultDesktopAuthCandidates as C, findWorkbuddyAppExecutableWithSource as Ct, isEncryptedCredentialError as D, macosNestedAppBundles as Dt, hasEncryptedCredentialFields as E, macosBundleExecutable as Et, WORKBUDDY_FALLBACK_SYSTEM_PROMPT as F, knownRegionOf as G, isConversationIdGateBody as H, WorkBuddyCredentialRejectedError as I, parseCreditMultiplier as J, modelIdOfBody as K, WorkBuddyUpstreamClient as L, workbuddyOwnAuthPath as M, resolveDshHome as Mt, CONTEXT_OVERFLOW_MARKER as N, withFileLock as Nt, isVaultAccountId as O, openEncryptedField as Ot, CREDENTIAL_REJECTED_CODE as P, writeFileAtomic as Pt, prepareChatBody as Q, classifyUpstreamError as R, authFileName as S, findWorkbuddyAppExecutable as St, defaultDesktopAuthPath as T, isWorkbuddyBundle as Tt, isCredentialRejectedError as U, isContextTooLongBody as V, isFirstMessageGateBody as W, parseUpstreamModel as X, parseReasoning as Y, perturbChannelFingerprints as Z, ENCRYPTED_CREDENTIAL_CODE as _, WORKBUDDY_APP_EXECUTABLE_ENV as _t, readHostHeartbeat as a, offDefaultFor as at, WorkBuddyCredentialStore as b, deriveAtRestKeyId as bt, WORKBUDDY_CONNECT_VERSION as c, withEffectiveOff as ct, FALLBACK_WORKBUDDY_MODELS_GLOBAL as d, pickImageModel as dt, attachBusyLevels as et, WorkBuddyCatalog as f, parseQueueAnswer as ft, withoutRouters as g, nativeModalityOf as gt, fallbackModelsFor as h, imageDefaultFor as ht, processStartTimeMs as i, lastRefusalFor as it, workbuddyAccountId as j, hostPeersInfo as jt, legacyWorkbuddyOwnAuthPath as k, readAtRestKey as kt, piAiRuntimeInfo as l, DEFAULT_IMAGE_SIZE as lt, deriveCatalog as m, NATIVE_MODALITY_BY_MODEL_ID as mt, clearHostHeartbeat as n, REFUSES_OFF_MODEL_IDS as nt, workbuddyHostHeartbeatPath as o, offRefused as ot, applyContextBudgets as p, queueNoticeText as pt, openingEvidenceOfBody as q, isHeartbeatProcessAlive as r, defaultOffModelIds as rt, writeHostHeartbeat as s, recordRefusal as st, WORKBUDDY_HOST_HEARTBEAT_FILENAME as t, busyDisplaySuffix as tt, FALLBACK_WORKBUDDY_MODELS as u, WorkBuddyImageError as ut, WORKBUDDY_AUTH_FILENAME as v, clearAtRestKeyCache as vt, defaultDesktopAuthDirs as w, isEncryptedFieldWrapper as wt, WorkBuddyEncryptedCredentialError as x, fetchAtRestKeyPayload as xt, WORKBUDDY_AUTH_FILE_ENV as y, deriveAtRestKey as yt, declaredTools as z };
5965
+ export { regionOf as $, parseWorkBuddyAuth as A, hostPeersInfo as At, forceNeutralHead as B, defaultDesktopAuthCandidates as C, isEncryptedFieldWrapper as Ct, isEncryptedCredentialError as D, openEncryptedField as Dt, hasEncryptedCredentialFields as E, macosNestedAppBundles as Et, WORKBUDDY_FALLBACK_SYSTEM_PROMPT as F, knownRegionOf as G, isConversationIdGateBody as H, WorkBuddyCredentialRejectedError as I, parseCreditMultiplier as J, modelIdOfBody as K, WorkBuddyUpstreamClient as L, workbuddyOwnAuthPath as M, withFileLock as Mt, CONTEXT_OVERFLOW_MARKER as N, writeFileAtomic as Nt, isVaultAccountId as O, readAtRestKey as Ot, CREDENTIAL_REJECTED_CODE as P, prepareChatBody as Q, classifyUpstreamError as R, authFileName as S, findWorkbuddyAppExecutableWithSource as St, defaultDesktopAuthPath as T, macosBundleExecutable as Tt, isCredentialRejectedError as U, isContextTooLongBody as V, isFirstMessageGateBody as W, parseUpstreamModel as X, parseReasoning as Y, perturbChannelFingerprints as Z, ENCRYPTED_CREDENTIAL_CODE as _, clearAtRestKeyCache as _t, readHostHeartbeat as a, offRefused as at, WorkBuddyCredentialStore as b, fetchAtRestKeyPayload as bt, WORKBUDDY_CONNECT_VERSION as c, DEFAULT_IMAGE_SIZE as ct, FALLBACK_WORKBUDDY_MODELS_GLOBAL as d, parseQueueAnswer as dt, attachBusyLevels as et, WorkBuddyCatalog as f, queueNoticeText as ft, withoutRouters as g, WORKBUDDY_APP_EXECUTABLE_ENV as gt, fallbackModelsFor as h, nativeModalityOf as ht, processStartTimeMs as i, offDefaultFor as it, workbuddyAccountId as j, resolveDshHome as jt, legacyWorkbuddyOwnAuthPath as k, workbuddyAppExecutableCandidates as kt, piAiRuntimeInfo as l, WorkBuddyImageError as lt, deriveCatalog as m, imageDefaultFor as mt, clearHostHeartbeat as n, defaultOffModelIds as nt, workbuddyHostHeartbeatPath as o, recordRefusal as ot, applyContextBudgets as p, NATIVE_MODALITY_BY_MODEL_ID as pt, openingEvidenceOfBody as q, isHeartbeatProcessAlive as r, lastRefusalFor as rt, writeHostHeartbeat as s, withEffectiveOff as st, WORKBUDDY_HOST_HEARTBEAT_FILENAME as t, REFUSES_OFF_MODEL_IDS as tt, FALLBACK_WORKBUDDY_MODELS as u, pickImageModel as ut, WORKBUDDY_AUTH_FILENAME as v, deriveAtRestKey as vt, defaultDesktopAuthDirs as w, isWorkbuddyBundle as wt, WorkBuddyEncryptedCredentialError as x, findWorkbuddyAppExecutable as xt, WORKBUDDY_AUTH_FILE_ENV as y, deriveAtRestKeyId as yt, declaredTools as z };
package/lib/index.d.ts CHANGED
@@ -1556,6 +1556,32 @@ declare class WorkBuddyCatalog {
1556
1556
  set(models: readonly WorkBuddyModelInfo[]): void;
1557
1557
  }
1558
1558
  //#endregion
1559
+ //#region src/cli-bridge/mount.d.ts
1560
+ /**
1561
+ * The `cliBridge` settings as they arrive from the config schema.
1562
+ *
1563
+ * Every field is optional because the schema may hand over a partial object, and
1564
+ * a user who edits only one key must not have to restate the rest.
1565
+ */
1566
+ interface CliBridgeSettings {
1567
+ enabled?: boolean;
1568
+ binary?: string;
1569
+ model?: string;
1570
+ permissionMode?: string;
1571
+ effort?: string;
1572
+ maxTurns?: number;
1573
+ timeoutSecs?: number;
1574
+ regionOrder?: string;
1575
+ workingDir?: string;
1576
+ allowedDirs?: string;
1577
+ appendSystemPrompt?: string;
1578
+ allowUnattended?: boolean;
1579
+ maxReplyChars?: number;
1580
+ injectResult?: boolean;
1581
+ maxTurnsPerSessionHour?: number;
1582
+ maxTurnsPerHour?: number;
1583
+ }
1584
+ //#endregion
1559
1585
  //#region src/off-thinking.d.ts
1560
1586
  /**
1561
1587
  * Ids observed to REFUSE `reasoning_effort: "off"` with HTTP 400 despite
@@ -2948,6 +2974,18 @@ interface WorkBuddyWebModel {
2948
2974
  nativeContextWindow: number;
2949
2975
  maxTokens: number;
2950
2976
  creditMultiplier?: number;
2977
+ /**
2978
+ * The model's load level, as read from the upstream's own probe.
2979
+ *
2980
+ * Carried so the CARD can draw it as an ICON. The host's model picker cannot
2981
+ * (its name is a plain string), which is why the picker gets a character and
2982
+ * the card gets a picture.
2983
+ *
2984
+ * ABSENT means "not measured right now" and is NOT the same as `normal`: the
2985
+ * card must not draw a level the upstream never stated. It is deliberately
2986
+ * not persisted into `lastCatalog` — load is a fact about this minute.
2987
+ */
2988
+ busyLevel?: WorkBuddyBusyLevel;
2951
2989
  /**
2952
2990
  * Upstream's own image-input default from the latest refresh. Used ONLY to
2953
2991
  * pre-fill the image checkboxes when "Refresh from WorkBuddy" overwrites the
@@ -3104,6 +3142,25 @@ type WorkBuddyWebUsage =
3104
3142
  * after a switch-off that never landed.
3105
3143
  */
3106
3144
  imageToolEnabled?: boolean;
3145
+ /**
3146
+ * Whether the OPTIONAL CodeBuddy CLI route is mounted (tool `codebuddy_ask`
3147
+ * + command `/codebuddy`).
3148
+ *
3149
+ * GLOBAL, not per region: the route has ONE switch for both regions, so the
3150
+ * same value rides on every region's answer and the card reads it off the
3151
+ * active tab. Absent reads as OFF — this switch authorizes a child process
3152
+ * that edits files and spends CodeBuddy quota, so a Host that cannot answer
3153
+ * must not be read as consent.
3154
+ */
3155
+ cliBridgeEnabled?: boolean;
3156
+ /**
3157
+ * The LIVE load level per model id, for the card's icon.
3158
+ *
3159
+ * A SEPARATE field from `models`, because the card's model list is the
3160
+ * SAVED roster (the one the user edits) and a saved roster has no load
3161
+ * level in it. Absent means "not measured right now" — never "normal".
3162
+ */
3163
+ busyLevels?: Readonly<Record<string, WorkBuddyBusyLevel>>;
3107
3164
  /** WHERE this region's readout sits (issue #62); absent means `composer`. */
3108
3165
  creditPosition?: WorkBuddyCreditPosition;
3109
3166
  message?: string;
@@ -3149,6 +3206,25 @@ type WorkBuddyWebUsage =
3149
3206
  * after a switch-off that never landed.
3150
3207
  */
3151
3208
  imageToolEnabled?: boolean;
3209
+ /**
3210
+ * Whether the OPTIONAL CodeBuddy CLI route is mounted (tool `codebuddy_ask`
3211
+ * + command `/codebuddy`).
3212
+ *
3213
+ * GLOBAL, not per region: the route has ONE switch for both regions, so the
3214
+ * same value rides on every region's answer and the card reads it off the
3215
+ * active tab. Absent reads as OFF — this switch authorizes a child process
3216
+ * that edits files and spends CodeBuddy quota, so a Host that cannot answer
3217
+ * must not be read as consent.
3218
+ */
3219
+ cliBridgeEnabled?: boolean;
3220
+ /**
3221
+ * The LIVE load level per model id, for the card's icon.
3222
+ *
3223
+ * A SEPARATE field from `models`, because the card's model list is the
3224
+ * SAVED roster (the one the user edits) and a saved roster has no load
3225
+ * level in it. Absent means "not measured right now" — never "normal".
3226
+ */
3227
+ busyLevels?: Readonly<Record<string, WorkBuddyBusyLevel>>;
3152
3228
  /** WHERE this region's readout sits (issue #62); absent means `composer`. */
3153
3229
  creditPosition?: WorkBuddyCreditPosition;
3154
3230
  source?: 'desktop' | 'dsh';
@@ -3629,6 +3705,27 @@ interface WorkBuddyStatusRouteOptions {
3629
3705
  * cannot answer must not be read as consent.
3630
3706
  */
3631
3707
  imageToolEnabled?(region: WorkBuddyRegion): boolean;
3708
+ /**
3709
+ * Whether the OPTIONAL CodeBuddy CLI route is mounted (`codebuddy_ask` tool +
3710
+ * `/codebuddy` command).
3711
+ *
3712
+ * GLOBAL rather than per region — one switch, one route — so it takes no
3713
+ * argument. Optional, and absent reads as OFF: this switch authorizes a child
3714
+ * process to edit files and spend CodeBuddy quota, so an older Host that
3715
+ * cannot answer must not be read as consent. The card reads it off the Host's
3716
+ * answer for the same measured reason as `imageToolEnabled`: the browser's
3717
+ * settings mirror is stale for this namespace on the affected 0.1.7
3718
+ * deployments, and a stale `true` here would claim a spending capability is on.
3719
+ */
3720
+ cliBridgeEnabled?(): boolean;
3721
+ /**
3722
+ * The LIVE load level per model id, for the card's icon.
3723
+ *
3724
+ * Optional, and absent means "not measured": the card draws no badge rather
3725
+ * than a made-up one. A SEPARATE read because the card's model list is the
3726
+ * SAVED roster, which carries no load level (`src/busy.ts`).
3727
+ */
3728
+ busyLevels?(region: WorkBuddyRegion): Readonly<Record<string, WorkBuddyBusyLevel>>;
3632
3729
  /**
3633
3730
  * Send one real-volume request to each named model of a region and report what
3634
3731
  * came back.
@@ -4207,6 +4304,15 @@ interface Config {
4207
4304
  imageModelIds?: string[];
4208
4305
  /** @deprecated See {@link Config.lastCatalog}. */
4209
4306
  contextBudgets?: Record<string, WorkBuddyContextBudget>;
4307
+ /**
4308
+ * The optional CLI route: let the locally signed-in CodeBuddy CLI do the work
4309
+ * in a separate agent instead of proxying the gateway.
4310
+ *
4311
+ * It is OFF by default and completely independent of the provider stacks, so a
4312
+ * config that never mentions it behaves exactly as before. This is a
4313
+ * client-fingerprint workaround, not an account one — see `cli-bridge/runner`.
4314
+ */
4315
+ cliBridge?: CliBridgeSettings;
4210
4316
  }
4211
4317
  /**
4212
4318
  * Mark a schema's field as volatile on the DSH lines that support it.
@@ -4224,28 +4330,6 @@ interface Config {
4224
4330
  * moved up — which is exactly how the volatile-path defect below went unseen.
4225
4331
  */
4226
4332
  declare function asVolatile<T>(schema: z<T>): z<T>;
4227
- /**
4228
- * Deep copy of a config value with every `{get(): T}` live reference replaced
4229
- * by the value it resolves to.
4230
- *
4231
- * {@link unwrapVolatile} only peels the ONE level a caller reads, which is all
4232
- * the ordinary read paths need. Handing a config object to a settings service
4233
- * is different: the service validates and `structuredClone`s the WHOLE object,
4234
- * so a reference surviving anywhere inside it fails schema validation with a
4235
- * message that names the field but not the cause —
4236
- * `$.authFile expected string but got [object Object]`.
4237
- *
4238
- * That is exactly what happened on the 0.1.5 line once volatile marking became
4239
- * active: `installSection` received the raw config, whose volatile fields were
4240
- * live references, and every field it validated threw. The namespace never
4241
- * registered, so the card's settings silently disappeared.
4242
- *
4243
- * The implementation now lives in the node-free host<->client bridge, because
4244
- * the browser half needs the SAME unwrap before it spreads a resolved field —
4245
- * spreading a live reference is `{get: <function>}`, which drops every sibling
4246
- * region. It is imported and re-exported from here so the Host entry keeps
4247
- * exposing it as part of its public API.
4248
- */
4249
4333
  declare const Config: z<Config>;
4250
4334
  /**
4251
4335
  * One region's saved model state. A config written before the region split has