@linxin666/dsh-pet 0.3.6 → 0.3.10
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.i18n.yaml +2 -2
- package/README.md +4 -0
- package/README.zh.md +4 -0
- package/lib/client.js +187 -88
- package/lib/client.js.map +1 -1
- package/lib/index.js +89 -11
- package/lib/live2d-vendor.js +106 -95
- package/lib/live2d-vendor.js.map +1 -1
- package/lib/types/announce.d.ts +53 -0
- package/lib/types/announce.d.ts.map +1 -0
- package/lib/types/announce.js +80 -0
- package/lib/types/client/PetDockEntry.d.ts +14 -5
- package/lib/types/client/PetDockEntry.d.ts.map +1 -1
- package/lib/types/client/PetDockEntry.js +6 -5
- package/lib/types/client/PetSettingsCard.d.ts +2 -1
- package/lib/types/client/PetSettingsCard.d.ts.map +1 -1
- package/lib/types/client/PetSprite.d.ts +8 -0
- package/lib/types/client/PetSprite.d.ts.map +1 -1
- package/lib/types/client/PetSprite.js +29 -4
- package/lib/types/client/index.d.ts +8 -5
- package/lib/types/client/index.d.ts.map +1 -1
- package/lib/types/client/index.js +11 -5
- package/lib/types/client/locales.d.ts +2 -2
- package/lib/types/client/locales.js +2 -2
- package/lib/types/client/pet-store.d.ts +1 -1
- package/lib/types/client/pet-store.d.ts.map +1 -1
- package/lib/types/client/pet-store.js +1 -1
- package/lib/types/client/settings-form.d.ts +35 -43
- package/lib/types/client/settings-form.d.ts.map +1 -1
- package/lib/types/client/settings-form.js +60 -53
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/index.js +10 -9
- package/lib/types/service.d.ts +18 -0
- package/lib/types/service.d.ts.map +1 -1
- package/lib/types/service.js +22 -0
- package/package.json +17 -13
- package/src/announce.ts +103 -0
- package/src/client/PetDockEntry.test.tsx +1 -1
- package/src/client/PetDockEntry.tsx +15 -4
- package/src/client/PetSettingsCard.tsx +2 -1
- package/src/client/PetSprite.test.tsx +18 -0
- package/src/client/PetSprite.tsx +66 -3
- package/src/client/gameplay-hud.test.tsx +1 -1
- package/src/client/index.test.tsx +2 -2
- package/src/client/index.ts +17 -6
- package/src/client/locales.ts +2 -2
- package/src/client/pet-store.ts +2 -2
- package/src/client/pet.module.css +104 -0
- package/src/client/settings-form.ts +78 -92
- package/src/dsh-home.ts +1 -1
- package/src/index.ts +17 -15
- package/src/service.ts +28 -1
package/lib/index.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { _ as RemarkPicker, a as AFFINITY_MAX, c as applyInteraction, d as emptyAffinity, f as rankOf, g as REMARK_LINE_MAX, h as REMARK_LINES_MAX, i as rowOf, l as applyTurnReward, m as REMARK_KINDS, n as animationForPhase, o as AFFINITY_RANKS, p as BUILTIN_REMARKS, r as defaultPetStateConfig, s as affinityViewOf, t as PetStateMachine, u as defaultAffinityConfig, v as builtinRemark, y as normalizePetRemarks } from "./state-NvDEoCln.js";
|
|
2
|
-
import { installSettingsSection, settingsNamespace } from "@deepseek-ai/dsh-settings";
|
|
3
2
|
import z from "schemastery";
|
|
4
3
|
import { Service } from "@deepseek-ai/cordis";
|
|
5
4
|
import { closeSync, existsSync, mkdirSync, openSync, readFileSync, readSync, readdirSync, realpathSync, renameSync, statSync, writeFileSync } from "node:fs";
|
|
@@ -8,6 +7,67 @@ import { homedir } from "node:os";
|
|
|
8
7
|
import { isAbsolute as isAbsolute$1, join as join$1 } from "node:path/posix";
|
|
9
8
|
import { fileURLToPath } from "node:url";
|
|
10
9
|
import { readFile } from "node:fs/promises";
|
|
10
|
+
//#region src/announce.ts
|
|
11
|
+
/** Default freshness window. */
|
|
12
|
+
const ANNOUNCE_DEFAULT_TTL_MS = 1e4;
|
|
13
|
+
/**
|
|
14
|
+
* Hard TTL ceiling. A repeating announcer (dsh-usage) declares its poll
|
|
15
|
+
* cadence as the TTL, so an `always`-mode bubble stays continuous across
|
|
16
|
+
* polls; the ceiling means a source that dies unmounts its bubble within at
|
|
17
|
+
* most one missed refresh cycle rather than lingering forever.
|
|
18
|
+
*/
|
|
19
|
+
const ANNOUNCE_MAX_TTL_MS = 72e5;
|
|
20
|
+
/** Hard bounds: lengths and the TTL range (1 s .. 60 s). */
|
|
21
|
+
const TITLE_MAX = 80;
|
|
22
|
+
const TEXT_MAX = 120;
|
|
23
|
+
const SOURCE_MAX = 64;
|
|
24
|
+
function boundedString(value, max) {
|
|
25
|
+
if (typeof value !== "string") return void 0;
|
|
26
|
+
const trimmed = value.trim();
|
|
27
|
+
if (trimmed === "") return void 0;
|
|
28
|
+
return trimmed.length <= max ? trimmed : trimmed.slice(0, max);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Validate one announce payload. Unknown fields are dropped, oversized text
|
|
32
|
+
* is truncated, and anything structurally wrong resolves to undefined — a
|
|
33
|
+
* malformed announcement never reaches the pet's bubble surface.
|
|
34
|
+
* @param input - the payload a sibling plugin passed to `pet.announce`.
|
|
35
|
+
* @param now - epoch ms the announcement arrived.
|
|
36
|
+
*/
|
|
37
|
+
function parseAnnouncement(input, now) {
|
|
38
|
+
if (typeof input !== "object" || input === null) return void 0;
|
|
39
|
+
const data = input;
|
|
40
|
+
const source = boundedString(data.source, SOURCE_MAX);
|
|
41
|
+
const title = boundedString(data.title, TITLE_MAX);
|
|
42
|
+
if (source === void 0 || title === void 0) return void 0;
|
|
43
|
+
const kind = data.kind === "balance" || data.kind === "cost" || data.kind === "plan" ? data.kind : void 0;
|
|
44
|
+
if (kind === void 0) return void 0;
|
|
45
|
+
const amount = boundedString(data.amount, TEXT_MAX);
|
|
46
|
+
const resetAt = boundedString(data.resetAt, TEXT_MAX);
|
|
47
|
+
const note = boundedString(data.note, TITLE_MAX);
|
|
48
|
+
const percent = typeof data.percent === "number" && Number.isFinite(data.percent) ? Math.max(0, Math.min(100, data.percent)) : void 0;
|
|
49
|
+
if ((kind === "balance" || kind === "cost") && amount === void 0) return void 0;
|
|
50
|
+
if (kind === "plan" && percent === void 0) return void 0;
|
|
51
|
+
const tone = data.tone === "warn" || data.tone === "low" ? data.tone : "ok";
|
|
52
|
+
const ttlMs = typeof data.ttlMs === "number" && Number.isFinite(data.ttlMs) ? Math.max(1e3, Math.min(ANNOUNCE_MAX_TTL_MS, data.ttlMs)) : ANNOUNCE_DEFAULT_TTL_MS;
|
|
53
|
+
return {
|
|
54
|
+
source,
|
|
55
|
+
kind,
|
|
56
|
+
title,
|
|
57
|
+
...amount !== void 0 ? { amount } : {},
|
|
58
|
+
...percent !== void 0 ? { percent } : {},
|
|
59
|
+
...resetAt !== void 0 ? { resetAt } : {},
|
|
60
|
+
...note !== void 0 ? { note } : {},
|
|
61
|
+
tone,
|
|
62
|
+
ttlMs,
|
|
63
|
+
at: now
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
/** Whether an announcement is still fresh at `now`. */
|
|
67
|
+
function announcementFresh(announcement, now) {
|
|
68
|
+
return now - announcement.at < announcement.ttlMs;
|
|
69
|
+
}
|
|
70
|
+
//#endregion
|
|
11
71
|
//#region src/chatter.ts
|
|
12
72
|
/** While a scene persists, its copy advances on this cadence (ms). */
|
|
13
73
|
const STATUS_ROTATE_MS = 4e3;
|
|
@@ -4090,6 +4150,8 @@ var PetService = class extends Service {
|
|
|
4090
4150
|
enabled;
|
|
4091
4151
|
/** Status-decoration master switch (M5, #567); mirrored from settings. */
|
|
4092
4152
|
decorationEnabled;
|
|
4153
|
+
/** The freshest plugin-authored announcement (dsh-usage linkage). */
|
|
4154
|
+
announcement;
|
|
4093
4155
|
disposeActivity;
|
|
4094
4156
|
/** Session whose most recent meaningful event currently drives the global pet. */
|
|
4095
4157
|
displaySession;
|
|
@@ -4167,6 +4229,18 @@ var PetService = class extends Service {
|
|
|
4167
4229
|
async state(currentSessionId) {
|
|
4168
4230
|
return this.view(currentSessionId);
|
|
4169
4231
|
}
|
|
4232
|
+
/**
|
|
4233
|
+
* RPC: one plugin-authored announcement bubble (dsh-usage linkage). The
|
|
4234
|
+
* payload is validated into a bounded PetAnnouncement; a malformed one is
|
|
4235
|
+
* dropped silently — a sibling plugin's bug must never surface as pet
|
|
4236
|
+
* breakage. The announcement is in-memory only.
|
|
4237
|
+
*/
|
|
4238
|
+
announce(input) {
|
|
4239
|
+
const parsed = parseAnnouncement(input, Date.now());
|
|
4240
|
+
if (parsed === void 0) return { ok: false };
|
|
4241
|
+
this.announcement = parsed;
|
|
4242
|
+
return { ok: true };
|
|
4243
|
+
}
|
|
4170
4244
|
/** Current persisted display config (read-only view). */
|
|
4171
4245
|
display() {
|
|
4172
4246
|
return { ...this.ledger.snapshot.display };
|
|
@@ -4646,6 +4720,7 @@ var PetService = class extends Service {
|
|
|
4646
4720
|
settleGameplay(state, gameplayDef, Date.now(), { sessionActive: snapshot.sessionActive });
|
|
4647
4721
|
gameplay = this.gameplayViewOf(state);
|
|
4648
4722
|
}
|
|
4723
|
+
const announcement = this.announcement !== void 0 && announcementFresh(this.announcement, Date.now()) ? this.announcement : void 0;
|
|
4649
4724
|
return {
|
|
4650
4725
|
animation: snapshot.animation,
|
|
4651
4726
|
...snapshot.bubble === void 0 ? {} : { bubble: snapshot.bubble },
|
|
@@ -4653,6 +4728,7 @@ var PetService = class extends Service {
|
|
|
4653
4728
|
sessionActive: snapshot.sessionActive,
|
|
4654
4729
|
sessions,
|
|
4655
4730
|
...decoration === void 0 ? {} : { decoration },
|
|
4731
|
+
...announcement === void 0 ? {} : { announcement },
|
|
4656
4732
|
affinity: this.ledger.affinityView(Date.now()),
|
|
4657
4733
|
display: { ...this.ledger.snapshot.display },
|
|
4658
4734
|
pet: {
|
|
@@ -5466,16 +5542,18 @@ function applyImpl(ctx, config = {}) {
|
|
|
5466
5542
|
disposeRoutes = void 0;
|
|
5467
5543
|
}
|
|
5468
5544
|
};
|
|
5469
|
-
|
|
5470
|
-
|
|
5471
|
-
|
|
5472
|
-
|
|
5473
|
-
|
|
5474
|
-
|
|
5475
|
-
|
|
5476
|
-
|
|
5477
|
-
|
|
5478
|
-
|
|
5545
|
+
ctx.inject(["settings"], (settingsCtx) => {
|
|
5546
|
+
settingsCtx.settings.installSection(ctx, "pet", makePetSettingsSchema(service.selectedPetId()), base, {
|
|
5547
|
+
setSource: (source) => {
|
|
5548
|
+
current = source;
|
|
5549
|
+
},
|
|
5550
|
+
onChange: () => {
|
|
5551
|
+
const section = current();
|
|
5552
|
+
service.applySettingsSection(section);
|
|
5553
|
+
service.setEnabled(section.enabled ?? true);
|
|
5554
|
+
syncRoutes();
|
|
5555
|
+
}
|
|
5556
|
+
});
|
|
5479
5557
|
});
|
|
5480
5558
|
syncRoutes();
|
|
5481
5559
|
}
|