dsh-multi-router 0.5.8 → 0.5.9
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 +10 -0
- package/README.md +24 -8
- package/cordis.patch.yml +2 -2
- package/lib/accounts.js +3 -1
- package/lib/{chunk-ILRW3ELD.js → chunk-I4EW5TI7.js} +250 -66
- package/lib/chunk-I4EW5TI7.js.map +7 -0
- package/lib/{chunk-OFFVP6YN.js → chunk-S6ZQ45SS.js} +20 -3
- package/lib/chunk-S6ZQ45SS.js.map +7 -0
- package/lib/cli.js +1 -1
- package/lib/client.js +404 -309
- package/lib/client.js.map +2 -2
- package/lib/{host-v0.5.8.js → host-v0.5.9.js} +6 -112
- package/lib/host.js +6 -112
- package/lib/index.js +6 -112
- package/lib/index.js.map +4 -4
- package/lib/manager.js +2 -2
- package/package.json +1 -1
- package/lib/chunk-ILRW3ELD.js.map +0 -7
- package/lib/chunk-OFFVP6YN.js.map +0 -7
|
@@ -11,8 +11,9 @@ import {
|
|
|
11
11
|
discoverLocalAccounts,
|
|
12
12
|
importAccount,
|
|
13
13
|
localAccountKey,
|
|
14
|
+
normalizeLocalAccountKey,
|
|
14
15
|
readPortableCredential
|
|
15
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-S6ZQ45SS.js";
|
|
16
17
|
import {
|
|
17
18
|
hostIsLoopback
|
|
18
19
|
} from "./chunk-DNQPZMPF.js";
|
|
@@ -39,12 +40,12 @@ import {
|
|
|
39
40
|
import { createHash, randomBytes as randomBytes3, timingSafeEqual } from "node:crypto";
|
|
40
41
|
|
|
41
42
|
// package.json
|
|
42
|
-
var version = "0.5.
|
|
43
|
+
var version = "0.5.9";
|
|
43
44
|
|
|
44
45
|
// src/manager.mjs
|
|
45
|
-
import { readFile as
|
|
46
|
-
import { watch } from "node:fs";
|
|
47
|
-
import { dirname as dirname3, join as
|
|
46
|
+
import { readFile as readFile4, mkdir as mkdir2, mkdtemp as mkdtemp2, rm as rm3 } from "node:fs/promises";
|
|
47
|
+
import { watch as watch2 } from "node:fs";
|
|
48
|
+
import { dirname as dirname3, join as join5, relative as relative2, resolve } from "node:path";
|
|
48
49
|
import { withFileLock as withFileLock3 } from "@deepseek-ai/dsh-atomic-write";
|
|
49
50
|
|
|
50
51
|
// upstream/qoder/src/status-paths.ts
|
|
@@ -239,14 +240,140 @@ async function prepareMigration(manager, raw, portable, mode) {
|
|
|
239
240
|
}
|
|
240
241
|
|
|
241
242
|
// src/plugin-updates.mjs
|
|
242
|
-
import { readFile, stat, rm as rm2 } from "node:fs/promises";
|
|
243
|
-
import { join as
|
|
243
|
+
import { readFile as readFile2, stat, rm as rm2 } from "node:fs/promises";
|
|
244
|
+
import { join as join4 } from "node:path";
|
|
244
245
|
import { randomUUID } from "node:crypto";
|
|
245
246
|
import { createRequire } from "node:module";
|
|
246
247
|
import { pathToFileURL } from "node:url";
|
|
247
248
|
import { parse as parseYaml } from "yaml";
|
|
248
249
|
import { withFileLock, writeFileAtomic as writeFileAtomic2 } from "@deepseek-ai/dsh-atomic-write";
|
|
249
250
|
|
|
251
|
+
// src/plugin-reload.mjs
|
|
252
|
+
import { readFile } from "node:fs/promises";
|
|
253
|
+
import { watch } from "node:fs";
|
|
254
|
+
import { join as join3 } from "node:path";
|
|
255
|
+
import { parse } from "yaml";
|
|
256
|
+
function outsideActivation(hmr, operation) {
|
|
257
|
+
const scope = hmr?.executing;
|
|
258
|
+
return typeof scope?.exit === "function" ? scope.exit(operation) : operation();
|
|
259
|
+
}
|
|
260
|
+
var PluginReload = class {
|
|
261
|
+
constructor({ service, profile, canReload, hmr = () => void 0, busy = () => false, now = Date.now, runningVersion }) {
|
|
262
|
+
Object.assign(this, { service, profile, canReload, hmr, busy, now, runningVersion });
|
|
263
|
+
this.phase = "current";
|
|
264
|
+
this.installedVersion = runningVersion;
|
|
265
|
+
this.retryAt = 0;
|
|
266
|
+
}
|
|
267
|
+
state() {
|
|
268
|
+
return { runningVersion: this.runningVersion, installedVersion: this.installedVersion, phase: this.phase, canReload: !!this.canReload(), message: this.message };
|
|
269
|
+
}
|
|
270
|
+
start() {
|
|
271
|
+
const dir = this.profile()?.dir;
|
|
272
|
+
this.watchers = [];
|
|
273
|
+
if (dir) for (const target of [dir, join3(dir, "node_modules")]) try {
|
|
274
|
+
const watcher = watch(target, () => this.schedule());
|
|
275
|
+
watcher.unref();
|
|
276
|
+
this.watchers.push(watcher);
|
|
277
|
+
} catch {
|
|
278
|
+
}
|
|
279
|
+
this.schedule();
|
|
280
|
+
}
|
|
281
|
+
schedule(delay = 500) {
|
|
282
|
+
if (this.closed) return;
|
|
283
|
+
clearTimeout(this.timer);
|
|
284
|
+
this.timer = setTimeout(() => {
|
|
285
|
+
void this.check().catch(() => {
|
|
286
|
+
});
|
|
287
|
+
}, delay);
|
|
288
|
+
this.timer.unref();
|
|
289
|
+
}
|
|
290
|
+
stop() {
|
|
291
|
+
this.closed = true;
|
|
292
|
+
clearTimeout(this.timer);
|
|
293
|
+
for (const watcher of this.watchers ?? []) watcher.close();
|
|
294
|
+
}
|
|
295
|
+
check() {
|
|
296
|
+
if (this.closed) return Promise.resolve();
|
|
297
|
+
if (this.flight) return this.flight;
|
|
298
|
+
this.flight = this.inspect().finally(() => {
|
|
299
|
+
this.flight = void 0;
|
|
300
|
+
});
|
|
301
|
+
return this.flight;
|
|
302
|
+
}
|
|
303
|
+
async inspect() {
|
|
304
|
+
const dir = this.profile()?.dir;
|
|
305
|
+
if (!dir) return;
|
|
306
|
+
let manifest, installed;
|
|
307
|
+
try {
|
|
308
|
+
manifest = JSON.parse(await readFile(join3(dir, "package.json"), "utf8"));
|
|
309
|
+
installed = JSON.parse(await readFile(join3(dir, "node_modules/dsh-multi-router/package.json"), "utf8"));
|
|
310
|
+
} catch {
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
if (this.closed || !manifest.dsh?.profile?.bundles?.includes("dsh-multi-router")) return;
|
|
314
|
+
if (installed.name !== "dsh-multi-router" || !/^\d+\.\d+\.\d+(?:-[\w.-]+)?$/.test(installed.version)) return;
|
|
315
|
+
this.installedVersion = installed.version;
|
|
316
|
+
if (installed.version === this.runningVersion) {
|
|
317
|
+
this.phase = "current";
|
|
318
|
+
this.message = void 0;
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
321
|
+
const declared = manifest.dependencies?.["dsh-multi-router"];
|
|
322
|
+
const exact = typeof declared === "string" && /^(?:npm:dsh-multi-router@)?(\d+\.\d+\.\d+(?:-[\w.-]+)?)$/.exec(declared)?.[1];
|
|
323
|
+
let installing = false;
|
|
324
|
+
const pid = Number(await readFile(join3(dir, "package.json.lock"), "utf8").catch(() => ""));
|
|
325
|
+
if (Number.isInteger(pid) && pid > 0) try {
|
|
326
|
+
process.kill(pid, 0);
|
|
327
|
+
installing = true;
|
|
328
|
+
} catch (e) {
|
|
329
|
+
installing = e.code !== "ESRCH";
|
|
330
|
+
}
|
|
331
|
+
if (installing || exact && exact !== installed.version) {
|
|
332
|
+
this.phase = "waiting";
|
|
333
|
+
this.message = "\u5B89\u88C5\u4E8B\u52A1\u5C1A\u672A\u5B8C\u6210\uFF0C\u6216\u5B89\u88C5\u5931\u8D25\u5DF2\u56DE\u6EDA\uFF1B\u7B49\u5F85\u914D\u7F6E\u4E0E\u6587\u4EF6\u7248\u672C\u4E00\u81F4\u540E\u518D\u52A0\u8F7D\u3002";
|
|
334
|
+
if (installing) this.schedule(1e3);
|
|
335
|
+
return;
|
|
336
|
+
}
|
|
337
|
+
if (!this.canReload() || !this.service()?.setBundleEnabled) {
|
|
338
|
+
this.phase = "restart-required";
|
|
339
|
+
this.message = "\u5F53\u524D DSH \u672A\u63D0\u4F9B\u8FD0\u884C\u4E2D\u91CD\u8F7D\uFF0C\u8BF7\u5347\u7EA7 DSH \u6216\u91CD\u542F\u5E94\u7528\u3002";
|
|
340
|
+
return;
|
|
341
|
+
}
|
|
342
|
+
if (this.busy()) {
|
|
343
|
+
this.phase = "waiting";
|
|
344
|
+
this.message = "\u65B0\u7248\u672C\u5DF2\u5B89\u88C5\uFF0C\u7B49\u5F85\u5F53\u524D\u8BF7\u6C42\u548C\u8D26\u53F7\u64CD\u4F5C\u7ED3\u675F\u540E\u81EA\u52A8\u751F\u6548\u3002";
|
|
345
|
+
this.schedule(1e3);
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
const root = join3(dir, "node_modules/dsh-multi-router");
|
|
349
|
+
try {
|
|
350
|
+
const patch = parse(await readFile(join3(root, "cordis.patch.yml"), "utf8"));
|
|
351
|
+
const row = Array.isArray(patch) && patch.flatMap((p) => p?.insert ?? []).find((e) => e?.id === `llm-multi-router-v2-${installed.version}`);
|
|
352
|
+
if (row?.name !== `./lib/host-v${installed.version}.js` || row.disabled) throw Error("legacy entry");
|
|
353
|
+
await readFile(join3(root, `lib/host-v${installed.version}.js`));
|
|
354
|
+
} catch {
|
|
355
|
+
this.phase = "restart-required";
|
|
356
|
+
this.message = "\u5B89\u88C5\u7248\u672C\u7F3A\u5C11\u7248\u672C\u5316\u5165\u53E3\uFF0C\u91CD\u65B0\u5B89\u88C5\u6700\u65B0\u7248\u540E\u518D\u8BD5\u3002";
|
|
357
|
+
return;
|
|
358
|
+
}
|
|
359
|
+
if (this.now() < this.retryAt) return;
|
|
360
|
+
this.phase = "reloading";
|
|
361
|
+
this.message = "\u6B63\u5728\u91CD\u65B0\u52A0\u8F7D\u63D2\u4EF6\u4E0E\u914D\u7F6E\u9762\u677F\u2026";
|
|
362
|
+
this.retryAt = this.now() + 6e4;
|
|
363
|
+
try {
|
|
364
|
+
const result = await outsideActivation(this.hmr(), () => this.service().setBundleEnabled("dsh-multi-router", true));
|
|
365
|
+
if (this.closed) return;
|
|
366
|
+
this.phase = "restart-required";
|
|
367
|
+
this.message = result.application === "applied" ? "DSH \u5C1A\u672A\u5207\u6362\u5230\u65B0\u7248\u672C\uFF0C\u8BF7\u91CD\u65B0\u52A0\u8F7D\u63D2\u4EF6\u6216\u67E5\u770B\u7EC4\u4EF6\u9519\u8BEF\u3002" : "DSH \u672A\u80FD\u91CD\u8F7D\u63D2\u4EF6\uFF0C\u8BF7\u5347\u7EA7 DSH \u6216\u91CD\u542F\u5E94\u7528\u3002";
|
|
368
|
+
} catch {
|
|
369
|
+
if (!this.closed) {
|
|
370
|
+
this.phase = "failed";
|
|
371
|
+
this.message = "\u63D2\u4EF6\u91CD\u8F7D\u672A\u5B8C\u6210\uFF0C\u53EF\u7A0D\u540E\u91CD\u8BD5\uFF1B\u5DF2\u4FDD\u5B58\u7684\u914D\u7F6E\u4FDD\u6301\u4E0D\u53D8\u3002";
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
};
|
|
376
|
+
|
|
250
377
|
// upstream/workbuddy/src/update.ts
|
|
251
378
|
var WORKBUDDY_REPOSITORY_URL = "https://github.com/corrinehu/dsh-workbuddy-connect";
|
|
252
379
|
var WORKBUDDY_UPDATE_PACKAGE_NAME = "dsh-workbuddy-connect";
|
|
@@ -322,7 +449,7 @@ function githubCommit(value) {
|
|
|
322
449
|
}
|
|
323
450
|
async function jsonFile(file) {
|
|
324
451
|
try {
|
|
325
|
-
return JSON.parse(await
|
|
452
|
+
return JSON.parse(await readFile2(file, "utf8"));
|
|
326
453
|
} catch {
|
|
327
454
|
return void 0;
|
|
328
455
|
}
|
|
@@ -330,11 +457,11 @@ async function jsonFile(file) {
|
|
|
330
457
|
async function locks(dir) {
|
|
331
458
|
let pnpm;
|
|
332
459
|
try {
|
|
333
|
-
pnpm = parseYaml(await
|
|
460
|
+
pnpm = parseYaml(await readFile2(join4(dir, "pnpm-lock.yaml"), "utf8"), { maxAliasCount: 20 });
|
|
334
461
|
} catch {
|
|
335
462
|
}
|
|
336
|
-
const npm = await jsonFile(
|
|
337
|
-
const times = await Promise.all(["pnpm-lock.yaml", "package-lock.json"].map((name) => stat(
|
|
463
|
+
const npm = await jsonFile(join4(dir, "package-lock.json"));
|
|
464
|
+
const times = await Promise.all(["pnpm-lock.yaml", "package-lock.json"].map((name) => stat(join4(dir, name)).then((s) => s.mtimeMs).catch(() => 0)));
|
|
338
465
|
return { pnpm, npm, preferNpm: times[1] > times[0] };
|
|
339
466
|
}
|
|
340
467
|
async function publicJson(url, fetchImpl, signal) {
|
|
@@ -355,11 +482,46 @@ async function publicJson(url, fetchImpl, signal) {
|
|
|
355
482
|
return /^[a-f0-9]{40}$/i.test(text) ? { sha: text } : JSON.parse(text);
|
|
356
483
|
}
|
|
357
484
|
var short = (sha) => sha?.slice(0, 8);
|
|
358
|
-
|
|
485
|
+
var installFailed = (r) => !!(r.error || ["failed", "cancelled"].includes(r.application) || r.packageResult && r.packageResult.exitCode !== 0);
|
|
486
|
+
function installFailure(result) {
|
|
487
|
+
const text = [result.error?.diagnostic, result.packageResult?.output, result.packageResult?.kind].filter((v) => typeof v === "string").join("\n");
|
|
488
|
+
let reason = "unknown", message = "\u5B89\u88C5\u672A\u5B8C\u6210\uFF1B\u8BF7\u5728 DSH \u539F\u751F\u63D2\u4EF6\u9875\u67E5\u770B\u5B89\u88C5\u65E5\u5FD7\uFF0C\u6216\u590D\u5236\u4E0B\u65B9\u8BCA\u65AD\u4FE1\u606F\u3002";
|
|
489
|
+
if (result.application === "cancelled") {
|
|
490
|
+
reason = "cancelled";
|
|
491
|
+
message = "\u5B89\u88C5\u5DF2\u53D6\u6D88\uFF0C\u53EF\u91CD\u65B0\u68C0\u67E5\u540E\u91CD\u8BD5\u3002";
|
|
492
|
+
} else if (/ERR_PNPM_(?:MINIMUM_RELEASE_AGE_VIOLATION|NO_MATURE_MATCHING_VERSION)|minimumReleaseAge/i.test(text)) {
|
|
493
|
+
reason = "release-age";
|
|
494
|
+
message = "\u65B0\u7248\u672C\u5C1A\u5728\u5B89\u88C5\u5668\u7684\u65B0\u5305\u7B49\u5F85\u671F\u5185\u3002\u8F93\u5165\u5305\u540D\u53EF\u80FD\u9009\u4E2D\u65E7\u7248\uFF0C\u6307\u5B9A\u65B0\u7248\u672C\u53EF\u80FD\u88AB\u62D2\u7EDD\uFF1B\u8BF7\u7B49\u5F85\u7B56\u7565\u89C4\u5B9A\u7684\u65F6\u95F4\u540E\u91CD\u8BD5\uFF0C\u6216\u7531\u7528\u6237\u660E\u786E\u4E3A\u8BE5\u7248\u672C\u8BBE\u7F6E\u4F8B\u5916\u3002\u6362\u955C\u50CF\u6216\u91CD\u542F\u4E0D\u4F1A\u89E3\u9664\u6B64\u9650\u5236\u3002";
|
|
495
|
+
} else if (result.pendingBuilds?.length) {
|
|
496
|
+
reason = "build";
|
|
497
|
+
message = "\u4F9D\u8D56\u6784\u5EFA\u811A\u672C\u9700\u8981\u6388\u6743\uFF0C\u8BF7\u5230 DSH \u63D2\u4EF6\u5B89\u88C5\u9875\u5141\u8BB8\u8FD9\u4E9B\u811A\u672C\u540E\u91CD\u8BD5\u3002";
|
|
498
|
+
} else if (result.error?.code === "incompatible-version") {
|
|
499
|
+
reason = "compatibility";
|
|
500
|
+
message = "\u63D2\u4EF6\u4E0E\u5F53\u524D DSH \u4E0D\u517C\u5BB9\uFF0C\u8BF7\u5148\u5347\u7EA7 DSH \u6216\u9009\u62E9\u517C\u5BB9\u7248\u672C\u3002";
|
|
501
|
+
} else if (/\b(?:EPERM|EBUSY|EACCES)\b|resource busy|file.*(?:locked|in use)/i.test(text)) {
|
|
502
|
+
reason = "files";
|
|
503
|
+
message = "\u63D2\u4EF6\u6587\u4EF6\u88AB\u5360\u7528\u6216\u76EE\u5F55\u6743\u9650\u4E0D\u8DB3\uFF0C\u5B89\u88C5\u672A\u5B8C\u6210\u3002\u8BF7\u5148\u5728 DSH \u505C\u7528\u8BE5\u63D2\u4EF6\u540E\u91CD\u8BD5\uFF0C\u5E76\u68C0\u67E5\u5B89\u88C5\u76EE\u5F55\u6743\u9650\uFF1B\u4ECD\u88AB\u5360\u7528\u65F6\u9700\u9000\u51FA\u6258\u76D8\u5E94\u7528\u3002";
|
|
504
|
+
} else if (/HMR transactions cannot be nested|activation|did not activate|entry.*activate/i.test(text)) {
|
|
505
|
+
reason = "activation";
|
|
506
|
+
message = "\u63D2\u4EF6\u52A0\u8F7D\u5931\u8D25\u3002\u8BF7\u68C0\u67E5 DSH \u63D2\u4EF6\u9875\u7684\u7EC4\u4EF6\u9519\u8BEF\uFF0C\u518D\u5173\u95ED\u5E76\u91CD\u65B0\u542F\u7528\uFF1B\u5B89\u88C5\u4E0E\u52A0\u8F7D\u662F\u4E24\u4E2A\u72EC\u7ACB\u6B65\u9AA4\u3002";
|
|
507
|
+
} else if (result.packageResult?.timedOut || /\b(?:ETIMEDOUT|ECONNRESET|ENOTFOUND|EAI_AGAIN|ECONNREFUSED)\b|network|fetch|download/i.test(text)) {
|
|
508
|
+
reason = "network";
|
|
509
|
+
message = "\u63D2\u4EF6\u4E0B\u8F7D\u6216\u7F51\u7EDC\u8BF7\u6C42\u5931\u8D25\uFF0C\u5B89\u88C5\u672A\u5B8C\u6210\u3002npm \u6765\u6E90\u53EF\u5207\u6362\u5230\u300Cnpm \u5B98\u65B9\u300D\u540E\u91CD\u8BD5\uFF1BGitHub \u6765\u6E90\u8BF7\u68C0\u67E5 GitHub \u7F51\u7EDC\u8FDE\u63A5\u3002";
|
|
510
|
+
}
|
|
511
|
+
const code = /\b(?:ERR_PNPM_MINIMUM_RELEASE_AGE_VIOLATION|ERR_PNPM_NO_MATURE_MATCHING_VERSION|EPERM|EBUSY|EACCES|ETIMEDOUT|ECONNRESET|ENOTFOUND|EAI_AGAIN|ECONNREFUSED)\b/.exec(text)?.[0] ?? (["operation-error", "incompatible-version"].includes(result.error?.code) ? result.error.code : "unknown");
|
|
512
|
+
return { status: "failed", application: result.application, message, diagnostic: {
|
|
513
|
+
reason,
|
|
514
|
+
code,
|
|
515
|
+
platform: process.platform,
|
|
516
|
+
stage: reason === "activation" ? "activation" : "install",
|
|
517
|
+
...Number.isInteger(result.packageResult?.exitCode) ? { exitCode: result.packageResult.exitCode } : {}
|
|
518
|
+
} };
|
|
519
|
+
}
|
|
520
|
+
async function registryVersion(service, profile, spec, signal, requestedRegistry) {
|
|
359
521
|
const require2 = createRequire(profile.installAnchor);
|
|
360
522
|
const { viewProfilePackage } = await import(pathToFileURL(require2.resolve("@deepseek-ai/dsh-plugin-manager/operations")).href);
|
|
361
523
|
const { registryPlan } = await import(pathToFileURL(require2.resolve("@deepseek-ai/dsh-plugin-manager/registry")).href);
|
|
362
|
-
for (const registry of registryPlan(
|
|
524
|
+
for (const registry of registryPlan(requestedRegistry, await service.registries())) {
|
|
363
525
|
const answer = await viewProfilePackage(profile.dir, spec, { ...profile.packageManager, registry, timeoutMs: 12e3, signal });
|
|
364
526
|
if (signal.aborted) throw Error("\u68C0\u67E5\u5DF2\u53D6\u6D88");
|
|
365
527
|
if (answer.exitCode !== 0) continue;
|
|
@@ -374,11 +536,11 @@ async function refreshGitPlugin(service, profile, row, options2, signal) {
|
|
|
374
536
|
const { registryPlan, attributeFailure } = await import(pathToFileURL(require2.resolve("@deepseek-ai/dsh-plugin-manager/registry")).href);
|
|
375
537
|
const { classifyInstallFailure } = await import(pathToFileURL(require2.resolve("@deepseek-ai/dsh-plugin-manager")).href);
|
|
376
538
|
const plan = registryPlan(options2.registry, await service.registries());
|
|
377
|
-
return withFileLock(
|
|
539
|
+
return withFileLock(join4(profile.dir, "package.json"), async () => {
|
|
378
540
|
const files = await Promise.all(["package.json", "pnpm-lock.yaml"].map(async (name) => {
|
|
379
|
-
const path =
|
|
541
|
+
const path = join4(profile.dir, name);
|
|
380
542
|
try {
|
|
381
|
-
return { path, content: await
|
|
543
|
+
return { path, content: await readFile2(path, "utf8") };
|
|
382
544
|
} catch (e) {
|
|
383
545
|
if (e.code !== "ENOENT") throw e;
|
|
384
546
|
return { path };
|
|
@@ -417,7 +579,7 @@ async function refreshGitPlugin(service, profile, row, options2, signal) {
|
|
|
417
579
|
}, { waitMs: 12e4 });
|
|
418
580
|
}
|
|
419
581
|
var PluginUpdates = class {
|
|
420
|
-
constructor({ service = () => void 0, profile = () => void 0, fetchImpl = (...args) => fetch(...args), lookup = registryVersion, refreshGit = refreshGitPlugin, onInstalled, stateFile, now = Date.now } = {}) {
|
|
582
|
+
constructor({ service = () => void 0, profile = () => void 0, hmr = () => void 0, fetchImpl = (...args) => fetch(...args), lookup = registryVersion, refreshGit = refreshGitPlugin, onInstalled, stateFile, now = Date.now } = {}) {
|
|
421
583
|
this.stateFile = stateFile;
|
|
422
584
|
this.now = now;
|
|
423
585
|
this.dismissed = {};
|
|
@@ -425,6 +587,7 @@ var PluginUpdates = class {
|
|
|
425
587
|
this.saveQueue = Promise.resolve();
|
|
426
588
|
this.service = service;
|
|
427
589
|
this.profile = profile;
|
|
590
|
+
this.hmr = hmr;
|
|
428
591
|
this.fetchImpl = fetchImpl;
|
|
429
592
|
this.rows = [];
|
|
430
593
|
this.abort = new AbortController();
|
|
@@ -485,7 +648,7 @@ var PluginUpdates = class {
|
|
|
485
648
|
this.rows = [];
|
|
486
649
|
return;
|
|
487
650
|
}
|
|
488
|
-
const [manifest, bundles, lock] = await Promise.all([jsonFile(
|
|
651
|
+
const [manifest, bundles, lock] = await Promise.all([jsonFile(join4(profile.dir, "package.json")), service.listBundles(), locks(profile.dir)]);
|
|
489
652
|
if (!manifest) throw Error("\u5F53\u524D DSH \u914D\u7F6E\u7684\u63D2\u4EF6\u6E05\u5355\u65E0\u6CD5\u8BFB\u53D6");
|
|
490
653
|
this.rows = bundles.filter((b) => (b.installed || b.version) && manifest.dependencies?.[b.name] && b.removable !== false).map((b) => {
|
|
491
654
|
const spec = manifest.dependencies?.[b.name];
|
|
@@ -578,7 +741,7 @@ var PluginUpdates = class {
|
|
|
578
741
|
});
|
|
579
742
|
}
|
|
580
743
|
async installRow(row, registry) {
|
|
581
|
-
const original = await jsonFile(
|
|
744
|
+
const original = await jsonFile(join4(this.profile().dir, "package.json"));
|
|
582
745
|
if (original?.dependencies?.[row.name] !== row.spec) throw Error("\u5B89\u88C5\u6765\u6E90\u5DF2\u6539\u53D8\uFF0C\u8BF7\u91CD\u65B0\u68C0\u67E5");
|
|
583
746
|
const current = (await this.service().listBundles()).find((b) => b.name === row.name);
|
|
584
747
|
if (!current || current.enabled !== row.checkedEnabled || current.version !== row.version) throw Error("\u63D2\u4EF6\u7248\u672C\u6216\u542F\u7528\u72B6\u6001\u5DF2\u6539\u53D8\uFF0C\u8BF7\u91CD\u65B0\u68C0\u67E5");
|
|
@@ -591,17 +754,8 @@ var PluginUpdates = class {
|
|
|
591
754
|
} finally {
|
|
592
755
|
this.gitAbort = void 0;
|
|
593
756
|
}
|
|
594
|
-
} else result = await this.service().installBundle(row.target, options2);
|
|
595
|
-
if (result
|
|
596
|
-
return {
|
|
597
|
-
name: row.name,
|
|
598
|
-
status: "failed",
|
|
599
|
-
application: result.application,
|
|
600
|
-
message: result.pendingBuilds?.length ? "\u4F9D\u8D56\u6784\u5EFA\u811A\u672C\u9700\u8981\u6388\u6743\uFF0C\u8BF7\u5230 DSH \u63D2\u4EF6\u5B89\u88C5\u9875\u5141\u8BB8\u8FD9\u4E9B\u811A\u672C\u540E\u91CD\u8BD5" : result.error?.code === "incompatible-version" ? "\u63D2\u4EF6\u4E0E\u5F53\u524D DSH \u4E0D\u517C\u5BB9\uFF0C\u8BF7\u5148\u5347\u7EA7 DSH \u6216\u9009\u62E9\u517C\u5BB9\u7248\u672C" : `\u5B89\u88C5\u672A\u5B8C\u6210\uFF08${result.error?.code ?? result.packageResult?.kind ?? "unknown"}\uFF09\uFF1B\u8BF7\u5230 DSH \u63D2\u4EF6\u9875\u67E5\u770B\u5B89\u88C5\u65E5\u5FD7`,
|
|
601
|
-
pendingBuilds: result.pendingBuilds ?? [],
|
|
602
|
-
logPath: result.packageResult?.logPath
|
|
603
|
-
};
|
|
604
|
-
}
|
|
757
|
+
} else result = await outsideActivation(this.hmr(), () => this.service().installBundle(row.target, options2));
|
|
758
|
+
if (installFailed(result)) return { name: row.name, ...installFailure(result), expectedVersion: row.latestVersion };
|
|
605
759
|
const installed = (await this.service().listBundles()).find((b) => b.name === row.name);
|
|
606
760
|
if (row.source.kind === "npm" && installed?.version !== row.latestVersion) return {
|
|
607
761
|
name: row.name,
|
|
@@ -654,7 +808,32 @@ var PluginUpdates = class {
|
|
|
654
808
|
this.start("install", async (job) => {
|
|
655
809
|
job.total = 1;
|
|
656
810
|
job.current = spec;
|
|
657
|
-
|
|
811
|
+
let expected;
|
|
812
|
+
if (npm?.kind === "npm" && github.kind !== "github") {
|
|
813
|
+
const found = await this.lookup(this.service(), this.profile(), `${npm.package}@${named[2] || "latest"}`, this.abort.signal, registry);
|
|
814
|
+
if (!parseWorkBuddyVersion(found.version)) throw Error("npm \u672A\u8FD4\u56DE\u6709\u6548\u7248\u672C\uFF0C\u8BF7\u68C0\u67E5\u5B89\u88C5\u6E90\u540E\u91CD\u8BD5");
|
|
815
|
+
expected = found.version;
|
|
816
|
+
}
|
|
817
|
+
const result = await outsideActivation(this.hmr(), () => this.service().installBundle(spec, { requestId: job.id, ...registry ? { registry } : {} }));
|
|
818
|
+
if (installFailed(result)) {
|
|
819
|
+
job.results.push({ name: result.bundle ?? spec, ...installFailure(result), expectedVersion: expected });
|
|
820
|
+
delete job.current;
|
|
821
|
+
await this.list();
|
|
822
|
+
return;
|
|
823
|
+
}
|
|
824
|
+
const installed = (await this.service().listBundles()).find((b) => b.name === (result.bundle ?? named?.[1]));
|
|
825
|
+
if (expected && installed?.version !== expected) {
|
|
826
|
+
job.results.push({
|
|
827
|
+
name: result.bundle ?? named[1],
|
|
828
|
+
status: "failed",
|
|
829
|
+
expectedVersion: expected,
|
|
830
|
+
installedVersion: installed?.version,
|
|
831
|
+
message: `\u5B9E\u9645\u5B89\u88C5\u7248\u672C ${installed?.version ?? "\u672A\u77E5"} \u4E0E\u68C0\u67E5\u7248\u672C ${expected} \u4E0D\u540C\uFF1B\u8BF7\u5207\u6362\u300Cnpm \u5B98\u65B9\u300D\u540E\u91CD\u65B0\u68C0\u67E5\u5E76\u5B89\u88C5\u6307\u5B9A\u7248\u672C\u3002`
|
|
832
|
+
});
|
|
833
|
+
delete job.current;
|
|
834
|
+
await this.list();
|
|
835
|
+
return;
|
|
836
|
+
}
|
|
658
837
|
const reloadPending = !result.error && result.packageResult?.exitCode === 0 && result.application === "restart-required" && this.onInstalled?.(result.bundle) === true;
|
|
659
838
|
job.results.push({
|
|
660
839
|
name: result.bundle ?? spec,
|
|
@@ -689,7 +868,7 @@ var PluginUpdates = class {
|
|
|
689
868
|
|
|
690
869
|
// src/workbuddy-login.mjs
|
|
691
870
|
import { randomBytes as randomBytes2 } from "node:crypto";
|
|
692
|
-
import { readFile as
|
|
871
|
+
import { readFile as readFile3 } from "node:fs/promises";
|
|
693
872
|
import { withFileLock as withFileLock2 } from "@deepseek-ai/dsh-atomic-write";
|
|
694
873
|
var WorkBuddyLogin = class {
|
|
695
874
|
constructor(file, { fetchImpl = (...args) => fetch(...args), now = Date.now } = {}) {
|
|
@@ -703,7 +882,7 @@ var WorkBuddyLogin = class {
|
|
|
703
882
|
await withFileLock2(this.file, async () => {
|
|
704
883
|
let state = {};
|
|
705
884
|
try {
|
|
706
|
-
state = JSON.parse(await
|
|
885
|
+
state = JSON.parse(await readFile3(this.file, "utf8"));
|
|
707
886
|
} catch (e) {
|
|
708
887
|
if (e.code !== "ENOENT") throw Error("\u767B\u5F55\u51B7\u5374\u8BB0\u5F55\u4E0D\u53EF\u8BFB\uFF0C\u8BF7\u68C0\u67E5\u672C\u673A\u6587\u4EF6");
|
|
709
888
|
}
|
|
@@ -715,7 +894,7 @@ var WorkBuddyLogin = class {
|
|
|
715
894
|
async pause() {
|
|
716
895
|
this.pending = void 0;
|
|
717
896
|
await withFileLock2(this.file, async () => {
|
|
718
|
-
const state = JSON.parse(await
|
|
897
|
+
const state = JSON.parse(await readFile3(this.file, "utf8"));
|
|
719
898
|
state.pausedUntil = this.now() + 15 * 6e4;
|
|
720
899
|
await writePrivateJson(this.file, state);
|
|
721
900
|
});
|
|
@@ -865,31 +1044,31 @@ var Manager = class {
|
|
|
865
1044
|
this.file = file;
|
|
866
1045
|
this.router = router;
|
|
867
1046
|
this.onChange = onChange;
|
|
868
|
-
this.catalogFile =
|
|
1047
|
+
this.catalogFile = join5(dirname3(file), "catalogs.json");
|
|
869
1048
|
this.catalogs = /* @__PURE__ */ new Map();
|
|
870
1049
|
this.catalogErrors = /* @__PURE__ */ new Map();
|
|
871
1050
|
this.refreshes = /* @__PURE__ */ new Map();
|
|
872
1051
|
this.closed = false;
|
|
873
1052
|
this.monitorFlights = /* @__PURE__ */ new Map();
|
|
874
1053
|
this.loginInfo = /* @__PURE__ */ new Map();
|
|
875
|
-
this.telemetry = new Telemetry(
|
|
876
|
-
this.plugins = new PluginUpdates({ ...pluginAccess, stateFile:
|
|
1054
|
+
this.telemetry = new Telemetry(join5(dirname3(file), "usage.json"));
|
|
1055
|
+
this.plugins = new PluginUpdates({ ...pluginAccess, stateFile: join5(dirname3(file), "plugin-updates.json"), onInstalled: (name) => {
|
|
877
1056
|
if (name !== "dsh-multi-router" || !this.runtime?.canReload()) return false;
|
|
878
1057
|
this.runtime.schedule();
|
|
879
1058
|
return true;
|
|
880
1059
|
} });
|
|
881
|
-
this.checkins = new Checkins(
|
|
882
|
-
this.workbuddyLogin = new WorkBuddyLogin(
|
|
883
|
-
this.setupFile =
|
|
1060
|
+
this.checkins = new Checkins(join5(dirname3(file), "checkins.json"), this);
|
|
1061
|
+
this.workbuddyLogin = new WorkBuddyLogin(join5(dirname3(file), "workbuddy-login.json"), { fetchImpl: pluginAccess.fetchImpl });
|
|
1062
|
+
this.setupFile = join5(dirname3(file), "initial-setup.json");
|
|
884
1063
|
router.telemetry = this.telemetry;
|
|
885
|
-
router.monitor = (a) => this.monitorAccount(a);
|
|
1064
|
+
router.monitor = (a) => this.monitorAccount(a, { maxAgeMs: 6e4 });
|
|
886
1065
|
router.prepareFree = () => this.checkFreeModels(true);
|
|
887
1066
|
router.freeModels = (account) => this.freeModels(account);
|
|
888
1067
|
}
|
|
889
1068
|
async load() {
|
|
890
|
-
this.raw = JSON.parse(await
|
|
1069
|
+
this.raw = JSON.parse(await readFile4(this.file, "utf8"));
|
|
891
1070
|
try {
|
|
892
|
-
this.setup = JSON.parse(await
|
|
1071
|
+
this.setup = JSON.parse(await readFile4(this.setupFile, "utf8"));
|
|
893
1072
|
} catch {
|
|
894
1073
|
this.setup = void 0;
|
|
895
1074
|
}
|
|
@@ -897,7 +1076,7 @@ var Manager = class {
|
|
|
897
1076
|
await this.checkins.load();
|
|
898
1077
|
await this.plugins.load();
|
|
899
1078
|
try {
|
|
900
|
-
const saved = JSON.parse(await
|
|
1079
|
+
const saved = JSON.parse(await readFile4(this.catalogFile, "utf8"));
|
|
901
1080
|
for (const account of this.config.accounts) {
|
|
902
1081
|
const item = saved[account.id];
|
|
903
1082
|
if (item?.credentialFile === account.credentialFile && Array.isArray(item.models)) {
|
|
@@ -939,12 +1118,12 @@ var Manager = class {
|
|
|
939
1118
|
if (this.closed || !discovered.accounts.length) return;
|
|
940
1119
|
await withFileLock3(this.file, async () => {
|
|
941
1120
|
if (this.closed) return;
|
|
942
|
-
let raw = JSON.parse(await
|
|
1121
|
+
let raw = JSON.parse(await readFile4(this.file, "utf8"));
|
|
943
1122
|
let changed = false;
|
|
944
1123
|
const saved = /* @__PURE__ */ new Map();
|
|
945
1124
|
for (const item of discovered.accounts) {
|
|
946
1125
|
const key = localAccountKey(item.provider, item.document);
|
|
947
|
-
if (!force && raw.ignoredLocalAccounts?.
|
|
1126
|
+
if (!force && raw.ignoredLocalAccounts?.some((k) => normalizeLocalAccountKey(k) === key)) continue;
|
|
948
1127
|
const config = validateConfig(raw, this.file);
|
|
949
1128
|
let existing, current;
|
|
950
1129
|
for (const a of config.accounts.filter((a2) => a2.provider === item.provider)) {
|
|
@@ -976,11 +1155,11 @@ var Manager = class {
|
|
|
976
1155
|
recordSaved();
|
|
977
1156
|
continue;
|
|
978
1157
|
}
|
|
979
|
-
const base =
|
|
1158
|
+
const base = join5(dirname3(this.file), "accounts");
|
|
980
1159
|
await mkdir2(base, { recursive: true, mode: 448 });
|
|
981
|
-
const staging = await mkdtemp2(
|
|
1160
|
+
const staging = await mkdtemp2(join5(base, `${id}-`));
|
|
982
1161
|
try {
|
|
983
|
-
const credentialFile =
|
|
1162
|
+
const credentialFile = join5(staging, "credential.json"), identityFile = join5(staging, "identity.json");
|
|
984
1163
|
await importAccount({ ...item, credentialFile, identityFile });
|
|
985
1164
|
const paths = {
|
|
986
1165
|
credentialFile: relative2(dirname3(this.file), credentialFile),
|
|
@@ -994,7 +1173,7 @@ var Manager = class {
|
|
|
994
1173
|
name: item.document.credential.nickname || item.document.credential.accountName || item.document.credential.uid || item.document.credential.userId,
|
|
995
1174
|
...paths
|
|
996
1175
|
});
|
|
997
|
-
next.ignoredLocalAccounts = (raw.ignoredLocalAccounts ?? []).filter((k) => k !== key);
|
|
1176
|
+
next.ignoredLocalAccounts = (raw.ignoredLocalAccounts ?? []).filter((k) => normalizeLocalAccountKey(k) !== key);
|
|
998
1177
|
validateConfig(next, this.file);
|
|
999
1178
|
await writePrivateJson(this.file, next);
|
|
1000
1179
|
raw = next;
|
|
@@ -1025,7 +1204,7 @@ var Manager = class {
|
|
|
1025
1204
|
if (this.setup?.completedAt) return;
|
|
1026
1205
|
await withFileLock3(this.setupFile, async () => {
|
|
1027
1206
|
try {
|
|
1028
|
-
this.setup = JSON.parse(await
|
|
1207
|
+
this.setup = JSON.parse(await readFile4(this.setupFile, "utf8"));
|
|
1029
1208
|
} catch {
|
|
1030
1209
|
}
|
|
1031
1210
|
if (this.setup?.completedAt) return;
|
|
@@ -1033,8 +1212,12 @@ var Manager = class {
|
|
|
1033
1212
|
await writePrivateJson(this.setupFile, this.setup);
|
|
1034
1213
|
});
|
|
1035
1214
|
}
|
|
1036
|
-
async monitorAccount(account) {
|
|
1215
|
+
async monitorAccount(account, { force = false, maxAgeMs = 3e5 } = {}) {
|
|
1037
1216
|
if (this.monitorFlights.has(account.id)) return this.monitorFlights.get(account.id);
|
|
1217
|
+
const cached = this.telemetry.row("accounts", account.id).balance;
|
|
1218
|
+
const last = cached?.error ? cached.attemptedAt : cached?.fetchedAt;
|
|
1219
|
+
const ttl = cached?.error ? 3e5 : maxAgeMs;
|
|
1220
|
+
if (!force && Number.isFinite(last) && Date.now() >= last && Date.now() - last < ttl) return;
|
|
1038
1221
|
const promise = (async () => {
|
|
1039
1222
|
try {
|
|
1040
1223
|
const client = await this.router.client(account);
|
|
@@ -1053,8 +1236,8 @@ var Manager = class {
|
|
|
1053
1236
|
this.monitorFlights.set(account.id, promise);
|
|
1054
1237
|
return promise;
|
|
1055
1238
|
}
|
|
1056
|
-
async monitorAll(provider) {
|
|
1057
|
-
await Promise.all(this.config.accounts.filter((a) => !provider || a.provider === provider).map((a) => this.monitorAccount(a)));
|
|
1239
|
+
async monitorAll(provider, options2) {
|
|
1240
|
+
await Promise.all(this.config.accounts.filter((a) => (!provider || a.provider === provider) && (options2?.force || a.enabled !== false)).map((a) => this.monitorAccount(a, options2)));
|
|
1058
1241
|
}
|
|
1059
1242
|
freeAccounts() {
|
|
1060
1243
|
const targets = Object.values(this.config.routes).filter((r) => r.freeOnly).flatMap((r) => r.targets);
|
|
@@ -1277,7 +1460,7 @@ var Manager = class {
|
|
|
1277
1460
|
}
|
|
1278
1461
|
}
|
|
1279
1462
|
if (input.action === "workbuddy.login") {
|
|
1280
|
-
if (input.revision !== revisionOf(JSON.parse(await
|
|
1463
|
+
if (input.revision !== revisionOf(JSON.parse(await readFile4(this.file, "utf8")))) throw new ManagementError(409, "\u914D\u7F6E\u5DF2\u66F4\u65B0\uFF0C\u8BF7\u5237\u65B0\u540E\u91CD\u65B0\u63D0\u4EA4\u767B\u5F55");
|
|
1281
1464
|
let login;
|
|
1282
1465
|
try {
|
|
1283
1466
|
login = await this.workbuddyLogin.complete(input.challenge, input.code, input.verify ?? true);
|
|
@@ -1357,7 +1540,7 @@ var Manager = class {
|
|
|
1357
1540
|
return this.state();
|
|
1358
1541
|
}
|
|
1359
1542
|
if (input.action === "account.export") {
|
|
1360
|
-
if (input.revision !== revisionOf(JSON.parse(await
|
|
1543
|
+
if (input.revision !== revisionOf(JSON.parse(await readFile4(this.file, "utf8")))) throw new ManagementError(409, "\u914D\u7F6E\u5DF2\u66F4\u65B0\uFF0C\u8BF7\u5237\u65B0\u540E\u63D0\u53D6\u51ED\u8BC1");
|
|
1361
1544
|
const account = this.config.accounts.find((a) => a.id === input.id);
|
|
1362
1545
|
if (!account) bad("\u8D26\u53F7\u4E0D\u5B58\u5728");
|
|
1363
1546
|
let credential;
|
|
@@ -1379,7 +1562,7 @@ var Manager = class {
|
|
|
1379
1562
|
} };
|
|
1380
1563
|
}
|
|
1381
1564
|
if (input.action === "config.export") {
|
|
1382
|
-
if (input.revision !== revisionOf(JSON.parse(await
|
|
1565
|
+
if (input.revision !== revisionOf(JSON.parse(await readFile4(this.file, "utf8")))) throw new ManagementError(409, "\u914D\u7F6E\u5DF2\u66F4\u65B0\uFF0C\u8BF7\u5237\u65B0\u540E\u5BFC\u51FA");
|
|
1383
1566
|
try {
|
|
1384
1567
|
return { ...this.state(), exported: { filename: `dsh-multi-router-${input.includeCredentials ? "encrypted" : "settings"}-${(/* @__PURE__ */ new Date()).toISOString().slice(0, 10)}.json`, document: await exportConfiguration(this, input) } };
|
|
1385
1568
|
} catch (e) {
|
|
@@ -1400,10 +1583,10 @@ var Manager = class {
|
|
|
1400
1583
|
const account = this.config.accounts.find((a) => a.id === input.id);
|
|
1401
1584
|
if (!account) bad("\u8D26\u53F7\u4E0D\u5B58\u5728");
|
|
1402
1585
|
this.router.clients.delete(account.id);
|
|
1403
|
-
await this.monitorAccount(account);
|
|
1586
|
+
await this.monitorAccount(account, { force: true });
|
|
1404
1587
|
} else {
|
|
1405
1588
|
await this.syncLocalAccounts(input.provider);
|
|
1406
|
-
await this.monitorAll(input.provider);
|
|
1589
|
+
await this.monitorAll(input.provider, { force: true });
|
|
1407
1590
|
}
|
|
1408
1591
|
return this.state();
|
|
1409
1592
|
}
|
|
@@ -1427,7 +1610,7 @@ var Manager = class {
|
|
|
1427
1610
|
return this.state();
|
|
1428
1611
|
}
|
|
1429
1612
|
return withFileLock3(this.file, async () => {
|
|
1430
|
-
let raw = JSON.parse(await
|
|
1613
|
+
let raw = JSON.parse(await readFile4(this.file, "utf8"));
|
|
1431
1614
|
if (input.revision !== revisionOf(raw)) throw new ManagementError(409, "\u914D\u7F6E\u5DF2\u66F4\u65B0\uFF0C\u8BF7\u5237\u65B0\u540E\u518D\u4FDD\u5B58");
|
|
1432
1615
|
raw.routes ??= structuredClone(this.config.routes);
|
|
1433
1616
|
let staging;
|
|
@@ -1450,10 +1633,10 @@ var Manager = class {
|
|
|
1450
1633
|
}
|
|
1451
1634
|
if (!/^[a-zA-Z0-9_-]{1,64}$/.test(input.id ?? "") || !PROVIDERS.includes(input.provider)) bad("\u8D26\u53F7 ID \u6216\u4F9B\u5E94\u5546\u65E0\u6548");
|
|
1452
1635
|
if (account && !replacing) bad("\u8D26\u53F7 ID \u5DF2\u5B58\u5728\uFF0C\u8BF7\u4F7F\u7528\u4E0D\u540C ID");
|
|
1453
|
-
const base =
|
|
1636
|
+
const base = join5(dirname3(this.file), "accounts");
|
|
1454
1637
|
await mkdir2(base, { recursive: true, mode: 448 });
|
|
1455
|
-
staging = await mkdtemp2(
|
|
1456
|
-
const credentialFile =
|
|
1638
|
+
staging = await mkdtemp2(join5(base, `${input.id}-`));
|
|
1639
|
+
const credentialFile = join5(staging, "credential.json"), identityFile = join5(staging, "identity.json");
|
|
1457
1640
|
const added = {
|
|
1458
1641
|
id: input.id,
|
|
1459
1642
|
name: input.name || account?.name || input.id,
|
|
@@ -1649,12 +1832,12 @@ var Manager = class {
|
|
|
1649
1832
|
}
|
|
1650
1833
|
watch(onError) {
|
|
1651
1834
|
let timer;
|
|
1652
|
-
const watcher =
|
|
1835
|
+
const watcher = watch2(dirname3(this.file), (_, filename) => {
|
|
1653
1836
|
if (filename && String(filename) !== this.file.split(/[\\/]/).pop()) return;
|
|
1654
1837
|
clearTimeout(timer);
|
|
1655
1838
|
timer = setTimeout(() => {
|
|
1656
1839
|
void withFileLock3(this.file, async () => {
|
|
1657
|
-
const raw = JSON.parse(await
|
|
1840
|
+
const raw = JSON.parse(await readFile4(this.file, "utf8"));
|
|
1658
1841
|
if (this.closed || revisionOf(raw) === this.revision) return;
|
|
1659
1842
|
const config = validateConfig(raw, this.file);
|
|
1660
1843
|
this.raw = raw;
|
|
@@ -1719,10 +1902,11 @@ function managementHandler(manager) {
|
|
|
1719
1902
|
|
|
1720
1903
|
export {
|
|
1721
1904
|
version,
|
|
1905
|
+
PluginReload,
|
|
1722
1906
|
MANAGEMENT_PATH,
|
|
1723
1907
|
ManagementError,
|
|
1724
1908
|
modelInfo,
|
|
1725
1909
|
Manager,
|
|
1726
1910
|
managementHandler
|
|
1727
1911
|
};
|
|
1728
|
-
//# sourceMappingURL=chunk-
|
|
1912
|
+
//# sourceMappingURL=chunk-I4EW5TI7.js.map
|