@linxin666/dsh-pet 0.1.14 → 0.1.16
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 +73 -38
- package/README.zh.md +91 -55
- package/assets/whale/pet.json +12 -1
- package/cordis.patch.yml +4 -4
- package/lib/client.js +296 -347
- package/lib/client.js.map +1 -1
- package/lib/index.js +975 -317
- package/lib/invariant.js +1 -1
- package/lib/{state-P-wsVJ6O.js → state-CFyJv0sQ.js} +15 -1
- package/lib/types/affinity.d.ts +15 -0
- package/lib/types/affinity.d.ts.map +1 -1
- package/lib/types/affinity.js +14 -0
- package/lib/types/client/PetDockEntry.d.ts +14 -12
- package/lib/types/client/PetDockEntry.d.ts.map +1 -1
- package/lib/types/client/PetDockEntry.js +13 -8
- package/lib/types/client/PetSettingsCard.d.ts +22 -9
- package/lib/types/client/PetSettingsCard.d.ts.map +1 -1
- package/lib/types/client/PetSettingsCard.js +42 -7
- package/lib/types/client/{WhalePet.d.ts → PetSprite.d.ts} +21 -20
- package/lib/types/client/PetSprite.d.ts.map +1 -0
- package/lib/types/client/{WhalePet.js → PetSprite.js} +44 -67
- package/lib/types/client/PluginSettingsCard.d.ts +26 -11
- package/lib/types/client/PluginSettingsCard.d.ts.map +1 -1
- package/lib/types/client/PluginSettingsCard.js +30 -8
- package/lib/types/client/index.d.ts +11 -8
- package/lib/types/client/index.d.ts.map +1 -1
- package/lib/types/client/index.js +32 -14
- package/lib/types/client/locales.d.ts +10 -10
- package/lib/types/client/locales.js +10 -10
- package/lib/types/client/pet-store.d.ts +5 -0
- package/lib/types/client/pet-store.d.ts.map +1 -1
- package/lib/types/client/pet-store.js +4 -0
- package/lib/types/client/settings-form.d.ts +76 -5
- package/lib/types/client/settings-form.d.ts.map +1 -1
- package/lib/types/client/settings-form.js +97 -20
- package/lib/types/client/spritesheet.d.ts +14 -48
- package/lib/types/client/spritesheet.d.ts.map +1 -1
- package/lib/types/client/spritesheet.js +13 -81
- package/lib/types/dsh-home.d.ts +17 -0
- package/lib/types/dsh-home.d.ts.map +1 -0
- package/lib/types/dsh-home.js +34 -0
- package/lib/types/event-projection.d.ts +36 -0
- package/lib/types/event-projection.d.ts.map +1 -0
- package/lib/types/event-projection.js +98 -0
- package/lib/types/index.d.ts +24 -11
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/index.js +53 -33
- package/lib/types/ledger.d.ts +79 -0
- package/lib/types/ledger.d.ts.map +1 -0
- package/lib/types/ledger.js +146 -0
- package/lib/types/persist.d.ts +15 -4
- package/lib/types/persist.d.ts.map +1 -1
- package/lib/types/persist.js +39 -8
- package/lib/types/registry.d.ts +158 -0
- package/lib/types/registry.d.ts.map +1 -0
- package/lib/types/registry.js +276 -0
- package/lib/types/routes.d.ts +10 -10
- package/lib/types/routes.d.ts.map +1 -1
- package/lib/types/routes.js +169 -51
- package/lib/types/service.d.ts +59 -57
- package/lib/types/service.d.ts.map +1 -1
- package/lib/types/service.js +111 -211
- package/package.json +2 -2
- package/src/affinity.ts +33 -0
- package/src/client/PetDockEntry.tsx +34 -26
- package/src/client/PetSettingsCard.tsx +67 -22
- package/src/client/{WhalePet.test.tsx → PetSprite.test.tsx} +56 -8
- package/src/client/{WhalePet.tsx → PetSprite.tsx} +55 -73
- package/src/client/PluginSettingsCard.tsx +90 -18
- package/src/client/index.ts +38 -16
- package/src/client/locales.ts +10 -10
- package/src/client/pet-store.ts +9 -0
- package/src/client/settings-card.module.css +9 -0
- package/src/client/settings-form.ts +153 -19
- package/src/client/spritesheet.ts +16 -92
- package/src/dsh-home.test.ts +35 -0
- package/src/dsh-home.ts +36 -0
- package/src/event-projection.ts +128 -0
- package/src/index.test.ts +23 -0
- package/src/index.ts +89 -45
- package/src/ledger.test.ts +69 -0
- package/src/ledger.ts +190 -0
- package/src/persist.test.ts +52 -3
- package/src/persist.ts +49 -11
- package/src/registry.test.ts +132 -0
- package/src/registry.ts +400 -0
- package/src/routes.ts +166 -53
- package/src/service.ts +153 -285
- package/lib/types/client/WhalePet.d.ts.map +0 -1
|
@@ -1,40 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* 5 failed, 6 waiting, 7 running, 8 review
|
|
8
|
-
*
|
|
9
|
-
* Frame counts and per-frame durations are per-track definitions below; the
|
|
10
|
-
* whale-girl atlas is produced by the hatch-pet pipeline, so calibrate
|
|
11
|
-
* `TRACKS` against the actual run (`pet_request.json` frame counts) when the
|
|
12
|
-
* asset lands. Tracks that do not loop hand off to `fallback`.
|
|
2
|
+
* Spritesheet geometry helpers — parameterized by the pet definition the
|
|
3
|
+
* host serves over '/api/pet/pets', so the browser half renders any registry
|
|
4
|
+
* entry without per-pet code. The per-track tables (frames, durations, loop,
|
|
5
|
+
* fallback) also come from the registry; these helpers only place frames,
|
|
6
|
+
* guard track lengths, and map the fixed 9-row animation contract.
|
|
13
7
|
* @module @linxin666/dsh-pet/client/spritesheet
|
|
14
8
|
*/
|
|
15
|
-
/**
|
|
16
|
-
export const FRAME_WIDTH = 192;
|
|
17
|
-
export const FRAME_HEIGHT = 208;
|
|
18
|
-
/** Columns per row (max frames per track). */
|
|
19
|
-
export const FRAME_COLUMNS = 8;
|
|
20
|
-
/**
|
|
21
|
-
* Track definitions for the whale-girl. Durations are tuned for a soft,
|
|
22
|
-
* slow-healing feel (roughly 2.5× the earlier fast draft — the pet should
|
|
23
|
-
* breathe, not race); calibrate frame counts against the hatch-pet run when
|
|
24
|
-
* the asset lands (rows may carry 4–8 frames).
|
|
25
|
-
*/
|
|
26
|
-
export const TRACKS = {
|
|
27
|
-
idle: { frames: [0, 1, 2, 3, 4, 5], durations: [400, 400, 500, 400, 400, 500], loop: true },
|
|
28
|
-
'running-right': { frames: [0, 1, 2, 3, 4, 5, 6, 7], durations: [225, 225, 225, 225, 225, 225, 225, 225], loop: true },
|
|
29
|
-
'running-left': { frames: [0, 1, 2, 3, 4, 5, 6, 7], durations: [225, 225, 225, 225, 225, 225, 225, 225], loop: true },
|
|
30
|
-
waving: { frames: [0, 1, 2, 3], durations: [350, 350, 350, 350], loop: true },
|
|
31
|
-
jumping: { frames: [0, 1, 2, 3, 4], durations: [300, 300, 300, 350, 350], loop: false, fallback: 'idle' },
|
|
32
|
-
failed: { frames: [0, 1, 2, 3, 4, 5, 6, 7], durations: [450, 450, 450, 500, 550, 600, 450, 450], loop: false, fallback: 'idle' },
|
|
33
|
-
waiting: { frames: [0, 1, 2, 3, 4, 5], durations: [450, 450, 500, 450, 450, 500], loop: true },
|
|
34
|
-
running: { frames: [0, 1, 2, 3, 4, 5], durations: [250, 250, 250, 250, 250, 250], loop: true },
|
|
35
|
-
review: { frames: [0, 1, 2, 3, 4, 5], durations: [550, 550, 550, 550, 550, 550], loop: true },
|
|
36
|
-
};
|
|
37
|
-
/** Row index of one animation track (mirrors state.ts rowOf). */
|
|
9
|
+
/** Row index of one animation track (the fixed 9-row contract). */
|
|
38
10
|
export function rowOfTrack(animation) {
|
|
39
11
|
const rows = {
|
|
40
12
|
idle: 0,
|
|
@@ -56,61 +28,21 @@ export function rowOfTrack(animation) {
|
|
|
56
28
|
* atlas coordinates here would drift each frame by the scale factor and
|
|
57
29
|
* render torn/overlapping frames.
|
|
58
30
|
*/
|
|
59
|
-
export function framePosition(row, col, scale = 1) {
|
|
60
|
-
return { x: -col *
|
|
31
|
+
export function framePosition(cell, columns, row, col, scale = 1) {
|
|
32
|
+
return { x: -col * cell.width * scale, y: -row * cell.height * scale };
|
|
61
33
|
}
|
|
62
34
|
/** Total duration of one track, ms. */
|
|
63
35
|
export function trackDuration(track) {
|
|
64
36
|
return track.durations.reduce((sum, d) => sum + d, 0);
|
|
65
37
|
}
|
|
66
38
|
/**
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
* @param image - the fully decoded spritesheet (natural size 1536×1872).
|
|
72
|
-
* @returns per-row frame counts, length 9.
|
|
73
|
-
*/
|
|
74
|
-
export function detectFrameCounts(image) {
|
|
75
|
-
const canvas = document.createElement('canvas');
|
|
76
|
-
canvas.width = image.naturalWidth;
|
|
77
|
-
canvas.height = image.naturalHeight;
|
|
78
|
-
const ctx = canvas.getContext('2d');
|
|
79
|
-
if (ctx === null)
|
|
80
|
-
return Array.from({ length: 9 }, () => FRAME_COLUMNS);
|
|
81
|
-
ctx.drawImage(image, 0, 0);
|
|
82
|
-
const data = ctx.getImageData(0, 0, canvas.width, canvas.height).data;
|
|
83
|
-
const counts = [];
|
|
84
|
-
const stride = FRAME_COLUMNS * FRAME_WIDTH;
|
|
85
|
-
const probeStep = 8;
|
|
86
|
-
const margin = 12;
|
|
87
|
-
for (let row = 0; row < 9; row++) {
|
|
88
|
-
let count = 0;
|
|
89
|
-
for (let col = 0; col < FRAME_COLUMNS; col++) {
|
|
90
|
-
let hasContent = false;
|
|
91
|
-
const x0 = col * FRAME_WIDTH;
|
|
92
|
-
const y0 = row * FRAME_HEIGHT;
|
|
93
|
-
for (let y = y0 + margin; y < y0 + FRAME_HEIGHT - margin && !hasContent; y += probeStep) {
|
|
94
|
-
for (let x = x0 + margin; x < x0 + FRAME_WIDTH - margin && !hasContent; x += probeStep) {
|
|
95
|
-
const idx = (y * stride + x) * 4;
|
|
96
|
-
if ((data[idx + 3] ?? 0) > 8)
|
|
97
|
-
hasContent = true;
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
if (hasContent)
|
|
101
|
-
count += 1;
|
|
102
|
-
}
|
|
103
|
-
counts.push(count);
|
|
104
|
-
}
|
|
105
|
-
return counts;
|
|
106
|
-
}
|
|
107
|
-
/**
|
|
108
|
-
* Trim a track to the actual frame count of its row. A row with 0 detected
|
|
109
|
-
* frames degrades to the first frame (the atlas is still loading or corrupt)
|
|
110
|
-
* so the pet never renders blank.
|
|
39
|
+
* Trim a track to the actual frame count of its row (the manifest's per-row
|
|
40
|
+
* counts are authoritative; this is a last-line guard against a definition
|
|
41
|
+
* whose row count disagrees with its track table). A row with 0 detected
|
|
42
|
+
* frames degrades to the first frame so the pet never renders blank.
|
|
111
43
|
*/
|
|
112
44
|
export function trimTrack(track, frameCount) {
|
|
113
|
-
const n = Math.max(1, Math.min(frameCount, track.frames.length));
|
|
45
|
+
const n = Math.max(1, Math.min(frameCount, track.frames.length, track.durations.length));
|
|
114
46
|
return {
|
|
115
47
|
frames: track.frames.slice(0, n),
|
|
116
48
|
durations: track.durations.slice(0, n),
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DSH_HOME resolution shared by the plugin family's Host halves: the
|
|
3
|
+
* environment override wins, the platform home fallback follows. Mirrors
|
|
4
|
+
* what dsh-pet and dsh-liangshen each used to implement locally.
|
|
5
|
+
*/
|
|
6
|
+
/** Expand a leading ~ (or ~user) in a path, platform-style. */
|
|
7
|
+
export declare function expandHome(path: string, home?: string): string;
|
|
8
|
+
/**
|
|
9
|
+
* Resolve the DSH home directory.
|
|
10
|
+
* @param env - process environment to read DSH_HOME from.
|
|
11
|
+
* @param home - platform home directory fallback (test seam).
|
|
12
|
+
* @returns the absolute DSH home path.
|
|
13
|
+
*/
|
|
14
|
+
export declare function resolveDshHome(env?: NodeJS.ProcessEnv, home?: string): string;
|
|
15
|
+
/** Resolve the DSH home directory from the live environment. */
|
|
16
|
+
export declare function dshHome(): string;
|
|
17
|
+
//# sourceMappingURL=dsh-home.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dsh-home.d.ts","sourceRoot":"","sources":["../../src/dsh-home.ts"],"names":[],"mappings":"AACA;;;;GAIG;AAKH,+DAA+D;AAC/D,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,MAAkB,GAAG,MAAM,CAIzE;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,EAAE,IAAI,GAAE,MAAkB,GAAG,MAAM,CAOrG;AAED,gEAAgE;AAChE,wBAAgB,OAAO,IAAI,MAAM,CAEhC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// Generated by scripts/sync-shared.mjs from shared/host/dsh-home.ts. Do not edit this copy; edit the shared source and run "node scripts/sync-shared.mjs".
|
|
2
|
+
/**
|
|
3
|
+
* DSH_HOME resolution shared by the plugin family's Host halves: the
|
|
4
|
+
* environment override wins, the platform home fallback follows. Mirrors
|
|
5
|
+
* what dsh-pet and dsh-liangshen each used to implement locally.
|
|
6
|
+
*/
|
|
7
|
+
import { homedir } from 'node:os';
|
|
8
|
+
import { isAbsolute, join } from 'node:path';
|
|
9
|
+
/** Expand a leading ~ (or ~user) in a path, platform-style. */
|
|
10
|
+
export function expandHome(path, home = homedir()) {
|
|
11
|
+
if (path === '~')
|
|
12
|
+
return home;
|
|
13
|
+
if (path.startsWith('~/') || path.startsWith('~\\'))
|
|
14
|
+
return join(home, path.slice(2));
|
|
15
|
+
return path;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Resolve the DSH home directory.
|
|
19
|
+
* @param env - process environment to read DSH_HOME from.
|
|
20
|
+
* @param home - platform home directory fallback (test seam).
|
|
21
|
+
* @returns the absolute DSH home path.
|
|
22
|
+
*/
|
|
23
|
+
export function resolveDshHome(env = process.env, home = homedir()) {
|
|
24
|
+
const raw = env.DSH_HOME;
|
|
25
|
+
if (raw !== undefined && raw.trim() !== '') {
|
|
26
|
+
const expanded = expandHome(raw.trim(), home);
|
|
27
|
+
return isAbsolute(expanded) ? expanded : join(process.cwd(), expanded);
|
|
28
|
+
}
|
|
29
|
+
return join(home, '.dsh');
|
|
30
|
+
}
|
|
31
|
+
/** Resolve the DSH home directory from the live environment. */
|
|
32
|
+
export function dshHome() {
|
|
33
|
+
return resolveDshHome();
|
|
34
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Official session event projection — pure. Maps the durable DSH session
|
|
3
|
+
* vocabulary onto the pet's visual phases and carries an optional completed-
|
|
4
|
+
* turn reward for the ledger. Holds no state of its own; callers keep a
|
|
5
|
+
* {@link ProjectionRuntime} per session and feed events in arrival order.
|
|
6
|
+
* @module @linxin666/dsh-pet/event-projection
|
|
7
|
+
*/
|
|
8
|
+
import type { SessionEvent } from '@deepseek-ai/dsh-session';
|
|
9
|
+
import type { PetStateInput } from './state.ts';
|
|
10
|
+
/** Runtime shape of the optional legacy activity event. */
|
|
11
|
+
export interface ActivityStatusEventLike {
|
|
12
|
+
phase?: string;
|
|
13
|
+
line?: string;
|
|
14
|
+
phrase?: string;
|
|
15
|
+
}
|
|
16
|
+
/** Per-session facts needed to project the official event stream. */
|
|
17
|
+
export interface ProjectionRuntime {
|
|
18
|
+
activeTools: Set<string>;
|
|
19
|
+
officialEventsSeen: boolean;
|
|
20
|
+
stepHadFailure: boolean;
|
|
21
|
+
}
|
|
22
|
+
/** One official event projection, optionally carrying a completed turn reward. */
|
|
23
|
+
export interface PetActivityTransition {
|
|
24
|
+
input: PetStateInput;
|
|
25
|
+
completedTurn?: number;
|
|
26
|
+
}
|
|
27
|
+
/** Fresh projection runtime for a newly seen session. */
|
|
28
|
+
export declare function emptyProjectionRuntime(): ProjectionRuntime;
|
|
29
|
+
/** Whether a legacy phase is part of the pet's supported vocabulary. */
|
|
30
|
+
export declare function isActivityPhase(phase: string): phase is PetStateInput['phase'];
|
|
31
|
+
/**
|
|
32
|
+
* Project the durable DSH session vocabulary into the pet's visual phases.
|
|
33
|
+
* Unknown and log-only events do not disturb the last meaningful activity.
|
|
34
|
+
*/
|
|
35
|
+
export declare function projectOfficialEvent(event: SessionEvent, runtime: ProjectionRuntime): PetActivityTransition | undefined;
|
|
36
|
+
//# sourceMappingURL=event-projection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-projection.d.ts","sourceRoot":"","sources":["../../src/event-projection.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAC5D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAE/C,2DAA2D;AAC3D,MAAM,WAAW,uBAAuB;IACtC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,qEAAqE;AACrE,MAAM,WAAW,iBAAiB;IAChC,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IACxB,kBAAkB,EAAE,OAAO,CAAA;IAC3B,cAAc,EAAE,OAAO,CAAA;CACxB;AAED,kFAAkF;AAClF,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,aAAa,CAAA;IACpB,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,yDAAyD;AACzD,wBAAgB,sBAAsB,IAAI,iBAAiB,CAE1D;AAQD,wEAAwE;AACxE,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,aAAa,CAAC,OAAO,CAAC,CAE9E;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,YAAY,EACnB,OAAO,EAAE,iBAAiB,GACzB,qBAAqB,GAAG,SAAS,CAyEnC"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Official session event projection — pure. Maps the durable DSH session
|
|
3
|
+
* vocabulary onto the pet's visual phases and carries an optional completed-
|
|
4
|
+
* turn reward for the ledger. Holds no state of its own; callers keep a
|
|
5
|
+
* {@link ProjectionRuntime} per session and feed events in arrival order.
|
|
6
|
+
* @module @linxin666/dsh-pet/event-projection
|
|
7
|
+
*/
|
|
8
|
+
/** Fresh projection runtime for a newly seen session. */
|
|
9
|
+
export function emptyProjectionRuntime() {
|
|
10
|
+
return { activeTools: new Set(), officialEventsSeen: false, stepHadFailure: false };
|
|
11
|
+
}
|
|
12
|
+
/** Keep tool names readable inside the compact status bubble. */
|
|
13
|
+
function displayToolName(name) {
|
|
14
|
+
const compact = name.replace(/\s+/g, ' ').trim() || '工具';
|
|
15
|
+
return compact.length <= 24 ? compact : `${compact.slice(0, 21)}...`;
|
|
16
|
+
}
|
|
17
|
+
/** Whether a legacy phase is part of the pet's supported vocabulary. */
|
|
18
|
+
export function isActivityPhase(phase) {
|
|
19
|
+
return ['idle', 'waiting', 'thinking', 'tool', 'review', 'done', 'failed'].includes(phase);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Project the durable DSH session vocabulary into the pet's visual phases.
|
|
23
|
+
* Unknown and log-only events do not disturb the last meaningful activity.
|
|
24
|
+
*/
|
|
25
|
+
export function projectOfficialEvent(event, runtime) {
|
|
26
|
+
switch (event.type) {
|
|
27
|
+
case 'turn/start':
|
|
28
|
+
runtime.activeTools.clear();
|
|
29
|
+
runtime.stepHadFailure = false;
|
|
30
|
+
return { input: { phase: 'waiting', line: '准备开始' } };
|
|
31
|
+
case 'step/start':
|
|
32
|
+
runtime.activeTools.clear();
|
|
33
|
+
runtime.stepHadFailure = false;
|
|
34
|
+
return { input: { phase: 'waiting', line: '等待模型响应' } };
|
|
35
|
+
case 'assistant/chunk': {
|
|
36
|
+
const { chunk } = event.data;
|
|
37
|
+
if (chunk.type === 'reasoning-delta' && chunk.text.length > 0) {
|
|
38
|
+
return { input: { phase: 'thinking', line: '正在思考' } };
|
|
39
|
+
}
|
|
40
|
+
if (chunk.type === 'text-delta' && chunk.text.length > 0) {
|
|
41
|
+
return { input: { phase: 'review', line: '整理回复中' } };
|
|
42
|
+
}
|
|
43
|
+
return undefined;
|
|
44
|
+
}
|
|
45
|
+
case 'assistant/message':
|
|
46
|
+
return { input: { phase: 'review', line: '整理回复中' } };
|
|
47
|
+
case 'tool/call':
|
|
48
|
+
runtime.activeTools.add(String(event.data.callId));
|
|
49
|
+
return {
|
|
50
|
+
input: {
|
|
51
|
+
phase: 'tool',
|
|
52
|
+
line: `正在使用 ${displayToolName(event.data.name)}`,
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
case 'tool/result': {
|
|
56
|
+
const block = event.data.message.content[0];
|
|
57
|
+
runtime.activeTools.delete(String(event.data.message.source.callId));
|
|
58
|
+
runtime.stepHadFailure ||= event.data.error !== undefined || block.isError === true;
|
|
59
|
+
if (runtime.activeTools.size > 0) {
|
|
60
|
+
return {
|
|
61
|
+
input: {
|
|
62
|
+
phase: 'tool',
|
|
63
|
+
line: `还有 ${runtime.activeTools.size} 个工具运行中`,
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
return runtime.stepHadFailure
|
|
68
|
+
? { input: { phase: 'failed', line: '工具执行失败' } }
|
|
69
|
+
: { input: { phase: 'thinking', line: '处理工具结果' } };
|
|
70
|
+
}
|
|
71
|
+
case 'turn/end': {
|
|
72
|
+
runtime.activeTools.clear();
|
|
73
|
+
switch (event.data.reason.kind) {
|
|
74
|
+
case 'completed':
|
|
75
|
+
return {
|
|
76
|
+
input: { phase: 'done', line: '完成啦' },
|
|
77
|
+
completedTurn: event.data.turn,
|
|
78
|
+
};
|
|
79
|
+
case 'error':
|
|
80
|
+
return { input: { phase: 'failed', line: '执行失败' } };
|
|
81
|
+
case 'max-tokens':
|
|
82
|
+
return { input: { phase: 'failed', line: '达到输出上限' } };
|
|
83
|
+
case 'interrupted':
|
|
84
|
+
return { input: { phase: 'failed', line: '执行意外中断' } };
|
|
85
|
+
case 'blocked':
|
|
86
|
+
return { input: { phase: 'waiting', line: '等待继续' } };
|
|
87
|
+
case 'aborted':
|
|
88
|
+
return { input: { phase: 'idle', line: '已停止' } };
|
|
89
|
+
default:
|
|
90
|
+
// TurnEndReasonMap is merge-extensible; a newer ending must not
|
|
91
|
+
// leave the pet showing stale in-progress work.
|
|
92
|
+
return { input: { phase: 'idle' } };
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
default:
|
|
96
|
+
return undefined;
|
|
97
|
+
}
|
|
98
|
+
}
|
package/lib/types/index.d.ts
CHANGED
|
@@ -1,43 +1,56 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* dsh-pet host half — mounts the pet service and its HTTP routes. The
|
|
3
|
-
* browser half (the
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
3
|
+
* browser half (the './client' entry) renders the selected pet and drives it
|
|
4
|
+
* through the same-origin '/api/pet/*' JSON endpoints plus the '/pet/<id>/*'
|
|
5
|
+
* media route. The host builds the multi-pet registry once at startup from
|
|
6
|
+
* the package assets, the hatch-pet custom pets directory, and composed
|
|
7
|
+
* config entries; adding a pet means dropping a manifest + atlas into one of
|
|
8
|
+
* those sources, never touching host or client code. Install via
|
|
9
|
+
* 'dsh plugin --profile web add link:<dsh-web-ui>/packages/dsh-pet'; the
|
|
10
|
+
* cordis.patch.yml inserts this plugin row.
|
|
7
11
|
* @module @linxin666/dsh-pet
|
|
8
12
|
*/
|
|
9
13
|
import { Context } from '@deepseek-ai/cordis';
|
|
10
14
|
import z from 'schemastery';
|
|
11
15
|
import { type PetConfig } from './service.ts';
|
|
12
16
|
export { PetService } from './service.ts';
|
|
13
|
-
export type { PetConfig, PetInteractResult, PetStateView, } from './service.ts';
|
|
17
|
+
export type { PetConfig, PetInteractResult, PetSettingsSection, PetStateView, } from './service.ts';
|
|
14
18
|
export { AFFINITY_MAX, AFFINITY_RANKS, applyInteraction, applyTurnReward, emptyAffinity, rankOf, } from './affinity.ts';
|
|
15
19
|
export type { AffinityConfig, AffinityState, InteractionOutcome, PetInteraction, } from './affinity.ts';
|
|
16
20
|
export { animationForPhase, PetStateMachine, rowOf, } from './state.ts';
|
|
17
21
|
export type { ActivityPhase, PetAnimation, PetStateConfig, PetStateInput, PetStateSnapshot, } from './state.ts';
|
|
18
22
|
export { consumeTreat, defaultTreatConfig, emptyTreatLedger, settleTreatGrants, } from './treats.ts';
|
|
19
23
|
export type { TreatConfig, TreatLedger, TreatSettlement } from './treats.ts';
|
|
20
|
-
export { defaultDisplayConfig, emptyPersist, loadPetPersist, petHomeDir, savePetPersist, } from './persist.ts';
|
|
24
|
+
export { DEFAULT_PET_ID, DEFAULT_PET_NAME, PET_NAME_MAX_LENGTH, defaultDisplayConfig, emptyPersist, loadPetPersist, petHomeDir, savePetPersist, } from './persist.ts';
|
|
21
25
|
export type { PetDisplayConfig, PetPersist } from './persist.ts';
|
|
22
|
-
export {
|
|
26
|
+
export { DEFAULT_FRAME_COUNTS, DEFAULT_PET_CELL, DEFAULT_PET_COLUMNS, DEFAULT_PET_ROW_COUNT, DEFAULT_TRACK_PATTERNS, PET_ROW_ORDER, codexPetsDir, loadPetRegistry, petEntryView, petPackageRoot, resolvePetManifest, } from './registry.ts';
|
|
27
|
+
export type { PetDefinition, PetEntry, PetManifest, PetRegistry, PetRegistryOptions, PetTrackDef, PetTrackOverride, } from './registry.ts';
|
|
28
|
+
export { makePetRoutes, PET_API_PREFIX, PET_ASSET_PREFIX, } from './routes.ts';
|
|
23
29
|
/** Stable cordis plugin name (matches cordis.patch.yml insert id). */
|
|
24
30
|
export declare const name = "pet";
|
|
25
31
|
/** Services required before the pet can mount its surfaces. */
|
|
26
32
|
export declare const inject: string[];
|
|
27
|
-
/**
|
|
28
|
-
|
|
33
|
+
/**
|
|
34
|
+
* Settings section schema: pet selection and display fields the web settings
|
|
35
|
+
* surface edits. petId is a plain string on purpose: the service clamps the
|
|
36
|
+
* resolved value against the registry, so a stored selection that points at
|
|
37
|
+
* a removed pet cannot invalidate the section (a strict union would refuse
|
|
38
|
+
* the whole registration). The settings card renders the actual registry
|
|
39
|
+
* choices itself from '/api/pet/pets'.
|
|
40
|
+
*/
|
|
41
|
+
export declare function makePetSettingsSchema(fallbackPetId: string): z<Schemastery.ObjectS<{
|
|
29
42
|
visible: z<boolean, boolean>;
|
|
30
43
|
size: z<number, number>;
|
|
31
44
|
right: z<number, number>;
|
|
32
45
|
bottom: z<number, number>;
|
|
33
|
-
|
|
46
|
+
petId: z<string, string>;
|
|
34
47
|
enabled: z<boolean, boolean>;
|
|
35
48
|
}>, Schemastery.ObjectT<{
|
|
36
49
|
visible: z<boolean, boolean>;
|
|
37
50
|
size: z<number, number>;
|
|
38
51
|
right: z<number, number>;
|
|
39
52
|
bottom: z<number, number>;
|
|
40
|
-
|
|
53
|
+
petId: z<string, string>;
|
|
41
54
|
enabled: z<boolean, boolean>;
|
|
42
55
|
}>>;
|
|
43
56
|
/** Register the pet service and its API + asset routes on the context. */
|
package/lib/types/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAG7C,OAAO,CAAC,MAAM,aAAa,CAAA;AAC3B,OAAO,EAAsC,KAAK,SAAS,EAA2B,MAAM,cAAc,CAAA;AAK1G,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AACzC,YAAY,EACV,SAAS,EACT,iBAAiB,EACjB,kBAAkB,EAClB,YAAY,GACb,MAAM,cAAc,CAAA;AACrB,OAAO,EACL,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,eAAe,EACf,aAAa,EACb,MAAM,GACP,MAAM,eAAe,CAAA;AACtB,YAAY,EACV,cAAc,EACd,aAAa,EACb,kBAAkB,EAClB,cAAc,GACf,MAAM,eAAe,CAAA;AACtB,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,KAAK,GACN,MAAM,YAAY,CAAA;AACnB,YAAY,EACV,aAAa,EACb,YAAY,EACZ,cAAc,EACd,aAAa,EACb,gBAAgB,GACjB,MAAM,YAAY,CAAA;AACnB,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,aAAa,CAAA;AACpB,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAC5E,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,mBAAmB,EACnB,oBAAoB,EACpB,YAAY,EACZ,cAAc,EACd,UAAU,EACV,cAAc,GACf,MAAM,cAAc,CAAA;AACrB,YAAY,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAChE,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,mBAAmB,EACnB,qBAAqB,EACrB,sBAAsB,EACtB,aAAa,EACb,YAAY,EACZ,eAAe,EACf,YAAY,EACZ,cAAc,EACd,kBAAkB,GACnB,MAAM,eAAe,CAAA;AACtB,YAAY,EACV,aAAa,EACb,QAAQ,EACR,WAAW,EACX,WAAW,EACX,kBAAkB,EAClB,WAAW,EACX,gBAAgB,GACjB,MAAM,eAAe,CAAA;AAEtB,OAAO,EACL,aAAa,EACb,cAAc,EACd,gBAAgB,GACjB,MAAM,aAAa,CAAA;AAEpB,sEAAsE;AACtE,eAAO,MAAM,IAAI,QAAQ,CAAA;AAEzB,+DAA+D;AAC/D,eAAO,MAAM,MAAM,UAAgB,CAAA;AAEnC;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,aAAa,EAAE,MAAM;;;;;;;;;;;;;;IAS1D;AAED,0EAA0E;AAC1E,wBAAgB,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,GAAE,SAAc,GAAG,IAAI,CA+DhE"}
|
package/lib/types/index.js
CHANGED
|
@@ -1,61 +1,81 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* dsh-pet host half — mounts the pet service and its HTTP routes. The
|
|
3
|
-
* browser half (the
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
3
|
+
* browser half (the './client' entry) renders the selected pet and drives it
|
|
4
|
+
* through the same-origin '/api/pet/*' JSON endpoints plus the '/pet/<id>/*'
|
|
5
|
+
* media route. The host builds the multi-pet registry once at startup from
|
|
6
|
+
* the package assets, the hatch-pet custom pets directory, and composed
|
|
7
|
+
* config entries; adding a pet means dropping a manifest + atlas into one of
|
|
8
|
+
* those sources, never touching host or client code. Install via
|
|
9
|
+
* 'dsh plugin --profile web add link:<dsh-web-ui>/packages/dsh-pet'; the
|
|
10
|
+
* cordis.patch.yml inserts this plugin row.
|
|
7
11
|
* @module @linxin666/dsh-pet
|
|
8
12
|
*/
|
|
9
13
|
import { installSettingsSection, settingsNamespace } from '@deepseek-ai/dsh-settings';
|
|
10
14
|
import z from 'schemastery';
|
|
11
15
|
import { PetService, PET_SETTINGS_NAMESPACE } from "./service.js";
|
|
12
|
-
import { makePetRoutes
|
|
13
|
-
import {
|
|
16
|
+
import { makePetRoutes } from "./routes.js";
|
|
17
|
+
import { loadPetRegistry, petPackageRoot } from "./registry.js";
|
|
18
|
+
import { DISPLAY_INSET_MAX, DISPLAY_SIZE_MAX, DISPLAY_SIZE_MIN } from "./persist.js";
|
|
14
19
|
export { PetService } from "./service.js";
|
|
15
20
|
export { AFFINITY_MAX, AFFINITY_RANKS, applyInteraction, applyTurnReward, emptyAffinity, rankOf, } from "./affinity.js";
|
|
16
21
|
export { animationForPhase, PetStateMachine, rowOf, } from "./state.js";
|
|
17
22
|
export { consumeTreat, defaultTreatConfig, emptyTreatLedger, settleTreatGrants, } from "./treats.js";
|
|
18
|
-
export { defaultDisplayConfig, emptyPersist, loadPetPersist, petHomeDir, savePetPersist, } from "./persist.js";
|
|
19
|
-
export {
|
|
23
|
+
export { DEFAULT_PET_ID, DEFAULT_PET_NAME, PET_NAME_MAX_LENGTH, defaultDisplayConfig, emptyPersist, loadPetPersist, petHomeDir, savePetPersist, } from "./persist.js";
|
|
24
|
+
export { DEFAULT_FRAME_COUNTS, DEFAULT_PET_CELL, DEFAULT_PET_COLUMNS, DEFAULT_PET_ROW_COUNT, DEFAULT_TRACK_PATTERNS, PET_ROW_ORDER, codexPetsDir, loadPetRegistry, petEntryView, petPackageRoot, resolvePetManifest, } from "./registry.js";
|
|
25
|
+
export { makePetRoutes, PET_API_PREFIX, PET_ASSET_PREFIX, } from "./routes.js";
|
|
20
26
|
/** Stable cordis plugin name (matches cordis.patch.yml insert id). */
|
|
21
27
|
export const name = 'pet';
|
|
22
28
|
/** Services required before the pet can mount its surfaces. */
|
|
23
29
|
export const inject = ['webServer'];
|
|
24
|
-
/**
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
/**
|
|
31
|
+
* Settings section schema: pet selection and display fields the web settings
|
|
32
|
+
* surface edits. petId is a plain string on purpose: the service clamps the
|
|
33
|
+
* resolved value against the registry, so a stored selection that points at
|
|
34
|
+
* a removed pet cannot invalidate the section (a strict union would refuse
|
|
35
|
+
* the whole registration). The settings card renders the actual registry
|
|
36
|
+
* choices itself from '/api/pet/pets'.
|
|
37
|
+
*/
|
|
38
|
+
export function makePetSettingsSchema(fallbackPetId) {
|
|
39
|
+
return z.object({
|
|
40
|
+
visible: z.boolean().default(true),
|
|
41
|
+
size: z.number().step(1).min(DISPLAY_SIZE_MIN).max(DISPLAY_SIZE_MAX).default(160),
|
|
42
|
+
right: z.number().step(1).min(0).max(DISPLAY_INSET_MAX).default(24),
|
|
43
|
+
bottom: z.number().step(1).min(0).max(DISPLAY_INSET_MAX).default(20),
|
|
44
|
+
petId: z.string().default(fallbackPetId),
|
|
45
|
+
enabled: z.boolean().default(true),
|
|
46
|
+
});
|
|
47
|
+
}
|
|
33
48
|
/** Register the pet service and its API + asset routes on the context. */
|
|
34
49
|
export function apply(ctx, config = {}) {
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
//
|
|
42
|
-
//
|
|
50
|
+
const registry = config.registry
|
|
51
|
+
?? loadPetRegistry({
|
|
52
|
+
packageRoot: petPackageRoot(import.meta.url),
|
|
53
|
+
...(config.pets === undefined ? {} : { extra: config.pets }),
|
|
54
|
+
});
|
|
55
|
+
const service = new PetService(ctx, { ...config, registry });
|
|
56
|
+
// The settings surface edits the pet selection + display config through
|
|
57
|
+
// the 'pet' namespace. The composition 'base' starts as the persisted
|
|
58
|
+
// pet.json values (clamped to schema bounds), so an empty user layer
|
|
59
|
+
// resolves to exactly what the pet already shows — a fresh deployment
|
|
60
|
+
// never overwrites a customized layout, and reset re-inherits it. Runtime
|
|
61
|
+
// drag interactions mirror back into the settings document through the
|
|
62
|
+
// service (see syncSettingsFromPet), keeping both views consistent.
|
|
43
63
|
let current = () => base;
|
|
44
64
|
const base = {
|
|
45
65
|
visible: service.display().visible,
|
|
46
66
|
size: service.display().size,
|
|
47
67
|
right: service.display().right,
|
|
48
68
|
bottom: service.display().bottom,
|
|
49
|
-
|
|
69
|
+
petId: service.selectedPetId(),
|
|
50
70
|
enabled: config.enabled ?? true,
|
|
51
71
|
};
|
|
52
72
|
// The browser half talks to the pet through same-origin JSON endpoints and
|
|
53
|
-
// loads
|
|
54
|
-
// platform-registered, so the pet serves its own API — the same
|
|
55
|
-
// dsh-remote-web-ui's /api/pair family). The routes are
|
|
56
|
-
// the plugin is enabled; toggling the setting off makes
|
|
57
|
-
// disappear until it is re-enabled.
|
|
58
|
-
const routes = makePetRoutes({ service
|
|
73
|
+
// loads each pet's atlas from the registry's own media route (RPC domains
|
|
74
|
+
// are platform-registered, so the pet serves its own API — the same
|
|
75
|
+
// pattern as dsh-remote-web-ui's /api/pair family). The routes are
|
|
76
|
+
// registered while the plugin is enabled; toggling the setting off makes
|
|
77
|
+
// the pet API disappear until it is re-enabled.
|
|
78
|
+
const routes = makePetRoutes({ service });
|
|
59
79
|
let disposeRoutes;
|
|
60
80
|
const syncRoutes = () => {
|
|
61
81
|
const enabled = current().enabled ?? true;
|
|
@@ -71,7 +91,7 @@ export function apply(ctx, config = {}) {
|
|
|
71
91
|
disposeRoutes = undefined;
|
|
72
92
|
}
|
|
73
93
|
};
|
|
74
|
-
installSettingsSection(ctx, settingsNamespace(PET_SETTINGS_NAMESPACE),
|
|
94
|
+
installSettingsSection(ctx, settingsNamespace(PET_SETTINGS_NAMESPACE), makePetSettingsSchema(service.selectedPetId()), base, {
|
|
75
95
|
setSource: (source) => { current = source; },
|
|
76
96
|
onChange: () => {
|
|
77
97
|
const section = current();
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pet affinity economy (ledger) — composes the pure affinity and treats
|
|
3
|
+
* modules with the cooldown/dedup bookkeeping and emits updated persistence
|
|
4
|
+
* snapshots, marking dirty so the owning facade decides when to flush. Read
|
|
5
|
+
* paths (view) no longer settle the economy; settlements happen on explicit
|
|
6
|
+
* economic events: completed-turn rewards (official or legacy) and feeds.
|
|
7
|
+
* @module @linxin666/dsh-pet/ledger
|
|
8
|
+
*/
|
|
9
|
+
import { type AffinityConfig, type PetAffinityView, type PetInteraction } from './affinity.ts';
|
|
10
|
+
import { type TreatConfig } from './treats.ts';
|
|
11
|
+
import type { PetDisplayConfig, PetPersist } from './persist.ts';
|
|
12
|
+
/** Tuning overrides for the affinity economy. */
|
|
13
|
+
export interface LedgerConfig {
|
|
14
|
+
affinity?: Partial<AffinityConfig>;
|
|
15
|
+
treats?: Partial<TreatConfig>;
|
|
16
|
+
}
|
|
17
|
+
/** Result of one ledger interaction (the shape the pet RPC returns). */
|
|
18
|
+
export interface LedgerInteractionResult {
|
|
19
|
+
/** Reaction copy bubble. */
|
|
20
|
+
reaction: string;
|
|
21
|
+
/** Points gained (0 when inside the cooldown). */
|
|
22
|
+
delta: number;
|
|
23
|
+
/** Full affinity snapshot (same shape as the state view). */
|
|
24
|
+
affinity: PetAffinityView;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Holds the current persistence snapshot and all economy bookkeeping. Every
|
|
28
|
+
* mutating call flags takeDirty so the facade persists exactly once per
|
|
29
|
+
* batch of changes; read methods (snapshot, affinityView) never write.
|
|
30
|
+
*/
|
|
31
|
+
export declare class PetLedger {
|
|
32
|
+
private readonly affinityConfig;
|
|
33
|
+
private readonly treatConfig;
|
|
34
|
+
private current;
|
|
35
|
+
/** Completed turns already rewarded, per session (turn numbers are per-session). */
|
|
36
|
+
private rewardedTurns;
|
|
37
|
+
private lastLegacyTurnRewardAt;
|
|
38
|
+
private dirty;
|
|
39
|
+
constructor(persist: PetPersist, config?: LedgerConfig);
|
|
40
|
+
/** Affinity cooldown/rank tuning (read-only). */
|
|
41
|
+
get affinity(): AffinityConfig;
|
|
42
|
+
/** The current persistence snapshot (trade a copy when mutating). */
|
|
43
|
+
get snapshot(): PetPersist;
|
|
44
|
+
/** Stock cap reported to clients. */
|
|
45
|
+
get treatMax(): number;
|
|
46
|
+
/** Consume the pending-write flag if any mutation occurred. */
|
|
47
|
+
takeDirty(): boolean;
|
|
48
|
+
/** Replace the display block (clamping stays a caller concern). */
|
|
49
|
+
setDisplay(display: PetDisplayConfig): void;
|
|
50
|
+
/** Replace the selected pet id (validation stays a caller concern). */
|
|
51
|
+
setPetId(petId: string): void;
|
|
52
|
+
/** Replace one pet's display name (validation stays a caller concern). */
|
|
53
|
+
setPetName(petId: string, name: string): void;
|
|
54
|
+
/**
|
|
55
|
+
* Settle the treat economy (work + time output since the last settlement).
|
|
56
|
+
* A zero-gain first settlement still starts the time clock (anchor write),
|
|
57
|
+
* which is how the 30-minute time output can ever accrue. Returns true when
|
|
58
|
+
* the in-memory ledger changed and should be persisted.
|
|
59
|
+
*/
|
|
60
|
+
settleTreats(nowMs: number): boolean;
|
|
61
|
+
/**
|
|
62
|
+
* Award the completed-turn reward once per session+turn (idempotent) and
|
|
63
|
+
* run the treat settlement that work output feeds. Returns true when the
|
|
64
|
+
* snapshot changed.
|
|
65
|
+
*/
|
|
66
|
+
rewardTurn(sessionId: string, turn: number, nowMs: number): boolean;
|
|
67
|
+
/** Preserve turn rewards for installations that only emit legacy activity. */
|
|
68
|
+
rewardLegacyTurn(nowMs: number): boolean;
|
|
69
|
+
private applyTurnReward;
|
|
70
|
+
/**
|
|
71
|
+
* Pet or feed the pet. Feeding settles first, then gates on the feed
|
|
72
|
+
* cooldown before spending stock — a feed inside the cooldown must not burn
|
|
73
|
+
* a treat for nothing.
|
|
74
|
+
*/
|
|
75
|
+
interact(kind: PetInteraction, nowMs: number): LedgerInteractionResult;
|
|
76
|
+
/** Current affinity view for the RPC snapshot. */
|
|
77
|
+
affinityView(nowMs: number): PetAffinityView;
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=ledger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ledger.d.ts","sourceRoot":"","sources":["../../src/ledger.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAKL,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,cAAc,EACpB,MAAM,eAAe,CAAA;AACtB,OAAO,EAIL,KAAK,WAAW,EACjB,MAAM,aAAa,CAAA;AACpB,OAAO,KAAK,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAEhE,iDAAiD;AACjD,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,CAAA;IAClC,MAAM,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,CAAA;CAC9B;AAED,wEAAwE;AACxE,MAAM,WAAW,uBAAuB;IACtC,4BAA4B;IAC5B,QAAQ,EAAE,MAAM,CAAA;IAChB,kDAAkD;IAClD,KAAK,EAAE,MAAM,CAAA;IACb,6DAA6D;IAC7D,QAAQ,EAAE,eAAe,CAAA;CAC1B;AAED;;;;GAIG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAgB;IAC/C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAa;IACzC,OAAO,CAAC,OAAO,CAAY;IAC3B,oFAAoF;IACpF,OAAO,CAAC,aAAa,CAA4B;IACjD,OAAO,CAAC,sBAAsB,CAAI;IAClC,OAAO,CAAC,KAAK,CAAQ;gBAET,OAAO,EAAE,UAAU,EAAE,MAAM,GAAE,YAAiB;IAM1D,iDAAiD;IACjD,IAAI,QAAQ,IAAI,cAAc,CAE7B;IAED,qEAAqE;IACrE,IAAI,QAAQ,IAAI,UAAU,CAEzB;IAED,qCAAqC;IACrC,IAAI,QAAQ,IAAI,MAAM,CAErB;IAED,+DAA+D;IAC/D,SAAS,IAAI,OAAO;IAMpB,mEAAmE;IACnE,UAAU,CAAC,OAAO,EAAE,gBAAgB,GAAG,IAAI;IAK3C,uEAAuE;IACvE,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAM7B,0EAA0E;IAC1E,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAK7C;;;;;OAKG;IACH,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAapC;;;;OAIG;IACH,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO;IASnE,8EAA8E;IAC9E,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IASxC,OAAO,CAAC,eAAe;IASvB;;;;OAIG;IACH,QAAQ,CAAC,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,GAAG,uBAAuB;IAyBtE,kDAAkD;IAClD,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe;CAG7C"}
|