@linxin666/dsh-pet 0.1.3 → 0.1.6

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/lib/client.js CHANGED
@@ -303,8 +303,8 @@ window.__ModuleLoader__.load({
303
303
  };
304
304
  }
305
305
  //#endregion
306
- //#region \0dsh-css:/Users/zcl/code/dsh-web-ui/packages/dsh-pet/src/client/pet.module.css.mjs
307
- const css$1 = ".Xhudva_float{pointer-events:auto;-webkit-user-select:none;user-select:none;flex-direction:column;align-items:center;display:flex;position:fixed}.Xhudva_sprite{image-rendering:auto;touch-action:none;position:relative}.Xhudva_bubble{white-space:nowrap;color:#fff;pointer-events:none;border-radius:999px;margin-bottom:6px;padding:4px 10px;font-size:12px;line-height:1.4;animation:2.6s ease-out forwards Xhudva_pet-bubble-pop;position:absolute;bottom:100%;box-shadow:0 2px 8px #00000040}.Xhudva_bubblePet{background:#f472b6eb}.Xhudva_bubbleFeed{background:#38bdf8eb}@keyframes Xhudva_pet-bubble-pop{0%{opacity:0;transform:translateY(6px)scale(.85)}15%{opacity:1;transform:translateY(0)scale(1.05)}25%{transform:translateY(0)scale(1)}75%{opacity:1}to{opacity:0;transform:translateY(-8px)scale(.95)}}.Xhudva_panel{color:#e2e8f0;backdrop-filter:blur(6px);background:#0f172aeb;border:1px solid #94a3b859;border-radius:10px;flex-direction:column;gap:6px;min-width:132px;padding:8px 10px;font-size:12px;display:flex;position:absolute;bottom:calc(100% + 4px);box-shadow:0 4px 16px #00000059}.Xhudva_rankRow{white-space:nowrap;justify-content:space-between;gap:10px;display:flex}.Xhudva_nameCell{font-weight:600}.Xhudva_renameRow{align-items:center;gap:6px;display:flex}.Xhudva_nameInput{color:#e2e8f0;background:#1e293be6;border:1px solid #7dd3fc80;border-radius:6px;outline:none;flex:1;min-width:0;padding:3px 6px;font-size:12px}.Xhudva_nameInput:focus{border-color:#38bdf8;box-shadow:0 0 0 2px #38bdf873}.Xhudva_actions{gap:6px;display:flex}.Xhudva_action{cursor:pointer;color:#0f172a;background:linear-gradient(#7dd3fc,#38bdf8);border:none;border-radius:6px;flex:1;padding:4px 8px;font-size:12px;transition:filter .12s,box-shadow .12s}.Xhudva_action:hover{filter:brightness(1.08)}.Xhudva_action:active{filter:brightness(.94)}.Xhudva_action:focus-visible{outline:none;box-shadow:0 0 0 2px #38bdf8d9}.Xhudva_summon{color:#7dd3fc;cursor:pointer;background:#0f172abf;border:1px dashed #7dd3fc99;border-radius:999px;padding:2px 10px;font-size:11px;transition:border-color .12s,color .12s,background .12s,box-shadow .12s}.Xhudva_summon:hover{color:#bae6fd;background:#0f172ae6;border-color:#7dd3fcf2}.Xhudva_summon:active{color:#7dd3fc;border-color:#7dd3fccc}.Xhudva_summon:focus-visible{outline:none;box-shadow:0 0 0 2px #38bdf8d9}@media (prefers-reduced-motion:reduce){.Xhudva_bubble{opacity:1;animation:none}.Xhudva_action,.Xhudva_summon{transition:none}}";
306
+ //#region \0dsh-css:/home/runner/work/dsh-web-ui/dsh-web-ui/packages/dsh-pet/src/client/pet.module.css.mjs
307
+ const css$1 = ".l0P8iq_float{pointer-events:auto;-webkit-user-select:none;user-select:none;flex-direction:column;align-items:center;display:flex;position:fixed}.l0P8iq_sprite{image-rendering:auto;touch-action:none;position:relative}.l0P8iq_bubble{white-space:nowrap;color:#fff;pointer-events:none;border-radius:999px;margin-bottom:6px;padding:4px 10px;font-size:12px;line-height:1.4;animation:2.6s ease-out forwards l0P8iq_pet-bubble-pop;position:absolute;bottom:100%;box-shadow:0 2px 8px #00000040}.l0P8iq_bubblePet{background:#f472b6eb}.l0P8iq_bubbleFeed{background:#38bdf8eb}@keyframes l0P8iq_pet-bubble-pop{0%{opacity:0;transform:translateY(6px)scale(.85)}15%{opacity:1;transform:translateY(0)scale(1.05)}25%{transform:translateY(0)scale(1)}75%{opacity:1}to{opacity:0;transform:translateY(-8px)scale(.95)}}.l0P8iq_panel{color:#e2e8f0;backdrop-filter:blur(6px);background:#0f172aeb;border:1px solid #94a3b859;border-radius:10px;flex-direction:column;gap:6px;min-width:132px;padding:8px 10px;font-size:12px;display:flex;position:absolute;bottom:calc(100% + 4px);box-shadow:0 4px 16px #00000059}.l0P8iq_rankRow{white-space:nowrap;justify-content:space-between;gap:10px;display:flex}.l0P8iq_nameCell{font-weight:600}.l0P8iq_renameRow{align-items:center;gap:6px;display:flex}.l0P8iq_nameInput{color:#e2e8f0;background:#1e293be6;border:1px solid #7dd3fc80;border-radius:6px;outline:none;flex:1;min-width:0;padding:3px 6px;font-size:12px}.l0P8iq_nameInput:focus{border-color:#38bdf8;box-shadow:0 0 0 2px #38bdf873}.l0P8iq_actions{gap:6px;display:flex}.l0P8iq_action{cursor:pointer;color:#0f172a;background:linear-gradient(#7dd3fc,#38bdf8);border:none;border-radius:6px;flex:1;padding:4px 8px;font-size:12px;transition:filter .12s,box-shadow .12s}.l0P8iq_action:hover{filter:brightness(1.08)}.l0P8iq_action:active{filter:brightness(.94)}.l0P8iq_action:focus-visible{outline:none;box-shadow:0 0 0 2px #38bdf8d9}.l0P8iq_summon{color:#7dd3fc;cursor:pointer;background:#0f172abf;border:1px dashed #7dd3fc99;border-radius:999px;padding:2px 10px;font-size:11px;transition:border-color .12s,color .12s,background .12s,box-shadow .12s}.l0P8iq_summon:hover{color:#bae6fd;background:#0f172ae6;border-color:#7dd3fcf2}.l0P8iq_summon:active{color:#7dd3fc;border-color:#7dd3fccc}.l0P8iq_summon:focus-visible{outline:none;box-shadow:0 0 0 2px #38bdf8d9}@media (prefers-reduced-motion:reduce){.l0P8iq_bubble{opacity:1;animation:none}.l0P8iq_action,.l0P8iq_summon{transition:none}}";
308
308
  const tagId$1 = "@linxin666/dsh-pet/pet.module.css";
309
309
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$1) + "]") === null) {
310
310
  const tag = document.createElement("style");
@@ -314,20 +314,20 @@ window.__ModuleLoader__.load({
314
314
  document.head.appendChild(tag);
315
315
  }
316
316
  var pet_module_css_default = {
317
- "action": "Xhudva_action",
318
- "actions": "Xhudva_actions",
319
- "bubble": "Xhudva_bubble",
320
- "bubbleFeed": "Xhudva_bubbleFeed",
321
- "bubblePet": "Xhudva_bubblePet",
322
- "float": "Xhudva_float",
323
- "nameCell": "Xhudva_nameCell",
324
- "nameInput": "Xhudva_nameInput",
325
- "panel": "Xhudva_panel",
326
- "pet-bubble-pop": "Xhudva_pet-bubble-pop",
327
- "rankRow": "Xhudva_rankRow",
328
- "renameRow": "Xhudva_renameRow",
329
- "sprite": "Xhudva_sprite",
330
- "summon": "Xhudva_summon"
317
+ "action": "l0P8iq_action",
318
+ "actions": "l0P8iq_actions",
319
+ "bubble": "l0P8iq_bubble",
320
+ "bubbleFeed": "l0P8iq_bubbleFeed",
321
+ "bubblePet": "l0P8iq_bubblePet",
322
+ "float": "l0P8iq_float",
323
+ "nameCell": "l0P8iq_nameCell",
324
+ "nameInput": "l0P8iq_nameInput",
325
+ "panel": "l0P8iq_panel",
326
+ "pet-bubble-pop": "l0P8iq_pet-bubble-pop",
327
+ "rankRow": "l0P8iq_rankRow",
328
+ "renameRow": "l0P8iq_renameRow",
329
+ "sprite": "l0P8iq_sprite",
330
+ "summon": "l0P8iq_summon"
331
331
  };
332
332
  //#endregion
333
333
  //#region src/client/WhalePet.tsx
@@ -652,8 +652,8 @@ window.__ModuleLoader__.load({
652
652
  });
653
653
  }
654
654
  //#endregion
655
- //#region \0dsh-css:/Users/zcl/code/dsh-web-ui/packages/dsh-pet/src/client/settings-card.module.css.mjs
656
- const css = "._2dHfjG_card{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:8px;list-style:none;transition:border-color .16s,background .16s;overflow:hidden}._2dHfjG_cardOpen{background:var(--dsw-alias-bg-layer-2);border-color:var(--dsw-alias-label-dimmed)}._2dHfjG_header{cursor:pointer;text-align:left;width:100%;font:inherit;background:0 0;border:0;align-items:center;gap:8px;padding:10px 14px;transition:background .12s;display:flex}._2dHfjG_header:hover{background:var(--dsw-alias-interactive-bg-hover)}._2dHfjG_header:active{background:var(--dsw-alias-interactive-bg-hover-solid)}._2dHfjG_header:focus-visible{box-shadow:inset 0 0 0 2px var(--dsw-alias-button-info-fill);outline:none}._2dHfjG_headText{flex-direction:column;flex:1;gap:2px;min-width:0;display:flex}._2dHfjG_name{color:var(--dsw-alias-label-primary);font-weight:600}._2dHfjG_description{color:var(--dsw-alias-label-tertiary);font-size:12px}._2dHfjG_pending{color:var(--dsw-alias-state-warn-primary);font-size:12px}._2dHfjG_chevron{color:var(--dsw-alias-label-tertiary);transition:transform .12s}._2dHfjG_chevronOpen{transform:rotate(180deg)}._2dHfjG_body{flex-direction:column;gap:14px;padding:0 14px 14px;display:flex}._2dHfjG_readOnly{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px}._2dHfjG_footer{justify-content:flex-end;align-items:center;gap:8px;display:flex}._2dHfjG_failed{color:var(--dsw-alias-state-error-primary);margin:0 auto 0 0;font-size:12px}._2dHfjG_discard,._2dHfjG_save{font:inherit;cursor:pointer;border-radius:6px;padding:5px 12px;font-size:13px;transition:color .12s,border-color .12s,background .12s,box-shadow .12s}._2dHfjG_discard{border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);background:0 0}._2dHfjG_discard:hover:not(:disabled){color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-label-dimmed)}._2dHfjG_discard:active:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}._2dHfjG_save{border:1px solid var(--dsw-alias-button-info-fill);background:var(--dsw-alias-button-info-fill);color:var(--dsw-alias-label-primary-foreground)}._2dHfjG_save:hover:not(:disabled){border-color:var(--dsw-alias-button-info-hover);background:var(--dsw-alias-button-info-hover)}._2dHfjG_save:active:not(:disabled){filter:brightness(.94)}._2dHfjG_discard:focus-visible:not(:disabled),._2dHfjG_save:focus-visible:not(:disabled){box-shadow:0 0 0 2px var(--dsw-alias-button-info-fill);outline:none}._2dHfjG_discard:disabled,._2dHfjG_save:disabled{opacity:.5;cursor:default}._2dHfjG_field{flex-direction:column;gap:4px;display:flex}._2dHfjG_head{align-items:center;gap:8px;display:flex}._2dHfjG_label{color:var(--dsw-alias-label-primary);font-size:13px;font-weight:500}._2dHfjG_badges{align-items:center;gap:6px;display:flex}._2dHfjG_badge{background:var(--dsw-alias-interactive-bg-hover-accent);color:var(--dsw-alias-state-business-primary);border-radius:999px;padding:1px 6px;font-size:11px}._2dHfjG_reset{color:var(--dsw-alias-state-business-primary);cursor:pointer;background:0 0;border:0;border-radius:3px;padding:0;font-size:11px;transition:color .12s,box-shadow .12s}._2dHfjG_reset:hover:not(:disabled){color:var(--dsw-alias-label-primary-bluish);text-decoration:underline}._2dHfjG_reset:active:not(:disabled){color:var(--dsw-alias-state-business-primary)}._2dHfjG_reset:focus-visible:not(:disabled){box-shadow:0 0 0 2px var(--dsw-alias-button-info-fill);outline:none}._2dHfjG_reset:disabled{opacity:.5;cursor:default}._2dHfjG_input,._2dHfjG_select{border:1px solid var(--dsw-alias-border-l2);font:inherit;color:var(--dsw-alias-label-primary);background:var(--dsw-specific-input-major);border-radius:6px;padding:6px 8px;font-size:13px}._2dHfjG_inputInvalid{border:1px solid var(--dsw-alias-state-error-primary);font:inherit;color:var(--dsw-alias-label-primary);border-radius:6px;padding:6px 8px;font-size:13px}._2dHfjG_input:disabled,._2dHfjG_select:disabled{opacity:.6}._2dHfjG_input:focus,._2dHfjG_select:focus{border-color:var(--dsw-alias-button-info-fill);box-shadow:0 0 0 2px var(--dsw-alias-button-info-fill);outline:none}._2dHfjG_inputInvalid:focus{box-shadow:0 0 0 2px var(--dsw-alias-state-error-primary);outline:none}._2dHfjG_hint{color:var(--dsw-alias-label-secondary);margin:0;font-size:12px}._2dHfjG_invalid{color:var(--dsw-alias-state-error-primary);margin:0;font-size:12px}@media (prefers-reduced-motion:reduce){._2dHfjG_card,._2dHfjG_header,._2dHfjG_chevron,._2dHfjG_chevronOpen,._2dHfjG_reset,._2dHfjG_discard,._2dHfjG_save{transition:none}}";
655
+ //#region \0dsh-css:/home/runner/work/dsh-web-ui/dsh-web-ui/packages/dsh-pet/src/client/settings-card.module.css.mjs
656
+ const css = ".bDVnfa_card{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:8px;list-style:none;transition:border-color .16s,background .16s;overflow:hidden}.bDVnfa_cardOpen{background:var(--dsw-alias-bg-layer-2);border-color:var(--dsw-alias-label-dimmed)}.bDVnfa_header{cursor:pointer;text-align:left;width:100%;font:inherit;background:0 0;border:0;align-items:center;gap:8px;padding:10px 14px;transition:background .12s;display:flex}.bDVnfa_header:hover{background:var(--dsw-alias-interactive-bg-hover)}.bDVnfa_header:active{background:var(--dsw-alias-interactive-bg-hover-solid)}.bDVnfa_header:focus-visible{box-shadow:inset 0 0 0 2px var(--dsw-alias-button-info-fill);outline:none}.bDVnfa_headText{flex-direction:column;flex:1;gap:2px;min-width:0;display:flex}.bDVnfa_name{color:var(--dsw-alias-label-primary);font-weight:600}.bDVnfa_description{color:var(--dsw-alias-label-tertiary);font-size:12px}.bDVnfa_pending{color:var(--dsw-alias-state-warn-primary);font-size:12px}.bDVnfa_chevron{color:var(--dsw-alias-label-tertiary);transition:transform .12s}.bDVnfa_chevronOpen{transform:rotate(180deg)}.bDVnfa_body{flex-direction:column;gap:14px;padding:0 14px 14px;display:flex}.bDVnfa_readOnly{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px}.bDVnfa_footer{justify-content:flex-end;align-items:center;gap:8px;display:flex}.bDVnfa_failed{color:var(--dsw-alias-state-error-primary);margin:0 auto 0 0;font-size:12px}.bDVnfa_discard,.bDVnfa_save{font:inherit;cursor:pointer;border-radius:6px;padding:5px 12px;font-size:13px;transition:color .12s,border-color .12s,background .12s,box-shadow .12s}.bDVnfa_discard{border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);background:0 0}.bDVnfa_discard:hover:not(:disabled){color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-label-dimmed)}.bDVnfa_discard:active:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.bDVnfa_save{border:1px solid var(--dsw-alias-button-info-fill);background:var(--dsw-alias-button-info-fill);color:var(--dsw-alias-label-primary-foreground)}.bDVnfa_save:hover:not(:disabled){border-color:var(--dsw-alias-button-info-hover);background:var(--dsw-alias-button-info-hover)}.bDVnfa_save:active:not(:disabled){filter:brightness(.94)}.bDVnfa_discard:focus-visible:not(:disabled),.bDVnfa_save:focus-visible:not(:disabled){box-shadow:0 0 0 2px var(--dsw-alias-button-info-fill);outline:none}.bDVnfa_discard:disabled,.bDVnfa_save:disabled{opacity:.5;cursor:default}.bDVnfa_field{flex-direction:column;gap:4px;display:flex}.bDVnfa_head{align-items:center;gap:8px;display:flex}.bDVnfa_label{color:var(--dsw-alias-label-primary);font-size:13px;font-weight:500}.bDVnfa_badges{align-items:center;gap:6px;display:flex}.bDVnfa_badge{background:var(--dsw-alias-interactive-bg-hover-accent);color:var(--dsw-alias-state-business-primary);border-radius:999px;padding:1px 6px;font-size:11px}.bDVnfa_reset{color:var(--dsw-alias-state-business-primary);cursor:pointer;background:0 0;border:0;border-radius:3px;padding:0;font-size:11px;transition:color .12s,box-shadow .12s}.bDVnfa_reset:hover:not(:disabled){color:var(--dsw-alias-label-primary-bluish);text-decoration:underline}.bDVnfa_reset:active:not(:disabled){color:var(--dsw-alias-state-business-primary)}.bDVnfa_reset:focus-visible:not(:disabled){box-shadow:0 0 0 2px var(--dsw-alias-button-info-fill);outline:none}.bDVnfa_reset:disabled{opacity:.5;cursor:default}.bDVnfa_input,.bDVnfa_select{border:1px solid var(--dsw-alias-border-l2);font:inherit;color:var(--dsw-alias-label-primary);background:var(--dsw-specific-input-major);border-radius:6px;padding:6px 8px;font-size:13px}.bDVnfa_inputInvalid{border:1px solid var(--dsw-alias-state-error-primary);font:inherit;color:var(--dsw-alias-label-primary);border-radius:6px;padding:6px 8px;font-size:13px}.bDVnfa_input:disabled,.bDVnfa_select:disabled{opacity:.6}.bDVnfa_input:focus,.bDVnfa_select:focus{border-color:var(--dsw-alias-button-info-fill);box-shadow:0 0 0 2px var(--dsw-alias-button-info-fill);outline:none}.bDVnfa_inputInvalid:focus{box-shadow:0 0 0 2px var(--dsw-alias-state-error-primary);outline:none}.bDVnfa_hint{color:var(--dsw-alias-label-secondary);margin:0;font-size:12px}.bDVnfa_invalid{color:var(--dsw-alias-state-error-primary);margin:0;font-size:12px}@media (prefers-reduced-motion:reduce){.bDVnfa_card,.bDVnfa_header,.bDVnfa_chevron,.bDVnfa_chevronOpen,.bDVnfa_reset,.bDVnfa_discard,.bDVnfa_save{transition:none}}";
657
657
  const tagId = "@linxin666/dsh-pet/settings-card.module.css";
658
658
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
659
659
  const tag = document.createElement("style");
@@ -663,32 +663,32 @@ window.__ModuleLoader__.load({
663
663
  document.head.appendChild(tag);
664
664
  }
665
665
  var settings_card_module_css_default = {
666
- "badge": "_2dHfjG_badge",
667
- "badges": "_2dHfjG_badges",
668
- "body": "_2dHfjG_body",
669
- "card": "_2dHfjG_card",
670
- "cardOpen": "_2dHfjG_cardOpen",
671
- "chevron": "_2dHfjG_chevron",
672
- "chevronOpen": "_2dHfjG_chevronOpen",
673
- "description": "_2dHfjG_description",
674
- "discard": "_2dHfjG_discard",
675
- "failed": "_2dHfjG_failed",
676
- "field": "_2dHfjG_field",
677
- "footer": "_2dHfjG_footer",
678
- "head": "_2dHfjG_head",
679
- "headText": "_2dHfjG_headText",
680
- "header": "_2dHfjG_header",
681
- "hint": "_2dHfjG_hint",
682
- "input": "_2dHfjG_input",
683
- "inputInvalid": "_2dHfjG_inputInvalid",
684
- "invalid": "_2dHfjG_invalid",
685
- "label": "_2dHfjG_label",
686
- "name": "_2dHfjG_name",
687
- "pending": "_2dHfjG_pending",
688
- "readOnly": "_2dHfjG_readOnly",
689
- "reset": "_2dHfjG_reset",
690
- "save": "_2dHfjG_save",
691
- "select": "_2dHfjG_select"
666
+ "badge": "bDVnfa_badge",
667
+ "badges": "bDVnfa_badges",
668
+ "body": "bDVnfa_body",
669
+ "card": "bDVnfa_card",
670
+ "cardOpen": "bDVnfa_cardOpen",
671
+ "chevron": "bDVnfa_chevron",
672
+ "chevronOpen": "bDVnfa_chevronOpen",
673
+ "description": "bDVnfa_description",
674
+ "discard": "bDVnfa_discard",
675
+ "failed": "bDVnfa_failed",
676
+ "field": "bDVnfa_field",
677
+ "footer": "bDVnfa_footer",
678
+ "head": "bDVnfa_head",
679
+ "headText": "bDVnfa_headText",
680
+ "header": "bDVnfa_header",
681
+ "hint": "bDVnfa_hint",
682
+ "input": "bDVnfa_input",
683
+ "inputInvalid": "bDVnfa_inputInvalid",
684
+ "invalid": "bDVnfa_invalid",
685
+ "label": "bDVnfa_label",
686
+ "name": "bDVnfa_name",
687
+ "pending": "bDVnfa_pending",
688
+ "readOnly": "bDVnfa_readOnly",
689
+ "reset": "bDVnfa_reset",
690
+ "save": "bDVnfa_save",
691
+ "select": "bDVnfa_select"
692
692
  };
693
693
  //#endregion
694
694
  //#region src/client/PluginSettingsCard.tsx
@@ -7,6 +7,7 @@
7
7
  * @module @linxin666/dsh-pet
8
8
  */
9
9
  import { Context } from '@deepseek-ai/cordis';
10
+ import z from 'schemastery';
10
11
  import { type PetConfig } from './service.ts';
11
12
  export { PetService } from './service.ts';
12
13
  export type { PetConfig, PetInteractResult, PetStateView, } from './service.ts';
@@ -24,20 +25,20 @@ export declare const name = "pet";
24
25
  /** Services required before the pet can mount its surfaces. */
25
26
  export declare const inject: string[];
26
27
  /** Settings section schema: the display fields and name the web settings surface edits. */
27
- export declare const PET_SETTINGS_SCHEMA: import("@deepseek-ai/schemastery").default<Schemastery.ObjectS<{
28
- visible: import("@deepseek-ai/schemastery").default<boolean, boolean>;
29
- size: import("@deepseek-ai/schemastery").default<number, number>;
30
- right: import("@deepseek-ai/schemastery").default<number, number>;
31
- bottom: import("@deepseek-ai/schemastery").default<number, number>;
32
- name: import("@deepseek-ai/schemastery").default<string, string>;
33
- enabled: import("@deepseek-ai/schemastery").default<boolean, boolean>;
28
+ export declare const PET_SETTINGS_SCHEMA: z<Schemastery.ObjectS<{
29
+ visible: z<boolean, boolean>;
30
+ size: z<number, number>;
31
+ right: z<number, number>;
32
+ bottom: z<number, number>;
33
+ name: z<string, string>;
34
+ enabled: z<boolean, boolean>;
34
35
  }>, Schemastery.ObjectT<{
35
- visible: import("@deepseek-ai/schemastery").default<boolean, boolean>;
36
- size: import("@deepseek-ai/schemastery").default<number, number>;
37
- right: import("@deepseek-ai/schemastery").default<number, number>;
38
- bottom: import("@deepseek-ai/schemastery").default<number, number>;
39
- name: import("@deepseek-ai/schemastery").default<string, string>;
40
- enabled: import("@deepseek-ai/schemastery").default<boolean, boolean>;
36
+ visible: z<boolean, boolean>;
37
+ size: z<number, number>;
38
+ right: z<number, number>;
39
+ bottom: z<number, number>;
40
+ name: z<string, string>;
41
+ enabled: z<boolean, boolean>;
41
42
  }>>;
42
43
  /** Register the pet service and its API + asset routes on the context. */
43
44
  export declare function apply(ctx: Context, config?: PetConfig): void;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAI7C,OAAO,EAAsC,KAAK,SAAS,EAA2B,MAAM,cAAc,CAAA;AAU1G,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AACzC,YAAY,EACV,SAAS,EACT,iBAAiB,EACjB,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,oBAAoB,EACpB,YAAY,EACZ,cAAc,EACd,UAAU,EACV,cAAc,GACf,MAAM,cAAc,CAAA;AACrB,YAAY,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAEhE,OAAO,EACL,aAAa,EACb,cAAc,EACd,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,2FAA2F;AAC3F,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;GAO9B,CAAA;AAEF,0EAA0E;AAC1E,wBAAgB,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,GAAE,SAAc,GAAG,IAAI,CAoDhE"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAG7C,OAAO,CAAC,MAAM,aAAa,CAAA;AAC3B,OAAO,EAAsC,KAAK,SAAS,EAA2B,MAAM,cAAc,CAAA;AAU1G,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AACzC,YAAY,EACV,SAAS,EACT,iBAAiB,EACjB,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,oBAAoB,EACpB,YAAY,EACZ,cAAc,EACd,UAAU,EACV,cAAc,GACf,MAAM,cAAc,CAAA;AACrB,YAAY,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAEhE,OAAO,EACL,aAAa,EACb,cAAc,EACd,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,2FAA2F;AAC3F,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;GAO9B,CAAA;AAEF,0EAA0E;AAC1E,wBAAgB,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,GAAE,SAAc,GAAG,IAAI,CAoDhE"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@linxin666/dsh-pet",
3
3
  "description": "鲸鱼娘宠物插件 for the dsh web GUI: a soft healing whale-girl companion that reacts to model activity (idle/waiting/thinking/tool/done), with petting/feeding interactions and an affinity score",
4
- "version": "0.1.3",
4
+ "version": "0.1.6",
5
5
  "type": "module",
6
6
  "engines": {
7
7
  "node": "^22.19.0 || >=24.0.0"
@@ -1,217 +0,0 @@
1
- //#region lib/types/affinity.js
2
- /**
3
- * Affinity score — pure, clock-injected. The pet grows closer the more you
4
- * work together and care for it: every completed turn earns a small reward,
5
- * petting earns a tiny one (cooldown-gated), feeding earns the most.
6
- * Persistence lives in the service; this module only computes transitions.
7
- * @module @deepseek-ai/dsh-pet/affinity
8
- */
9
- const AFFINITY_MAX = 100;
10
- /** Affinity ranks by points; the pet visibly grows with its rank. */
11
- const AFFINITY_RANKS = [
12
- {
13
- min: 0,
14
- name: "幼鲸",
15
- emoji: "🐣"
16
- },
17
- {
18
- min: 25,
19
- name: "伙伴",
20
- emoji: "🐬"
21
- },
22
- {
23
- min: 50,
24
- name: "挚友",
25
- emoji: "🐳"
26
- },
27
- {
28
- min: 80,
29
- name: "深海羁绊",
30
- emoji: "💙"
31
- }
32
- ];
33
- const defaultAffinityConfig = {
34
- turnReward: 1,
35
- petReward: 1,
36
- petCooldownMs: 1e4,
37
- feedReward: 5,
38
- feedCooldownMs: 3e4
39
- };
40
- function emptyAffinity() {
41
- return {
42
- points: 0,
43
- lastPetAt: 0,
44
- lastFeedAt: 0,
45
- pets: 0,
46
- feeds: 0,
47
- turns: 0
48
- };
49
- }
50
- /** Rank for a point total. */
51
- function rankOf(points) {
52
- let rank = AFFINITY_RANKS[0];
53
- for (const candidate of AFFINITY_RANKS) if (points >= candidate.min) rank = candidate;
54
- return rank;
55
- }
56
- function clamp(points) {
57
- return Math.min(100, Math.max(0, points));
58
- }
59
- /**
60
- * Apply one interaction to a copy of the state (immutable style: returns a
61
- * new object; the caller replaces the persisted state). Cooldowns only
62
- * apply once the pet has been interacted with at least once (last*At === 0
63
- * means "never", so the first pet/feed always lands).
64
- */
65
- function applyInteraction(state, kind, nowMs, config = defaultAffinityConfig) {
66
- const next = { ...state };
67
- if (kind === "pet") {
68
- if (state.lastPetAt !== 0 && nowMs - state.lastPetAt < config.petCooldownMs) return {
69
- affinity: state,
70
- delta: 0,
71
- reaction: "摸过头啦,让鲸鱼娘歇口气~",
72
- accepted: false
73
- };
74
- next.lastPetAt = nowMs;
75
- next.pets += 1;
76
- next.points = clamp(state.points + config.petReward);
77
- return {
78
- affinity: next,
79
- delta: config.petReward,
80
- reaction: "咕噜咕噜~被摸摸好舒服!",
81
- accepted: true
82
- };
83
- }
84
- if (kind === "feed") {
85
- if (state.lastFeedAt !== 0 && nowMs - state.lastFeedAt < config.feedCooldownMs) return {
86
- affinity: state,
87
- delta: 0,
88
- reaction: "吃饱啦,晚点再喂~",
89
- accepted: false
90
- };
91
- next.lastFeedAt = nowMs;
92
- next.feeds += 1;
93
- next.points = clamp(state.points + config.feedReward);
94
- return {
95
- affinity: next,
96
- delta: config.feedReward,
97
- reaction: "呜哇!小鱼干好好吃!",
98
- accepted: true
99
- };
100
- }
101
- return {
102
- affinity: state,
103
- delta: 0,
104
- reaction: "",
105
- accepted: false
106
- };
107
- }
108
- /** Reward one completed turn (called by the host on `done`). */
109
- function applyTurnReward(state, config = defaultAffinityConfig) {
110
- const next = { ...state };
111
- next.turns += 1;
112
- next.points = clamp(state.points + config.turnReward);
113
- return next;
114
- }
115
- //#endregion
116
- //#region lib/types/state.js
117
- /**
118
- * Pet state machine — pure, clock-injected. Maps the DSH `activity/status`
119
- * phase vocabulary (session events) onto the 9-state Codex pet
120
- * animation contract, plus the session lifecycle transitions the web UI
121
- * exposes (turn end celebration, no-session idle).
122
- *
123
- * The machine is deliberately dumb: it holds the last input phase, the
124
- * animation decision, and a one-shot "celebration" window after `done` so the
125
- * pet visibly jumps before settling back to idle. Everything here is a pure
126
- * function of (input, nowMs); persistence and RPC live in the service.
127
- * @module @deepseek-ai/dsh-pet/state
128
- */
129
- const defaultPetStateConfig = { celebrateMs: 2400 };
130
- /**
131
- * Map one activity phase onto the animation contract.
132
- * - thinking / tool → `running` (focused work), with `running-right` as the
133
- * side-alternating variant the client may use for tool activity.
134
- * - waiting → `waiting` (expectant pose, needs user input).
135
- * - done → `jumping` (celebration), then back to `idle` after the window.
136
- * - idle → `idle` (calm breathing loop).
137
- * `failed` has no DSH phase source yet; the machine keeps the mapping table
138
- * so a future error event can light it up.
139
- */
140
- function animationForPhase(phase) {
141
- switch (phase) {
142
- case "thinking": return "running";
143
- case "tool": return "running-right";
144
- case "waiting": return "waiting";
145
- case "done": return "jumping";
146
- case "idle": return "idle";
147
- }
148
- }
149
- /** The spritesheet row index for one animation track. */
150
- function rowOf(animation) {
151
- return {
152
- "idle": 0,
153
- "running-right": 1,
154
- "running-left": 2,
155
- "waving": 3,
156
- "jumping": 4,
157
- "failed": 5,
158
- "waiting": 6,
159
- "running": 7,
160
- "review": 8
161
- }[animation];
162
- }
163
- /**
164
- * PetStateMachine — one instance per host process. Holds only the latest
165
- * input snapshot and the celebration timing; no storage, no side effects.
166
- */
167
- var PetStateMachine = class {
168
- config;
169
- now;
170
- phase = "idle";
171
- line;
172
- phrase;
173
- sessionActive = false;
174
- doneAt;
175
- constructor(config = defaultPetStateConfig, now = Date.now) {
176
- this.config = config;
177
- this.now = now;
178
- }
179
- /** Consume one `activity/status` session event. */
180
- onActivityStatus(input) {
181
- this.phase = input.phase;
182
- this.line = input.line;
183
- this.phrase = input.phrase;
184
- if (input.phase === "done") this.doneAt = this.now();
185
- }
186
- /** A session became the active one (or a fresh session started). */
187
- onSessionActive() {
188
- this.sessionActive = true;
189
- }
190
- /** The active session was disposed (or none left). */
191
- onSessionDisposed() {
192
- this.sessionActive = false;
193
- this.phase = "idle";
194
- this.line = void 0;
195
- this.phrase = void 0;
196
- this.doneAt = void 0;
197
- }
198
- /** Render the current animation decision. */
199
- render() {
200
- const nowMs = this.now();
201
- let animation = animationForPhase(this.phase);
202
- if (this.phase === "done" && this.doneAt !== void 0) {
203
- if (nowMs - this.doneAt < this.config.celebrateMs) animation = "jumping";
204
- else animation = "idle";
205
- }
206
- const bubble = this.phrase ?? this.line;
207
- return {
208
- animation,
209
- ...bubble === void 0 ? {} : { bubble },
210
- animationStartedAt: nowMs,
211
- phase: this.phase,
212
- sessionActive: this.sessionActive
213
- };
214
- }
215
- };
216
- //#endregion
217
- export { AFFINITY_MAX as a, applyTurnReward as c, rankOf as d, rowOf as i, defaultAffinityConfig as l, animationForPhase as n, AFFINITY_RANKS as o, defaultPetStateConfig as r, applyInteraction as s, PetStateMachine as t, emptyAffinity as u };
@@ -1,196 +0,0 @@
1
- //#region src/affinity.ts
2
- const AFFINITY_MAX = 100;
3
- /** Affinity ranks by points; the pet visibly grows with its rank. */
4
- const AFFINITY_RANKS = [
5
- {
6
- min: 0,
7
- name: "幼鲸",
8
- emoji: "🐣"
9
- },
10
- {
11
- min: 25,
12
- name: "伙伴",
13
- emoji: "🐬"
14
- },
15
- {
16
- min: 50,
17
- name: "挚友",
18
- emoji: "🐳"
19
- },
20
- {
21
- min: 80,
22
- name: "深海羁绊",
23
- emoji: "💙"
24
- }
25
- ];
26
- const defaultAffinityConfig = {
27
- turnReward: 1,
28
- petReward: 1,
29
- petCooldownMs: 1e4,
30
- feedReward: 5,
31
- feedCooldownMs: 3e4
32
- };
33
- function emptyAffinity() {
34
- return {
35
- points: 0,
36
- lastPetAt: 0,
37
- lastFeedAt: 0,
38
- pets: 0,
39
- feeds: 0,
40
- turns: 0
41
- };
42
- }
43
- /** Rank for a point total. */
44
- function rankOf(points) {
45
- let rank = AFFINITY_RANKS[0];
46
- for (const candidate of AFFINITY_RANKS) if (points >= candidate.min) rank = candidate;
47
- return rank;
48
- }
49
- function clamp(points) {
50
- return Math.min(100, Math.max(0, points));
51
- }
52
- /**
53
- * Apply one interaction to a copy of the state (immutable style: returns a
54
- * new object; the caller replaces the persisted state). Cooldowns only
55
- * apply once the pet has been interacted with at least once (last*At === 0
56
- * means "never", so the first pet/feed always lands).
57
- */
58
- function applyInteraction(state, kind, nowMs, config = defaultAffinityConfig) {
59
- const next = { ...state };
60
- if (kind === "pet") {
61
- if (state.lastPetAt !== 0 && nowMs - state.lastPetAt < config.petCooldownMs) return {
62
- affinity: state,
63
- delta: 0,
64
- reaction: "摸过头啦,让鲸鱼娘歇口气~",
65
- accepted: false
66
- };
67
- next.lastPetAt = nowMs;
68
- next.pets += 1;
69
- next.points = clamp(state.points + config.petReward);
70
- return {
71
- affinity: next,
72
- delta: config.petReward,
73
- reaction: "咕噜咕噜~被摸摸好舒服!",
74
- accepted: true
75
- };
76
- }
77
- if (kind === "feed") {
78
- if (state.lastFeedAt !== 0 && nowMs - state.lastFeedAt < config.feedCooldownMs) return {
79
- affinity: state,
80
- delta: 0,
81
- reaction: "吃饱啦,晚点再喂~",
82
- accepted: false
83
- };
84
- next.lastFeedAt = nowMs;
85
- next.feeds += 1;
86
- next.points = clamp(state.points + config.feedReward);
87
- return {
88
- affinity: next,
89
- delta: config.feedReward,
90
- reaction: "呜哇!小鱼干好好吃!",
91
- accepted: true
92
- };
93
- }
94
- return {
95
- affinity: state,
96
- delta: 0,
97
- reaction: "",
98
- accepted: false
99
- };
100
- }
101
- /** Reward one completed turn (called by the host on `done`). */
102
- function applyTurnReward(state, config = defaultAffinityConfig) {
103
- const next = { ...state };
104
- next.turns += 1;
105
- next.points = clamp(state.points + config.turnReward);
106
- return next;
107
- }
108
- //#endregion
109
- //#region src/state.ts
110
- const defaultPetStateConfig = { celebrateMs: 2400 };
111
- /**
112
- * Map one activity phase onto the animation contract.
113
- * - thinking / tool → `running` (focused work), with `running-right` as the
114
- * side-alternating variant the client may use for tool activity.
115
- * - waiting → `waiting` (expectant pose, needs user input).
116
- * - done → `jumping` (celebration), then back to `idle` after the window.
117
- * - idle → `idle` (calm breathing loop).
118
- * `failed` has no DSH phase source yet; the machine keeps the mapping table
119
- * so a future error event can light it up.
120
- */
121
- function animationForPhase(phase) {
122
- switch (phase) {
123
- case "thinking": return "running";
124
- case "tool": return "running-right";
125
- case "waiting": return "waiting";
126
- case "done": return "jumping";
127
- case "idle": return "idle";
128
- }
129
- }
130
- /** The spritesheet row index for one animation track. */
131
- function rowOf(animation) {
132
- return {
133
- "idle": 0,
134
- "running-right": 1,
135
- "running-left": 2,
136
- "waving": 3,
137
- "jumping": 4,
138
- "failed": 5,
139
- "waiting": 6,
140
- "running": 7,
141
- "review": 8
142
- }[animation];
143
- }
144
- /**
145
- * PetStateMachine — one instance per host process. Holds only the latest
146
- * input snapshot and the celebration timing; no storage, no side effects.
147
- */
148
- var PetStateMachine = class {
149
- config;
150
- now;
151
- phase = "idle";
152
- line;
153
- phrase;
154
- sessionActive = false;
155
- doneAt;
156
- constructor(config = defaultPetStateConfig, now = Date.now) {
157
- this.config = config;
158
- this.now = now;
159
- }
160
- /** Consume one `activity/status` session event. */
161
- onActivityStatus(input) {
162
- this.phase = input.phase;
163
- this.line = input.line;
164
- this.phrase = input.phrase;
165
- if (input.phase === "done") this.doneAt = this.now();
166
- }
167
- /** A session became the active one (or a fresh session started). */
168
- onSessionActive() {
169
- this.sessionActive = true;
170
- }
171
- /** The active session was disposed (or none left). */
172
- onSessionDisposed() {
173
- this.sessionActive = false;
174
- this.phase = "idle";
175
- this.line = void 0;
176
- this.phrase = void 0;
177
- this.doneAt = void 0;
178
- }
179
- /** Render the current animation decision. */
180
- render() {
181
- const nowMs = this.now();
182
- let animation = animationForPhase(this.phase);
183
- if (this.phase === "done" && this.doneAt !== void 0) if (nowMs - this.doneAt < this.config.celebrateMs) animation = "jumping";
184
- else animation = "idle";
185
- const bubble = this.phrase ?? this.line;
186
- return {
187
- animation,
188
- ...bubble === void 0 ? {} : { bubble },
189
- animationStartedAt: nowMs,
190
- phase: this.phase,
191
- sessionActive: this.sessionActive
192
- };
193
- }
194
- };
195
- //#endregion
196
- export { AFFINITY_MAX as a, applyTurnReward as c, rankOf as d, rowOf as i, defaultAffinityConfig as l, animationForPhase as n, AFFINITY_RANKS as o, defaultPetStateConfig as r, applyInteraction as s, PetStateMachine as t, emptyAffinity as u };
@@ -1,198 +0,0 @@
1
- //#region src/affinity.ts
2
- const AFFINITY_MAX = 100;
3
- /** Affinity ranks by points; the pet visibly grows with its rank. */
4
- const AFFINITY_RANKS = [
5
- {
6
- min: 0,
7
- name: "幼鲸",
8
- emoji: "🐣"
9
- },
10
- {
11
- min: 25,
12
- name: "伙伴",
13
- emoji: "🐬"
14
- },
15
- {
16
- min: 50,
17
- name: "挚友",
18
- emoji: "🐳"
19
- },
20
- {
21
- min: 80,
22
- name: "深海羁绊",
23
- emoji: "💙"
24
- }
25
- ];
26
- const defaultAffinityConfig = {
27
- turnReward: 1,
28
- petReward: 1,
29
- petCooldownMs: 1e4,
30
- feedReward: 5,
31
- feedCooldownMs: 3e4
32
- };
33
- function emptyAffinity() {
34
- return {
35
- points: 0,
36
- lastPetAt: 0,
37
- lastFeedAt: 0,
38
- pets: 0,
39
- feeds: 0,
40
- turns: 0
41
- };
42
- }
43
- /** Rank for a point total. */
44
- function rankOf(points) {
45
- let rank = AFFINITY_RANKS[0];
46
- for (const candidate of AFFINITY_RANKS) if (points >= candidate.min) rank = candidate;
47
- return rank;
48
- }
49
- function clamp(points) {
50
- return Math.min(100, Math.max(0, points));
51
- }
52
- /**
53
- * Apply one interaction to a copy of the state (immutable style: returns a
54
- * new object; the caller replaces the persisted state). Cooldowns only
55
- * apply once the pet has been interacted with at least once (last*At === 0
56
- * means "never", so the first pet/feed always lands).
57
- */
58
- function applyInteraction(state, kind, nowMs, config = defaultAffinityConfig) {
59
- const next = { ...state };
60
- if (kind === "pet") {
61
- if (state.lastPetAt !== 0 && nowMs - state.lastPetAt < config.petCooldownMs) return {
62
- affinity: state,
63
- delta: 0,
64
- reaction: "摸过头啦,让鲸鱼娘歇口气~",
65
- accepted: false
66
- };
67
- next.lastPetAt = nowMs;
68
- next.pets += 1;
69
- next.points = clamp(state.points + config.petReward);
70
- return {
71
- affinity: next,
72
- delta: config.petReward,
73
- reaction: "咕噜咕噜~被摸摸好舒服!",
74
- accepted: true
75
- };
76
- }
77
- if (kind === "feed") {
78
- if (state.lastFeedAt !== 0 && nowMs - state.lastFeedAt < config.feedCooldownMs) return {
79
- affinity: state,
80
- delta: 0,
81
- reaction: "吃饱啦,晚点再喂~",
82
- accepted: false
83
- };
84
- next.lastFeedAt = nowMs;
85
- next.feeds += 1;
86
- next.points = clamp(state.points + config.feedReward);
87
- return {
88
- affinity: next,
89
- delta: config.feedReward,
90
- reaction: "呜哇!小鱼干好好吃!",
91
- accepted: true
92
- };
93
- }
94
- return {
95
- affinity: state,
96
- delta: 0,
97
- reaction: "",
98
- accepted: false
99
- };
100
- }
101
- /** Reward one completed turn (called by the host on `done`). */
102
- function applyTurnReward(state, config = defaultAffinityConfig) {
103
- const next = { ...state };
104
- next.turns += 1;
105
- next.points = clamp(state.points + config.turnReward);
106
- return next;
107
- }
108
- //#endregion
109
- //#region src/state.ts
110
- const defaultPetStateConfig = { celebrateMs: 2400 };
111
- /**
112
- * Map one activity phase onto the animation contract.
113
- * - thinking / tool → `running` (focused work), with `running-right` as the
114
- * side-alternating variant the client may use for tool activity.
115
- * - waiting → `waiting` (expectant pose, needs user input).
116
- * - done → `jumping` (celebration), then back to `idle` after the window.
117
- * - idle → `idle` (calm breathing loop).
118
- * `failed` has no DSH phase source yet; the machine keeps the mapping table
119
- * so a future error event can light it up.
120
- */
121
- function animationForPhase(phase) {
122
- switch (phase) {
123
- case "thinking": return "running";
124
- case "tool": return "running-right";
125
- case "waiting": return "waiting";
126
- case "done": return "jumping";
127
- case "idle": return "idle";
128
- }
129
- }
130
- /** The spritesheet row index for one animation track. */
131
- function rowOf(animation) {
132
- return {
133
- "idle": 0,
134
- "running-right": 1,
135
- "running-left": 2,
136
- "waving": 3,
137
- "jumping": 4,
138
- "failed": 5,
139
- "waiting": 6,
140
- "running": 7,
141
- "review": 8
142
- }[animation];
143
- }
144
- /**
145
- * PetStateMachine — one instance per host process. Holds only the latest
146
- * input snapshot and the celebration timing; no storage, no side effects.
147
- */
148
- var PetStateMachine = class {
149
- config;
150
- now;
151
- phase = "idle";
152
- line;
153
- phrase;
154
- sessionActive = false;
155
- doneAt;
156
- constructor(config = defaultPetStateConfig, now = Date.now) {
157
- this.config = config;
158
- this.now = now;
159
- }
160
- /** Consume one `activity/status` session event. */
161
- onActivityStatus(input) {
162
- this.phase = input.phase;
163
- this.line = input.line;
164
- this.phrase = input.phrase;
165
- if (input.phase === "done") this.doneAt = this.now();
166
- }
167
- /** A session became the active one (or a fresh session started). */
168
- onSessionActive() {
169
- this.sessionActive = true;
170
- }
171
- /** The active session was disposed (or none left). */
172
- onSessionDisposed() {
173
- this.sessionActive = false;
174
- this.phase = "idle";
175
- this.line = void 0;
176
- this.phrase = void 0;
177
- this.doneAt = void 0;
178
- }
179
- /** Render the current animation decision. */
180
- render() {
181
- const nowMs = this.now();
182
- let animation = animationForPhase(this.phase);
183
- if (this.phase === "done" && this.doneAt !== void 0) {
184
- if (nowMs - this.doneAt < this.config.celebrateMs) animation = "jumping";
185
- else animation = "idle";
186
- }
187
- const bubble = this.phrase ?? this.line;
188
- return {
189
- animation,
190
- ...bubble === void 0 ? {} : { bubble },
191
- animationStartedAt: nowMs,
192
- phase: this.phase,
193
- sessionActive: this.sessionActive
194
- };
195
- }
196
- };
197
- //#endregion
198
- export { AFFINITY_MAX as a, applyTurnReward as c, rankOf as d, rowOf as i, defaultAffinityConfig as l, animationForPhase as n, AFFINITY_RANKS as o, defaultPetStateConfig as r, applyInteraction as s, PetStateMachine as t, emptyAffinity as u };
@@ -1,23 +0,0 @@
1
- /**
2
- * Dock-band fallback seat for the pet.
3
- *
4
- * Current dsh web shells declare `conversation.input.dock` (the composer dock
5
- * band, a list slot) instead of the legacy `conversation.input.selector.context`
6
- * hole this plugin was written against. The dock band renders only for an
7
- * active session, so on shells that carry it the pet follows the session seat
8
- * — an acceptable degradation until the upstream shell restores the context
9
- * hole. The underlying entry ignores owner props (it reads only injected
10
- * actions and the locale), so this wrapper is a pure props re-cast.
11
- */
12
- import type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';
13
- import { type PetInjected } from './PetDockEntry.tsx';
14
- import { NS } from './locales.ts';
15
- /** Composed props of the dock-band fallback seat. */
16
- export type DockPetDockEntryProps = PropsRuntime<'conversation.input.dock'> & PetInjected & PropsLocale<typeof NS>;
17
- /**
18
- * Render the pet dock from the composer dock band.
19
- * @param props - composed slot props (dock band seat).
20
- * @returns the dock entry element tree.
21
- */
22
- export declare function DockPetDockEntry(props: DockPetDockEntryProps): import("react").JSX.Element;
23
- //# sourceMappingURL=DockPetDockEntry.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"DockPetDockEntry.d.ts","sourceRoot":"","sources":["../../../src/client/DockPetDockEntry.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAA;AAEjF,OAAO,EAAwC,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAC3F,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAA;AAEjC,qDAAqD;AACrD,MAAM,MAAM,qBAAqB,GAAG,YAAY,CAAC,yBAAyB,CAAC,GAAG,WAAW,GAAG,WAAW,CAAC,OAAO,EAAE,CAAC,CAAA;AAElH;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,+BAE5D"}
@@ -1,10 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import { PetDockEntry } from "./PetDockEntry.js";
3
- /**
4
- * Render the pet dock from the composer dock band.
5
- * @param props - composed slot props (dock band seat).
6
- * @returns the dock entry element tree.
7
- */
8
- export function DockPetDockEntry(props) {
9
- return _jsx(PetDockEntry, { ...props });
10
- }