@linxin666/dsh-pet 0.2.3 → 0.2.5
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 +65 -2
- package/README.zh.md +65 -2
- package/assets/decorations/whale/decoration.json +20 -0
- package/assets/decorations/whale/whale-frames.png +0 -0
- package/contracts/pet-manifest-v2.schema.json +281 -0
- package/contracts/status-decoration-v1.schema.json +144 -0
- package/contracts/voice-pack-v1.schema.json +234 -0
- package/lib/client.js +251 -43
- package/lib/client.js.map +1 -1
- package/lib/index.js +1139 -100
- package/lib/types/access.d.ts +16 -0
- package/lib/types/access.d.ts.map +1 -0
- package/lib/types/access.js +20 -0
- package/lib/types/chatter.d.ts +61 -3
- package/lib/types/chatter.d.ts.map +1 -1
- package/lib/types/chatter.js +71 -12
- package/lib/types/client/PetSettingsCard.d.ts +4 -0
- package/lib/types/client/PetSettingsCard.d.ts.map +1 -1
- package/lib/types/client/PetSettingsCard.js +11 -3
- package/lib/types/client/PetSprite.d.ts.map +1 -1
- package/lib/types/client/PetSprite.js +111 -4
- package/lib/types/client/locales.d.ts +4 -0
- package/lib/types/client/locales.d.ts.map +1 -1
- package/lib/types/client/locales.js +4 -0
- package/lib/types/client/renderers/live2d/Live2dVisualMount.d.ts.map +1 -1
- package/lib/types/client/renderers/live2d/Live2dVisualMount.js +1 -0
- package/lib/types/client/renderers/live2d/runtime.d.ts +13 -1
- package/lib/types/client/renderers/live2d/runtime.d.ts.map +1 -1
- package/lib/types/client/renderers/live2d.d.ts.map +1 -1
- package/lib/types/client/renderers/live2d.js +133 -25
- package/lib/types/client/settings-form.d.ts.map +1 -1
- package/lib/types/client/settings-form.js +9 -6
- package/lib/types/contracts/status-decoration.d.ts +85 -0
- package/lib/types/contracts/status-decoration.d.ts.map +1 -0
- package/lib/types/contracts/status-decoration.js +21 -0
- package/lib/types/decoration.d.ts +39 -0
- package/lib/types/decoration.d.ts.map +1 -0
- package/lib/types/decoration.js +210 -0
- package/lib/types/event-projection.d.ts +8 -3
- package/lib/types/event-projection.d.ts.map +1 -1
- package/lib/types/event-projection.js +9 -4
- package/lib/types/image-dimensions.d.ts +26 -0
- package/lib/types/image-dimensions.d.ts.map +1 -0
- package/lib/types/image-dimensions.js +77 -0
- package/lib/types/index.d.ts +2 -0
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/index.js +3 -1
- package/lib/types/registry.d.ts +55 -2
- package/lib/types/registry.d.ts.map +1 -1
- package/lib/types/registry.js +240 -16
- package/lib/types/routes.d.ts +6 -1
- package/lib/types/routes.d.ts.map +1 -1
- package/lib/types/routes.js +163 -32
- package/lib/types/service.d.ts +33 -0
- package/lib/types/service.d.ts.map +1 -1
- package/lib/types/service.js +42 -3
- package/lib/types/voice-pack.d.ts +98 -0
- package/lib/types/voice-pack.d.ts.map +1 -0
- package/lib/types/voice-pack.js +384 -0
- package/package.json +11 -10
- package/src/access.ts +40 -0
- package/src/chatter.test.ts +89 -2
- package/src/chatter.ts +120 -14
- package/src/client/PetSettingsCard.tsx +26 -2
- package/src/client/PetSprite.test.tsx +325 -12
- package/src/client/PetSprite.tsx +150 -25
- package/src/client/locales.ts +4 -0
- package/src/client/renderers/live2d/Live2dVisualMount.test.tsx +72 -0
- package/src/client/renderers/live2d/Live2dVisualMount.tsx +1 -0
- package/src/client/renderers/live2d/runtime.ts +8 -2
- package/src/client/renderers/live2d.test.ts +233 -9
- package/src/client/renderers/live2d.ts +143 -30
- package/src/client/settings-form.ts +8 -6
- package/src/contracts/status-decoration.ts +78 -0
- package/src/decoration.test.ts +178 -0
- package/src/decoration.ts +220 -0
- package/src/event-projection.ts +10 -5
- package/src/image-dimensions.test.ts +85 -0
- package/src/image-dimensions.ts +76 -0
- package/src/index.ts +3 -1
- package/src/registry.test.ts +276 -0
- package/src/registry.ts +274 -15
- package/src/routes.ts +162 -33
- package/src/service.ts +59 -3
- package/src/voice-pack.test.ts +216 -0
- package/src/voice-pack.ts +413 -0
package/lib/types/service.d.ts
CHANGED
|
@@ -17,6 +17,7 @@ import type { TreatConfig } from './treats.ts';
|
|
|
17
17
|
import { type LedgerInteractionResult } from './ledger.ts';
|
|
18
18
|
import { type PetDisplayConfig } from './persist.ts';
|
|
19
19
|
import { type PetDefinition, type PetManifest, type PetRegistry, type PetRegistryDiagnostic } from './registry.ts';
|
|
20
|
+
import type { DecorationView } from './contracts/status-decoration.ts';
|
|
20
21
|
import { type PetStateConfig, type PetStateSnapshot } from './state.ts';
|
|
21
22
|
/** Plugin configuration. */
|
|
22
23
|
export interface PetConfig {
|
|
@@ -30,6 +31,8 @@ export interface PetConfig {
|
|
|
30
31
|
persistDir?: string;
|
|
31
32
|
/** Master switch for the plugin (browser half + host routes). */
|
|
32
33
|
enabled?: boolean;
|
|
34
|
+
/** Status-decoration master switch (pet-center M5, #567); defaults to on. */
|
|
35
|
+
decorationEnabled?: boolean;
|
|
33
36
|
/** Prebuilt registry (tests); defaults to scanning the package + user dirs. */
|
|
34
37
|
registry?: PetRegistry;
|
|
35
38
|
/** Extra manifest entries composed by the embedding application. */
|
|
@@ -55,6 +58,11 @@ export interface PetSettingsSection {
|
|
|
55
58
|
bottom: number;
|
|
56
59
|
/** Master switch for the plugin (browser half + host routes). */
|
|
57
60
|
enabled?: boolean;
|
|
61
|
+
/**
|
|
62
|
+
* Status-decoration master switch (pet-center M5, #567). Defaults to on;
|
|
63
|
+
* the settings surface mirrors this field and can turn it off.
|
|
64
|
+
*/
|
|
65
|
+
decorationEnabled?: boolean;
|
|
58
66
|
}
|
|
59
67
|
/** Settings namespace of the pet capability. Spelled here rather than imported: the browser half spells the same value. */
|
|
60
68
|
export declare const PET_SETTINGS_NAMESPACE = "pet";
|
|
@@ -119,6 +127,12 @@ export interface PetStateView {
|
|
|
119
127
|
* rendered by the client as a distinct whisper bubble.
|
|
120
128
|
*/
|
|
121
129
|
whisper?: string;
|
|
130
|
+
/**
|
|
131
|
+
* The active status decoration (pet-center M5, #567), when the master
|
|
132
|
+
* switch is on and the default decoration entry exists. Absent means the
|
|
133
|
+
* browser half renders no ornament.
|
|
134
|
+
*/
|
|
135
|
+
decoration?: DecorationView;
|
|
122
136
|
}
|
|
123
137
|
/** Result of `pet.interact`. */
|
|
124
138
|
export type PetInteractResult = LedgerInteractionResult;
|
|
@@ -141,9 +155,17 @@ export declare class PetService extends Service {
|
|
|
141
155
|
private readonly registry;
|
|
142
156
|
private readonly persistDir;
|
|
143
157
|
private enabled;
|
|
158
|
+
/** Status-decoration master switch (M5, #567); mirrored from settings. */
|
|
159
|
+
private decorationEnabled;
|
|
144
160
|
private disposeActivity;
|
|
145
161
|
/** Session whose most recent meaningful event currently drives the global pet. */
|
|
146
162
|
private displaySession;
|
|
163
|
+
/**
|
|
164
|
+
* Effective voice-pack overrides for the currently selected pet (M4,
|
|
165
|
+
* #677). Cached per pet id; the registry is an immutable snapshot, so the
|
|
166
|
+
* global pack and each entry's pack cannot change behind the cache.
|
|
167
|
+
*/
|
|
168
|
+
private voiceCache;
|
|
147
169
|
/**
|
|
148
170
|
* Per-session activity, most recent last (Map insertion order). Bounded by
|
|
149
171
|
* MAX_SESSION_BUBBLES so a burst of sessions cannot grow it without bound;
|
|
@@ -151,6 +173,12 @@ export declare class PetService extends Service {
|
|
|
151
173
|
*/
|
|
152
174
|
private readonly sessionActivity;
|
|
153
175
|
constructor(ctx: Context, config?: PetConfig);
|
|
176
|
+
/**
|
|
177
|
+
* The draw-time voice-pool provider handed to every projection runtime.
|
|
178
|
+
* It re-resolves when the selected pet changes, so live engines re-voice
|
|
179
|
+
* on the next draw without being rebuilt (M4, #677).
|
|
180
|
+
*/
|
|
181
|
+
private voicePools;
|
|
154
182
|
/** Whether the pet service consumes session activity while enabled. */
|
|
155
183
|
isEnabled(): boolean;
|
|
156
184
|
/** RPC: current pet state snapshot. */
|
|
@@ -165,6 +193,11 @@ export declare class PetService extends Service {
|
|
|
165
193
|
diagnostics(): Promise<{
|
|
166
194
|
diagnostics: PetRegistryDiagnostic[];
|
|
167
195
|
}>;
|
|
196
|
+
/**
|
|
197
|
+
* The active status decoration view (M5, #567): the default 'whale' entry
|
|
198
|
+
* (user directories override built-ins by id), gated by the master switch.
|
|
199
|
+
*/
|
|
200
|
+
private activeDecoration;
|
|
168
201
|
/** The selected pet's registry entry. */
|
|
169
202
|
activeEntry(): NonNullable<PetRegistry['entries'][number]>;
|
|
170
203
|
/** Currently selected pet id (persisted). */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAEtD,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AACpF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAQ9C,OAAO,EAAgC,KAAK,uBAAuB,EAAE,MAAM,aAAa,CAAA;AACxF,OAAO,EASL,KAAK,gBAAgB,EACtB,MAAM,cAAc,CAAA;AACrB,OAAO,
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/service.ts"],"names":[],"mappings":"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"}
|
package/lib/types/service.js
CHANGED
|
@@ -15,8 +15,9 @@ import { Service } from '@deepseek-ai/cordis';
|
|
|
15
15
|
import { emptyProjectionRuntime, isActivityPhase, projectOfficialEvent, } from './event-projection.js';
|
|
16
16
|
import { PetLedger } from './ledger.js';
|
|
17
17
|
import { DEFAULT_PET_NAME, DISPLAY_INSET_MAX, DISPLAY_SIZE_MAX, DISPLAY_SIZE_MIN, PET_NAME_MAX_LENGTH, loadPetPersist, petHomeDir, savePetPersist, } from './persist.js';
|
|
18
|
-
import { loadPetRegistry, petEntryView, petPackageRoot, } from './registry.js';
|
|
18
|
+
import { DEFAULT_DECORATION_ID, decorationView, loadPetRegistry, petEntryView, petPackageRoot, } from './registry.js';
|
|
19
19
|
import { WHISPER_TTL_MS } from './chatter.js';
|
|
20
|
+
import { mergeVoicePacks } from './voice-pack.js';
|
|
20
21
|
import { defaultPetStateConfig, PetStateMachine, } from './state.js';
|
|
21
22
|
/** Settings namespace of the pet capability. Spelled here rather than imported: the browser half spells the same value. */
|
|
22
23
|
export const PET_SETTINGS_NAMESPACE = 'pet';
|
|
@@ -36,9 +37,17 @@ export class PetService extends Service {
|
|
|
36
37
|
registry;
|
|
37
38
|
persistDir;
|
|
38
39
|
enabled;
|
|
40
|
+
/** Status-decoration master switch (M5, #567); mirrored from settings. */
|
|
41
|
+
decorationEnabled;
|
|
39
42
|
disposeActivity;
|
|
40
43
|
/** Session whose most recent meaningful event currently drives the global pet. */
|
|
41
44
|
displaySession;
|
|
45
|
+
/**
|
|
46
|
+
* Effective voice-pack overrides for the currently selected pet (M4,
|
|
47
|
+
* #677). Cached per pet id; the registry is an immutable snapshot, so the
|
|
48
|
+
* global pack and each entry's pack cannot change behind the cache.
|
|
49
|
+
*/
|
|
50
|
+
voiceCache;
|
|
42
51
|
/**
|
|
43
52
|
* Per-session activity, most recent last (Map insertion order). Bounded by
|
|
44
53
|
* MAX_SESSION_BUBBLES so a burst of sessions cannot grow it without bound;
|
|
@@ -72,8 +81,25 @@ export class PetService extends Service {
|
|
|
72
81
|
this.stateConfig = { ...defaultPetStateConfig, ...(config.state ?? {}) };
|
|
73
82
|
this.machine = new PetStateMachine(this.stateConfig);
|
|
74
83
|
this.enabled = config.enabled ?? true;
|
|
84
|
+
this.decorationEnabled = config.decorationEnabled ?? true;
|
|
75
85
|
this.syncActivity();
|
|
76
86
|
}
|
|
87
|
+
/**
|
|
88
|
+
* The draw-time voice-pool provider handed to every projection runtime.
|
|
89
|
+
* It re-resolves when the selected pet changes, so live engines re-voice
|
|
90
|
+
* on the next draw without being rebuilt (M4, #677).
|
|
91
|
+
*/
|
|
92
|
+
voicePools() {
|
|
93
|
+
return () => {
|
|
94
|
+
const entry = this.activeEntry();
|
|
95
|
+
if (this.voiceCache !== undefined && this.voiceCache.petId === entry.id) {
|
|
96
|
+
return this.voiceCache.overrides;
|
|
97
|
+
}
|
|
98
|
+
const overrides = mergeVoicePacks(this.registry.globalVoice, entry.voice)?.overrides ?? {};
|
|
99
|
+
this.voiceCache = { petId: entry.id, overrides };
|
|
100
|
+
return overrides;
|
|
101
|
+
};
|
|
102
|
+
}
|
|
77
103
|
/** Whether the pet service consumes session activity while enabled. */
|
|
78
104
|
isEnabled() {
|
|
79
105
|
return this.enabled;
|
|
@@ -88,7 +114,7 @@ export class PetService extends Service {
|
|
|
88
114
|
}
|
|
89
115
|
/** RPC: the registry entries the browser half renders and selects from. */
|
|
90
116
|
async pets() {
|
|
91
|
-
return this.registry.entries.map(petEntryView);
|
|
117
|
+
return this.registry.entries.map(entry => petEntryView(entry, this.registry.globalVoice));
|
|
92
118
|
}
|
|
93
119
|
/** The loaded registry (the asset routes serve its entries). */
|
|
94
120
|
registrySnapshot() {
|
|
@@ -98,6 +124,16 @@ export class PetService extends Service {
|
|
|
98
124
|
async diagnostics() {
|
|
99
125
|
return { diagnostics: this.registry.diagnostics };
|
|
100
126
|
}
|
|
127
|
+
/**
|
|
128
|
+
* The active status decoration view (M5, #567): the default 'whale' entry
|
|
129
|
+
* (user directories override built-ins by id), gated by the master switch.
|
|
130
|
+
*/
|
|
131
|
+
activeDecoration() {
|
|
132
|
+
if (!this.decorationEnabled)
|
|
133
|
+
return undefined;
|
|
134
|
+
const entry = this.registry.decorationById?.(DEFAULT_DECORATION_ID);
|
|
135
|
+
return entry === undefined ? undefined : decorationView(entry);
|
|
136
|
+
}
|
|
101
137
|
/** The selected pet's registry entry. */
|
|
102
138
|
activeEntry() {
|
|
103
139
|
return this.registry.byId(this.selectedPetId()) ?? this.registry.defaultEntry();
|
|
@@ -199,7 +235,7 @@ export class PetService extends Service {
|
|
|
199
235
|
let activity = this.sessionActivity.get(session);
|
|
200
236
|
if (activity === undefined) {
|
|
201
237
|
activity = {
|
|
202
|
-
runtime: emptyProjectionRuntime(),
|
|
238
|
+
runtime: emptyProjectionRuntime(this.voicePools()),
|
|
203
239
|
machine: new PetStateMachine(this.stateConfig),
|
|
204
240
|
};
|
|
205
241
|
this.sessionActivity.set(session, activity);
|
|
@@ -277,6 +313,7 @@ export class PetService extends Service {
|
|
|
277
313
|
* @param section - the resolved settings section.
|
|
278
314
|
*/
|
|
279
315
|
applySettingsSection(section) {
|
|
316
|
+
this.decorationEnabled = section.decorationEnabled ?? true;
|
|
280
317
|
const selected = typeof section.petId === 'string' ? this.registry.byId(section.petId) : undefined;
|
|
281
318
|
if (selected !== undefined) {
|
|
282
319
|
this.ledger.setPetId(selected.id);
|
|
@@ -355,6 +392,7 @@ export class PetService extends Service {
|
|
|
355
392
|
const freshWhisper = whisper !== undefined && Date.now() - whisper.at < WHISPER_TTL_MS
|
|
356
393
|
? whisper.text
|
|
357
394
|
: undefined;
|
|
395
|
+
const decoration = this.activeDecoration();
|
|
358
396
|
// Read-only: the ledger settles on economic events only, never on a read,
|
|
359
397
|
// so polling the state cannot trigger pet.json writes.
|
|
360
398
|
return {
|
|
@@ -364,6 +402,7 @@ export class PetService extends Service {
|
|
|
364
402
|
sessionActive: snapshot.sessionActive,
|
|
365
403
|
sessions,
|
|
366
404
|
...(freshWhisper === undefined ? {} : { whisper: freshWhisper }),
|
|
405
|
+
...(decoration === undefined ? {} : { decoration }),
|
|
367
406
|
affinity: this.ledger.affinityView(Date.now()),
|
|
368
407
|
display: { ...this.ledger.snapshot.display },
|
|
369
408
|
pet: {
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Voice-pack normalization and merge (pet-center M4, issue #677).
|
|
3
|
+
*
|
|
4
|
+
* A voice pack is the optional 'voice.json' inside a pet directory, or the
|
|
5
|
+
* global '$DSH_HOME/pets/.voice.json' override file — pure JSON content that
|
|
6
|
+
* layers pet copy over the built-in pools. Two halves:
|
|
7
|
+
*
|
|
8
|
+
* - 'overrides': the chatter pools (status / tools / toolRemaining /
|
|
9
|
+
* whispers) handed to the chatter engines through a VoicePoolsProvider;
|
|
10
|
+
* - 'panel': the hover-panel chrome (button labels, stat formats, action
|
|
11
|
+
* subset) served to the browser half through PetDefinition.panel.
|
|
12
|
+
*
|
|
13
|
+
* Discipline split matches the registry: STRUCTURE is fail-closed per file
|
|
14
|
+
* (a non-object root drops the whole pack with a warning), CONTENT is
|
|
15
|
+
* warn-and-drop per slot — one bad line never breaks a pet. The JSON Schema
|
|
16
|
+
* twin lives at contracts/voice-pack-v1.schema.json for documentation and
|
|
17
|
+
* external tooling; this hand-rolled normalizer is authoritative (the
|
|
18
|
+
* repository ships no schema-validator runtime).
|
|
19
|
+
*
|
|
20
|
+
* Placeholder policy (each pool kind whitelists its own tokens):
|
|
21
|
+
* - status / whisper pools / panel labels: no placeholders allowed — a line
|
|
22
|
+
* carrying any '{...}' token is dropped with a warning;
|
|
23
|
+
* - tools: {tool} and {hint}; toolRemaining: {n}; panel stats:
|
|
24
|
+
* {rank} / {n} / {points}.
|
|
25
|
+
*
|
|
26
|
+
* This file is imported directly by scripts/dsh-pet under node's strip-only
|
|
27
|
+
* TypeScript mode: keep it erasable-syntax-only.
|
|
28
|
+
* @module @linxin666/dsh-pet/voice-pack
|
|
29
|
+
*/
|
|
30
|
+
import { type VoicePackOverrides, type WhisperRule } from './chatter.ts';
|
|
31
|
+
/** Schema version this module normalizes (optional field; missing = 1). */
|
|
32
|
+
export declare const VOICE_PACK_V1: 1;
|
|
33
|
+
/** Hover-panel action buttons a pack can show or hide (canonical order). */
|
|
34
|
+
export declare const PANEL_ACTIONS: readonly ['feed', 'rename', 'hide'];
|
|
35
|
+
export type PanelAction = (typeof PANEL_ACTIONS)[number];
|
|
36
|
+
/** Panel label slots (unset slots keep the client's i18n dictionary copy). */
|
|
37
|
+
export declare const PANEL_LABEL_KEYS: readonly ['feed', 'rename', 'hide', 'confirm'];
|
|
38
|
+
export type PanelLabelKey = (typeof PANEL_LABEL_KEYS)[number];
|
|
39
|
+
/** Panel stat slots ({rank}/{n}/{points} interpolate the live values). */
|
|
40
|
+
export declare const PANEL_STAT_KEYS: readonly ['rank', 'treats', 'points'];
|
|
41
|
+
export type PanelStatKey = (typeof PANEL_STAT_KEYS)[number];
|
|
42
|
+
/** Hover-panel chrome overrides served to the browser half. */
|
|
43
|
+
export interface PetPanelView {
|
|
44
|
+
/** Button / input labels; unset slots keep the i18n dictionary copy. */
|
|
45
|
+
labels?: Partial<Record<PanelLabelKey, string>>;
|
|
46
|
+
/** Stat line formats; unset slots keep the i18n dictionary copy. */
|
|
47
|
+
stats?: Partial<Record<PanelStatKey, string>>;
|
|
48
|
+
/** Actions to render in canonical order; absent = all three; [] = none. */
|
|
49
|
+
actions?: PanelAction[];
|
|
50
|
+
}
|
|
51
|
+
/** One normalized voice pack (a pet's voice.json or the global override). */
|
|
52
|
+
export interface VoicePack {
|
|
53
|
+
/** Chatter pool overrides (draw-time merged with the built-in pools). */
|
|
54
|
+
overrides: VoicePackOverrides;
|
|
55
|
+
/** Hover-panel chrome, when the pack declares any. */
|
|
56
|
+
panel?: PetPanelView;
|
|
57
|
+
}
|
|
58
|
+
/** Hard caps shared by every pool slot (mirrors the remarks discipline). */
|
|
59
|
+
export declare const VOICE_POOL_LINES_MAX = 64;
|
|
60
|
+
export declare const VOICE_LINE_MAX = 160;
|
|
61
|
+
export declare const VOICE_KEYWORDS_PER_RULE_MAX = 16;
|
|
62
|
+
export declare const VOICE_KEYWORD_MAX = 40;
|
|
63
|
+
export declare const VOICE_RULES_MAX = 32;
|
|
64
|
+
export declare const VOICE_LABEL_MAX = 40;
|
|
65
|
+
export declare const VOICE_STAT_MAX = 80;
|
|
66
|
+
type PoolKind = 'status' | 'tools' | 'toolRemaining' | 'whisperGeneric' | 'whisperRule' | 'label' | 'stat';
|
|
67
|
+
/**
|
|
68
|
+
* Normalize one pool slot. Accepts a single line or an array; non-string
|
|
69
|
+
* entries warn and drop, empty lines drop silently, lines over the length
|
|
70
|
+
* cap truncate, illegal placeholders drop the line, and pools over the line
|
|
71
|
+
* cap keep their first lines. An explicit empty pool normalizes to [] (the
|
|
72
|
+
* whisper channels read that as mute) while an absent slot normalizes to
|
|
73
|
+
* undefined (the slot keeps the built-in pool).
|
|
74
|
+
*/
|
|
75
|
+
export declare function normalizePool(raw: unknown, kind: PoolKind, onWarning?: (message: string) => void): string[] | undefined;
|
|
76
|
+
/** Normalize the ordered keyword-rule list ([] disables the keyword channel). */
|
|
77
|
+
export declare function normalizeWhisperRules(raw: unknown, onWarning?: (message: string) => void): WhisperRule[] | undefined;
|
|
78
|
+
/** Normalize the panel block (labels / stats / actions; warn-and-drop). */
|
|
79
|
+
export declare function normalizePanel(raw: unknown, onWarning?: (message: string) => void): PetPanelView | undefined;
|
|
80
|
+
/** Voice-pack top-level fields ('$schema' mirrors the schema twin; drift-locked in tests). */
|
|
81
|
+
export declare const VOICE_PACK_KEYS: Set<string>;
|
|
82
|
+
/** Allowed whisper-section fields (drift-locked in tests). */
|
|
83
|
+
export declare const WHISPER_KEYS: Set<string>;
|
|
84
|
+
/**
|
|
85
|
+
* Normalize one raw voice.json document into a VoicePack, or undefined when
|
|
86
|
+
* the file cannot serve as a pack at all (non-object root — structure is
|
|
87
|
+
* fail-closed per file). Every slot issue is a warning, never a throw.
|
|
88
|
+
*/
|
|
89
|
+
export declare function normalizeVoicePack(raw: unknown, onWarning?: (message: string) => void): VoicePack | undefined;
|
|
90
|
+
/**
|
|
91
|
+
* Merge voice-pack layers into one pack; later layers win per slot. The
|
|
92
|
+
* built-in pools are NOT a layer here — the chatter engines fall back to
|
|
93
|
+
* them per key at draw time. Merge order for a selected pet:
|
|
94
|
+
* mergeVoicePacks(registry.globalVoice, entry.voice).
|
|
95
|
+
*/
|
|
96
|
+
export declare function mergeVoicePacks(...layers: (VoicePack | undefined)[]): VoicePack | undefined;
|
|
97
|
+
export {};
|
|
98
|
+
//# sourceMappingURL=voice-pack.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"voice-pack.d.ts","sourceRoot":"","sources":["../../src/voice-pack.ts"],"names":[],"mappings":"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"}
|