@linxin666/dsh-pet 0.3.3 → 0.3.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.
Files changed (123) hide show
  1. package/README.i18n.yaml +2 -2
  2. package/README.md +30 -13
  3. package/README.zh.md +30 -13
  4. package/assets/ouo-neko/pet.json +31 -0
  5. package/assets/ouo-neko/previews/failed.gif +0 -0
  6. package/assets/ouo-neko/previews/idle.gif +0 -0
  7. package/assets/ouo-neko/previews/jumping.gif +0 -0
  8. package/assets/ouo-neko/previews/review.gif +0 -0
  9. package/assets/ouo-neko/previews/running-left.gif +0 -0
  10. package/assets/ouo-neko/previews/running-right.gif +0 -0
  11. package/assets/ouo-neko/previews/running.gif +0 -0
  12. package/assets/ouo-neko/previews/waiting.gif +0 -0
  13. package/assets/ouo-neko/previews/waving.gif +0 -0
  14. package/assets/ouo-neko/spritesheet.webp +0 -0
  15. package/contracts/pet-manifest-v2.schema.json +102 -1
  16. package/contracts/voice-pack-v1.schema.json +23 -28
  17. package/lib/client.js +781 -40
  18. package/lib/client.js.map +1 -1
  19. package/lib/index.js +1567 -482
  20. package/lib/types/chatter.d.ts +68 -46
  21. package/lib/types/chatter.d.ts.map +1 -1
  22. package/lib/types/chatter.js +243 -301
  23. package/lib/types/client/PetDockEntry.d.ts +3 -0
  24. package/lib/types/client/PetDockEntry.d.ts.map +1 -1
  25. package/lib/types/client/PetDockEntry.js +18 -2
  26. package/lib/types/client/PetSprite.d.ts +23 -0
  27. package/lib/types/client/PetSprite.d.ts.map +1 -1
  28. package/lib/types/client/PetSprite.js +49 -45
  29. package/lib/types/client/PluginSettingsCard.d.ts +2 -0
  30. package/lib/types/client/PluginSettingsCard.d.ts.map +1 -1
  31. package/lib/types/client/PluginSettingsCard.js +2 -2
  32. package/lib/types/client/drag-stream.d.ts +19 -0
  33. package/lib/types/client/drag-stream.d.ts.map +1 -0
  34. package/lib/types/client/drag-stream.js +26 -0
  35. package/lib/types/client/gameplay-hud.d.ts +50 -0
  36. package/lib/types/client/gameplay-hud.d.ts.map +1 -0
  37. package/lib/types/client/gameplay-hud.js +274 -0
  38. package/lib/types/client/index.d.ts.map +1 -1
  39. package/lib/types/client/index.js +38 -9
  40. package/lib/types/client/locales.d.ts +34 -0
  41. package/lib/types/client/locales.d.ts.map +1 -1
  42. package/lib/types/client/locales.js +36 -0
  43. package/lib/types/client/pet-store.d.ts +7 -1
  44. package/lib/types/client/pet-store.d.ts.map +1 -1
  45. package/lib/types/client/pet-store.js +4 -0
  46. package/lib/types/client/renderers/Frames2dVisualMount.d.ts +29 -0
  47. package/lib/types/client/renderers/Frames2dVisualMount.d.ts.map +1 -0
  48. package/lib/types/client/renderers/Frames2dVisualMount.js +83 -0
  49. package/lib/types/client/renderers/PetRendererSwitch.d.ts +6 -0
  50. package/lib/types/client/renderers/PetRendererSwitch.d.ts.map +1 -1
  51. package/lib/types/client/renderers/PetRendererSwitch.js +14 -1
  52. package/lib/types/client/renderers/frames2d.d.ts +36 -0
  53. package/lib/types/client/renderers/frames2d.d.ts.map +1 -0
  54. package/lib/types/client/renderers/frames2d.js +196 -0
  55. package/lib/types/defaults.d.ts +6 -0
  56. package/lib/types/defaults.d.ts.map +1 -0
  57. package/lib/types/defaults.js +5 -0
  58. package/lib/types/dsh-home.d.ts.map +1 -1
  59. package/lib/types/dsh-home.js +9 -3
  60. package/lib/types/event-projection.d.ts +9 -4
  61. package/lib/types/event-projection.d.ts.map +1 -1
  62. package/lib/types/event-projection.js +46 -14
  63. package/lib/types/gameplay.d.ts +182 -0
  64. package/lib/types/gameplay.d.ts.map +1 -0
  65. package/lib/types/gameplay.js +618 -0
  66. package/lib/types/ledger.d.ts +14 -0
  67. package/lib/types/ledger.d.ts.map +1 -1
  68. package/lib/types/ledger.js +30 -0
  69. package/lib/types/manifest-v2.d.ts +38 -1
  70. package/lib/types/manifest-v2.d.ts.map +1 -1
  71. package/lib/types/manifest-v2.js +182 -2
  72. package/lib/types/persist.d.ts +4 -4
  73. package/lib/types/persist.d.ts.map +1 -1
  74. package/lib/types/persist.js +41 -4
  75. package/lib/types/registry.d.ts +29 -0
  76. package/lib/types/registry.d.ts.map +1 -1
  77. package/lib/types/registry.js +170 -1
  78. package/lib/types/routes.d.ts.map +1 -1
  79. package/lib/types/routes.js +30 -3
  80. package/lib/types/service.d.ts +63 -11
  81. package/lib/types/service.d.ts.map +1 -1
  82. package/lib/types/service.js +208 -19
  83. package/lib/types/voice-pack.d.ts +6 -7
  84. package/lib/types/voice-pack.d.ts.map +1 -1
  85. package/lib/types/voice-pack.js +44 -47
  86. package/package.json +5 -2
  87. package/src/chatter.test.ts +68 -38
  88. package/src/chatter.ts +269 -316
  89. package/src/client/PetDockEntry.test.tsx +6 -0
  90. package/src/client/PetDockEntry.tsx +32 -1
  91. package/src/client/PetSprite.test.tsx +68 -21
  92. package/src/client/PetSprite.tsx +63 -45
  93. package/src/client/PluginSettingsCard.tsx +4 -2
  94. package/src/client/drag-stream.ts +35 -0
  95. package/src/client/gameplay-hud.test.tsx +338 -0
  96. package/src/client/gameplay-hud.tsx +403 -0
  97. package/src/client/index.test.tsx +10 -1
  98. package/src/client/index.ts +46 -11
  99. package/src/client/locales.ts +36 -0
  100. package/src/client/pet-store.ts +10 -1
  101. package/src/client/pet.module.css +192 -29
  102. package/src/client/renderers/Frames2dVisualMount.tsx +111 -0
  103. package/src/client/renderers/PetRendererSwitch.tsx +28 -1
  104. package/src/client/renderers/frames2d.test.ts +137 -0
  105. package/src/client/renderers/frames2d.ts +216 -0
  106. package/src/client/settings-card.module.css +5 -0
  107. package/src/defaults.ts +7 -0
  108. package/src/dsh-home.ts +9 -3
  109. package/src/event-projection.ts +57 -16
  110. package/src/gameplay.test.ts +239 -0
  111. package/src/gameplay.ts +692 -0
  112. package/src/ledger.test.ts +16 -0
  113. package/src/ledger.ts +31 -0
  114. package/src/manifest-v2.test.ts +130 -1
  115. package/src/manifest-v2.ts +181 -2
  116. package/src/persist.test.ts +3 -0
  117. package/src/persist.ts +43 -6
  118. package/src/registry.test.ts +168 -1
  119. package/src/registry.ts +199 -1
  120. package/src/routes.ts +28 -4
  121. package/src/service.ts +240 -29
  122. package/src/voice-pack.test.ts +48 -25
  123. package/src/voice-pack.ts +50 -47
@@ -38,6 +38,7 @@ import { PET_DECORATION_API_VERSION } from "./contracts/status-decoration.js";
38
38
  import { dshHome } from "./dsh-home.js";
39
39
  import { parsePetManifest } from "./manifest-v2.js";
40
40
  import { collectModel3References } from "./model3.js";
41
+ import { DEFAULT_PET_ID } from "./defaults.js";
41
42
  /** Fixed row order of the 9-state animation contract. */
42
43
  export const PET_ROW_ORDER = [
43
44
  'idle',
@@ -367,6 +368,169 @@ function resolveLive2dEntry(manifest, dir, options) {
367
368
  ...(remarks === undefined ? {} : { remarks }),
368
369
  };
369
370
  }
371
+ /** Filename-encoded frame duration tail ('<base>_<index>_<ms>.webp'). */
372
+ const FRAMES2D_FILENAME_MS = /_(\d+)\.[^.]+$/;
373
+ /** Trailing frame index, allowing an optional '_<ms>' duration tail after it. */
374
+ const FRAMES2D_FRAME_INDEX = /(\d+)(?:_\d+)?\.[^.]+$/;
375
+ /** Default per-frame duration when neither frameMs nor the filename encodes one. */
376
+ const FRAMES2D_DEFAULT_FRAME_MS = 200;
377
+ /** Image extensions a frames2d track directory may list. */
378
+ const FRAMES2D_IMAGE_EXTENSIONS = new Set(['.webp', '.png', '.gif', '.jpg', '.jpeg']);
379
+ /**
380
+ * Resolve a validated frames2d manifest into a renderable entry. Track frame
381
+ * lists come from the manifest's explicit list or from listing
382
+ * '<dir>/<track>/' in filename order; durations resolve frameMs[i] >
383
+ * filename-encoded '_<ms>' tail > defaultFrameMs. Missing frames warn and
384
+ * skip (the live2d closure discipline); a track left with zero frames is
385
+ * dropped, and if the idle-mapped track ends up empty the entry is rejected
386
+ * fail-closed. The sprite fields carry contract defaults: the chrome sizes
387
+ * frames2d pets off 'display.size', not the atlas.
388
+ */
389
+ function resolveFrames2dEntry(manifest, dir, options) {
390
+ const assetPrefix = options.assetPrefix ?? '/pet';
391
+ const record = (level, message) => {
392
+ options.diagnostics?.push({ level, source: dir, message });
393
+ options.warnings?.push(message);
394
+ };
395
+ const block = manifest.frames2d;
396
+ if (block === undefined) {
397
+ record('error', 'pet ' + manifest.id + ': renderer frames2d requires a frames2d block');
398
+ return undefined;
399
+ }
400
+ const root = block.dir ?? '.';
401
+ const defaultMs = block.defaultFrameMs ?? FRAMES2D_DEFAULT_FRAME_MS;
402
+ const idleTrack = block.phases.idle;
403
+ const tracks = {};
404
+ const servable = [];
405
+ const firstFrameRel = {};
406
+ for (const [name, track] of Object.entries(block.tracks)) {
407
+ const trackDir = root === '.' ? name : root + '/' + name;
408
+ let relFrames = [];
409
+ if (track.frames !== undefined) {
410
+ for (const frame of track.frames) {
411
+ const rel = trackDir + '/' + frame;
412
+ if (!existsSync(join(dir, rel))) {
413
+ record('warning', 'pet ' + manifest.id + ': frames2d frame missing: ' + rel);
414
+ continue;
415
+ }
416
+ relFrames.push(rel);
417
+ }
418
+ }
419
+ else {
420
+ let files = [];
421
+ try {
422
+ files = readdirSync(join(dir, trackDir)).filter(file => {
423
+ if (file.startsWith('.'))
424
+ return false;
425
+ const dot = file.lastIndexOf('.');
426
+ return dot > 0 && FRAMES2D_IMAGE_EXTENSIONS.has(file.slice(dot).toLowerCase());
427
+ });
428
+ }
429
+ catch {
430
+ files = [];
431
+ }
432
+ // Natural frame order: the trailing index (before any _<ms> duration
433
+ // suffix) sorts numerically, so 'eat10' comes after 'eat9' — plain
434
+ // lexicographic order would break any track with 10+ frames.
435
+ files.sort((a, b) => {
436
+ const ia = FRAMES2D_FRAME_INDEX.exec(a)?.[1];
437
+ const ib = FRAMES2D_FRAME_INDEX.exec(b)?.[1];
438
+ if (ia !== undefined && ib !== undefined && ia !== ib)
439
+ return Number(ia) - Number(ib);
440
+ return a < b ? -1 : a > b ? 1 : 0;
441
+ });
442
+ relFrames = files.map(file => trackDir + '/' + file);
443
+ }
444
+ if (relFrames.length === 0) {
445
+ record('warning', 'pet ' + manifest.id + ': frames2d track ' + JSON.stringify(name) + ' has no frames on disk; dropped');
446
+ continue;
447
+ }
448
+ const durations = relFrames.map((rel, index) => {
449
+ if (track.frameMs !== undefined)
450
+ return track.frameMs[index] ?? defaultMs;
451
+ const match = FRAMES2D_FILENAME_MS.exec(rel);
452
+ if (match !== null) {
453
+ const ms = Number(match[1]);
454
+ if (Number.isInteger(ms) && ms >= 16 && ms <= 5000)
455
+ return ms;
456
+ }
457
+ return defaultMs;
458
+ });
459
+ const loop = track.loop ?? true;
460
+ const view = {
461
+ frames: relFrames.map(rel => assetUrl(assetPrefix, manifest.id, rel)),
462
+ durations,
463
+ loop,
464
+ ...(loop ? {} : { fallback: track.fallback ?? idleTrack }),
465
+ };
466
+ tracks[name] = view;
467
+ firstFrameRel[name] = relFrames[0];
468
+ servable.push(...relFrames);
469
+ }
470
+ if (tracks[idleTrack] === undefined) {
471
+ record('error', 'pet ' + manifest.id + ': frames2d idle track ' + JSON.stringify(idleTrack) + ' has no frames on disk');
472
+ return undefined;
473
+ }
474
+ const phases = { ...block.phases };
475
+ for (const [phase, target] of Object.entries(phases)) {
476
+ if (target !== undefined && tracks[target] === undefined) {
477
+ record('warning', 'pet ' + manifest.id + ': frames2d phase ' + phase + ' maps to dropped track ' + JSON.stringify(target) + '; using idle');
478
+ phases[phase] = idleTrack;
479
+ }
480
+ }
481
+ const remarks = normalizePetRemarks(manifest.remarks, message => record('warning', 'pet ' + manifest.id + ': ' + message));
482
+ // Gameplay layer: shop item icons are manifest-relative frame paths —
483
+ // verify them, promote them to browser URLs, and add them to the servable
484
+ // allow-list so the asset route can serve them.
485
+ let gameplay;
486
+ if (manifest.gameplay !== undefined) {
487
+ gameplay = manifest.gameplay;
488
+ if (gameplay.shop !== undefined) {
489
+ const items = [];
490
+ for (const item of gameplay.shop.items) {
491
+ if (item.image === undefined) {
492
+ items.push(item);
493
+ continue;
494
+ }
495
+ if (!existsSync(join(dir, item.image))) {
496
+ record('warning', 'pet ' + manifest.id + ': gameplay shop item ' + item.id + ' image missing: ' + item.image);
497
+ const { image, ...rest } = item;
498
+ items.push(rest);
499
+ continue;
500
+ }
501
+ servable.push(item.image);
502
+ items.push({ ...item, image: assetUrl(assetPrefix, manifest.id, item.image) });
503
+ }
504
+ gameplay = { ...gameplay, shop: { ...gameplay.shop, items } };
505
+ }
506
+ }
507
+ const flatTracks = buildTracks(DEFAULT_FRAME_COUNTS, DEFAULT_PET_COLUMNS, {}, message => record('warning', 'pet ' + manifest.id + ': ' + message));
508
+ if (flatTracks === undefined)
509
+ return undefined;
510
+ // The render box comes from the first idle frame when decodable.
511
+ const firstAbs = join(dir, firstFrameRel[idleTrack]);
512
+ const dims = existsSync(firstAbs) ? readImageDimensions(firstAbs) : undefined;
513
+ const cell = dims !== undefined && dims.width >= 1 && dims.height >= 1 ? dims : { ...DEFAULT_PET_CELL };
514
+ return {
515
+ id: manifest.id,
516
+ displayName: manifest.displayName,
517
+ description: manifest.description ?? '',
518
+ renderer: 'frames2d',
519
+ frames2d: { tracks, phases },
520
+ ...(gameplay === undefined ? {} : { gameplay }),
521
+ cell,
522
+ columns: DEFAULT_PET_COLUMNS,
523
+ rows: [...DEFAULT_FRAME_COUNTS],
524
+ atlasRows: DEFAULT_PET_ROW_COUNT,
525
+ tracks: flatTracks,
526
+ atlasUrl: tracks[idleTrack].frames[0],
527
+ manifestUrl: assetUrl(assetPrefix, manifest.id, 'pet.json'),
528
+ dir,
529
+ spritesheetPath: firstFrameRel[idleTrack],
530
+ servable,
531
+ ...(remarks === undefined ? {} : { remarks }),
532
+ };
533
+ }
370
534
  /** Scan one directory of pet folders; entries come back in name order. */
371
535
  function scanPetDir(dir, options) {
372
536
  if (!existsSync(dir))
@@ -399,6 +563,9 @@ function scanPetDir(dir, options) {
399
563
  if (verdict.manifest.renderer === 'live2d') {
400
564
  entry = resolveLive2dEntry(verdict.manifest, entryDir, options);
401
565
  }
566
+ else if (verdict.manifest.renderer === 'frames2d') {
567
+ entry = resolveFrames2dEntry(verdict.manifest, entryDir, options);
568
+ }
402
569
  else {
403
570
  const legacy = flattenV2Sprite2d(verdict.manifest);
404
571
  if (legacy === undefined) {
@@ -695,7 +862,7 @@ export function loadPetRegistry(options) {
695
862
  warnings,
696
863
  diagnostics,
697
864
  byId: (id) => byId.get(id),
698
- defaultEntry: () => entries.find(entry => builtinIds.has(entry.id)) ?? entries[0],
865
+ defaultEntry: () => entries.find(entry => (entry.id === DEFAULT_PET_ID && builtinIds.has(entry.id))) ?? entries.find(entry => builtinIds.has(entry.id)) ?? entries[0],
699
866
  ...(globalVoice === undefined ? {} : { globalVoice }),
700
867
  decorations,
701
868
  decorationById: (id) => decorationById.get(id),
@@ -733,6 +900,8 @@ export function petEntryView(entry, globalVoice) {
733
900
  description: entry.description,
734
901
  renderer: entry.renderer,
735
902
  ...(entry.live2d === undefined ? {} : { live2d: entry.live2d }),
903
+ ...(entry.frames2d === undefined ? {} : { frames2d: entry.frames2d }),
904
+ ...(entry.gameplay === undefined ? {} : { gameplay: entry.gameplay }),
736
905
  cell: entry.cell,
737
906
  columns: entry.columns,
738
907
  rows: entry.rows,
@@ -1 +1 @@
1
- {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/routes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAMH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAA;AAC/D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAO9C,+CAA+C;AAC/C,eAAO,MAAM,cAAc,aAAa,CAAA;AAExC,0EAA0E;AAC1E,eAAO,MAAM,gBAAgB,SAAS,CAAA;AAMtC;;;;GAIG;AACH,eAAO,MAAM,cAAc;IACzB,yBAAyB;;IAEzB,iDAAiD;;IAEjD,8EAA8E;;CAEtE,CAAA;AAEV,6DAA6D;AAC7D,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;CACd;AAWD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAUrF;AAwND,4EAA4E;AAC5E,eAAO,MAAM,kBAAkB,QAA8B,CAAA;AAe7D,4EAA4E;AAC5E,eAAO,MAAM,eAAe,QAAmB,CAAA;AAE/C,6EAA6E;AAC7E,MAAM,WAAW,eAAe;IAC9B,+EAA+E;IAC/E,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,sEAAsE;IACtE,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAwMD,4EAA4E;AAC5E,wBAAgB,aAAa,CAAC,IAAI,EAAE;IAAE,OAAO,EAAE,UAAU,CAAC;IAAC,GAAG,EAAE,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,YAAY,CAAA;CAAE,GAAG,eAAe,GAAG,QAAQ,EAAE,CAwDjI;AAGD,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA"}
1
+ {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/routes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAMH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAA;AAC/D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAO9C,+CAA+C;AAC/C,eAAO,MAAM,cAAc,aAAa,CAAA;AAExC,0EAA0E;AAC1E,eAAO,MAAM,gBAAgB,SAAS,CAAA;AAMtC;;;;GAIG;AACH,eAAO,MAAM,cAAc;IACzB,yBAAyB;;IAEzB,iDAAiD;;IAEjD,8EAA8E;;CAEtE,CAAA;AAEV,6DAA6D;AAC7D,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;CACd;AAWD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAUrF;AAwND,4EAA4E;AAC5E,eAAO,MAAM,kBAAkB,QAA8B,CAAA;AAe7D,4EAA4E;AAC5E,eAAO,MAAM,eAAe,QAAmB,CAAA;AAE/C,6EAA6E;AAC7E,MAAM,WAAW,eAAe;IAC9B,+EAA+E;IAC/E,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,sEAAsE;IACtE,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAwMD,4EAA4E;AAC5E,wBAAgB,aAAa,CAAC,IAAI,EAAE;IAAE,OAAO,EAAE,UAAU,CAAC;IAAC,GAAG,EAAE,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,YAAY,CAAA;CAAE,GAAG,eAAe,GAAG,QAAQ,EAAE,CAgFjI;AAGD,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA"}
@@ -91,7 +91,7 @@ function guard(ctx, req, res) {
91
91
  writeJson(res, 403, { ok: false, error: 'forbidden: loopback-only' });
92
92
  return false;
93
93
  }
94
- /** Wrap one async service call as a GET JSON route. */
94
+ /** Wrap one async service call as a GET JSON route (request passed through for query params). */
95
95
  function getRoute(ctx, path, run) {
96
96
  return {
97
97
  kind: 'exact',
@@ -101,7 +101,7 @@ function getRoute(ctx, path, run) {
101
101
  return;
102
102
  if (!requireMethod(req, res, 'GET'))
103
103
  return;
104
- run().then((value) => writeJson(res, 200, value), (error) => {
104
+ run(req).then((value) => writeJson(res, 200, value), (error) => {
105
105
  writeJson(res, 500, { ok: false, error: error instanceof Error ? error.message : String(error) });
106
106
  });
107
107
  },
@@ -506,7 +506,12 @@ function decorationHandler(ctx, registry, caps) {
506
506
  export function makePetRoutes(deps) {
507
507
  const { service, ctx } = deps;
508
508
  const apiRoutes = [
509
- getRoute(ctx, PET_API_PREFIX + '/state', () => service.state()),
509
+ getRoute(ctx, PET_API_PREFIX + '/state', (req) => {
510
+ // The browser half reports the GUI's current session id so the bubble
511
+ // stack can lead with the session the user is actually looking at.
512
+ const current = new URL(req.url ?? '/', 'http://pet.local').searchParams.get('current');
513
+ return service.state(current === null || current === '' ? undefined : current);
514
+ }),
510
515
  getRoute(ctx, PET_API_PREFIX + '/pets', () => service.pets()),
511
516
  getRoute(ctx, PET_API_PREFIX + '/diagnostics', () => service.diagnostics()),
512
517
  postRoute(ctx, PET_API_PREFIX + '/interact', (body) => {
@@ -539,6 +544,28 @@ export function makePetRoutes(deps) {
539
544
  return Promise.reject(new Error('invalid-pet'));
540
545
  return service.setPetId(petId);
541
546
  }),
547
+ // Gameplay verbs (miku-pet generalization): touch rolls a named zone's
548
+ // branch; the omitted-zone form is the plain-click boost during a touch
549
+ // animation. Mode/tick/buy drive the work, sleep and shop loops.
550
+ postRoute(ctx, PET_API_PREFIX + '/gameplay/touch', (body) => {
551
+ const zone = body.zone;
552
+ if (zone !== undefined && typeof zone !== 'string')
553
+ return Promise.reject(new Error('invalid-zone'));
554
+ return service.gameplayTouch(zone);
555
+ }),
556
+ postRoute(ctx, PET_API_PREFIX + '/gameplay/mode', (body) => {
557
+ const mode = body.mode;
558
+ if (mode !== null && mode !== 'work' && mode !== 'sleep')
559
+ return Promise.reject(new Error('invalid-mode'));
560
+ return service.gameplaySetMode(mode);
561
+ }),
562
+ postRoute(ctx, PET_API_PREFIX + '/gameplay/work-tick', () => service.gameplayWorkTick()),
563
+ postRoute(ctx, PET_API_PREFIX + '/gameplay/buy', (body) => {
564
+ const item = body.item;
565
+ if (typeof item !== 'string')
566
+ return Promise.reject(new Error('invalid-item'));
567
+ return service.gameplayBuy(item);
568
+ }),
542
569
  ];
543
570
  const assetRoute = {
544
571
  kind: 'prefix',
@@ -83,6 +83,8 @@ export interface PetSessionView {
83
83
  bubble: string;
84
84
  /** This session's raw activity phase. */
85
85
  phase: PetStateSnapshot['phase'];
86
+ /** This session's fresh inner whisper (碎碎念), when one is within its TTL. */
87
+ whisper?: string;
86
88
  }
87
89
  /** Hard cap on simultaneously displayed session bubbles (most recent first). */
88
90
  export declare const MAX_SESSION_BUBBLES = 12;
@@ -93,10 +95,10 @@ export interface PetStateView {
93
95
  phase: PetStateSnapshot['phase'];
94
96
  sessionActive: boolean;
95
97
  /**
96
- * Per-session bubbles for every concurrently active TOP-LEVEL session,
97
- * most recent first; optional so older hosts without the multi-session
98
- * view stay consumable. The single 'bubble' above mirrors the display
99
- * session.
98
+ * Per-session bubbles for every concurrently active TOP-LEVEL session:
99
+ * the GUI's current session first when reported, the rest most recently
100
+ * active first; optional so older hosts without the multi-session view
101
+ * stay consumable. The single 'bubble' above mirrors the display session.
100
102
  */
101
103
  sessions?: PetSessionView[];
102
104
  /** Affinity ledger snapshot. */
@@ -121,21 +123,45 @@ export interface PetStateView {
121
123
  /** Stock cap. */
122
124
  max: number;
123
125
  };
124
- /**
125
- * The display session's fresh inner whisper (碎碎念), when one is within
126
- * its TTL — short inner-voice copy woken by the model's own output,
127
- * rendered by the client as a distinct whisper bubble.
128
- */
129
- whisper?: string;
130
126
  /**
131
127
  * The active status decoration (pet-center M5, #567), when the master
132
128
  * switch is on and the default decoration entry exists. Absent means the
133
129
  * browser half renders no ornament.
134
130
  */
135
131
  decoration?: DecorationView;
132
+ /**
133
+ * The selected pet's gameplay view (miku-pet generalization), present
134
+ * when the pet declares a gameplay block. Read-only projection: polling
135
+ * settles the view in memory but never writes pet.json.
136
+ */
137
+ gameplay?: PetGameplayStateView;
136
138
  }
137
139
  /** Result of `pet.interact`. */
138
140
  export type PetInteractResult = LedgerInteractionResult;
141
+ /** The gameplay slice of the state view (dynamic state only; defs ride the pet definition). */
142
+ export interface PetGameplayStateView {
143
+ /** Stat values rounded for display. */
144
+ stats: Record<string, number>;
145
+ mode: 'work' | 'sleep' | null;
146
+ }
147
+ /** Result of the gameplay verbs (touch / setMode / workTick / buy). */
148
+ export interface PetGameplayVerbResult {
149
+ ok: boolean;
150
+ error?: string;
151
+ /** Touch: whether a branch hit, plus its presentation. */
152
+ hit?: boolean;
153
+ state?: string;
154
+ stateMs?: number;
155
+ phrase?: string;
156
+ /** Work tick outcome. */
157
+ outcome?: 'success' | 'fail';
158
+ /** Shop purchase: the drawn prize, when the item was a lottery. */
159
+ prize?: {
160
+ amount: number;
161
+ currency: string;
162
+ };
163
+ view?: PetGameplayStateView;
164
+ }
139
165
  declare module '@deepseek-ai/cordis' {
140
166
  interface Context {
141
167
  pet: PetService;
@@ -188,7 +214,7 @@ export declare class PetService extends Service {
188
214
  /** Whether the pet service consumes session activity while enabled. */
189
215
  isEnabled(): boolean;
190
216
  /** RPC: current pet state snapshot. */
191
- state(): Promise<PetStateView>;
217
+ state(currentSessionId?: string): Promise<PetStateView>;
192
218
  /** Current persisted display config (read-only view). */
193
219
  display(): PetDisplayConfig;
194
220
  /** RPC: the registry entries the browser half renders and selects from. */
@@ -233,6 +259,32 @@ export declare class PetService extends Service {
233
259
  private applyActivity;
234
260
  /** RPC: pet or feed the pet. */
235
261
  interact(kind: PetInteraction): Promise<PetInteractResult>;
262
+ /** The active pet's gameplay block, if it declares one. */
263
+ private gameplayDef;
264
+ /** The persisted (or fresh) gameplay state of the selected pet. */
265
+ private gameplayState;
266
+ /** Display view of one gameplay state (rounded stats; treats ride the shared treat ledger). */
267
+ private gameplayViewOf;
268
+ /**
269
+ * Move gameplay 'treats' currency (the unified post-wallet currency) from
270
+ * the engine's settle work area into the shared treat ledger, capped by
271
+ * the stock cap. The engine keeps its generic currency record for settle
272
+ * math; this drain is the only bridge to the wallet-free economy.
273
+ */
274
+ private drainGameplayTreats;
275
+ /** Persist the mutated gameplay state of one verb call. */
276
+ private commitGameplay;
277
+ /**
278
+ * RPC: a touch on the pet. 'zone' names a touch zone (roll a branch);
279
+ * omitted means a plain click while a touch animation holds (clickBoost).
280
+ */
281
+ gameplayTouch(zone?: string): Promise<PetGameplayVerbResult>;
282
+ /** RPC: enter or leave a gameplay mode ('work' | 'sleep' | null). */
283
+ gameplaySetMode(mode: 'work' | 'sleep' | null): Promise<PetGameplayVerbResult>;
284
+ /** RPC: one work-round adjudication (only while the work mode holds). */
285
+ gameplayWorkTick(): Promise<PetGameplayVerbResult>;
286
+ /** RPC: buy one shop item (effects, currency swap, or a lottery draw). */
287
+ gameplayBuy(itemId: string): Promise<PetGameplayVerbResult>;
236
288
  /** RPC: show or hide the pet. */
237
289
  setVisible(visible: boolean): Promise<{
238
290
  ok: true;
@@ -1 +1 @@
1
- {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/service.ts"],"names":[],"mappings":"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"}