deepseek-harness-background 0.5.4 → 0.5.6
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/README.md +9 -6
- package/README.zh.md +9 -6
- package/lib/client.js +173 -94
- package/lib/client.js.map +1 -1
- package/lib/index.js +281 -19
- package/package.json +85 -85
package/lib/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import z from "@deepseek-ai/schemastery";
|
|
2
2
|
import { randomBytes } from "node:crypto";
|
|
3
|
-
import { existsSync, mkdirSync, statSync, unlinkSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { existsSync, mkdirSync, readFileSync, statSync, unlinkSync, writeFileSync } from "node:fs";
|
|
4
4
|
import { readFile } from "node:fs/promises";
|
|
5
5
|
import { extname, join, resolve } from "node:path";
|
|
6
6
|
import { homedir } from "node:os";
|
|
@@ -52,12 +52,11 @@ const FIT_MODES = ["cover", "contain"];
|
|
|
52
52
|
//#region src/schema.ts
|
|
53
53
|
/** Host-side schema for the `ui-background` settings namespace. */
|
|
54
54
|
/**
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
* the schema's toJSON wire serialization).
|
|
55
|
+
* The section's fields, in schema order — ONE definition feeding both
|
|
56
|
+
* generations. Field schemas are immutable builders (`volatile()` clones),
|
|
57
|
+
* so deriving the volatile view below leaves this one unmarked.
|
|
59
58
|
*/
|
|
60
|
-
const
|
|
59
|
+
const BackgroundSettingsFields = {
|
|
61
60
|
enabled: z.boolean().default(false),
|
|
62
61
|
/** Content-addressed local upload id or empty. */
|
|
63
62
|
uploadId: z.string().default(""),
|
|
@@ -70,7 +69,32 @@ const BackgroundSettingsSchema = z.object({
|
|
|
70
69
|
wallpaperBlur: z.number().min(0).max(60).default(0),
|
|
71
70
|
fit: z.union([...FIT_MODES]).default(DEFAULT_FIT),
|
|
72
71
|
timeline: z.boolean().default(true)
|
|
73
|
-
}
|
|
72
|
+
};
|
|
73
|
+
/**
|
|
74
|
+
* Durable background section; also the wire envelope the browser scope
|
|
75
|
+
* validates against and the namespace schema registered on dsh 0.1.5/0.1.6.
|
|
76
|
+
* `uploadId` and `url` name the two exclusive sources; the schema stays
|
|
77
|
+
* structural (no trim/transform — a function callback would break the
|
|
78
|
+
* schema's toJSON wire serialization).
|
|
79
|
+
*/
|
|
80
|
+
const BackgroundSettingsSchema = z.object(BackgroundSettingsFields);
|
|
81
|
+
/** The same fields, each marked volatile (the marker is cloned, so the plain
|
|
82
|
+
* view above stays unmarked). */
|
|
83
|
+
function volatileFields(fields) {
|
|
84
|
+
return Object.fromEntries(Object.entries(fields).map(([key, field]) => [key, field.volatile()]));
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* The plugin's live configuration as dsh 0.1.7+ reads it: the settings
|
|
88
|
+
* service projects each active profile entry's exported `Config` into a form
|
|
89
|
+
* and keys the section on the entry id. Every field is volatile — "editable
|
|
90
|
+
* without remounting" — which is exactly what a wholesale
|
|
91
|
+
* `settings.replace(entryId, section)` demands of each written path
|
|
92
|
+
* (`isVolatilePath` walks to a volatile ancestor or refuses the write).
|
|
93
|
+
*
|
|
94
|
+
* The wire schema above stays unmarked: it is also the 0.1.5/0.1.6
|
|
95
|
+
* registration schema, where `volatile` has no meaning.
|
|
96
|
+
*/
|
|
97
|
+
const Config = z.object(volatileFields(BackgroundSettingsFields));
|
|
74
98
|
//#endregion
|
|
75
99
|
//#region src/harness-home.ts
|
|
76
100
|
/**
|
|
@@ -108,6 +132,167 @@ function resolveHarnessHome(env = process.env) {
|
|
|
108
132
|
/** Subdirectory under the harness home that this plugin owns. */
|
|
109
133
|
const PLUGIN_HOME_REL = join("deepseek-harness-background");
|
|
110
134
|
//#endregion
|
|
135
|
+
//#region src/migrate.ts
|
|
136
|
+
/**
|
|
137
|
+
* Legacy-settings migration.
|
|
138
|
+
*
|
|
139
|
+
* dsh <= 0.1.6 stored this plugin's section in `~/.dsh/settings.yaml`. dsh
|
|
140
|
+
* 0.1.7 imports that document once, BY PROFILE ENTRY ID, then renames it to
|
|
141
|
+
* `settings.yaml.imported`; `ui-background` is not an entry id, so the section
|
|
142
|
+
* is logged and skipped — the renamed file is the one surviving copy of a
|
|
143
|
+
* user's background settings.
|
|
144
|
+
*
|
|
145
|
+
* This module reads that copy back and hands it to the 0.1.7 settings service
|
|
146
|
+
* under the entry-id namespace, so an upgrade does not silently reset every
|
|
147
|
+
* background. The document is user-editable, so each value is validated
|
|
148
|
+
* against the section schema and a value the schema refuses is dropped (its
|
|
149
|
+
* default then applies) rather than poisoning the whole migration.
|
|
150
|
+
*/
|
|
151
|
+
/**
|
|
152
|
+
* Settings documents an older dsh left in the harness home, in precedence
|
|
153
|
+
* order: the live document first, then the copy 0.1.7 renamed away.
|
|
154
|
+
*/
|
|
155
|
+
const LEGACY_SETTINGS_FILES = ["settings.yaml", "settings.yaml.imported"];
|
|
156
|
+
/** Marker written into the plugin home once a migration has been attempted. */
|
|
157
|
+
const MIGRATION_MARKER = ".migrated-from-legacy-settings";
|
|
158
|
+
/**
|
|
159
|
+
* One scalar as the settings provider's YAML writer emitted it. The section is
|
|
160
|
+
* flat and holds only scalars, so this covers the whole surface; a quoted
|
|
161
|
+
* scalar stays a string (a quoted `"2"` must not become the number 2).
|
|
162
|
+
*/
|
|
163
|
+
function parseScalar(raw) {
|
|
164
|
+
const text = raw.trim();
|
|
165
|
+
if (text === "") return "";
|
|
166
|
+
if (text === "true") return true;
|
|
167
|
+
if (text === "false") return false;
|
|
168
|
+
if (text === "null" || text === "~") return null;
|
|
169
|
+
if (text.startsWith("\"") && text.endsWith("\"") || text.startsWith("'") && text.endsWith("'")) return text.slice(1, -1);
|
|
170
|
+
const uncommented = text.replace(/\s+#.*$/, "");
|
|
171
|
+
const numeric = Number(uncommented);
|
|
172
|
+
if (uncommented !== "" && Number.isFinite(numeric)) return numeric;
|
|
173
|
+
return uncommented;
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* The lines of one TOP-LEVEL `namespace:` block, or undefined when the document
|
|
177
|
+
* has no such key. Only the block's own indent level is returned: a deeper
|
|
178
|
+
* mapping that happens to reuse the field names belongs to some other section.
|
|
179
|
+
*/
|
|
180
|
+
function sectionFields(text, namespace) {
|
|
181
|
+
const lines = text.split(/\r?\n/);
|
|
182
|
+
const header = new RegExp(`^${namespace}\\s*:(?:\\s*#.*)?$`);
|
|
183
|
+
const start = lines.findIndex((line) => header.test(line));
|
|
184
|
+
if (start < 0) return void 0;
|
|
185
|
+
const fields = {};
|
|
186
|
+
let indent;
|
|
187
|
+
for (let index = start + 1; index < lines.length; index += 1) {
|
|
188
|
+
const line = lines[index] ?? "";
|
|
189
|
+
if (line.trim() === "") continue;
|
|
190
|
+
const match = /^(\s+)([A-Za-z0-9_-]+)\s*:\s*(.*)$/.exec(line);
|
|
191
|
+
if (match === null) {
|
|
192
|
+
if (!/^\s/.test(line)) break;
|
|
193
|
+
continue;
|
|
194
|
+
}
|
|
195
|
+
indent ??= match[1]?.length;
|
|
196
|
+
if (match[1]?.length !== indent) continue;
|
|
197
|
+
const key = match[2] ?? "";
|
|
198
|
+
if (!BACKGROUND_SETTINGS_FIELDS.includes(key)) continue;
|
|
199
|
+
fields[key] = parseScalar(match[3] ?? "");
|
|
200
|
+
}
|
|
201
|
+
return Object.keys(fields).length === 0 ? void 0 : fields;
|
|
202
|
+
}
|
|
203
|
+
/** Keep one field only when the section schema accepts it. */
|
|
204
|
+
function acceptedFields(candidate) {
|
|
205
|
+
const accepted = {};
|
|
206
|
+
for (const [key, value] of Object.entries(candidate)) try {
|
|
207
|
+
BackgroundSettingsSchema({ [key]: value });
|
|
208
|
+
accepted[key] = value;
|
|
209
|
+
} catch {}
|
|
210
|
+
return accepted;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Read the plugin's section out of the newest settings document that carries
|
|
214
|
+
* one.
|
|
215
|
+
* @param home - harness home (defaults to the resolved one).
|
|
216
|
+
* @returns the schema-resolved section and its source, or undefined when no
|
|
217
|
+
* legacy document holds a usable section.
|
|
218
|
+
*/
|
|
219
|
+
function readLegacyBackgroundSection(home = resolveHarnessHome()) {
|
|
220
|
+
for (const file of LEGACY_SETTINGS_FILES) {
|
|
221
|
+
const path = join(home, file);
|
|
222
|
+
if (!existsSync(path)) continue;
|
|
223
|
+
let text;
|
|
224
|
+
try {
|
|
225
|
+
text = readFileSync(path, "utf8");
|
|
226
|
+
} catch {
|
|
227
|
+
continue;
|
|
228
|
+
}
|
|
229
|
+
const candidate = sectionFields(text, "ui-background");
|
|
230
|
+
if (candidate === void 0) continue;
|
|
231
|
+
const accepted = acceptedFields(candidate);
|
|
232
|
+
if (Object.keys(accepted).length === 0) continue;
|
|
233
|
+
return {
|
|
234
|
+
from: file,
|
|
235
|
+
section: BackgroundSettingsSchema(accepted)
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Whether a descriptor actually carries a user layer. dsh 0.1.7's `describe()`
|
|
241
|
+
* projects the raw user section through the form, so an entry with no config
|
|
242
|
+
* row reports `user: {}` rather than leaving the field off — an empty object
|
|
243
|
+
* IS the fresh-upgrade state this migration exists for.
|
|
244
|
+
*/
|
|
245
|
+
function hasUserSection(user) {
|
|
246
|
+
if (user === void 0 || user === null) return false;
|
|
247
|
+
if (typeof user === "object") return Object.keys(user).length > 0;
|
|
248
|
+
return true;
|
|
249
|
+
}
|
|
250
|
+
/** The plugin's own directory under the harness home. */
|
|
251
|
+
function pluginHome$1(home) {
|
|
252
|
+
return join(home, PLUGIN_HOME_REL);
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Bring a pre-0.1.7 section forward into the entry-keyed document, ONCE.
|
|
256
|
+
*
|
|
257
|
+
* Runs lazily from the first settings read rather than from `apply`: the
|
|
258
|
+
* settings service refuses a write until this plugin's fiber is ACTIVE, and a
|
|
259
|
+
* route handler only ever runs once it is. The marker file is what makes it
|
|
260
|
+
* one-shot — a user who resets every field to its default deletes the entry's
|
|
261
|
+
* config row, and without the marker the next boot would resurrect the old
|
|
262
|
+
* background.
|
|
263
|
+
*
|
|
264
|
+
* @param settings - the mounted settings service.
|
|
265
|
+
* @param namespace - the entry-keyed namespace to write.
|
|
266
|
+
* @param home - harness home (defaults to the resolved one).
|
|
267
|
+
* @returns what the attempt did.
|
|
268
|
+
*/
|
|
269
|
+
async function ensureLegacyMigration(settings, namespace, home = resolveHarnessHome()) {
|
|
270
|
+
const marker = join(pluginHome$1(home), MIGRATION_MARKER);
|
|
271
|
+
if (existsSync(marker)) return {
|
|
272
|
+
kind: "skipped",
|
|
273
|
+
reason: "already-migrated"
|
|
274
|
+
};
|
|
275
|
+
const descriptor = settings.describe().find((candidate) => candidate.ns === namespace);
|
|
276
|
+
if (descriptor !== void 0 && hasUserSection(descriptor.user)) return {
|
|
277
|
+
kind: "skipped",
|
|
278
|
+
reason: "target-has-user-section"
|
|
279
|
+
};
|
|
280
|
+
const legacy = readLegacyBackgroundSection(home);
|
|
281
|
+
if (legacy === void 0) return {
|
|
282
|
+
kind: "skipped",
|
|
283
|
+
reason: "no-legacy-section"
|
|
284
|
+
};
|
|
285
|
+
await settings.replace(namespace, legacy.section);
|
|
286
|
+
try {
|
|
287
|
+
mkdirSync(pluginHome$1(home), { recursive: true });
|
|
288
|
+
writeFileSync(marker, `${(/* @__PURE__ */ new Date()).toISOString()}\n${legacy.from}\n`, "utf8");
|
|
289
|
+
} catch {}
|
|
290
|
+
return {
|
|
291
|
+
kind: "migrated",
|
|
292
|
+
from: legacy.from
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
//#endregion
|
|
111
296
|
//#region src/routes.ts
|
|
112
297
|
/**
|
|
113
298
|
* Host HTTP routes for the background plugin — the browser half talks to the
|
|
@@ -146,6 +331,22 @@ function pickKnown(section) {
|
|
|
146
331
|
for (const key of BACKGROUND_SETTINGS_FIELDS) if (key in src) out[key] = src[key];
|
|
147
332
|
return out;
|
|
148
333
|
}
|
|
334
|
+
/**
|
|
335
|
+
* Resolve the plugin's section from whatever settings generation is mounted.
|
|
336
|
+
* Both generations return the schema-resolved value from `describe()`, so one
|
|
337
|
+
* read path serves 0.1.5, 0.1.6 and 0.1.7; an absent namespace (or a settings
|
|
338
|
+
* service that has not finished registering) resolves to the schema defaults.
|
|
339
|
+
* @param settings - the mounted settings service.
|
|
340
|
+
* @param namespace - the namespace/entry id owning the section.
|
|
341
|
+
* @returns the resolved section, defaults filled in.
|
|
342
|
+
*/
|
|
343
|
+
function readBackgroundSection(settings, namespace = BACKGROUND_SETTINGS_NAMESPACE) {
|
|
344
|
+
const described = settings.describe().find((descriptor) => descriptor.ns === namespace)?.value;
|
|
345
|
+
return {
|
|
346
|
+
...DEFAULTS,
|
|
347
|
+
...described
|
|
348
|
+
};
|
|
349
|
+
}
|
|
149
350
|
/** Accepted upload MIME type → file extension. */
|
|
150
351
|
const ACCEPTED_TYPES = {
|
|
151
352
|
"image/jpeg": "jpg",
|
|
@@ -407,15 +608,38 @@ function mimeForPath(path) {
|
|
|
407
608
|
if (ext === "webp") return "image/webp";
|
|
408
609
|
if (ext === "gif") return "image/gif";
|
|
409
610
|
}
|
|
611
|
+
/**
|
|
612
|
+
* Lazily attempt the pre-0.1.7 settings migration exactly once per mounted
|
|
613
|
+
* route family.
|
|
614
|
+
*
|
|
615
|
+
* It runs from the first settings READ rather than from `apply` for two
|
|
616
|
+
* reasons: the settings service refuses a write until this plugin's fiber is
|
|
617
|
+
* ACTIVE, and a route handler only ever runs once it is; and the read that
|
|
618
|
+
* triggers it is the browser half's own first `load()`, so the very response
|
|
619
|
+
* that carries the adopted section also carries the `migrated` notice.
|
|
620
|
+
* @param settings - the mounted settings service.
|
|
621
|
+
* @param namespace - the entry-keyed namespace to write.
|
|
622
|
+
* @param home - harness home override (tests); production resolves the env.
|
|
623
|
+
*/
|
|
624
|
+
function createMigrationGate(settings, namespace, home) {
|
|
625
|
+
let attempted = false;
|
|
626
|
+
return async () => {
|
|
627
|
+
if (attempted) return void 0;
|
|
628
|
+
attempted = true;
|
|
629
|
+
try {
|
|
630
|
+
const outcome = await ensureLegacyMigration(settings, namespace, home ?? resolveHarnessHome());
|
|
631
|
+
return outcome.kind === "migrated" ? { from: outcome.from } : void 0;
|
|
632
|
+
} catch (error) {
|
|
633
|
+
console.error("[deepseek-harness-background] legacy settings migration failed:", error);
|
|
634
|
+
return;
|
|
635
|
+
}
|
|
636
|
+
};
|
|
637
|
+
}
|
|
410
638
|
/** One background API route family over the settings provider + home. */
|
|
411
639
|
function makeBackgroundRoutes(settings, opts = {}) {
|
|
412
|
-
const
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
...DEFAULTS,
|
|
416
|
-
...section
|
|
417
|
-
};
|
|
418
|
-
};
|
|
640
|
+
const namespace = opts.namespace ?? "ui-background";
|
|
641
|
+
const readSection = () => readBackgroundSection(settings, namespace);
|
|
642
|
+
const migrate = createMigrationGate(settings, namespace, opts.home);
|
|
419
643
|
return [
|
|
420
644
|
{
|
|
421
645
|
kind: "exact",
|
|
@@ -429,9 +653,11 @@ function makeBackgroundRoutes(settings, opts = {}) {
|
|
|
429
653
|
return;
|
|
430
654
|
}
|
|
431
655
|
if (req.method === "GET") {
|
|
656
|
+
const migrated = await migrate();
|
|
432
657
|
json(res, 200, {
|
|
433
658
|
ok: true,
|
|
434
|
-
value: readSection()
|
|
659
|
+
value: readSection(),
|
|
660
|
+
...migrated === void 0 ? {} : { migrated }
|
|
435
661
|
});
|
|
436
662
|
return;
|
|
437
663
|
}
|
|
@@ -458,7 +684,7 @@ function makeBackgroundRoutes(settings, opts = {}) {
|
|
|
458
684
|
});
|
|
459
685
|
return;
|
|
460
686
|
}
|
|
461
|
-
await settings.replace(
|
|
687
|
+
await settings.replace(namespace, merged);
|
|
462
688
|
const after = readSection();
|
|
463
689
|
if (before.uploadId !== "" && before.uploadId !== after.uploadId) deleteUploadFile(before.uploadId, opts.home);
|
|
464
690
|
json(res, 200, {
|
|
@@ -585,6 +811,32 @@ function makeBackgroundRoutes(settings, opts = {}) {
|
|
|
585
811
|
//#endregion
|
|
586
812
|
//#region src/index.ts
|
|
587
813
|
/**
|
|
814
|
+
* Entry id this plugin's bundle patch inserts into the profile. From dsh
|
|
815
|
+
* 0.1.7 on it doubles as the settings namespace, and it is the documented
|
|
816
|
+
* fallback when the running kernel exposes no Loader entry (a bare
|
|
817
|
+
* `ctx.plugin()` mount in tests, or a future loader that moves the handle).
|
|
818
|
+
*/
|
|
819
|
+
const BACKGROUND_ENTRY_ID = "deepseek-harness-background";
|
|
820
|
+
/**
|
|
821
|
+
* Whether the mounted settings service is the pre-0.1.7 provider. The one
|
|
822
|
+
* generation test: `register` was removed in the 0.1.7 rewrite, so its
|
|
823
|
+
* presence IS the older generation (never a version compare).
|
|
824
|
+
* @param settings - the mounted settings service.
|
|
825
|
+
*/
|
|
826
|
+
function isLegacySettingsService(settings) {
|
|
827
|
+
return typeof settings.register === "function";
|
|
828
|
+
}
|
|
829
|
+
/**
|
|
830
|
+
* The namespace the section lives under on the running generation: the
|
|
831
|
+
* plugin-owned `ui-background` on 0.1.5/0.1.6, the profile entry id from
|
|
832
|
+
* 0.1.7 on.
|
|
833
|
+
* @param settings - the mounted settings service.
|
|
834
|
+
* @param entryId - this plugin's Loader entry id, when the kernel exposes one.
|
|
835
|
+
*/
|
|
836
|
+
function resolveBackgroundNamespace(settings, entryId) {
|
|
837
|
+
return isLegacySettingsService(settings) ? BACKGROUND_SETTINGS_NAMESPACE : entryId ?? "deepseek-harness-background";
|
|
838
|
+
}
|
|
839
|
+
/**
|
|
588
840
|
* Register the durable background section and its API routes when the Host
|
|
589
841
|
* settings/webServer services are composed. Effect timing is `live`: the
|
|
590
842
|
* browser half repaints through the route without a restart.
|
|
@@ -592,13 +844,23 @@ function makeBackgroundRoutes(settings, opts = {}) {
|
|
|
592
844
|
*/
|
|
593
845
|
function apply(ctx) {
|
|
594
846
|
ctx.inject(["settings", "webServer"], (hostCtx) => {
|
|
595
|
-
|
|
847
|
+
const settings = hostCtx.settings;
|
|
848
|
+
const entryId = ctx.fiber.entry?.options?.id;
|
|
849
|
+
const namespace = resolveBackgroundNamespace(settings, entryId);
|
|
850
|
+
if (isLegacySettingsService(settings)) {
|
|
851
|
+
if (!settings.describe().some((descriptor) => descriptor.ns === namespace)) settings.register?.(namespace, BackgroundSettingsSchema, { applies: "live" });
|
|
852
|
+
} else if (typeof settings.configure === "function") hostCtx.effect(() => {
|
|
853
|
+
const dispose = settings.configure?.({ auto: false }, ctx.fiber);
|
|
854
|
+
return () => {
|
|
855
|
+
dispose?.();
|
|
856
|
+
};
|
|
857
|
+
}, "deepseek-harness-background: settings presentation");
|
|
596
858
|
try {
|
|
597
|
-
for (const route of makeBackgroundRoutes(
|
|
859
|
+
for (const route of makeBackgroundRoutes(settings, { namespace })) hostCtx.effect(() => hostCtx.webServer.register(route), "deepseek-harness-background: settings route");
|
|
598
860
|
} catch (error) {
|
|
599
861
|
console.error("[deepseek-harness-background] route registration failed:", error);
|
|
600
862
|
}
|
|
601
863
|
});
|
|
602
864
|
}
|
|
603
865
|
//#endregion
|
|
604
|
-
export { BACKGROUND_API_PREFIX, BACKGROUND_SETTINGS_NAMESPACE, BackgroundSettingsSchema, DEFAULT_FIT, DEFAULT_OPACITY, DEFAULT_PANEL_OPACITY, DEFAULT_SCRIM, FIT_MODES, OPACITY_MAX, OPACITY_MIN, PLUGIN_HOME_REL, SCRIM_MAX, SCRIM_MIN, apply, makeBackgroundRoutes, resolveHarnessHome };
|
|
866
|
+
export { BACKGROUND_API_PREFIX, BACKGROUND_ENTRY_ID, BACKGROUND_SETTINGS_NAMESPACE, BackgroundSettingsSchema, Config, DEFAULT_FIT, DEFAULT_OPACITY, DEFAULT_PANEL_OPACITY, DEFAULT_SCRIM, FIT_MODES, OPACITY_MAX, OPACITY_MIN, PLUGIN_HOME_REL, SCRIM_MAX, SCRIM_MIN, apply, isLegacySettingsService, makeBackgroundRoutes, readBackgroundSection, resolveBackgroundNamespace, resolveHarnessHome };
|
package/package.json
CHANGED
|
@@ -1,85 +1,85 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "deepseek-harness-background",
|
|
3
|
-
"description": "Custom background image plugin for the DeepSeek Harness web GUI: upload a local picture or paste an image URL, and render it behind the whole app surface with adjustable opacity, scrim, panel transparency and frosted-glass blur.",
|
|
4
|
-
"version": "0.5.
|
|
5
|
-
"keywords": [
|
|
6
|
-
"deepseek-harness",
|
|
7
|
-
"dsh",
|
|
8
|
-
"plugin",
|
|
9
|
-
"dsh-plugin",
|
|
10
|
-
"theme",
|
|
11
|
-
"wallpaper",
|
|
12
|
-
"background",
|
|
13
|
-
"web-ui"
|
|
14
|
-
],
|
|
15
|
-
"author": "HaoyueQin",
|
|
16
|
-
"license": "MIT",
|
|
17
|
-
"repository": {
|
|
18
|
-
"type": "git",
|
|
19
|
-
"url": "git+https://github.com/HaoyueQin/deepseek-harness-background.git"
|
|
20
|
-
},
|
|
21
|
-
"homepage": "https://github.com/HaoyueQin/deepseek-harness-background",
|
|
22
|
-
"packageManager": "pnpm@11.9.0",
|
|
23
|
-
"type": "module",
|
|
24
|
-
"main": "lib/index.js",
|
|
25
|
-
"exports": {
|
|
26
|
-
".": "./lib/index.js",
|
|
27
|
-
"./client": "./lib/client.js",
|
|
28
|
-
"./package.json": "./package.json"
|
|
29
|
-
},
|
|
30
|
-
"dsh": {
|
|
31
|
-
"bundle": {
|
|
32
|
-
"patch": "./cordis.patch.yml"
|
|
33
|
-
},
|
|
34
|
-
"client": {
|
|
35
|
-
"inject": [
|
|
36
|
-
"@deepseek-ai/dsh-client-locale"
|
|
37
|
-
],
|
|
38
|
-
"platform": "web"
|
|
39
|
-
}
|
|
40
|
-
},
|
|
41
|
-
"scripts": {
|
|
42
|
-
"build": "tsdown",
|
|
43
|
-
"prepare": "tsdown",
|
|
44
|
-
"watch": "tsdown --watch",
|
|
45
|
-
"test": "vitest run",
|
|
46
|
-
"typecheck": "tsc --noEmit -p tsconfig.json"
|
|
47
|
-
},
|
|
48
|
-
"files": [
|
|
49
|
-
"lib",
|
|
50
|
-
"cordis.patch.yml",
|
|
51
|
-
"README.md",
|
|
52
|
-
"README.zh.md"
|
|
53
|
-
],
|
|
54
|
-
"peerDependencies": {
|
|
55
|
-
"@deepseek-ai/cordis": "^4.0.1",
|
|
56
|
-
"@deepseek-ai/dsh-client-locale": ">=0.1.2-rc.1 || >=0.1.3-alpha.1 || >=0.1.5-alpha.1",
|
|
57
|
-
"@deepseek-ai/dsh-client-ui-slots": ">=0.1.2-rc.1 || >=0.1.3-alpha.1 || >=0.1.5-alpha.1",
|
|
58
|
-
"@deepseek-ai/dsh-settings": ">=0.1.2-rc.1 || >=0.1.3-alpha.1 || >=0.1.5-alpha.1",
|
|
59
|
-
"react": "^18.2.0"
|
|
60
|
-
},
|
|
61
|
-
"dependencies": {
|
|
62
|
-
"@deepseek-ai/schemastery": "^3.18.
|
|
63
|
-
},
|
|
64
|
-
"devDependencies": {
|
|
65
|
-
"@deepseek-ai/cordis": "^4.0.1",
|
|
66
|
-
"@deepseek-ai/dsh-client-locale": ">=0.1.2-rc.1 || >=0.1.3-alpha.1 || >=0.1.5-alpha.1",
|
|
67
|
-
"@deepseek-ai/dsh-client-ui-slots": ">=0.1.2-rc.1 || >=0.1.3-alpha.1 || >=0.1.5-alpha.1",
|
|
68
|
-
"@deepseek-ai/dsh-host-webserver": ">=0.1.2-rc.1 || >=0.1.3-alpha.1 || >=0.1.5-alpha.1",
|
|
69
|
-
"@deepseek-ai/dsh-settings": ">=0.1.2-rc.1 || >=0.1.3-alpha.1 || >=0.1.5-alpha.1",
|
|
70
|
-
"@deepseek-ai/schemastery": "^3.18.
|
|
71
|
-
"@testing-library/dom": "^10.4.1",
|
|
72
|
-
"@testing-library/react": "^16.3.0",
|
|
73
|
-
"@types/node": "^22.0.0",
|
|
74
|
-
"@types/react": "~18.3.1",
|
|
75
|
-
"@types/react-dom": "~18.3.0",
|
|
76
|
-
"clsx": "^2.1.1",
|
|
77
|
-
"jsdom": "^29.1.1",
|
|
78
|
-
"lightningcss": "^1.33.0",
|
|
79
|
-
"react": "^18.2.0",
|
|
80
|
-
"react-dom": "^18.2.0",
|
|
81
|
-
"tsdown": "^0.22.14",
|
|
82
|
-
"typescript": "^5.8.0",
|
|
83
|
-
"vitest": "^4.1.8"
|
|
84
|
-
}
|
|
85
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "deepseek-harness-background",
|
|
3
|
+
"description": "Custom background image plugin for the DeepSeek Harness web GUI: upload a local picture or paste an image URL, and render it behind the whole app surface with adjustable opacity, scrim, panel transparency and frosted-glass blur.",
|
|
4
|
+
"version": "0.5.6",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"deepseek-harness",
|
|
7
|
+
"dsh",
|
|
8
|
+
"plugin",
|
|
9
|
+
"dsh-plugin",
|
|
10
|
+
"theme",
|
|
11
|
+
"wallpaper",
|
|
12
|
+
"background",
|
|
13
|
+
"web-ui"
|
|
14
|
+
],
|
|
15
|
+
"author": "HaoyueQin",
|
|
16
|
+
"license": "MIT",
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "git+https://github.com/HaoyueQin/deepseek-harness-background.git"
|
|
20
|
+
},
|
|
21
|
+
"homepage": "https://github.com/HaoyueQin/deepseek-harness-background",
|
|
22
|
+
"packageManager": "pnpm@11.9.0",
|
|
23
|
+
"type": "module",
|
|
24
|
+
"main": "lib/index.js",
|
|
25
|
+
"exports": {
|
|
26
|
+
".": "./lib/index.js",
|
|
27
|
+
"./client": "./lib/client.js",
|
|
28
|
+
"./package.json": "./package.json"
|
|
29
|
+
},
|
|
30
|
+
"dsh": {
|
|
31
|
+
"bundle": {
|
|
32
|
+
"patch": "./cordis.patch.yml"
|
|
33
|
+
},
|
|
34
|
+
"client": {
|
|
35
|
+
"inject": [
|
|
36
|
+
"@deepseek-ai/dsh-client-locale"
|
|
37
|
+
],
|
|
38
|
+
"platform": "web"
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"scripts": {
|
|
42
|
+
"build": "tsdown",
|
|
43
|
+
"prepare": "tsdown",
|
|
44
|
+
"watch": "tsdown --watch",
|
|
45
|
+
"test": "vitest run",
|
|
46
|
+
"typecheck": "tsc --noEmit -p tsconfig.json"
|
|
47
|
+
},
|
|
48
|
+
"files": [
|
|
49
|
+
"lib",
|
|
50
|
+
"cordis.patch.yml",
|
|
51
|
+
"README.md",
|
|
52
|
+
"README.zh.md"
|
|
53
|
+
],
|
|
54
|
+
"peerDependencies": {
|
|
55
|
+
"@deepseek-ai/cordis": "^4.0.1",
|
|
56
|
+
"@deepseek-ai/dsh-client-locale": ">=0.1.2-rc.1 || >=0.1.3-alpha.1 || >=0.1.5-alpha.1 || >=0.1.5-rc.1 || >=0.1.5-rc.2 || >=0.1.6-alpha.1 || >=0.1.6-alpha.2 || >=0.1.7-alpha.1",
|
|
57
|
+
"@deepseek-ai/dsh-client-ui-slots": ">=0.1.2-rc.1 || >=0.1.3-alpha.1 || >=0.1.5-alpha.1 || >=0.1.5-rc.1 || >=0.1.5-rc.2 || >=0.1.6-alpha.1 || >=0.1.6-alpha.2 || >=0.1.7-alpha.1",
|
|
58
|
+
"@deepseek-ai/dsh-settings": ">=0.1.2-rc.1 || >=0.1.3-alpha.1 || >=0.1.5-alpha.1 || >=0.1.5-rc.1 || >=0.1.5-rc.2 || >=0.1.6-alpha.1 || >=0.1.6-alpha.2 || >=0.1.7-alpha.1",
|
|
59
|
+
"react": "^18.2.0"
|
|
60
|
+
},
|
|
61
|
+
"dependencies": {
|
|
62
|
+
"@deepseek-ai/schemastery": "^3.18.3"
|
|
63
|
+
},
|
|
64
|
+
"devDependencies": {
|
|
65
|
+
"@deepseek-ai/cordis": "^4.0.1",
|
|
66
|
+
"@deepseek-ai/dsh-client-locale": ">=0.1.2-rc.1 || >=0.1.3-alpha.1 || >=0.1.5-alpha.1 || >=0.1.5-rc.1 || >=0.1.5-rc.2 || >=0.1.6-alpha.1 || >=0.1.6-alpha.2 || >=0.1.7-alpha.1",
|
|
67
|
+
"@deepseek-ai/dsh-client-ui-slots": ">=0.1.2-rc.1 || >=0.1.3-alpha.1 || >=0.1.5-alpha.1 || >=0.1.5-rc.1 || >=0.1.5-rc.2 || >=0.1.6-alpha.1 || >=0.1.6-alpha.2 || >=0.1.7-alpha.1",
|
|
68
|
+
"@deepseek-ai/dsh-host-webserver": ">=0.1.2-rc.1 || >=0.1.3-alpha.1 || >=0.1.5-alpha.1 || >=0.1.5-rc.1 || >=0.1.5-rc.2 || >=0.1.6-alpha.1 || >=0.1.6-alpha.2 || >=0.1.7-alpha.1",
|
|
69
|
+
"@deepseek-ai/dsh-settings": ">=0.1.2-rc.1 || >=0.1.3-alpha.1 || >=0.1.5-alpha.1 || >=0.1.5-rc.1 || >=0.1.5-rc.2 || >=0.1.6-alpha.1 || >=0.1.6-alpha.2 || >=0.1.7-alpha.1",
|
|
70
|
+
"@deepseek-ai/schemastery": "^3.18.3",
|
|
71
|
+
"@testing-library/dom": "^10.4.1",
|
|
72
|
+
"@testing-library/react": "^16.3.0",
|
|
73
|
+
"@types/node": "^22.0.0",
|
|
74
|
+
"@types/react": "~18.3.1",
|
|
75
|
+
"@types/react-dom": "~18.3.0",
|
|
76
|
+
"clsx": "^2.1.1",
|
|
77
|
+
"jsdom": "^29.1.1",
|
|
78
|
+
"lightningcss": "^1.33.0",
|
|
79
|
+
"react": "^18.2.0",
|
|
80
|
+
"react-dom": "^18.2.0",
|
|
81
|
+
"tsdown": "^0.22.14",
|
|
82
|
+
"typescript": "^5.8.0",
|
|
83
|
+
"vitest": "^4.1.8"
|
|
84
|
+
}
|
|
85
|
+
}
|