@linxin666/dsh-pet 0.1.1
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/LICENSE +29 -0
- package/README.md +106 -0
- package/assets/whale/pet.json +7 -0
- package/assets/whale/previews/failed.gif +0 -0
- package/assets/whale/previews/idle.gif +0 -0
- package/assets/whale/previews/jumping.gif +0 -0
- package/assets/whale/previews/review.gif +0 -0
- package/assets/whale/previews/running-left.gif +0 -0
- package/assets/whale/previews/running-right.gif +0 -0
- package/assets/whale/previews/running.gif +0 -0
- package/assets/whale/previews/waiting.gif +0 -0
- package/assets/whale/previews/waving.gif +0 -0
- package/assets/whale/spritesheet.webp +0 -0
- package/cordis.patch.yml +10 -0
- package/lib/client.js +1515 -0
- package/lib/index.js +642 -0
- package/lib/invariant.js +34 -0
- package/lib/types/affinity.d.ts +83 -0
- package/lib/types/affinity.d.ts.map +1 -0
- package/lib/types/client/PetDockEntry.d.ts +44 -0
- package/lib/types/client/PetDockEntry.d.ts.map +1 -0
- package/lib/types/client/PetSettingsCard.d.ts +67 -0
- package/lib/types/client/PetSettingsCard.d.ts.map +1 -0
- package/lib/types/client/PluginSettingsCard.d.ts +78 -0
- package/lib/types/client/PluginSettingsCard.d.ts.map +1 -0
- package/lib/types/client/WhalePet.d.ts +49 -0
- package/lib/types/client/WhalePet.d.ts.map +1 -0
- package/lib/types/client/index.d.ts +46 -0
- package/lib/types/client/index.d.ts.map +1 -0
- package/lib/types/client/locales.d.ts +101 -0
- package/lib/types/client/locales.d.ts.map +1 -0
- package/lib/types/client/pet-store.d.ts +49 -0
- package/lib/types/client/pet-store.d.ts.map +1 -0
- package/lib/types/client/settings-form.d.ts +119 -0
- package/lib/types/client/settings-form.d.ts.map +1 -0
- package/lib/types/client/slots-augment.d.ts +19 -0
- package/lib/types/client/slots-augment.d.ts.map +1 -0
- package/lib/types/client/spritesheet.d.ts +69 -0
- package/lib/types/client/spritesheet.d.ts.map +1 -0
- package/lib/types/index.d.ts +44 -0
- package/lib/types/index.d.ts.map +1 -0
- package/lib/types/invariant.d.ts +10 -0
- package/lib/types/invariant.d.ts.map +1 -0
- package/lib/types/persist.d.ts +45 -0
- package/lib/types/persist.d.ts.map +1 -0
- package/lib/types/routes.d.ts +22 -0
- package/lib/types/routes.d.ts.map +1 -0
- package/lib/types/service.d.ts +161 -0
- package/lib/types/service.d.ts.map +1 -0
- package/lib/types/state.d.ts +80 -0
- package/lib/types/state.d.ts.map +1 -0
- package/lib/types/treats.d.ts +59 -0
- package/lib/types/treats.d.ts.map +1 -0
- package/package.json +100 -0
- package/src/affinity.test.ts +74 -0
- package/src/affinity.ts +144 -0
- package/src/client/PetDockEntry.tsx +95 -0
- package/src/client/PetSettingsCard.tsx +186 -0
- package/src/client/PluginSettingsCard.tsx +207 -0
- package/src/client/WhalePet.tsx +342 -0
- package/src/client/css-modules.d.ts +6 -0
- package/src/client/index.ts +261 -0
- package/src/client/locales.ts +108 -0
- package/src/client/pet-store.ts +80 -0
- package/src/client/pet.module.css +185 -0
- package/src/client/settings-card.module.css +277 -0
- package/src/client/settings-form.ts +294 -0
- package/src/client/slots-augment.ts +27 -0
- package/src/client/spritesheet.ts +138 -0
- package/src/index.ts +148 -0
- package/src/invariant.ts +40 -0
- package/src/persist.test.ts +96 -0
- package/src/persist.ts +128 -0
- package/src/routes.ts +171 -0
- package/src/service.ts +389 -0
- package/src/state.test.ts +65 -0
- package/src/state.ts +156 -0
- package/src/treats.test.ts +86 -0
- package/src/treats.ts +101 -0
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Affinity score — pure, clock-injected. The pet grows closer the more you
|
|
3
|
+
* work together and care for it: every completed turn earns a small reward,
|
|
4
|
+
* petting earns a tiny one (cooldown-gated), feeding earns the most.
|
|
5
|
+
* Persistence lives in the service; this module only computes transitions.
|
|
6
|
+
* @module @linxin666/dsh-pet/affinity
|
|
7
|
+
*/
|
|
8
|
+
/** One interaction the user can perform on the pet. */
|
|
9
|
+
export type PetInteraction = 'pet' | 'feed';
|
|
10
|
+
/** Affinity state as persisted. */
|
|
11
|
+
export interface AffinityState {
|
|
12
|
+
/** Total affinity points, capped at AFFINITY_MAX. */
|
|
13
|
+
points: number;
|
|
14
|
+
/** Epoch ms of the last pet interaction. */
|
|
15
|
+
lastPetAt: number;
|
|
16
|
+
/** Epoch ms of the last feed. */
|
|
17
|
+
lastFeedAt: number;
|
|
18
|
+
/** Total pet count (lifetime). */
|
|
19
|
+
pets: number;
|
|
20
|
+
/** Total feed count (lifetime). */
|
|
21
|
+
feeds: number;
|
|
22
|
+
/** Total completed turns witnessed (lifetime). */
|
|
23
|
+
turns: number;
|
|
24
|
+
}
|
|
25
|
+
export declare const AFFINITY_MAX = 100;
|
|
26
|
+
/** Affinity ranks by points; the pet visibly grows with its rank.
|
|
27
|
+
* Marker glyphs are plain ASCII (the repo bans all emoji characters);
|
|
28
|
+
* they read as a growing star trail alongside the rank name. */
|
|
29
|
+
export declare const AFFINITY_RANKS: readonly [{
|
|
30
|
+
readonly min: 0;
|
|
31
|
+
readonly name: "幼鲸";
|
|
32
|
+
readonly emoji: "*";
|
|
33
|
+
}, {
|
|
34
|
+
readonly min: 25;
|
|
35
|
+
readonly name: "伙伴";
|
|
36
|
+
readonly emoji: "**";
|
|
37
|
+
}, {
|
|
38
|
+
readonly min: 50;
|
|
39
|
+
readonly name: "挚友";
|
|
40
|
+
readonly emoji: "***";
|
|
41
|
+
}, {
|
|
42
|
+
readonly min: 80;
|
|
43
|
+
readonly name: "深海羁绊";
|
|
44
|
+
readonly emoji: "****";
|
|
45
|
+
}];
|
|
46
|
+
/** Interaction tuning (all in points / ms). */
|
|
47
|
+
export interface AffinityConfig {
|
|
48
|
+
/** Points per completed turn. */
|
|
49
|
+
turnReward: number;
|
|
50
|
+
/** Points per pet; applied only outside the pet cooldown. */
|
|
51
|
+
petReward: number;
|
|
52
|
+
/** Cooldown between pets, ms. */
|
|
53
|
+
petCooldownMs: number;
|
|
54
|
+
/** Points per feed. */
|
|
55
|
+
feedReward: number;
|
|
56
|
+
/** Cooldown between feeds, ms. */
|
|
57
|
+
feedCooldownMs: number;
|
|
58
|
+
}
|
|
59
|
+
export declare const defaultAffinityConfig: AffinityConfig;
|
|
60
|
+
export declare function emptyAffinity(): AffinityState;
|
|
61
|
+
/** Outcome of one interaction. */
|
|
62
|
+
export interface InteractionOutcome {
|
|
63
|
+
/** Mutated affinity state (caller persists it). */
|
|
64
|
+
affinity: AffinityState;
|
|
65
|
+
/** Points actually gained (0 when inside the cooldown). */
|
|
66
|
+
delta: number;
|
|
67
|
+
/** Human-readable reaction copy the UI shows as a bubble. */
|
|
68
|
+
reaction: string;
|
|
69
|
+
/** True when the interaction was accepted (outside cooldown). */
|
|
70
|
+
accepted: boolean;
|
|
71
|
+
}
|
|
72
|
+
/** Rank for a point total. */
|
|
73
|
+
export declare function rankOf(points: number): (typeof AFFINITY_RANKS)[number];
|
|
74
|
+
/**
|
|
75
|
+
* Apply one interaction to a copy of the state (immutable style: returns a
|
|
76
|
+
* new object; the caller replaces the persisted state). Cooldowns only
|
|
77
|
+
* apply once the pet has been interacted with at least once (last*At === 0
|
|
78
|
+
* means "never", so the first pet/feed always lands).
|
|
79
|
+
*/
|
|
80
|
+
export declare function applyInteraction(state: AffinityState, kind: PetInteraction, nowMs: number, config?: AffinityConfig): InteractionOutcome;
|
|
81
|
+
/** Reward one completed turn (called by the host on `done`). */
|
|
82
|
+
export declare function applyTurnReward(state: AffinityState, config?: AffinityConfig): AffinityState;
|
|
83
|
+
//# sourceMappingURL=affinity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"affinity.d.ts","sourceRoot":"","sources":["../../src/affinity.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,uDAAuD;AACvD,MAAM,MAAM,cAAc,GAAG,KAAK,GAAG,MAAM,CAAA;AAE3C,mCAAmC;AACnC,MAAM,WAAW,aAAa;IAC5B,qDAAqD;IACrD,MAAM,EAAE,MAAM,CAAA;IACd,4CAA4C;IAC5C,SAAS,EAAE,MAAM,CAAA;IACjB,iCAAiC;IACjC,UAAU,EAAE,MAAM,CAAA;IAClB,kCAAkC;IAClC,IAAI,EAAE,MAAM,CAAA;IACZ,mCAAmC;IACnC,KAAK,EAAE,MAAM,CAAA;IACb,kDAAkD;IAClD,KAAK,EAAE,MAAM,CAAA;CACd;AAED,eAAO,MAAM,YAAY,MAAM,CAAA;AAE/B;;iEAEiE;AACjE,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;EAKjB,CAAA;AAEV,+CAA+C;AAC/C,MAAM,WAAW,cAAc;IAC7B,iCAAiC;IACjC,UAAU,EAAE,MAAM,CAAA;IAClB,6DAA6D;IAC7D,SAAS,EAAE,MAAM,CAAA;IACjB,iCAAiC;IACjC,aAAa,EAAE,MAAM,CAAA;IACrB,uBAAuB;IACvB,UAAU,EAAE,MAAM,CAAA;IAClB,kCAAkC;IAClC,cAAc,EAAE,MAAM,CAAA;CACvB;AAED,eAAO,MAAM,qBAAqB,EAAE,cAMnC,CAAA;AAED,wBAAgB,aAAa,IAAI,aAAa,CAE7C;AAED,kCAAkC;AAClC,MAAM,WAAW,kBAAkB;IACjC,mDAAmD;IACnD,QAAQ,EAAE,aAAa,CAAA;IACvB,2DAA2D;IAC3D,KAAK,EAAE,MAAM,CAAA;IACb,6DAA6D;IAC7D,QAAQ,EAAE,MAAM,CAAA;IAChB,iEAAiE;IACjE,QAAQ,EAAE,OAAO,CAAA;CAClB;AAED,8BAA8B;AAC9B,wBAAgB,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAMtE;AAMD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,aAAa,EACpB,IAAI,EAAE,cAAc,EACpB,KAAK,EAAE,MAAM,EACb,MAAM,GAAE,cAAsC,GAC7C,kBAAkB,CA+BpB;AAED,gEAAgE;AAChE,wBAAgB,eAAe,CAC7B,KAAK,EAAE,aAAa,EACpB,MAAM,GAAE,cAAsC,GAC7C,aAAa,CAKf"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dock anchor inside `conversation.input.selector.context`: the input
|
|
3
|
+
* selector row mounts in EVERY conversation phase (no-session cold start,
|
|
4
|
+
* the blank-session hero, and the active seat), so the floating pet stays on
|
|
5
|
+
* screen on the new-conversation screen too. While visible it mounts the
|
|
6
|
+
* floating WhalePet (portal); while hidden it renders the summon button.
|
|
7
|
+
* @module @linxin666/dsh-pet/client/PetDockEntry
|
|
8
|
+
*/
|
|
9
|
+
import { type ReactElement } from 'react';
|
|
10
|
+
import type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';
|
|
11
|
+
import type { PetStoreInstance } from './pet-store.ts';
|
|
12
|
+
import { NS } from './locales.ts';
|
|
13
|
+
/** Injected actions handed to the dock entry component. */
|
|
14
|
+
export interface PetInjected {
|
|
15
|
+
/** The app-wide pet store instance (snapshot + feedback). */
|
|
16
|
+
store: PetStoreInstance;
|
|
17
|
+
/** Ensure the first snapshot is fetched (called on mount). */
|
|
18
|
+
ensure: () => void;
|
|
19
|
+
/** Pet the whale girl (click). */
|
|
20
|
+
pet: () => void;
|
|
21
|
+
/** Feed the whale girl. */
|
|
22
|
+
feed: () => void;
|
|
23
|
+
/** Hide the whale girl. */
|
|
24
|
+
hide: () => void;
|
|
25
|
+
/** Summon the hidden whale girl back. */
|
|
26
|
+
summon: () => void;
|
|
27
|
+
/** Persist a drag position. */
|
|
28
|
+
dragEnd: (right: number, bottom: number) => void;
|
|
29
|
+
/** Rename the pet (persisted by the host). */
|
|
30
|
+
rename: (name: string) => void;
|
|
31
|
+
/** Clear the reaction bubble. */
|
|
32
|
+
feedbackDone: () => void;
|
|
33
|
+
}
|
|
34
|
+
/** Composed props of the dock entry (runtime + locale + injected). */
|
|
35
|
+
export type PetDockEntryProps = PropsRuntime<'conversation.input.selector.context'> & PetInjected & PropsLocale<typeof NS>;
|
|
36
|
+
/**
|
|
37
|
+
* Dock entry: while the pet is visible, mount the floating WhalePet (it
|
|
38
|
+
* portals itself onto document.body); while hidden, render the summon
|
|
39
|
+
* button so the pet can always come back. The store is the plugin-owned
|
|
40
|
+
* single instance — the slot system provides none because the pet is
|
|
41
|
+
* host-global, not session-scoped.
|
|
42
|
+
*/
|
|
43
|
+
export declare function PetDockEntry(props: PetDockEntryProps): ReactElement;
|
|
44
|
+
//# sourceMappingURL=PetDockEntry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PetDockEntry.d.ts","sourceRoot":"","sources":["../../../src/client/PetDockEntry.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAmC,KAAK,YAAY,EAAE,MAAM,OAAO,CAAA;AAC1E,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAA;AAGjF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AAEtD,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAA;AAGjC,2DAA2D;AAC3D,MAAM,WAAW,WAAW;IAC1B,6DAA6D;IAC7D,KAAK,EAAE,gBAAgB,CAAA;IACvB,8DAA8D;IAC9D,MAAM,EAAE,MAAM,IAAI,CAAA;IAClB,kCAAkC;IAClC,GAAG,EAAE,MAAM,IAAI,CAAA;IACf,2BAA2B;IAC3B,IAAI,EAAE,MAAM,IAAI,CAAA;IAChB,2BAA2B;IAC3B,IAAI,EAAE,MAAM,IAAI,CAAA;IAChB,yCAAyC;IACzC,MAAM,EAAE,MAAM,IAAI,CAAA;IAClB,+BAA+B;IAC/B,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAA;IAChD,8CAA8C;IAC9C,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IAC9B,iCAAiC;IACjC,YAAY,EAAE,MAAM,IAAI,CAAA;CACzB;AAED,sEAAsE;AACtE,MAAM,MAAM,iBAAiB,GAC3B,YAAY,CAAC,qCAAqC,CAAC,GACjD,WAAW,GACX,WAAW,CAAC,OAAO,EAAE,CAAC,CAAA;AAI1B;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,GAAG,YAAY,CAuCnE"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The pet settings card: display layout and name, bound to the `pet` settings
|
|
3
|
+
* namespace the host plugin registers. Registered into the
|
|
4
|
+
* `settings.plugin.item` slot the plugin-configuration section renders.
|
|
5
|
+
*/
|
|
6
|
+
import type { InjectFace, PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';
|
|
7
|
+
import type { SettingsScope, SnapshotStore } from '@deepseek-ai/dsh-client-runtime/client';
|
|
8
|
+
import { type CardActions, type CardShell, type FieldState as CardFieldState } from './settings-form.ts';
|
|
9
|
+
/** The pet's settings fields this card edits (the namespace's full schema). */
|
|
10
|
+
export interface PetSettings {
|
|
11
|
+
/** Master switch for the plugin. */
|
|
12
|
+
enabled?: boolean;
|
|
13
|
+
/** Master switch. */
|
|
14
|
+
visible?: boolean;
|
|
15
|
+
/** Scale of the rendered pet in px (sprite cell height). */
|
|
16
|
+
size?: number;
|
|
17
|
+
/** Horizontal inset from the viewport right edge, px. */
|
|
18
|
+
right?: number;
|
|
19
|
+
/** Vertical inset from the viewport bottom edge, px. */
|
|
20
|
+
bottom?: number;
|
|
21
|
+
/** User-customizable pet display name. */
|
|
22
|
+
name?: string;
|
|
23
|
+
}
|
|
24
|
+
/** What the pet settings card renders. */
|
|
25
|
+
export interface PetSettingsCardState extends CardShell {
|
|
26
|
+
/** Plugin master switch. */
|
|
27
|
+
enabled: CardFieldState;
|
|
28
|
+
/** Master switch. */
|
|
29
|
+
visible: CardFieldState;
|
|
30
|
+
/** Pet scale. */
|
|
31
|
+
size: CardFieldState;
|
|
32
|
+
/** Right inset. */
|
|
33
|
+
right: CardFieldState;
|
|
34
|
+
/** Bottom inset. */
|
|
35
|
+
bottom: CardFieldState;
|
|
36
|
+
/** Pet name. */
|
|
37
|
+
name: CardFieldState;
|
|
38
|
+
}
|
|
39
|
+
/** The registration-side face the card's slot entry injects. */
|
|
40
|
+
export interface PetSettingsCardFace extends CardActions {
|
|
41
|
+
hooks: {
|
|
42
|
+
/** Card snapshot bound by the renderer as usePetSettingsCard. */
|
|
43
|
+
petSettingsCard: SnapshotStore<PetSettingsCardState>;
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
/** Bridges the `pet` scope onto the card's staged form. */
|
|
47
|
+
export declare class PetSettingsCardController {
|
|
48
|
+
private readonly form;
|
|
49
|
+
private readonly store;
|
|
50
|
+
/** @param scope - the bound settings scope for the `pet` namespace. */
|
|
51
|
+
constructor(scope: SettingsScope<PetSettings>);
|
|
52
|
+
private projection;
|
|
53
|
+
/**
|
|
54
|
+
* Build the face the card's slot registration injects.
|
|
55
|
+
* @returns the card's snapshot and its form actions.
|
|
56
|
+
*/
|
|
57
|
+
inject(): PetSettingsCardFace;
|
|
58
|
+
}
|
|
59
|
+
/** Props the renderer binds for the pet settings card. */
|
|
60
|
+
export type PetSettingsCardProps = PropsRuntime<'web-ui.plugin.item'> & PropsLocale<'pet'> & InjectFace<PetSettingsCardFace>;
|
|
61
|
+
/**
|
|
62
|
+
* Render the pet settings card.
|
|
63
|
+
* @param props - locale copy, the card snapshot, and its form actions.
|
|
64
|
+
* @returns the card.
|
|
65
|
+
*/
|
|
66
|
+
export declare function PetSettingsCard(props: PetSettingsCardProps): import("react").JSX.Element;
|
|
67
|
+
//# sourceMappingURL=PetSettingsCard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PetSettingsCard.d.ts","sourceRoot":"","sources":["../../../src/client/PetSettingsCard.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAA;AAC7F,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,wCAAwC,CAAA;AAE1F,OAAO,EAAkD,KAAK,WAAW,EAAE,KAAK,SAAS,EAAE,KAAK,UAAU,IAAI,cAAc,EAAE,MAAM,oBAAoB,CAAA;AAExJ,+EAA+E;AAC/E,MAAM,WAAW,WAAW;IAC1B,oCAAoC;IACpC,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,qBAAqB;IACrB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,4DAA4D;IAC5D,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,yDAAyD;IACzD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,wDAAwD;IACxD,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,0CAA0C;IAC1C,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED,0CAA0C;AAC1C,MAAM,WAAW,oBAAqB,SAAQ,SAAS;IACrD,4BAA4B;IAC5B,OAAO,EAAE,cAAc,CAAA;IACvB,qBAAqB;IACrB,OAAO,EAAE,cAAc,CAAA;IACvB,iBAAiB;IACjB,IAAI,EAAE,cAAc,CAAA;IACpB,mBAAmB;IACnB,KAAK,EAAE,cAAc,CAAA;IACrB,oBAAoB;IACpB,MAAM,EAAE,cAAc,CAAA;IACtB,gBAAgB;IAChB,IAAI,EAAE,cAAc,CAAA;CACrB;AAED,gEAAgE;AAChE,MAAM,WAAW,mBAAoB,SAAQ,WAAW;IACtD,KAAK,EAAE;QACL,iEAAiE;QACjE,eAAe,EAAE,aAAa,CAAC,oBAAoB,CAAC,CAAA;KACrD,CAAA;CACF;AAED,2DAA2D;AAC3D,qBAAa,yBAAyB;IACpC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAuB;IAC5C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAqC;IAE3D,uEAAuE;gBAC3D,KAAK,EAAE,aAAa,CAAC,WAAW,CAAC;IAY7C,OAAO,CAAC,UAAU;IAYlB;;;OAGG;IACH,MAAM,IAAI,mBAAmB;CAG9B;AAED,0DAA0D;AAC1D,MAAM,MAAM,oBAAoB,GAC9B,YAAY,CAAC,oBAAoB,CAAC,GAChC,WAAW,CAAC,KAAK,CAAC,GAClB,UAAU,CAAC,mBAAmB,CAAC,CAAA;AAEnC;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,oBAAoB,+BAoF1D"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared chrome for the plugin settings card: a disclosure header naming the
|
|
3
|
+
* plugin and what its settings govern, the controls inside, and the save that
|
|
4
|
+
* writes them. Renders nothing while the namespace is unavailable — a
|
|
5
|
+
* deployment that does not compose the owning plugin should show no trace of
|
|
6
|
+
* it. Mirrors the official ui-plugin-config PluginCard in a self-contained
|
|
7
|
+
* slice (this package must not depend on a sibling UI package).
|
|
8
|
+
*/
|
|
9
|
+
import { type ReactNode } from 'react';
|
|
10
|
+
import type { CardShell } from './settings-form.ts';
|
|
11
|
+
import type { SettingsCardKey } from './locales.ts';
|
|
12
|
+
/** Card chrome shared by every plugin settings card. */
|
|
13
|
+
export interface PluginSettingsCardProps {
|
|
14
|
+
/** Locale reader for this card's copy. */
|
|
15
|
+
t: (key: SettingsCardKey) => string;
|
|
16
|
+
/** Locale key of the plugin's name. */
|
|
17
|
+
titleKey: SettingsCardKey;
|
|
18
|
+
/** Locale key of the line describing what this plugin's settings govern. */
|
|
19
|
+
descriptionKey: SettingsCardKey;
|
|
20
|
+
/** The card's form state: availability, writability, and what a save would do. */
|
|
21
|
+
state: CardShell;
|
|
22
|
+
/** Write every staged edit. */
|
|
23
|
+
onSave: () => void;
|
|
24
|
+
/** Drop every staged edit. */
|
|
25
|
+
onDiscard: () => void;
|
|
26
|
+
/** The plugin's controls. */
|
|
27
|
+
children: ReactNode;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Render one plugin settings card.
|
|
31
|
+
* @param props - the plugin's copy keys, its form state, and its controls.
|
|
32
|
+
* @returns the card, or nothing when the namespace is unavailable.
|
|
33
|
+
*/
|
|
34
|
+
export declare function PluginSettingsCard(props: PluginSettingsCardProps): import("react").JSX.Element | null;
|
|
35
|
+
/** Props every field control needs regardless of its value type. */
|
|
36
|
+
export interface FieldProps {
|
|
37
|
+
/** Stable id associating the label with its control. */
|
|
38
|
+
id: string;
|
|
39
|
+
/** Visible label. */
|
|
40
|
+
label: string;
|
|
41
|
+
/** One-line explanation rendered under the control. */
|
|
42
|
+
hint: string;
|
|
43
|
+
/** Draft text this control renders. */
|
|
44
|
+
text: string;
|
|
45
|
+
/** True when saving would leave a user-layer entry for this field. */
|
|
46
|
+
overridden: boolean;
|
|
47
|
+
/** True when the draft is not a value this field accepts. */
|
|
48
|
+
invalid: boolean;
|
|
49
|
+
/** Copy for the overridden badge. */
|
|
50
|
+
overriddenLabel: string;
|
|
51
|
+
/** Copy for the reset control. */
|
|
52
|
+
resetLabel: string;
|
|
53
|
+
/** Copy shown in place of the hint while the draft is invalid. */
|
|
54
|
+
invalidLabel: string;
|
|
55
|
+
/** Disables every control (read-only document, or an unavailable namespace). */
|
|
56
|
+
disabled: boolean;
|
|
57
|
+
/** Stage draft text. */
|
|
58
|
+
onEdit: (text: string) => void;
|
|
59
|
+
/** Stage a clear so the field re-inherits the composition layer. */
|
|
60
|
+
onReset: () => void;
|
|
61
|
+
}
|
|
62
|
+
/** A staged value field. `numeric` only hints the keypad: which drafts a field accepts is decided by its spec. */
|
|
63
|
+
export declare function ValueField(props: FieldProps & {
|
|
64
|
+
/** Hints a numeric keypad without narrowing what the control accepts. */
|
|
65
|
+
numeric?: boolean;
|
|
66
|
+
/** Placeholder shown while the draft is empty. */
|
|
67
|
+
placeholder?: string;
|
|
68
|
+
}): import("react").JSX.Element;
|
|
69
|
+
/** A staged boolean field: 继承 / 开 / 关. */
|
|
70
|
+
export declare function BooleanField(props: FieldProps & {
|
|
71
|
+
/** Copy for the inherit option. */
|
|
72
|
+
inheritLabel: string;
|
|
73
|
+
/** Copy for the on option. */
|
|
74
|
+
onLabel: string;
|
|
75
|
+
/** Copy for the off option. */
|
|
76
|
+
offLabel: string;
|
|
77
|
+
}): import("react").JSX.Element;
|
|
78
|
+
//# sourceMappingURL=PluginSettingsCard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PluginSettingsCard.d.ts","sourceRoot":"","sources":["../../../src/client/PluginSettingsCard.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAY,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAChD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;AACnD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAGnD,wDAAwD;AACxD,MAAM,WAAW,uBAAuB;IACtC,0CAA0C;IAC1C,CAAC,EAAE,CAAC,GAAG,EAAE,eAAe,KAAK,MAAM,CAAA;IACnC,uCAAuC;IACvC,QAAQ,EAAE,eAAe,CAAA;IACzB,4EAA4E;IAC5E,cAAc,EAAE,eAAe,CAAA;IAC/B,kFAAkF;IAClF,KAAK,EAAE,SAAS,CAAA;IAChB,+BAA+B;IAC/B,MAAM,EAAE,MAAM,IAAI,CAAA;IAClB,8BAA8B;IAC9B,SAAS,EAAE,MAAM,IAAI,CAAA;IACrB,6BAA6B;IAC7B,QAAQ,EAAE,SAAS,CAAA;CACpB;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,uBAAuB,sCAmDhE;AAED,oEAAoE;AACpE,MAAM,WAAW,UAAU;IACzB,wDAAwD;IACxD,EAAE,EAAE,MAAM,CAAA;IACV,qBAAqB;IACrB,KAAK,EAAE,MAAM,CAAA;IACb,uDAAuD;IACvD,IAAI,EAAE,MAAM,CAAA;IACZ,uCAAuC;IACvC,IAAI,EAAE,MAAM,CAAA;IACZ,sEAAsE;IACtE,UAAU,EAAE,OAAO,CAAA;IACnB,6DAA6D;IAC7D,OAAO,EAAE,OAAO,CAAA;IAChB,qCAAqC;IACrC,eAAe,EAAE,MAAM,CAAA;IACvB,kCAAkC;IAClC,UAAU,EAAE,MAAM,CAAA;IAClB,kEAAkE;IAClE,YAAY,EAAE,MAAM,CAAA;IACpB,gFAAgF;IAChF,QAAQ,EAAE,OAAO,CAAA;IACjB,wBAAwB;IACxB,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IAC9B,oEAAoE;IACpE,OAAO,EAAE,MAAM,IAAI,CAAA;CACpB;AAED,kHAAkH;AAClH,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG;IAC7C,yEAAyE;IACzE,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,kDAAkD;IAClD,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,+BAqCA;AAED,0CAA0C;AAC1C,wBAAgB,YAAY,CAAC,KAAK,EAAE,UAAU,GAAG;IAC/C,mCAAmC;IACnC,YAAY,EAAE,MAAM,CAAA;IACpB,8BAA8B;IAC9B,OAAO,EAAE,MAAM,CAAA;IACf,+BAA+B;IAC/B,QAAQ,EAAE,MAAM,CAAA;CACjB,+BAmCA"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whale-girl companion component — the browser half's centerpiece. Renders a
|
|
3
|
+
* fixed-position floating sprite (React portal onto document.body), plays
|
|
4
|
+
* the spritesheet track matching the host animation snapshot, and exposes
|
|
5
|
+
* the interaction surface: click to pet, hover panel with feed/hide, drag to
|
|
6
|
+
* reposition (persisted via setConfig).
|
|
7
|
+
* @module @linxin666/dsh-pet/client/WhalePet
|
|
8
|
+
*/
|
|
9
|
+
import type { ReactPortal } from 'react';
|
|
10
|
+
import type { TranslateNS } from '@deepseek-ai/dsh-client-ui-slots';
|
|
11
|
+
import type { PetDisplayConfig } from '../persist.ts';
|
|
12
|
+
import type { PetStateView } from '../service.ts';
|
|
13
|
+
import type { PetFeedback } from './pet-store.ts';
|
|
14
|
+
import { NS } from './locales.ts';
|
|
15
|
+
/** Browser URL of the whale-girl atlas (served by the host half's own route). */
|
|
16
|
+
export declare const PET_SPRITESHEET_URL = "/pet/whale/spritesheet.webp";
|
|
17
|
+
/** Browser URL of the whale-girl manifest (authoritative per-row frame counts). */
|
|
18
|
+
export declare const PET_MANIFEST_URL = "/pet/whale/pet.json";
|
|
19
|
+
/** Props injected by the slot registration (store actions + locale). */
|
|
20
|
+
export interface WhalePetProps {
|
|
21
|
+
/** Latest host snapshot; null while loading. */
|
|
22
|
+
snapshot: PetStateView | null;
|
|
23
|
+
/** Display configuration (persisted by the host). */
|
|
24
|
+
display: PetDisplayConfig;
|
|
25
|
+
/** Active reaction bubble, if any. */
|
|
26
|
+
feedback: PetFeedback | null;
|
|
27
|
+
/** Pet the whale girl (click). */
|
|
28
|
+
onPet: () => void;
|
|
29
|
+
/** Feed the whale girl (panel button). */
|
|
30
|
+
onFeed: () => void;
|
|
31
|
+
/** Hide the whale girl (panel button). */
|
|
32
|
+
onHide: () => void;
|
|
33
|
+
/** Persist a drag position. */
|
|
34
|
+
onDragEnd: (right: number, bottom: number) => void;
|
|
35
|
+
/** Rename the pet (persisted by the host). */
|
|
36
|
+
onRename: (name: string) => void;
|
|
37
|
+
/** Clear the reaction bubble (after its CSS animation). */
|
|
38
|
+
onFeedbackDone: () => void;
|
|
39
|
+
/** Locale translate seat (namespace-bound). */
|
|
40
|
+
t: TranslateNS<typeof NS>;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* The floating pet. The spritesheet frame advances on requestAnimationFrame
|
|
44
|
+
* with per-frame durations from TRACKS; the atlas image is loaded once and
|
|
45
|
+
* the background position is written straight to the sprite element (no
|
|
46
|
+
* per-frame React state).
|
|
47
|
+
*/
|
|
48
|
+
export declare function WhalePet(props: WhalePetProps): ReactPortal;
|
|
49
|
+
//# sourceMappingURL=WhalePet.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WhalePet.d.ts","sourceRoot":"","sources":["../../../src/client/WhalePet.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAqC,WAAW,EAAE,MAAM,OAAO,CAAA;AAE3E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAA;AACnE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AACrD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AACjD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAGjD,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAA;AAGjC,iFAAiF;AACjF,eAAO,MAAM,mBAAmB,gCAAgC,CAAA;AAEhE,mFAAmF;AACnF,eAAO,MAAM,gBAAgB,wBAAwB,CAAA;AAErD,wEAAwE;AACxE,MAAM,WAAW,aAAa;IAC5B,gDAAgD;IAChD,QAAQ,EAAE,YAAY,GAAG,IAAI,CAAA;IAC7B,qDAAqD;IACrD,OAAO,EAAE,gBAAgB,CAAA;IACzB,sCAAsC;IACtC,QAAQ,EAAE,WAAW,GAAG,IAAI,CAAA;IAC5B,kCAAkC;IAClC,KAAK,EAAE,MAAM,IAAI,CAAA;IACjB,0CAA0C;IAC1C,MAAM,EAAE,MAAM,IAAI,CAAA;IAClB,0CAA0C;IAC1C,MAAM,EAAE,MAAM,IAAI,CAAA;IAClB,+BAA+B;IAC/B,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAA;IAClD,8CAA8C;IAC9C,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IAChC,2DAA2D;IAC3D,cAAc,EAAE,MAAM,IAAI,CAAA;IAC1B,+CAA+C;IAC/C,CAAC,EAAE,WAAW,CAAC,OAAO,EAAE,CAAC,CAAA;CAC1B;AAOD;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,aAAa,GAAG,WAAW,CAuR1D"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dsh-pet browser half — registers the whale-girl into the conversation
|
|
3
|
+
* input selector row (the same every-phase row the git branch chip uses) and
|
|
4
|
+
* drives it from the host's same-origin `/api/pet/*` JSON endpoints: poll the
|
|
5
|
+
* host snapshot (~800 ms), forward interactions, persist drag positions. The
|
|
6
|
+
* row anchor mounts the floating pet via portal; when the pet is hidden the
|
|
7
|
+
* anchor becomes the summon button. Anchoring in the selector row (rather
|
|
8
|
+
* than the session-only composer dock band) keeps the pet floating on the
|
|
9
|
+
* new-conversation screen too, where no session exists to scope a slot by.
|
|
10
|
+
* @module @linxin666/dsh-pet/client
|
|
11
|
+
*/
|
|
12
|
+
import type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client';
|
|
13
|
+
/** Required services. */
|
|
14
|
+
export declare const inject: string[];
|
|
15
|
+
/** Re-exported for consumers that type against the injected face. */
|
|
16
|
+
export type { PetInjected, PetDockEntryProps } from './PetDockEntry.tsx';
|
|
17
|
+
export type { PetUiState, PetFeedback } from './pet-store.ts';
|
|
18
|
+
export type { PetSettingsCardFace, PetSettingsCardState } from './PetSettingsCard.tsx';
|
|
19
|
+
declare module '@deepseek-ai/dsh-client-ui-slots' {
|
|
20
|
+
interface SlotMap {
|
|
21
|
+
/**
|
|
22
|
+
* The child slot the Web UI plugin group declares; this card registers
|
|
23
|
+
* into the group instead of the top-level `settings.plugin.item` list.
|
|
24
|
+
* Spelled here with the same shape so this package can register without
|
|
25
|
+
* depending on the sibling UI package.
|
|
26
|
+
*/
|
|
27
|
+
'web-ui.plugin.item': {
|
|
28
|
+
kind: 'list';
|
|
29
|
+
scope: 'root';
|
|
30
|
+
owner: SettingsPluginItemOwnerProps;
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/** Owner share of a plugin card (the group card supplies nothing). */
|
|
35
|
+
export interface SettingsPluginItemOwnerProps {
|
|
36
|
+
/** Marker field: card owner props are intentionally empty. */
|
|
37
|
+
children?: never;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Client plugin body: register dictionaries, mount the dock entry and poll
|
|
41
|
+
* loop while the plugin is enabled, and seat the settings card in the Web UI
|
|
42
|
+
* plugin group.
|
|
43
|
+
* @param ctx - client root context.
|
|
44
|
+
*/
|
|
45
|
+
export declare function apply(ctx: ClientContext): void;
|
|
46
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wCAAwC,CAAA;AAsD3E,yBAAyB;AACzB,eAAO,MAAM,MAAM,UAA+D,CAAA;AAElF,qEAAqE;AACrE,YAAY,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AACxE,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAC7D,YAAY,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAA;AAEtF,OAAO,QAAQ,kCAAkC,CAAC;IAChD,UAAU,OAAO;QACf;;;;;WAKG;QACH,oBAAoB,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,4BAA4B,CAAA;SAAE,CAAA;KAC3F;CACF;AAED,sEAAsE;AACtE,MAAM,WAAW,4BAA4B;IAC3C,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,KAAK,CAAA;CACjB;AAED;;;;;GAKG;AACH,wBAAgB,KAAK,CAAC,GAAG,EAAE,aAAa,GAAG,IAAI,CAkK9C"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dsh-pet locale dictionaries (zh/en).
|
|
3
|
+
* @module @linxin666/dsh-pet/client/locales
|
|
4
|
+
*/
|
|
5
|
+
/** Dictionary namespace this package registers. */
|
|
6
|
+
export declare const NS = "pet";
|
|
7
|
+
/** Chinese copy. */
|
|
8
|
+
export declare const zh: {
|
|
9
|
+
readonly 'pet.feed': "喂食";
|
|
10
|
+
readonly 'pet.hide': "隐藏";
|
|
11
|
+
readonly 'pet.rename': "改名";
|
|
12
|
+
readonly 'pet.confirm': "确定";
|
|
13
|
+
readonly 'pet.namePlaceholder': "输入新名字";
|
|
14
|
+
readonly 'pet.summon': "召唤{name}";
|
|
15
|
+
readonly 'pet.rank': "亲密度 {rank}";
|
|
16
|
+
readonly 'pet.points': "{points} 点";
|
|
17
|
+
readonly 'pet.treats': "小鱼干 ×{n}";
|
|
18
|
+
readonly 'pet.state.loading': "鲸鱼娘正在赶来…";
|
|
19
|
+
readonly 'pet.state.error': "鲸鱼娘迷路了(连接失败)";
|
|
20
|
+
readonly 'settings.title': "宠物";
|
|
21
|
+
readonly 'settings.description': "鲸鱼娘的显示布局与名字。";
|
|
22
|
+
readonly 'settings.enabled': "启用宠物";
|
|
23
|
+
readonly 'settings.enabledHint': "关闭后隐藏宠物并停止轮询,可在设置里重新启用。";
|
|
24
|
+
readonly 'settings.visible': "显示宠物";
|
|
25
|
+
readonly 'settings.visibleHint': "关闭后宠物隐藏,可从聊天输入区重新召唤。";
|
|
26
|
+
readonly 'settings.size': "大小(px)";
|
|
27
|
+
readonly 'settings.sizeHint': "精灵单元高度,范围 32–512。";
|
|
28
|
+
readonly 'settings.right': "距右侧(px)";
|
|
29
|
+
readonly 'settings.rightHint': "距视口右边缘的水平内缩距离。";
|
|
30
|
+
readonly 'settings.bottom': "距底部(px)";
|
|
31
|
+
readonly 'settings.bottomHint': "距视口底边的垂直内缩距离。";
|
|
32
|
+
readonly 'settings.name': "名字";
|
|
33
|
+
readonly 'settings.nameHint': "宠物显示名,1–20 个字符。";
|
|
34
|
+
readonly 'settings.inherit': "继承";
|
|
35
|
+
readonly 'settings.on': "开";
|
|
36
|
+
readonly 'settings.off': "关";
|
|
37
|
+
readonly 'settings.overridden': "已覆盖";
|
|
38
|
+
readonly 'settings.reset': "恢复默认";
|
|
39
|
+
readonly 'settings.readOnly': "当前部署的设置只读。";
|
|
40
|
+
readonly 'settings.expand': "展开设置";
|
|
41
|
+
readonly 'settings.collapse': "收起设置";
|
|
42
|
+
readonly 'settings.save': "保存";
|
|
43
|
+
readonly 'settings.saving': "保存中…";
|
|
44
|
+
readonly 'settings.discard': "放弃";
|
|
45
|
+
readonly 'settings.unsaved': "未保存";
|
|
46
|
+
readonly 'settings.saveFailed': "部署未接受这些值,已保留供你修改。";
|
|
47
|
+
readonly 'settings.invalidNumber': "请输入数字,留空则使用默认值。";
|
|
48
|
+
};
|
|
49
|
+
/** English copy. */
|
|
50
|
+
export declare const en: {
|
|
51
|
+
readonly 'pet.feed': "Feed";
|
|
52
|
+
readonly 'pet.hide': "Hide";
|
|
53
|
+
readonly 'pet.rename': "Rename";
|
|
54
|
+
readonly 'pet.confirm': "OK";
|
|
55
|
+
readonly 'pet.namePlaceholder': "Enter a new name";
|
|
56
|
+
readonly 'pet.summon': "Summon {name}";
|
|
57
|
+
readonly 'pet.rank': "Affinity {rank}";
|
|
58
|
+
readonly 'pet.points': "{points} pts";
|
|
59
|
+
readonly 'pet.treats': "Treats ×{n}";
|
|
60
|
+
readonly 'pet.state.loading': "The whale girl is on her way…";
|
|
61
|
+
readonly 'pet.state.error': "The whale girl is lost (connection failed)";
|
|
62
|
+
readonly 'settings.title': "Pet";
|
|
63
|
+
readonly 'settings.description': "The whale girl’s display layout and name.";
|
|
64
|
+
readonly 'settings.enabled': "Enable the pet";
|
|
65
|
+
readonly 'settings.enabledHint': "When off, the pet hides and polling stops; re-enable it here.";
|
|
66
|
+
readonly 'settings.visible': "Show the pet";
|
|
67
|
+
readonly 'settings.visibleHint': "When off, the pet hides; summon it again from the input row.";
|
|
68
|
+
readonly 'settings.size': "Size (px)";
|
|
69
|
+
readonly 'settings.sizeHint': "Sprite cell height, 32–512.";
|
|
70
|
+
readonly 'settings.right': "Right inset (px)";
|
|
71
|
+
readonly 'settings.rightHint': "Horizontal inset from the viewport right edge.";
|
|
72
|
+
readonly 'settings.bottom': "Bottom inset (px)";
|
|
73
|
+
readonly 'settings.bottomHint': "Vertical inset from the viewport bottom edge.";
|
|
74
|
+
readonly 'settings.name': "Name";
|
|
75
|
+
readonly 'settings.nameHint': "The pet’s display name, 1–20 characters.";
|
|
76
|
+
readonly 'settings.inherit': "Inherit";
|
|
77
|
+
readonly 'settings.on': "On";
|
|
78
|
+
readonly 'settings.off': "Off";
|
|
79
|
+
readonly 'settings.overridden': "Overridden";
|
|
80
|
+
readonly 'settings.reset': "Reset to default";
|
|
81
|
+
readonly 'settings.readOnly': "This deployment stores settings read-only.";
|
|
82
|
+
readonly 'settings.expand': "Show settings";
|
|
83
|
+
readonly 'settings.collapse': "Hide settings";
|
|
84
|
+
readonly 'settings.save': "Save";
|
|
85
|
+
readonly 'settings.saving': "Saving…";
|
|
86
|
+
readonly 'settings.discard': "Discard";
|
|
87
|
+
readonly 'settings.unsaved': "Unsaved";
|
|
88
|
+
readonly 'settings.saveFailed': "The deployment did not accept these values; they were left for you to correct.";
|
|
89
|
+
readonly 'settings.invalidNumber': "Enter a number, or leave blank to use the default.";
|
|
90
|
+
};
|
|
91
|
+
/** Key union for this namespace. */
|
|
92
|
+
export type PetKey = keyof typeof zh;
|
|
93
|
+
/** The settings-card slice of the pet dictionary. */
|
|
94
|
+
export type SettingsCardKey = PetKey;
|
|
95
|
+
declare module '@deepseek-ai/dsh-client-ui-slots' {
|
|
96
|
+
interface LocaleNamespaceMap {
|
|
97
|
+
/** dsh-pet UI copy. */
|
|
98
|
+
pet: PetKey;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=locales.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"locales.d.ts","sourceRoot":"","sources":["../../../src/client/locales.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,mDAAmD;AACnD,eAAO,MAAM,EAAE,QAAQ,CAAA;AAEvB,oBAAoB;AACpB,eAAO,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyCL,CAAA;AAEV,oBAAoB;AACpB,eAAO,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyCL,CAAA;AAEV,oCAAoC;AACpC,MAAM,MAAM,MAAM,GAAG,MAAM,OAAO,EAAE,CAAA;AAEpC,qDAAqD;AACrD,MAAM,MAAM,eAAe,GAAG,MAAM,CAAA;AAEpC,OAAO,QAAQ,kCAAkC,CAAC;IAChD,UAAU,kBAAkB;QAC1B,uBAAuB;QACvB,GAAG,EAAE,MAAM,CAAA;KACZ;CACF"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser-side pet store: the pet state snapshot plus transient UI feedback
|
|
3
|
+
* (reaction bubbles), written only through the store's audit actions. The
|
|
4
|
+
* RPC polling and interactions live in the plugin apply body; components
|
|
5
|
+
* only ever read snapshots.
|
|
6
|
+
* @module @linxin666/dsh-pet/client/pet-store
|
|
7
|
+
*/
|
|
8
|
+
import type { EngineStoreHandle, EngineStoreInstance } from '@deepseek-ai/dsh-client-runtime/client';
|
|
9
|
+
import type { PetStateView } from '../service.ts';
|
|
10
|
+
import type { PetInteraction } from '../affinity.ts';
|
|
11
|
+
/** One transient reaction bubble on the pet. */
|
|
12
|
+
export interface PetFeedback {
|
|
13
|
+
/** Bubble copy. */
|
|
14
|
+
text: string;
|
|
15
|
+
/** Interaction kind driving the reaction animation. */
|
|
16
|
+
kind: PetInteraction | 'none';
|
|
17
|
+
/** Epoch ms when the bubble appeared (for expiry). */
|
|
18
|
+
at: number;
|
|
19
|
+
}
|
|
20
|
+
/** Pet UI state as consumers see it. */
|
|
21
|
+
export interface PetUiState {
|
|
22
|
+
/** Latest host snapshot; null before the first successful fetch. */
|
|
23
|
+
snapshot: PetStateView | null;
|
|
24
|
+
/** Fetch lifecycle. */
|
|
25
|
+
state: 'loading' | 'ready' | 'error';
|
|
26
|
+
/** Transport error message (for the debug surface), when any. */
|
|
27
|
+
error: string | null;
|
|
28
|
+
/** Active reaction bubble, if any. */
|
|
29
|
+
feedback: PetFeedback | null;
|
|
30
|
+
}
|
|
31
|
+
/** Store write set. */
|
|
32
|
+
export type PetUiActions = {
|
|
33
|
+
/** Replace the host snapshot (poll result). */
|
|
34
|
+
setSnapshot: (draft: PetUiState, snapshot: PetStateView) => void;
|
|
35
|
+
/** Mark the fetch lifecycle. */
|
|
36
|
+
setState: (draft: PetUiState, state: PetUiState['state'], error: string | null) => void;
|
|
37
|
+
/** Show a reaction bubble. */
|
|
38
|
+
setFeedback: (draft: PetUiState, feedback: PetFeedback | null) => void;
|
|
39
|
+
};
|
|
40
|
+
/** Create the pet store handle (apply world only; never module-level). */
|
|
41
|
+
export declare function createPetStore(): EngineStoreHandle<PetUiState, PetUiActions>;
|
|
42
|
+
export type { PetInteraction };
|
|
43
|
+
/**
|
|
44
|
+
* A live pet store instance (one per host, owned by the plugin apply body —
|
|
45
|
+
* the pet itself is host-global, so its UI state must not ride the slot
|
|
46
|
+
* system's per-session store scoping).
|
|
47
|
+
*/
|
|
48
|
+
export type PetStoreInstance = EngineStoreInstance<PetUiState, PetUiActions>;
|
|
49
|
+
//# sourceMappingURL=pet-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pet-store.d.ts","sourceRoot":"","sources":["../../../src/client/pet-store.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,wCAAwC,CAAA;AACpG,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AACjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAEpD,gDAAgD;AAChD,MAAM,WAAW,WAAW;IAC1B,mBAAmB;IACnB,IAAI,EAAE,MAAM,CAAA;IACZ,uDAAuD;IACvD,IAAI,EAAE,cAAc,GAAG,MAAM,CAAA;IAC7B,sDAAsD;IACtD,EAAE,EAAE,MAAM,CAAA;CACX;AAED,wCAAwC;AACxC,MAAM,WAAW,UAAU;IACzB,oEAAoE;IACpE,QAAQ,EAAE,YAAY,GAAG,IAAI,CAAA;IAC7B,uBAAuB;IACvB,KAAK,EAAE,SAAS,GAAG,OAAO,GAAG,OAAO,CAAA;IACpC,iEAAiE;IACjE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,sCAAsC;IACtC,QAAQ,EAAE,WAAW,GAAG,IAAI,CAAA;CAC7B;AAED,uBAAuB;AACvB,MAAM,MAAM,YAAY,GAAG;IACzB,+CAA+C;IAC/C,WAAW,EAAE,CAAC,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,YAAY,KAAK,IAAI,CAAA;IAChE,gCAAgC;IAChC,QAAQ,EAAE,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAA;IACvF,8BAA8B;IAC9B,WAAW,EAAE,CAAC,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,WAAW,GAAG,IAAI,KAAK,IAAI,CAAA;CACvE,CAAA;AAED,0EAA0E;AAC1E,wBAAgB,cAAc,IAAI,iBAAiB,CAAC,UAAU,EAAE,YAAY,CAAC,CAuB5E;AAED,YAAY,EAAE,cAAc,EAAE,CAAA;AAE9B;;;;GAIG;AACH,MAAM,MAAM,gBAAgB,GAAG,mBAAmB,CAAC,UAAU,EAAE,YAAY,CAAC,CAAA"}
|