dsh-connect-workbuddy 3.6.0 → 4.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/CHANGELOG.md +28 -0
- package/README.en.md +3 -0
- package/README.md +3 -0
- package/docs/assets/dsh-connect-workbuddy-composer-credits.png +0 -0
- package/lib/bin.js +1 -1
- package/lib/client.js +930 -18
- package/lib/{host-heartbeat-Cg2ahl1n.js → host-heartbeat-vvVjdY_q.js} +1 -1
- package/lib/index.d.ts +51 -0
- package/lib/index.js +109 -2
- package/package.json +1 -1
- package/screenshots.json +2 -1
|
@@ -2855,7 +2855,7 @@ function generationOf(version) {
|
|
|
2855
2855
|
//#endregion
|
|
2856
2856
|
//#region src/version.ts
|
|
2857
2857
|
/** The npm package version this build was produced from. */
|
|
2858
|
-
const WORKBUDDY_CONNECT_VERSION = "
|
|
2858
|
+
const WORKBUDDY_CONNECT_VERSION = "4.0.0";
|
|
2859
2859
|
//#endregion
|
|
2860
2860
|
//#region src/host-heartbeat.ts
|
|
2861
2861
|
/**
|
package/lib/index.d.ts
CHANGED
|
@@ -1983,6 +1983,17 @@ type WorkBuddyWebUsage =
|
|
|
1983
1983
|
accounts: readonly WorkBuddyWebAccount[];
|
|
1984
1984
|
/** Whether this region's provider is currently offered to DSH. */
|
|
1985
1985
|
enabled?: boolean;
|
|
1986
|
+
/**
|
|
1987
|
+
* Whether this region's sidebar credit line is shown.
|
|
1988
|
+
*
|
|
1989
|
+
* Carried on the Host's answer rather than read from the browser settings
|
|
1990
|
+
* mirror, for the same measured reason as `contextBudgets`: on the affected
|
|
1991
|
+
* 0.1.7 deployment the mirror never picks up this plugin's writes (a save
|
|
1992
|
+
* through the Host endpoint leaves it stale), so a control reading it kept
|
|
1993
|
+
* showing the old value and looked like it could not be turned off — the
|
|
1994
|
+
* "关闭不了" report.
|
|
1995
|
+
*/
|
|
1996
|
+
showCreditsInMainUi?: boolean;
|
|
1986
1997
|
message?: string;
|
|
1987
1998
|
/** The persisted account id matches no local account. */
|
|
1988
1999
|
selectionLost?: boolean;
|
|
@@ -2011,6 +2022,12 @@ type WorkBuddyWebUsage =
|
|
|
2011
2022
|
region: WorkBuddyWebRegion;
|
|
2012
2023
|
/** Whether this region's provider is currently offered to DSH. */
|
|
2013
2024
|
enabled?: boolean;
|
|
2025
|
+
/**
|
|
2026
|
+
* Whether this region's sidebar credit line is shown. See the signed-out
|
|
2027
|
+
* variant for why this travels on the Host's answer instead of the browser
|
|
2028
|
+
* settings mirror.
|
|
2029
|
+
*/
|
|
2030
|
+
showCreditsInMainUi?: boolean;
|
|
2014
2031
|
source?: 'desktop' | 'dsh';
|
|
2015
2032
|
tokenExpiresAtMs: number;
|
|
2016
2033
|
/** A saved per-region choice is in effect (false = following the app). */
|
|
@@ -2317,6 +2334,19 @@ interface WorkBuddyStatusRouteOptions {
|
|
|
2317
2334
|
* committed settings value rather than a local guess.
|
|
2318
2335
|
*/
|
|
2319
2336
|
regionEnabled(region: WorkBuddyRegion): boolean;
|
|
2337
|
+
/**
|
|
2338
|
+
* Whether the region's sidebar credit line is shown.
|
|
2339
|
+
*
|
|
2340
|
+
* Read from the COMMITTED settings value here rather than in the browser, for
|
|
2341
|
+
* the same reason as `regionEnabled` — and additionally because the browser's
|
|
2342
|
+
* settings mirror is documented as stale for this namespace on the affected
|
|
2343
|
+
* 0.1.7 deployments, which made the checkbox appear unable to turn the line
|
|
2344
|
+
* off ("关闭不了"). The card reads this field off the Host's answer.
|
|
2345
|
+
*
|
|
2346
|
+
* Optional so a Host that predates the setting still satisfies the interface;
|
|
2347
|
+
* absent reads as ON, matching the schema's `default(true)`.
|
|
2348
|
+
*/
|
|
2349
|
+
showCreditsInMainUi?(region: WorkBuddyRegion): boolean;
|
|
2320
2350
|
/**
|
|
2321
2351
|
* Send one real-volume request to each named model of a region and report what
|
|
2322
2352
|
* came back.
|
|
@@ -2359,6 +2389,18 @@ interface WorkBuddyStatusRouteOptions {
|
|
|
2359
2389
|
* probe.
|
|
2360
2390
|
*/
|
|
2361
2391
|
accountUsable?(region: WorkBuddyRegion, account: WorkBuddyRecoveryCandidate): Promise<boolean>;
|
|
2392
|
+
/**
|
|
2393
|
+
* Why each of the region's accounts cannot serve right now, keyed by account
|
|
2394
|
+
* id. Absent key (or an absent dep) means "no reason known" — the composer
|
|
2395
|
+
* panel then marks nothing, which is the honest answer for an account that has
|
|
2396
|
+
* never been measured.
|
|
2397
|
+
*
|
|
2398
|
+
* The rule is the SAME one the pool ranks by (`exclusionOf`), including its
|
|
2399
|
+
* cooldown-expiry handling, so an account the pool calls usable and one the
|
|
2400
|
+
* panel calls rate-limited can never be the same account at the same moment.
|
|
2401
|
+
* Reimplementing the expiry check here would let the two drift.
|
|
2402
|
+
*/
|
|
2403
|
+
accountExclusions?(region: WorkBuddyRegion): Promise<Readonly<Record<string, WorkBuddyWebPoolExclusion>>>;
|
|
2362
2404
|
/**
|
|
2363
2405
|
* The region's account pool, assembled on the Host.
|
|
2364
2406
|
*
|
|
@@ -2508,6 +2550,15 @@ interface WorkBuddyRegionState {
|
|
|
2508
2550
|
* row (see `syncRegionRegistration`).
|
|
2509
2551
|
*/
|
|
2510
2552
|
enabled?: boolean;
|
|
2553
|
+
/**
|
|
2554
|
+
* Whether this region's credit balance shows at the DSH sidebar foot.
|
|
2555
|
+
*
|
|
2556
|
+
* Per-region, independently switched: WB CN and WB AI are separate accounts
|
|
2557
|
+
* on separate gateways, so a user holding only one of them must be able to
|
|
2558
|
+
* show exactly that one. Opt-out — an absent value reads as ON, so a config
|
|
2559
|
+
* written before this switch existed keeps whatever the default was.
|
|
2560
|
+
*/
|
|
2561
|
+
showCreditsInMainUi?: boolean;
|
|
2511
2562
|
/** The last-refreshed directory for this region; what the card displays. */
|
|
2512
2563
|
lastCatalog?: WorkBuddyModelInfo[];
|
|
2513
2564
|
/** The user's selection in this region, as model ids. */
|
package/lib/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as macosNestedAppBundles, A as workbuddyOwnAuthPath, B as parseUpstreamModel, C as defaultDesktopAuthDirs, D as legacyWorkbuddyOwnAuthPath, E as isEncryptedCredentialError, F as classifyUpstreamError, G as deriveAtRestKey, H as regionOf, I as declaredTools, J as findWorkbuddyAppExecutable, K as deriveAtRestKeyId, L as isCredentialRejectedError, M as WORKBUDDY_FALLBACK_SYSTEM_PROMPT, N as WorkBuddyCredentialRejectedError, O as parseWorkBuddyAuth, P as WorkBuddyUpstreamClient, Q as macosBundleExecutable, R as parseCreditMultiplier, S as defaultDesktopAuthCandidates, T as hasEncryptedCredentialFields, U as WORKBUDDY_APP_EXECUTABLE_ENV, V as prepareChatBody, W as clearAtRestKeyCache, X as isEncryptedFieldWrapper, Z as isWorkbuddyBundle, _ as WORKBUDDY_AUTH_FILENAME, a as readHostHeartbeat, b as WorkBuddyEncryptedCredentialError, c as WORKBUDDY_CONNECT_VERSION, d as FALLBACK_WORKBUDDY_MODELS_GLOBAL, et as openEncryptedField, f as WorkBuddyCatalog, g as ENCRYPTED_CREDENTIAL_CODE, h as fallbackModelsFor, i as processStartTimeMs, j as CREDENTIAL_REJECTED_CODE, k as workbuddyAccountId, l as piAiRuntimeInfo, m as deriveCatalog, n as clearHostHeartbeat, nt as workbuddyAppExecutableCandidates, o as workbuddyHostHeartbeatPath, p as applyContextBudgets, q as fetchAtRestKeyPayload, r as isHeartbeatProcessAlive, s as writeHostHeartbeat, t as WORKBUDDY_HOST_HEARTBEAT_FILENAME, tt as readAtRestKey, u as FALLBACK_WORKBUDDY_MODELS, v as WORKBUDDY_AUTH_FILE_ENV, w as defaultDesktopAuthPath, x as authFileName, y as WorkBuddyCredentialStore, z as parseReasoning } from "./host-heartbeat-
|
|
1
|
+
import { $ as macosNestedAppBundles, A as workbuddyOwnAuthPath, B as parseUpstreamModel, C as defaultDesktopAuthDirs, D as legacyWorkbuddyOwnAuthPath, E as isEncryptedCredentialError, F as classifyUpstreamError, G as deriveAtRestKey, H as regionOf, I as declaredTools, J as findWorkbuddyAppExecutable, K as deriveAtRestKeyId, L as isCredentialRejectedError, M as WORKBUDDY_FALLBACK_SYSTEM_PROMPT, N as WorkBuddyCredentialRejectedError, O as parseWorkBuddyAuth, P as WorkBuddyUpstreamClient, Q as macosBundleExecutable, R as parseCreditMultiplier, S as defaultDesktopAuthCandidates, T as hasEncryptedCredentialFields, U as WORKBUDDY_APP_EXECUTABLE_ENV, V as prepareChatBody, W as clearAtRestKeyCache, X as isEncryptedFieldWrapper, Z as isWorkbuddyBundle, _ as WORKBUDDY_AUTH_FILENAME, a as readHostHeartbeat, b as WorkBuddyEncryptedCredentialError, c as WORKBUDDY_CONNECT_VERSION, d as FALLBACK_WORKBUDDY_MODELS_GLOBAL, et as openEncryptedField, f as WorkBuddyCatalog, g as ENCRYPTED_CREDENTIAL_CODE, h as fallbackModelsFor, i as processStartTimeMs, j as CREDENTIAL_REJECTED_CODE, k as workbuddyAccountId, l as piAiRuntimeInfo, m as deriveCatalog, n as clearHostHeartbeat, nt as workbuddyAppExecutableCandidates, o as workbuddyHostHeartbeatPath, p as applyContextBudgets, q as fetchAtRestKeyPayload, r as isHeartbeatProcessAlive, s as writeHostHeartbeat, t as WORKBUDDY_HOST_HEARTBEAT_FILENAME, tt as readAtRestKey, u as FALLBACK_WORKBUDDY_MODELS, v as WORKBUDDY_AUTH_FILE_ENV, w as defaultDesktopAuthPath, x as authFileName, y as WorkBuddyCredentialStore, z as parseReasoning } from "./host-heartbeat-vvVjdY_q.js";
|
|
2
2
|
import z from "@deepseek-ai/schemastery";
|
|
3
3
|
import { readFile } from "node:fs/promises";
|
|
4
4
|
import { randomBytes, randomUUID, timingSafeEqual } from "node:crypto";
|
|
@@ -2832,6 +2832,18 @@ async function writePoolProbes(region, updates) {
|
|
|
2832
2832
|
*/
|
|
2833
2833
|
/** Plugin-owned usage endpoint consumed by its browser half. */
|
|
2834
2834
|
const WORKBUDDY_USAGE_PATH = "/plugins/dsh-connect-workbuddy/usage";
|
|
2835
|
+
/**
|
|
2836
|
+
* Per-account credit balances for one region, read ONLY while the composer
|
|
2837
|
+
* panel is open.
|
|
2838
|
+
*
|
|
2839
|
+
* Separate from {@link WORKBUDDY_USAGE_PATH} because its cost is different in
|
|
2840
|
+
* kind: the usage document is one upstream read for the selected account, while
|
|
2841
|
+
* this is one read PER account in the region. Folding it into the usage route
|
|
2842
|
+
* would make every 5-minute refresh pay for a table nobody is looking at, so it
|
|
2843
|
+
* is fetched on demand instead — the same principle the pool applies to its
|
|
2844
|
+
* per-account figures.
|
|
2845
|
+
*/
|
|
2846
|
+
const WORKBUDDY_ACCOUNT_CREDITS_PATH = "/plugins/dsh-connect-workbuddy/account-credits";
|
|
2835
2847
|
/** Plugin-owned live model refresh endpoint. */
|
|
2836
2848
|
const WORKBUDDY_MODELS_REFRESH_PATH = "/plugins/dsh-connect-workbuddy/models/refresh";
|
|
2837
2849
|
/** Plugin-owned local account rescan endpoint. */
|
|
@@ -3158,6 +3170,39 @@ function volatileFlagOf(field) {
|
|
|
3158
3170
|
return Config.dict?.[field]?.meta?.volatile === true;
|
|
3159
3171
|
}
|
|
3160
3172
|
/**
|
|
3173
|
+
* Per-account credit balances for one region, for the composer panel's table.
|
|
3174
|
+
*
|
|
3175
|
+
* ONE upstream read per account, which is exactly why this is its own route:
|
|
3176
|
+
* the panel calls it only while it is open, so the 5-minute readout never
|
|
3177
|
+
* multiplies its cost by the account count.
|
|
3178
|
+
*
|
|
3179
|
+
* Every account is listed even when its balance cannot be read — a credential
|
|
3180
|
+
* that no longer resolves, or an upstream that refused — because the panel's
|
|
3181
|
+
* job is to show which accounts exist and let the user switch. Such a row
|
|
3182
|
+
* carries NO `credits` field rather than `0`, so the panel renders "—" instead
|
|
3183
|
+
* of telling the user they are out of credits.
|
|
3184
|
+
*
|
|
3185
|
+
* Failures are contained per account: one dead credential must not blank the
|
|
3186
|
+
* table for the accounts that are fine.
|
|
3187
|
+
*/
|
|
3188
|
+
async function workBuddyAccountCredits(deps, region) {
|
|
3189
|
+
const store = deps.store(region);
|
|
3190
|
+
const accounts = await store.accounts();
|
|
3191
|
+
const exclusions = await deps.accountExclusions?.(region).catch(() => void 0) ?? {};
|
|
3192
|
+
return Promise.all(accounts.map(async (account) => {
|
|
3193
|
+
const credential = await store.credentialFor(account.id).catch(() => void 0);
|
|
3194
|
+
const credits = credential === void 0 ? void 0 : await deps.client.fetchCredits(credential).then((answer) => answer.total).catch(() => void 0);
|
|
3195
|
+
const excludedBy = exclusions[account.id];
|
|
3196
|
+
return {
|
|
3197
|
+
id: account.id,
|
|
3198
|
+
accountName: account.accountName,
|
|
3199
|
+
selected: account.selected,
|
|
3200
|
+
...credits === void 0 ? {} : { credits },
|
|
3201
|
+
...excludedBy === void 0 ? {} : { excludedBy }
|
|
3202
|
+
};
|
|
3203
|
+
}));
|
|
3204
|
+
}
|
|
3205
|
+
/**
|
|
3161
3206
|
* Assemble one region's card document. `region` is the tab the card is on;
|
|
3162
3207
|
* the region-scoped store already answers with only that region's accounts,
|
|
3163
3208
|
* so the document's model slots and account list are that region's by
|
|
@@ -3169,13 +3214,15 @@ async function workBuddyWebStatus(deps, region) {
|
|
|
3169
3214
|
const accounts = await store.accounts();
|
|
3170
3215
|
deps.regionUsable?.(region, accounts.length > 0);
|
|
3171
3216
|
const enabled = deps.regionEnabled(region);
|
|
3217
|
+
const showCreditsInMainUi = deps.showCreditsInMainUi?.(region) ?? true;
|
|
3172
3218
|
const authStatus = await store.status();
|
|
3173
3219
|
const selectionExplicit = store.hasExplicitSelection();
|
|
3174
3220
|
if (authStatus.state !== "signed-out" && accounts.length === 0) return {
|
|
3175
3221
|
status: "signed-out",
|
|
3176
3222
|
accounts: [],
|
|
3177
3223
|
selectionExplicit,
|
|
3178
|
-
enabled
|
|
3224
|
+
enabled,
|
|
3225
|
+
showCreditsInMainUi
|
|
3179
3226
|
};
|
|
3180
3227
|
let credential;
|
|
3181
3228
|
try {
|
|
@@ -3188,6 +3235,7 @@ async function workBuddyWebStatus(deps, region) {
|
|
|
3188
3235
|
message: safeMessage(error),
|
|
3189
3236
|
selectionExplicit,
|
|
3190
3237
|
enabled,
|
|
3238
|
+
showCreditsInMainUi,
|
|
3191
3239
|
...await store.selectionLost() ? { selectionLost: true } : {},
|
|
3192
3240
|
...webAccounts.length === 0 ? await searchedPaths(store) : {}
|
|
3193
3241
|
};
|
|
@@ -3202,6 +3250,7 @@ async function workBuddyWebStatus(deps, region) {
|
|
|
3202
3250
|
tokenExpiresAtMs: credential.expiresAtMs,
|
|
3203
3251
|
selectionExplicit,
|
|
3204
3252
|
enabled,
|
|
3253
|
+
showCreditsInMainUi,
|
|
3205
3254
|
accounts: accounts.map(toWebAccount),
|
|
3206
3255
|
models: deps.displayModels(region).map((model) => toWebModel(model, deps.contextBudgets(region))),
|
|
3207
3256
|
enabledModelIds: [...deps.enabledModelIds(region)],
|
|
@@ -3354,6 +3403,21 @@ function registerWorkBuddyStatusRoute(ctx, deps) {
|
|
|
3354
3403
|
}
|
|
3355
3404
|
}
|
|
3356
3405
|
});
|
|
3406
|
+
const disposeAccountCredits = ctx.webServer.register({
|
|
3407
|
+
kind: "exact",
|
|
3408
|
+
path: WORKBUDDY_ACCOUNT_CREDITS_PATH,
|
|
3409
|
+
handler: async (req, res) => {
|
|
3410
|
+
if (req.method !== "GET") return json(res, 405, { error: "method not allowed" });
|
|
3411
|
+
if (!loopbackOrigin(req)) return json(res, 403, { error: "origin-not-trusted" });
|
|
3412
|
+
const region = requestRegion(req, res);
|
|
3413
|
+
if (region === void 0) return;
|
|
3414
|
+
try {
|
|
3415
|
+
json(res, 200, { accounts: await workBuddyAccountCredits(deps, region) });
|
|
3416
|
+
} catch (error) {
|
|
3417
|
+
json(res, 500, { error: safeMessage(error) });
|
|
3418
|
+
}
|
|
3419
|
+
}
|
|
3420
|
+
});
|
|
3357
3421
|
const disposeAccounts = ctx.webServer.register({
|
|
3358
3422
|
kind: "exact",
|
|
3359
3423
|
path: WORKBUDDY_ACCOUNTS_REFRESH_PATH,
|
|
@@ -3586,6 +3650,7 @@ function registerWorkBuddyStatusRoute(ctx, deps) {
|
|
|
3586
3650
|
disposeCheckin();
|
|
3587
3651
|
disposeAccounts();
|
|
3588
3652
|
disposeUsage();
|
|
3653
|
+
disposeAccountCredits();
|
|
3589
3654
|
disposeProbe();
|
|
3590
3655
|
disposePool();
|
|
3591
3656
|
disposeDiagWrite();
|
|
@@ -3785,6 +3850,22 @@ const poolConfig = z.object({
|
|
|
3785
3850
|
});
|
|
3786
3851
|
const regionStateConfig = z.object({
|
|
3787
3852
|
enabled: z.boolean().default(true).description("Whether this region's provider is offered to DSH (opt-out; false withdraws it entirely)"),
|
|
3853
|
+
/**
|
|
3854
|
+
* Whether this region's credit line shows at the DSH sidebar foot.
|
|
3855
|
+
*
|
|
3856
|
+
* Per-REGION rather than one global switch, because the two sides are
|
|
3857
|
+
* independent providers the user may hold only one account on: a CN-only user
|
|
3858
|
+
* has nothing to read from the international line and vice versa, and a
|
|
3859
|
+
* single shared switch would force them to either show a permanently empty
|
|
3860
|
+
* row or lose the one that works.
|
|
3861
|
+
*
|
|
3862
|
+
* ON by default (opt-out). The plugin card is not reachable in every host —
|
|
3863
|
+
* a market plugin can own the Plugins tab and never render
|
|
3864
|
+
* `plugins.bundle.config` — so a feature that is off until discovered would be
|
|
3865
|
+
* off forever for those users. The line carries its own `×` in the sidebar,
|
|
3866
|
+
* which is reachable exactly where the feature renders.
|
|
3867
|
+
*/
|
|
3868
|
+
showCreditsInMainUi: z.boolean().default(true).description("Show this region's remaining credits at the DSH sidebar foot (opt-out; the line carries its own hide button)"),
|
|
3788
3869
|
lastCatalog: z.array(modelConfig).default([]),
|
|
3789
3870
|
enabledModelIds: z.array(z.string()).default([]),
|
|
3790
3871
|
imageModelIds: z.array(z.string()).default([]),
|
|
@@ -4140,6 +4221,25 @@ function apply(ctx, config) {
|
|
|
4140
4221
|
store: (region) => stacks[region].store,
|
|
4141
4222
|
client,
|
|
4142
4223
|
accountUsable: accountUsabilityProbe,
|
|
4224
|
+
/**
|
|
4225
|
+
* Why each of the region's accounts cannot serve right now, for the composer
|
|
4226
|
+
* panel's table.
|
|
4227
|
+
*
|
|
4228
|
+
* Runs the SAME `exclusionOf` the pool ranks by, against every account the
|
|
4229
|
+
* region knows — not only pool members. Deriving it any other way (a second
|
|
4230
|
+
* expiry comparison, or `probe.outcome` read raw) would let the panel call an
|
|
4231
|
+
* account rate-limited while the pool has already moved past its cooldown.
|
|
4232
|
+
*/
|
|
4233
|
+
accountExclusions: async (region) => {
|
|
4234
|
+
const probes = await readPoolProbes(region);
|
|
4235
|
+
const nowMs = Date.now();
|
|
4236
|
+
const out = {};
|
|
4237
|
+
for (const [accountId, probe] of Object.entries(probes)) {
|
|
4238
|
+
const excludedBy = exclusionOf(probe, nowMs);
|
|
4239
|
+
if (excludedBy !== void 0) out[accountId] = excludedBy;
|
|
4240
|
+
}
|
|
4241
|
+
return out;
|
|
4242
|
+
},
|
|
4143
4243
|
displayModels: (region) => displayModels(current(), region),
|
|
4144
4244
|
enabledModelIds: (region) => regionStateOf(current(), region).enabledModelIds ?? [],
|
|
4145
4245
|
imageModelIds: (region) => regionStateOf(current(), region).imageModelIds ?? [],
|
|
@@ -4148,6 +4248,13 @@ function apply(ctx, config) {
|
|
|
4148
4248
|
discoverModels,
|
|
4149
4249
|
regionEnabled: (region) => regionEnabled(current(), region),
|
|
4150
4250
|
/**
|
|
4251
|
+
* The region's committed sidebar-credit flag, read from the same config the
|
|
4252
|
+
* card writes. Exposed on the Host's answer because the browser settings
|
|
4253
|
+
* mirror goes stale for this namespace on the affected 0.1.7 deployments,
|
|
4254
|
+
* which made the switch look unable to turn the line off ("关闭不了").
|
|
4255
|
+
*/
|
|
4256
|
+
showCreditsInMainUi: (region) => regionStateOf(current(), region).showCreditsInMainUi !== false,
|
|
4257
|
+
/**
|
|
4151
4258
|
* One minimal request per named model, through the region's own credential.
|
|
4152
4259
|
*
|
|
4153
4260
|
* Resolved here rather than in the route so the browser half never touches a
|
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": "
|
|
5
|
+
"version": "4.0.0",
|
|
6
6
|
"author": "dingminhua",
|
|
7
7
|
"copyright": "Copyright (c) 2026 LaoDing",
|
|
8
8
|
"license": "MIT",
|
package/screenshots.json
CHANGED