dsh-wisp 1.44.0 → 1.48.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/README.md +599 -32
  2. package/assets/canon/attn.webp +0 -0
  3. package/assets/canon/eat.webp +0 -0
  4. package/assets/canon/happy.webp +0 -0
  5. package/assets/canon/idle.webp +0 -0
  6. package/assets/canon/poked.webp +0 -0
  7. package/assets/canon/proud.webp +0 -0
  8. package/assets/canon/sleepy.webp +0 -0
  9. package/assets/canon/work.webp +0 -0
  10. package/assets/classic/attn.webp +0 -0
  11. package/assets/classic/eat.webp +0 -0
  12. package/assets/classic/happy.webp +0 -0
  13. package/assets/classic/idle.webp +0 -0
  14. package/assets/classic/poked.webp +0 -0
  15. package/assets/classic/proud.webp +0 -0
  16. package/assets/classic/work.webp +0 -0
  17. package/assets/deepsea/attn.webp +0 -0
  18. package/assets/deepsea/eat.webp +0 -0
  19. package/assets/deepsea/happy.webp +0 -0
  20. package/assets/deepsea/idle.webp +0 -0
  21. package/assets/deepsea/poked.webp +0 -0
  22. package/assets/deepsea/proud.webp +0 -0
  23. package/assets/deepsea/sleepy.webp +0 -0
  24. package/assets/deepsea/work.webp +0 -0
  25. package/assets/motion/idle.webp +0 -0
  26. package/assets/motion/sleepy.webm +0 -0
  27. package/assets/motion/sleepy.webp +0 -0
  28. package/assets/motion/swim_attn.webp +0 -0
  29. package/assets/motion/swim_eat.webp +0 -0
  30. package/assets/motion/swim_happy.webp +0 -0
  31. package/assets/motion/swim_idle.webp +0 -0
  32. package/assets/motion/swim_poked.webp +0 -0
  33. package/assets/motion/swim_proud.webp +0 -0
  34. package/assets/motion/swim_sleepy.webp +0 -0
  35. package/assets/motion/swim_work.webp +0 -0
  36. package/assets/night/attn.webp +0 -0
  37. package/assets/night/eat.webp +0 -0
  38. package/assets/night/happy.webp +0 -0
  39. package/assets/night/idle.webp +0 -0
  40. package/assets/night/poked.webp +0 -0
  41. package/assets/night/proud.webp +0 -0
  42. package/assets/night/sleepy.webp +0 -0
  43. package/assets/night/work.webp +0 -0
  44. package/assets/pajama/attn.webp +0 -0
  45. package/assets/pajama/eat.webp +0 -0
  46. package/assets/pajama/happy.webp +0 -0
  47. package/assets/pajama/idle.webp +0 -0
  48. package/assets/pajama/poked.webp +0 -0
  49. package/assets/pajama/proud.webp +0 -0
  50. package/assets/pajama/sleepy.webp +0 -0
  51. package/assets/pajama/work.webp +0 -0
  52. package/assets/swim/attn.webp +0 -0
  53. package/assets/swim/eat.webp +0 -0
  54. package/assets/swim/happy.webp +0 -0
  55. package/assets/swim/idle.webp +0 -0
  56. package/assets/swim/poked.webp +0 -0
  57. package/assets/swim/proud.webp +0 -0
  58. package/assets/swim/sleepy.webp +0 -0
  59. package/assets/swim/work.webp +0 -0
  60. package/audit/generation-audit.jsonl +57 -0
  61. package/build.mjs +130 -8
  62. package/lib/client.js +826 -92
  63. package/lib/client.template.js +765 -53
  64. package/lib/index.js +194 -1
  65. package/package.json +1 -1
  66. package/tools/CHARACTER-PROMPT.md +65 -9
  67. package/tools/audit-log.mjs +11 -2
  68. package/tools/engine-probe.mjs +500 -2
  69. package/verify-wisp.mjs +1263 -32
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -33,3 +33,60 @@
33
33
  {"index":32,"prev":"0cf1a63cf80010ebbd60732da414c498e737982541bd99cd6ff17630dc400be8","kind":"confirm","source":"registry-backfill","at":"2026-09-29T19:38:40.585Z","name":"pj2_attn","skin":"pajama","mood":"attn","registry":{"tool":"batch_generate_images","createdAt":"2026-09-29T19:16:09.300Z","localPath":"assets/image/pj2_attn_20260929191609.png"},"master":{"path":"F:\\孤屿\\assets\\image\\pj2_attn_20260929191609.png","sha256":"88c210219d8ec51d06a0cbf0688501b63edfbfe4e8483560cb27cf26770b1ed5"},"output":{"path":"assets/pajama/attn.webp","sha256":"4b83d0824414b2010512bf69adca90a67a52c2a900dee768480c892d08f18b7d","bytes":120264},"declared":null,"note":"回溯补录:只有代理登记表的事实,没有当次自我声明的参数","hash":"87af13c5d179617c97ee9c0af6d4bc25a7f90d0ce670bb033fe2accfa977e01e"}
34
34
  {"index":33,"prev":"87af13c5d179617c97ee9c0af6d4bc25a7f90d0ce670bb033fe2accfa977e01e","kind":"confirm","source":"registry-backfill","at":"2026-09-29T19:38:40.593Z","name":"pj2_poked","skin":"pajama","mood":"poked","registry":{"tool":"batch_generate_images","createdAt":"2026-09-29T19:16:09.300Z","localPath":"assets/image/pj2_poked_20260929191609.png"},"master":{"path":"F:\\孤屿\\assets\\image\\pj2_poked_20260929191609.png","sha256":"ddc769a7d748a076dd555af189410851ef73af2cb141f75a876de602b296ecda"},"output":{"path":"assets/pajama/poked.webp","sha256":"f61e303037c9a67bc2ec769ae240f88a4ba8722311e8975258ea8a0a2350ef03","bytes":110922},"declared":null,"note":"回溯补录:只有代理登记表的事实,没有当次自我声明的参数","hash":"15e5ec5b886db9837bb139d644c7999e3afa1dec60355a8314585ea4c042feeb"}
35
35
  {"index":34,"prev":"15e5ec5b886db9837bb139d644c7999e3afa1dec60355a8314585ea4c042feeb","kind":"confirm","source":"registry-backfill","at":"2026-09-29T19:38:40.602Z","name":"pj2_proud","skin":"pajama","mood":"proud","registry":{"tool":"batch_generate_images","createdAt":"2026-09-29T19:16:09.300Z","localPath":"assets/image/pj2_proud_20260929191609.png"},"master":{"path":"F:\\孤屿\\assets\\image\\pj2_proud_20260929191609.png","sha256":"565c20a42a41c5ee5e3b25eb460e2baa8e67b1c58cf2ceef3d8b94e1add8ae44"},"output":{"path":"assets/pajama/proud.webp","sha256":"bb70bd99c8cb259edf4291414fca4d93fa7a3245d95433f611b8e4ddcd34d7a9","bytes":102080},"declared":null,"note":"回溯补录:只有代理登记表的事实,没有当次自我声明的参数","hash":"79943856f73dff0063ac4c91efb2e4c447b0b73e3aa95739f002f0cba56b0d3d"}
36
+ {"index":35,"prev":"79943856f73dff0063ac4c91efb2e4c447b0b73e3aa95739f002f0cba56b0d3d","kind":"confirm","source":"manifest+registry","at":"2026-10-03T09:23:27.927Z","name":"swim_idle","skin":"swim","mood":"idle","registry":{"tool":"generate_image","createdAt":"2026-10-03T09:12:14.282Z","localPath":"assets/image/swim_idle_20261003091214.png"},"master":{"path":"E:\\github\\wisp-art\\assets\\image\\swim_idle_20261003091214.png","sha256":"29bf5ece41172f2d1da731ce70535ccf7200d80f089b5b9a7fb7387d17afe767"},"output":{"path":"assets/swim/idle.webp","sha256":"34b966c92b1e30119c96bea5ae558c4f9b1244550a3dfb10ec819ae2f5b8ee26","bytes":120176},"promptMatchesRegistry":false,"hash":"beccee2cbe5b3f8284754ed7699ad6016d2d332d33af68d3680e34ace5008b88"}
37
+ {"index":36,"prev":"beccee2cbe5b3f8284754ed7699ad6016d2d332d33af68d3680e34ace5008b88","kind":"confirm","source":"manifest+registry","at":"2026-10-03T09:23:27.927Z","name":"swim_happy_v2","skin":"swim","mood":"happy","registry":{"tool":"generate_image","createdAt":"2026-10-03T09:21:32.771Z","localPath":"assets/image/swim_happy_v2_20261003092132.png"},"master":{"path":"E:\\github\\wisp-art\\assets\\image\\swim_happy_v2_20261003092132.png","sha256":"e4744f7939b454cad12c00bbca6ca019bc2608667ba451dd042f228c93dcdd36"},"output":{"path":"assets/swim/happy.webp","sha256":"73a935165c65934f46ca25c9ad96860a67a02c9e46fb708510c2e542b8cb2a90","bytes":115818},"promptMatchesRegistry":true,"hash":"ccd66604708607c1d7788830e576e798376c023e84b7ea8d2459eff5fafb5a3b"}
38
+ {"index":37,"prev":"ccd66604708607c1d7788830e576e798376c023e84b7ea8d2459eff5fafb5a3b","kind":"confirm","source":"manifest+registry","at":"2026-10-03T09:23:27.927Z","name":"swim_sleepy","skin":"swim","mood":"sleepy","registry":{"tool":"generate_image","createdAt":"2026-10-03T09:17:25.088Z","localPath":"assets/image/swim_sleepy_20261003091725.png"},"master":{"path":"E:\\github\\wisp-art\\assets\\image\\swim_sleepy_20261003091725.png","sha256":"0b84bd23351b74491cbf62252cfc4ae377665de269241d1088f58f0ca2a45a1f"},"output":{"path":"assets/swim/sleepy.webp","sha256":"ffc0b4d23f7ab823aad4aa9eb8a3d933d394391bfb3005cf0e86808f878b3806","bytes":131300},"promptMatchesRegistry":true,"hash":"ddde1230a17c13e7e0344e187551d3d5120f61684d9c0b95170057efd58d498c"}
39
+ {"index":38,"prev":"ddde1230a17c13e7e0344e187551d3d5120f61684d9c0b95170057efd58d498c","kind":"confirm","source":"manifest+registry","at":"2026-10-03T09:23:27.927Z","name":"swim_work","skin":"swim","mood":"work","registry":{"tool":"generate_image","createdAt":"2026-10-03T09:18:01.507Z","localPath":"assets/image/swim_work_20261003091801.png"},"master":{"path":"E:\\github\\wisp-art\\assets\\image\\swim_work_20261003091801.png","sha256":"5a5af396edf859dc0ab12e1c66ff582340be3c6ccbeeed87a35ffb55baa74fbd"},"output":{"path":"assets/swim/work.webp","sha256":"757f063c436cde35fe80658375a3ba2d64b5b8976392d1ba0fe1a46b5b7d6633","bytes":108606},"promptMatchesRegistry":true,"hash":"116fb91c70c1652b175815c241cd37a2d6b852de24dd2b977952aa211a38786f"}
40
+ {"index":39,"prev":"116fb91c70c1652b175815c241cd37a2d6b852de24dd2b977952aa211a38786f","kind":"confirm","source":"manifest+registry","at":"2026-10-03T09:23:27.927Z","name":"swim_attn","skin":"swim","mood":"attn","registry":{"tool":"generate_image","createdAt":"2026-10-03T09:18:30.235Z","localPath":"assets/image/swim_attn_20261003091830.png"},"master":{"path":"E:\\github\\wisp-art\\assets\\image\\swim_attn_20261003091830.png","sha256":"088c76aa3ec8050255c53fa32243f4233e426b321e56a3a84fbb3264c2126008"},"output":{"path":"assets/swim/attn.webp","sha256":"723b3da12c98028c03e80c1d1e810d04abf779afabbd8e36d1d42b6d72c606bc","bytes":137540},"promptMatchesRegistry":true,"hash":"701fc3056daf9a67865be579a3ee91aa1c0369e956cbb992bf50a5df0ea44c45"}
41
+ {"index":40,"prev":"701fc3056daf9a67865be579a3ee91aa1c0369e956cbb992bf50a5df0ea44c45","kind":"confirm","source":"manifest+registry","at":"2026-10-03T09:23:27.927Z","name":"swim_poked","skin":"swim","mood":"poked","registry":{"tool":"generate_image","createdAt":"2026-10-03T09:19:08.736Z","localPath":"assets/image/swim_poked_20261003091908.png"},"master":{"path":"E:\\github\\wisp-art\\assets\\image\\swim_poked_20261003091908.png","sha256":"5f50d70efb3f1dab6ecc51b2bfa2d37f9a8a2b07974ed56adb8924cb5be97d92"},"output":{"path":"assets/swim/poked.webp","sha256":"d62232787a41fbb07b51568c1b86c0d170493f5814fc3d52e9469f678fe9a1ee","bytes":133528},"promptMatchesRegistry":true,"hash":"ec05a7635c98a460404f51d67928654a0fdf6c330ad85370a54abda189fab8c8"}
42
+ {"index":41,"prev":"ec05a7635c98a460404f51d67928654a0fdf6c330ad85370a54abda189fab8c8","kind":"confirm","source":"manifest+registry","at":"2026-10-03T09:23:27.927Z","name":"swim_proud","skin":"swim","mood":"proud","registry":{"tool":"generate_image","createdAt":"2026-10-03T09:19:37.118Z","localPath":"assets/image/swim_proud_20261003091937.png"},"master":{"path":"E:\\github\\wisp-art\\assets\\image\\swim_proud_20261003091937.png","sha256":"6db7d7a9ec5943dd9e955e670125e8f24d7f2c128201cdf987b0c38e784fe10a"},"output":{"path":"assets/swim/proud.webp","sha256":"fffb37166fab2141b048179cbe0acd61654beb260136d3fdc828c69280709d3d","bytes":124188},"promptMatchesRegistry":true,"hash":"6028da6f7276832c20af60a7e54c1d54f5e5432cc53965ac96fea1f9a8b1c53c"}
43
+ {"index":42,"prev":"6028da6f7276832c20af60a7e54c1d54f5e5432cc53965ac96fea1f9a8b1c53c","kind":"confirm","source":"manifest+registry","at":"2026-10-03T09:23:27.927Z","name":"swim_eat","skin":"swim","mood":"eat","registry":{"tool":"generate_image","createdAt":"2026-10-03T09:20:11.205Z","localPath":"assets/image/swim_eat_20261003092011.png"},"master":{"path":"E:\\github\\wisp-art\\assets\\image\\swim_eat_20261003092011.png","sha256":"24ba77a99ed0406cfeda18d117fbe7b4692c32fc57055b5d5e95b8c3e71aa8ef"},"output":{"path":"assets/swim/eat.webp","sha256":"8b954cc93d83cb1fc30406132b9f71d12b210f79b99dc0aa2d3ac7993a4ea018","bytes":143186},"promptMatchesRegistry":true,"hash":"9bb5c8a99ca19ee9f9fae12332315f7639221cac5d71a070034bf242862d26e5"}
44
+ {"index":43,"prev":"9bb5c8a99ca19ee9f9fae12332315f7639221cac5d71a070034bf242862d26e5","kind":"confirm","source":"manifest+registry","at":"2026-10-03T09:46:12.270Z","name":"swim_happy_v3","skin":"swim","mood":"happy","registry":{"tool":"generate_image","createdAt":"2026-10-03T09:45:28.042Z","localPath":"assets/image/swim_happy_v3_20261003094528.png"},"master":{"path":"E:\\github\\wisp-art\\assets\\image\\swim_happy_v3_20261003094528.png","sha256":"d9e87e0f124bb8233e11e32ed8498152a7575adaca352c09a7d6f49fb053c8e4"},"output":{"path":"assets/swim/happy.webp","sha256":"311fe375cf1726e8f40aa80d34d6e340d41c550cb4971fcc0435e510b72dd282","bytes":144512},"promptMatchesRegistry":true,"hash":"414ae675956866f49bd234a8e36c4c7e0d3ecaaebdc02ba443ae3e6460392c98"}
45
+ {"index":44,"prev":"414ae675956866f49bd234a8e36c4c7e0d3ecaaebdc02ba443ae3e6460392c98","kind":"confirm","source":"manifest+registry","at":"2026-10-03T09:57:04.114Z","name":"night_attn_v2","skin":"night","mood":"attn","registry":{"tool":"generate_image","createdAt":"2026-10-03T09:56:39.858Z","localPath":"assets/image/night_attn_v2_20261003095639.png"},"master":{"path":"E:\\github\\wisp-art\\assets\\image\\night_attn_v2_20261003095639.png","sha256":"b18dade49e58beea0875707431b98e175cd804e9efded37c4b0e3956feffd945"},"output":{"path":"assets/night/attn.webp","sha256":"2a7a2edf5eb494340b2d4f4e50111c8bc6fd26d7bc9053b87a59603fa9d905d0","bytes":141852},"promptMatchesRegistry":true,"hash":"f2fa8e15059004cec7b3ca906168a93b66a3f9383dc760fcbc1eea85bd9d3b20"}
46
+ {"index":45,"prev":"f2fa8e15059004cec7b3ca906168a93b66a3f9383dc760fcbc1eea85bd9d3b20","kind":"confirm","source":"manifest+registry","at":"2026-10-03T10:14:22.813Z","name":"night_idle_v2","skin":"night","mood":"idle","registry":{"tool":"generate_image","createdAt":"2026-10-03T10:10:21.213Z","localPath":"assets/image/night_idle_v2_20261003101021.png"},"master":{"path":"E:\\github\\wisp-art\\assets\\image\\night_idle_v2_20261003101021.png","sha256":"8af1701dcb6e9882cca3c7be9878430fc8020b4aede0b8fefe813fbb177606a9"},"output":{"path":"assets/night/idle.webp","sha256":"715d4169ec21ba85bf9f09d11f5b3cf196f1e6a77b8663dd22a074490052499b","bytes":128604},"promptMatchesRegistry":true,"hash":"cd1e8ab1eeb649da48b52c81e7d7f53f56bcbfedc8c9bede7bd29e5115e5c4bf"}
47
+ {"index":46,"prev":"cd1e8ab1eeb649da48b52c81e7d7f53f56bcbfedc8c9bede7bd29e5115e5c4bf","kind":"confirm","source":"manifest+registry","at":"2026-10-03T10:14:22.813Z","name":"night_happy_v2","skin":"night","mood":"happy","registry":{"tool":"generate_image","createdAt":"2026-10-03T10:10:52.378Z","localPath":"assets/image/night_happy_v2_20261003101052.png"},"master":{"path":"E:\\github\\wisp-art\\assets\\image\\night_happy_v2_20261003101052.png","sha256":"4c4403a6965394c9cc3019572b579eb6ff4812495a880e4408b8fb5dee593de5"},"output":{"path":"assets/night/happy.webp","sha256":"8d176013aa74ee8c75ed23f57256bb250a3e8542bf599849c227c39354c31367","bytes":132790},"promptMatchesRegistry":true,"hash":"b0e6a3be424505091461f6ca59949e2ae1fdfad8951b28302e9bc7f84e0eed90"}
48
+ {"index":47,"prev":"b0e6a3be424505091461f6ca59949e2ae1fdfad8951b28302e9bc7f84e0eed90","kind":"confirm","source":"manifest+registry","at":"2026-10-03T10:14:22.813Z","name":"night_sleepy_v2","skin":"night","mood":"sleepy","registry":{"tool":"generate_image","createdAt":"2026-10-03T10:11:20.014Z","localPath":"assets/image/night_sleepy_v2_20261003101120.png"},"master":{"path":"E:\\github\\wisp-art\\assets\\image\\night_sleepy_v2_20261003101120.png","sha256":"52916de2b29fef978726a7ef65ea81dd06f199d3c61037a719220f2c7fcf36b5"},"output":{"path":"assets/night/sleepy.webp","sha256":"b99f023b65ceec95387b3fa45c6009b00925f1eb517a6424d50eea303cff298e","bytes":117374},"promptMatchesRegistry":true,"hash":"9b3d70fc84beeb8ffdbeb08f21afd66743880786ecc027d777ac4e8e1a5118bf"}
49
+ {"index":48,"prev":"9b3d70fc84beeb8ffdbeb08f21afd66743880786ecc027d777ac4e8e1a5118bf","kind":"confirm","source":"manifest+registry","at":"2026-10-03T10:14:22.813Z","name":"night_work_v2","skin":"night","mood":"work","registry":{"tool":"generate_image","createdAt":"2026-10-03T10:12:07.363Z","localPath":"assets/image/night_work_v2_20261003101207.png"},"master":{"path":"E:\\github\\wisp-art\\assets\\image\\night_work_v2_20261003101207.png","sha256":"b1570556a335cbbd7614873bfa7b24cc6abc8338c28832daaa357a98ffa84dc1"},"output":{"path":"assets/night/work.webp","sha256":"c437d40b7bc6077ad3e737d6763a48edc97c593c6b775f4485a0e6678b81d4e6","bytes":118984},"promptMatchesRegistry":true,"hash":"f7b31c91ad50619ff6eed329f8a7c13150b67be26066f041a6ce70cd35bd012c"}
50
+ {"index":49,"prev":"f7b31c91ad50619ff6eed329f8a7c13150b67be26066f041a6ce70cd35bd012c","kind":"confirm","source":"manifest+registry","at":"2026-10-03T10:14:22.813Z","name":"night_poked_v2","skin":"night","mood":"poked","registry":{"tool":"generate_image","createdAt":"2026-10-03T10:12:38.326Z","localPath":"assets/image/night_poked_v2_20261003101238.png"},"master":{"path":"E:\\github\\wisp-art\\assets\\image\\night_poked_v2_20261003101238.png","sha256":"2ac7e90f81e52df5096ea2307563e579f55bc059ae17f542e6726d0f2eccd94c"},"output":{"path":"assets/night/poked.webp","sha256":"bcaacc47be466a696da4318ef7f9796fc4803ebdc4c82c16e957a1759601cba3","bytes":129200},"promptMatchesRegistry":true,"hash":"ef311151f1d4c8437d596c8d77b8af3de77e201d748f479cc6cb12cf87f72809"}
51
+ {"index":50,"prev":"ef311151f1d4c8437d596c8d77b8af3de77e201d748f479cc6cb12cf87f72809","kind":"confirm","source":"manifest+registry","at":"2026-10-03T10:14:22.813Z","name":"night_proud_v2","skin":"night","mood":"proud","registry":{"tool":"generate_image","createdAt":"2026-10-03T10:13:05.539Z","localPath":"assets/image/night_proud_v2_20261003101305.png"},"master":{"path":"E:\\github\\wisp-art\\assets\\image\\night_proud_v2_20261003101305.png","sha256":"66d868077a6d075f48893884c4c3b392df67bab34c91dce9fa9054cbb0ef7158"},"output":{"path":"assets/night/proud.webp","sha256":"329a1752ad9951583bce84ac36d8ca596f30821b350c1b58bc00bbc85b2f894f","bytes":115230},"promptMatchesRegistry":true,"hash":"98d50938bf1835cb8a69498b4d517963a67d72dce9fca754bc3b0f26ae2eb81f"}
52
+ {"index":51,"prev":"98d50938bf1835cb8a69498b4d517963a67d72dce9fca754bc3b0f26ae2eb81f","kind":"confirm","source":"manifest+registry","at":"2026-10-03T10:14:22.813Z","name":"night_eat_v2","skin":"night","mood":"eat","registry":{"tool":"generate_image","createdAt":"2026-10-03T10:13:37.500Z","localPath":"assets/image/night_eat_v2_20261003101337.png"},"master":{"path":"E:\\github\\wisp-art\\assets\\image\\night_eat_v2_20261003101337.png","sha256":"4adfb757fc3588937a8505881d7755a4e5fb14aa0657f643f992dc57605c06f0"},"output":{"path":"assets/night/eat.webp","sha256":"0ab4825c8e6630da100d0bce8bdf19a6a18edf828f6fa0769e5eca8c253abd7d","bytes":114702},"promptMatchesRegistry":true,"hash":"fb8e2250fb4da38015ce0c49b910894131022e5a0573e69be92e2e7b141b90c9"}
53
+ {"index":52,"prev":"fb8e2250fb4da38015ce0c49b910894131022e5a0573e69be92e2e7b141b90c9","kind":"confirm","source":"manifest+registry","at":"2026-10-03T16:41:14.016Z","name":"deepsea_idle_v2","skin":"deepsea","mood":"idle","registry":{"tool":"generate_image","createdAt":"2026-10-03T11:14:56.739Z","localPath":"assets/image/deepsea_idle_v2_20261003111456.png"},"master":{"path":"E:\\github\\wisp-art\\assets\\image\\deepsea_idle_v2_20261003111456.png","sha256":"4daceaa4eabed1aeefe6f4f9863e91bcfde46d6b1ad3756b8f81a09fb262f274"},"output":{"path":"assets/deepsea/idle.webp","sha256":"cacf8609605d867f454103ea3cfd2ea9844284d7757ed2dcf8a39acd83f5e33c","bytes":121638},"promptMatchesRegistry":true,"hash":"de564e1207512b937ff00dcff3516835fcc94dd4a06a9cd2032e1fed3bcb929c"}
54
+ {"index":53,"prev":"de564e1207512b937ff00dcff3516835fcc94dd4a06a9cd2032e1fed3bcb929c","kind":"confirm","source":"manifest+registry","at":"2026-10-03T16:41:14.016Z","name":"deepsea_happy_v2","skin":"deepsea","mood":"happy","registry":{"tool":"generate_image","createdAt":"2026-10-03T16:15:29.669Z","localPath":"assets/image/deepsea_happy_v2_20261003161529.png"},"master":{"path":"E:\\github\\wisp-art\\assets\\image\\deepsea_happy_v2_20261003161529.png","sha256":"0ea5cd269100efe677db07f35f22bdefb63f704944d15d852fe5107405f55e0d"},"output":{"path":"assets/deepsea/happy.webp","sha256":"39710e65cb02ae0fd3d19d3422c1cb251f1cffb0cd5e5fda3c636d67e91bfb55","bytes":118256},"promptMatchesRegistry":true,"hash":"d738a66085143a213c85ac4a4b5e2827723dd59295969efb23a8ad6aed9b6c96"}
55
+ {"index":54,"prev":"d738a66085143a213c85ac4a4b5e2827723dd59295969efb23a8ad6aed9b6c96","kind":"confirm","source":"manifest+registry","at":"2026-10-03T16:41:14.016Z","name":"deepsea_sleepy_v2","skin":"deepsea","mood":"sleepy","registry":{"tool":"generate_image","createdAt":"2026-10-03T16:16:00.699Z","localPath":"assets/image/deepsea_sleepy_v2_20261003161600.png"},"master":{"path":"E:\\github\\wisp-art\\assets\\image\\deepsea_sleepy_v2_20261003161600.png","sha256":"792a1aa110b329de7b2c3799f8fb8a70b3f99213be121656fb6c04ec8ae38989"},"output":{"path":"assets/deepsea/sleepy.webp","sha256":"3c35b8ff143a72e98155180a6d2f160b55a374e02a286b409021657cf1600cb5","bytes":113446},"promptMatchesRegistry":true,"hash":"472e87d4cc7dff8b19ed212bf80b9f07ee583d54f8daa796d5ca5b7ff0975fc1"}
56
+ {"index":55,"prev":"472e87d4cc7dff8b19ed212bf80b9f07ee583d54f8daa796d5ca5b7ff0975fc1","kind":"confirm","source":"manifest+registry","at":"2026-10-03T16:41:14.016Z","name":"deepsea_work_v2","skin":"deepsea","mood":"work","registry":{"tool":"generate_image","createdAt":"2026-10-03T16:17:17.664Z","localPath":"assets/image/deepsea_work_v2_20261003161717.png"},"master":{"path":"E:\\github\\wisp-art\\assets\\image\\deepsea_work_v2_20261003161717.png","sha256":"c93221a31ae054d1abf0f88b7f164ff52cbbdb45bd38996b9eb753905686bb66"},"output":{"path":"assets/deepsea/work.webp","sha256":"76a7a0aa43ed07a7cd4c3b8411ccf685b8a69c9f29969d392c2e9e34be02bfea","bytes":130120},"promptMatchesRegistry":true,"hash":"be0dc3878481cce5b51bb7fa520a51aa6b76e27d12249ee58e33f0c1d5f34778"}
57
+ {"index":56,"prev":"be0dc3878481cce5b51bb7fa520a51aa6b76e27d12249ee58e33f0c1d5f34778","kind":"confirm","source":"manifest+registry","at":"2026-10-03T16:41:14.016Z","name":"deepsea_attn_v2","skin":"deepsea","mood":"attn","registry":{"tool":"generate_image","createdAt":"2026-10-03T16:17:51.965Z","localPath":"assets/image/deepsea_attn_v2_20261003161751.png"},"master":{"path":"E:\\github\\wisp-art\\assets\\image\\deepsea_attn_v2_20261003161751.png","sha256":"9bf8a13d6e85912ec1c43f61694dada24fefdc7e2fd2e452b2aa4d7fc36d0e24"},"output":{"path":"assets/deepsea/attn.webp","sha256":"d77743d67f4d426bd99e51c39f6b95cdea327b36422c2da2e6dfe8dc3ad47714","bytes":128422},"promptMatchesRegistry":true,"hash":"3b0e6346d326c613684ca5bcc53ab59410873563a2f3b03c36170e9c97f0f6e4"}
58
+ {"index":57,"prev":"3b0e6346d326c613684ca5bcc53ab59410873563a2f3b03c36170e9c97f0f6e4","kind":"confirm","source":"manifest+registry","at":"2026-10-03T16:41:14.016Z","name":"deepsea_poked_v2","skin":"deepsea","mood":"poked","registry":{"tool":"generate_image","createdAt":"2026-10-03T16:18:23.424Z","localPath":"assets/image/deepsea_poked_v2_20261003161823.png"},"master":{"path":"E:\\github\\wisp-art\\assets\\image\\deepsea_poked_v2_20261003161823.png","sha256":"6f674bef49889bf468c82b8c1a4979a481b8f00af90a048e99d86dff0e2ead90"},"output":{"path":"assets/deepsea/poked.webp","sha256":"5b3d476e2f57c0ded20e371790f5f5a5b2cc60ee99011c792b9752ba0ab45a22","bytes":122092},"promptMatchesRegistry":true,"hash":"f31d5546d541e8e17a0bef8b2396bd1de5d0397e7f411154db8821b09c36d412"}
59
+ {"index":58,"prev":"f31d5546d541e8e17a0bef8b2396bd1de5d0397e7f411154db8821b09c36d412","kind":"confirm","source":"manifest+registry","at":"2026-10-03T16:41:14.016Z","name":"deepsea_proud_v2","skin":"deepsea","mood":"proud","registry":{"tool":"generate_image","createdAt":"2026-10-03T16:18:57.676Z","localPath":"assets/image/deepsea_proud_v2_20261003161857.png"},"master":{"path":"E:\\github\\wisp-art\\assets\\image\\deepsea_proud_v2_20261003161857.png","sha256":"cad7924f15936b949d494ad8068a48f96ceeac6de71a041547fa031dd9e6b30a"},"output":{"path":"assets/deepsea/proud.webp","sha256":"656df8fb110cf15e895df5ab980fa50c37a7b635886d28714c77d1065f19bf18","bytes":110900},"promptMatchesRegistry":true,"hash":"d6bf21aa2d922f4f7e79e5fd112723ed0097f95d8fc6543f8c5573bc7768885f"}
60
+ {"index":59,"prev":"d6bf21aa2d922f4f7e79e5fd112723ed0097f95d8fc6543f8c5573bc7768885f","kind":"confirm","source":"manifest+registry","at":"2026-10-03T16:41:14.016Z","name":"deepsea_eat_v2","skin":"deepsea","mood":"eat","registry":{"tool":"generate_image","createdAt":"2026-10-03T16:19:40.805Z","localPath":"assets/image/deepsea_eat_v2_20261003161940.png"},"master":{"path":"E:\\github\\wisp-art\\assets\\image\\deepsea_eat_v2_20261003161940.png","sha256":"6a90ac39b2ca8b0715dabfad03c54c02a7098a53b30c104e6467b3c0eb7ef115"},"output":{"path":"assets/deepsea/eat.webp","sha256":"8632cde266b1e5ab7069c66c9dec88cb8b3c7bb9ecb32c6ff886a9db1dbc3bbb","bytes":123670},"promptMatchesRegistry":true,"hash":"3cf713682cd5444f6ed29be483c80354c0900755528a3f66ab0a91a66b4c8726"}
61
+ {"index":60,"prev":"3cf713682cd5444f6ed29be483c80354c0900755528a3f66ab0a91a66b4c8726","kind":"confirm","source":"manifest+registry","at":"2026-10-03T16:41:14.212Z","name":"canon_idle_v2","skin":"canon","mood":"idle","registry":{"tool":"generate_image","createdAt":"2026-10-03T16:36:38.259Z","localPath":"assets/image/canon_idle_v2_20261003163638.png"},"master":{"path":"E:\\github\\wisp-art\\assets\\image\\canon_idle_v2_20261003163638.png","sha256":"21c9410b6b896eef4a9149678bd7816b6d1671eb83c15d0eef157fafe65dd5e6"},"output":{"path":"assets/canon/idle.webp","sha256":"2bd644a4cec6783ace58eef0ec8a513a034a120e121a6ebbb6a6a5b9e78bdd52","bytes":148604},"promptMatchesRegistry":true,"hash":"a5d9991e4e74e3bad0cb82869c4675db7661b2d05f6645bc2e0284444f0ec977"}
62
+ {"index":61,"prev":"a5d9991e4e74e3bad0cb82869c4675db7661b2d05f6645bc2e0284444f0ec977","kind":"confirm","source":"manifest+registry","at":"2026-10-03T16:41:14.212Z","name":"canon_happy_v2","skin":"canon","mood":"happy","registry":{"tool":"generate_image","createdAt":"2026-10-03T16:37:13.216Z","localPath":"assets/image/canon_happy_v2_20261003163713.png"},"master":{"path":"E:\\github\\wisp-art\\assets\\image\\canon_happy_v2_20261003163713.png","sha256":"e957f5a08d53a8e75d6809cebec794f09973fbeeb5a60622597e1de71ba00f98"},"output":{"path":"assets/canon/happy.webp","sha256":"01f35c652289894a8f1cfd89ec408a0372ada0110b7d7451ff2258019d5061bf","bytes":168454},"promptMatchesRegistry":true,"hash":"fcbc0c1e1304dd1a46591b2d457a8098ade4dfffa39b3e1b9c7f8d814f13b461"}
63
+ {"index":62,"prev":"fcbc0c1e1304dd1a46591b2d457a8098ade4dfffa39b3e1b9c7f8d814f13b461","kind":"confirm","source":"manifest+registry","at":"2026-10-03T16:41:14.212Z","name":"canon_sleepy_v2","skin":"canon","mood":"sleepy","registry":{"tool":"generate_image","createdAt":"2026-10-03T16:37:47.052Z","localPath":"assets/image/canon_sleepy_v2_20261003163747.png"},"master":{"path":"E:\\github\\wisp-art\\assets\\image\\canon_sleepy_v2_20261003163747.png","sha256":"c0ab08eaf70931d15090361232cb66ad64d1fbef651d327ee5203a800bbf4aa3"},"output":{"path":"assets/canon/sleepy.webp","sha256":"9ef276ec97939aa9fcba0a98ed28f9ae7f4d8e1fc89a6505d2aa4eddf75f01ab","bytes":151408},"promptMatchesRegistry":true,"hash":"ac3940d11eb0e4e7bc9ef2ff600361278813f82adec2edc89eb2efdf4f28ac7e"}
64
+ {"index":63,"prev":"ac3940d11eb0e4e7bc9ef2ff600361278813f82adec2edc89eb2efdf4f28ac7e","kind":"confirm","source":"manifest+registry","at":"2026-10-03T16:41:14.212Z","name":"canon_work_v2","skin":"canon","mood":"work","registry":{"tool":"generate_image","createdAt":"2026-10-03T16:38:21.816Z","localPath":"assets/image/canon_work_v2_20261003163821.png"},"master":{"path":"E:\\github\\wisp-art\\assets\\image\\canon_work_v2_20261003163821.png","sha256":"b713711e5943633e027d76b95304d5f20915214b551b3b54489d68389e982646"},"output":{"path":"assets/canon/work.webp","sha256":"d2bc5e9c88e077786afaf0572d41ca8f8d7c6542a2236db75eed2daa66662617","bytes":155260},"promptMatchesRegistry":true,"hash":"6dcdbcaaf0725039b5f23953c9afbff2b56d82f6b1ca70f0011380680d8da965"}
65
+ {"index":64,"prev":"6dcdbcaaf0725039b5f23953c9afbff2b56d82f6b1ca70f0011380680d8da965","kind":"confirm","source":"manifest+registry","at":"2026-10-03T16:41:14.212Z","name":"canon_attn_v2","skin":"canon","mood":"attn","registry":{"tool":"generate_image","createdAt":"2026-10-03T16:38:51.254Z","localPath":"assets/image/canon_attn_v2_20261003163851.png"},"master":{"path":"E:\\github\\wisp-art\\assets\\image\\canon_attn_v2_20261003163851.png","sha256":"3277ae886f6d084a47a09850e4ac18689ff90a9bc1793b49a9562d61baebfe36"},"output":{"path":"assets/canon/attn.webp","sha256":"0894e83dbd96be38f78e575c586f073056ed68d298fc3e35032db402497b3a6b","bytes":148504},"promptMatchesRegistry":true,"hash":"b6a5f54cc1c3f470fd318ac0e0376a37a20532c490915dd2e49f81f6f297ebab"}
66
+ {"index":65,"prev":"b6a5f54cc1c3f470fd318ac0e0376a37a20532c490915dd2e49f81f6f297ebab","kind":"confirm","source":"manifest+registry","at":"2026-10-03T16:41:14.212Z","name":"canon_poked_v2","skin":"canon","mood":"poked","registry":{"tool":"generate_image","createdAt":"2026-10-03T16:39:26.067Z","localPath":"assets/image/canon_poked_v2_20261003163926.png"},"master":{"path":"E:\\github\\wisp-art\\assets\\image\\canon_poked_v2_20261003163926.png","sha256":"3019dd7faebce588f2ae10c914500d3ef9248e608231952bb7be8a0c1ebb16a2"},"output":{"path":"assets/canon/poked.webp","sha256":"7738a9e3090b91ea89cb2e78f6c8bc5c37c684570c81568ae05e739b5efcefc8","bytes":158842},"promptMatchesRegistry":true,"hash":"fe6b8d80ee4dd8374d7ac1e7d920ac31d358da355da04bc1e4de2a677a341301"}
67
+ {"index":66,"prev":"fe6b8d80ee4dd8374d7ac1e7d920ac31d358da355da04bc1e4de2a677a341301","kind":"confirm","source":"manifest+registry","at":"2026-10-03T16:41:14.212Z","name":"canon_proud_v2","skin":"canon","mood":"proud","registry":{"tool":"generate_image","createdAt":"2026-10-03T16:40:00.601Z","localPath":"assets/image/canon_proud_v2_20261003164000.png"},"master":{"path":"E:\\github\\wisp-art\\assets\\image\\canon_proud_v2_20261003164000.png","sha256":"63f26371746cb05ec651ed009f20b57c126c1837ec684e64696b5f75384a7793"},"output":{"path":"assets/canon/proud.webp","sha256":"11601a73ed1e4b7b94bebaf3f7a0488de729dfc3db7707a2f88c5604246eb298","bytes":149524},"promptMatchesRegistry":true,"hash":"3b1fe5ff8cb11a415f3bae895b20ec9f32d35c812e131fcc45b3ad81066528f0"}
68
+ {"index":67,"prev":"3b1fe5ff8cb11a415f3bae895b20ec9f32d35c812e131fcc45b3ad81066528f0","kind":"confirm","source":"manifest+registry","at":"2026-10-03T16:41:14.212Z","name":"canon_eat_v2","skin":"canon","mood":"eat","registry":{"tool":"generate_image","createdAt":"2026-10-03T16:40:51.342Z","localPath":"assets/image/canon_eat_v2_20261003164051.png"},"master":{"path":"E:\\github\\wisp-art\\assets\\image\\canon_eat_v2_20261003164051.png","sha256":"13f87bf4440cba18044224b5f0683bf0881684926553fd8550150aaa1b5ac377"},"output":{"path":"assets/canon/eat.webp","sha256":"ed9615e943c4320a317d85bf938a0cf75f450c81da66d363e812a2ecfd0ff987","bytes":147480},"promptMatchesRegistry":true,"hash":"88e6cbe32451e64abe39cc627d3856fd925cf8957fc02a5625a89df532e288f9"}
69
+ {"index":68,"prev":"88e6cbe32451e64abe39cc627d3856fd925cf8957fc02a5625a89df532e288f9","kind":"confirm","source":"manifest+registry","at":"2026-10-03T16:41:14.427Z","name":"classic_idle_v2","skin":"classic","mood":"idle","registry":{"tool":"generate_image","createdAt":"2026-10-03T16:25:19.137Z","localPath":"assets/image/classic_idle_v2_20261003162519.png"},"master":{"path":"E:\\github\\wisp-art\\assets\\image\\classic_idle_v2_20261003162519.png","sha256":"9e04e6794cdb39744d1f2baef8ce0779647511f0b82abdb47a837ab2d19e7ab5"},"output":{"path":"assets/classic/idle.webp","sha256":"6a0515d50595e8073ba1c2da157982b7262d156c9c325e8a7722d29a022ce142","bytes":109818},"promptMatchesRegistry":true,"hash":"85786af9018dcb4602c3c42423f06988e35832a8578a731664ad58bee1731a31"}
70
+ {"index":69,"prev":"85786af9018dcb4602c3c42423f06988e35832a8578a731664ad58bee1731a31","kind":"confirm","source":"manifest+registry","at":"2026-10-03T16:41:14.427Z","name":"classic_happy_v2","skin":"classic","mood":"happy","registry":{"tool":"generate_image","createdAt":"2026-10-03T16:26:00.255Z","localPath":"assets/image/classic_happy_v2_20261003162600.png"},"master":{"path":"E:\\github\\wisp-art\\assets\\image\\classic_happy_v2_20261003162600.png","sha256":"47a18378b7dded9be18e7fff10f2c80ffcc4a12460004af246f4c9650072dc3b"},"output":{"path":"assets/classic/happy.webp","sha256":"cb6e095c8a5660d4b0aabca5a3dc51b4413b7c7878622e722f6962e6d3c2ff27","bytes":121596},"promptMatchesRegistry":true,"hash":"c55aeecd5fcdac302ac6aef458585b54cc0b7cd421eeebaaa556f27525d4d595"}
71
+ {"index":70,"prev":"c55aeecd5fcdac302ac6aef458585b54cc0b7cd421eeebaaa556f27525d4d595","kind":"confirm","source":"manifest+registry","at":"2026-10-03T16:41:14.427Z","name":"classic_sleepy_v2","skin":"classic","mood":"sleepy","registry":{"tool":"generate_image","createdAt":"2026-10-03T16:26:48.056Z","localPath":"assets/image/classic_sleepy_v2_20261003162648.png"},"master":{"path":"E:\\github\\wisp-art\\assets\\image\\classic_sleepy_v2_20261003162648.png","sha256":"e9b2ae47be5f0d975cb418e8e617a25c1a8d7e1150236235dd95f84e941b8f94"},"output":{"path":"assets/classic/sleepy.webp","sha256":"b2f0fa8abd6cb141eea431a41c1075b432e76072477a9e79548d4a16ee3913e9","bytes":90266},"promptMatchesRegistry":true,"hash":"ff69f98c10e9ccd6b83ab4737141d6e5a3d4e59a71e00b08172da50065d59307"}
72
+ {"index":71,"prev":"ff69f98c10e9ccd6b83ab4737141d6e5a3d4e59a71e00b08172da50065d59307","kind":"confirm","source":"manifest+registry","at":"2026-10-03T16:41:14.427Z","name":"classic_work_v2","skin":"classic","mood":"work","registry":{"tool":"generate_image","createdAt":"2026-10-03T16:27:20.292Z","localPath":"assets/image/classic_work_v2_20261003162720.png"},"master":{"path":"E:\\github\\wisp-art\\assets\\image\\classic_work_v2_20261003162720.png","sha256":"10efaacbbb353a4e2c78e9d59b27b95542fe0a94d3e6fa76e51ccd5573155b77"},"output":{"path":"assets/classic/work.webp","sha256":"93de2ba1bee1317216334b46aaf0c62f970ea68eb44dafe4fcb0273c72e6f066","bytes":106220},"promptMatchesRegistry":true,"hash":"192edfaeeabeb885eab97351e434a0824e6839aabc92a6ab53c35908bd848ced"}
73
+ {"index":72,"prev":"192edfaeeabeb885eab97351e434a0824e6839aabc92a6ab53c35908bd848ced","kind":"confirm","source":"manifest+registry","at":"2026-10-03T16:41:14.427Z","name":"classic_attn_v2","skin":"classic","mood":"attn","registry":{"tool":"generate_image","createdAt":"2026-10-03T16:28:14.325Z","localPath":"assets/image/classic_attn_v2_20261003162814.png"},"master":{"path":"E:\\github\\wisp-art\\assets\\image\\classic_attn_v2_20261003162814.png","sha256":"e74b16cada8014dea88ddfd22b4745b4d6ef71dd7ec6bb52b103212b8b319218"},"output":{"path":"assets/classic/attn.webp","sha256":"8ac2a02b9ba56aa4dbadde34cbf4bfda4e03c59d5cbe6f92a5cd27f07d7a2ec2","bytes":106618},"promptMatchesRegistry":true,"hash":"13f140d1dc8e73c7d5aa21992af583fee85fc165e3c73ed4578d5b2568a98394"}
74
+ {"index":73,"prev":"13f140d1dc8e73c7d5aa21992af583fee85fc165e3c73ed4578d5b2568a98394","kind":"confirm","source":"manifest+registry","at":"2026-10-03T16:41:14.427Z","name":"classic_poked_v2","skin":"classic","mood":"poked","registry":{"tool":"generate_image","createdAt":"2026-10-03T16:29:09.675Z","localPath":"assets/image/classic_poked_v2_20261003162909.png"},"master":{"path":"E:\\github\\wisp-art\\assets\\image\\classic_poked_v2_20261003162909.png","sha256":"acad516dfc8cf0500395f619aa9a253c37cfe7878ec132713503282578e39d31"},"output":{"path":"assets/classic/poked.webp","sha256":"6e2b52172a925d1caa787ffda1d7c5fd8ad9dee4810533fa7d6500475614a43d","bytes":121044},"promptMatchesRegistry":true,"hash":"c4df82d8a24cb8c59ba9c2055d114bcc63c7628b4e6a57d2c336b038026bf6bf"}
75
+ {"index":74,"prev":"c4df82d8a24cb8c59ba9c2055d114bcc63c7628b4e6a57d2c336b038026bf6bf","kind":"confirm","source":"manifest+registry","at":"2026-10-03T16:41:14.427Z","name":"classic_proud_v2","skin":"classic","mood":"proud","registry":{"tool":"generate_image","createdAt":"2026-10-03T16:29:37.465Z","localPath":"assets/image/classic_proud_v2_20261003162937.png"},"master":{"path":"E:\\github\\wisp-art\\assets\\image\\classic_proud_v2_20261003162937.png","sha256":"92113d8d5e6e301d3ccd16bfc3826050b0cd8bef10cccc9c956b0250487c0ef7"},"output":{"path":"assets/classic/proud.webp","sha256":"2de0555f098749ce0b9ffe327921b2b2ee190d95d152721ffc6f51a771fcbee0","bytes":103570},"promptMatchesRegistry":true,"hash":"79fa1784e135b4bb9a04fca630ed9fab7dfec7207d669ad3a9001707e5106d11"}
76
+ {"index":75,"prev":"79fa1784e135b4bb9a04fca630ed9fab7dfec7207d669ad3a9001707e5106d11","kind":"confirm","source":"manifest+registry","at":"2026-10-03T16:41:14.427Z","name":"classic_eat_v2","skin":"classic","mood":"eat","registry":{"tool":"generate_image","createdAt":"2026-10-03T16:30:10.148Z","localPath":"assets/image/classic_eat_v2_20261003163010.png"},"master":{"path":"E:\\github\\wisp-art\\assets\\image\\classic_eat_v2_20261003163010.png","sha256":"c5cddc77205e4f26176668cd7ab3b881bc1cc5bec08a2db5586686539d530366"},"output":{"path":"assets/classic/eat.webp","sha256":"068e1bfb5391523a6864872a1811ca69481b3b754b32ee1155b5e53b6170c145","bytes":110174},"promptMatchesRegistry":true,"hash":"f9bd45f51737dbfc7f8f211eae18a609add058ab0c5be9ed1a0d7fd5529b21c9"}
77
+ {"index":76,"prev":"f9bd45f51737dbfc7f8f211eae18a609add058ab0c5be9ed1a0d7fd5529b21c9","kind":"confirm","source":"manifest+registry","at":"2026-10-03T16:41:14.613Z","name":"pajama_idle_v2","skin":"pajama","mood":"idle","registry":{"tool":"generate_image","createdAt":"2026-10-03T16:30:43.442Z","localPath":"assets/image/pajama_idle_v2_20261003163043.png"},"master":{"path":"E:\\github\\wisp-art\\assets\\image\\pajama_idle_v2_20261003163043.png","sha256":"8e0f62ed8b9a7b366064fc02365f4c1cb4d2926c5cdf8a331c21256828f3aacc"},"output":{"path":"assets/pajama/idle.webp","sha256":"f057c915fee2ba0f26a093a0ad90967ac22bbc0a4f0cd1eb1d178a079b3fc483","bytes":132796},"promptMatchesRegistry":true,"hash":"db2f6c7615925547b9d72ec5925436ac51af78003f0a2ff7dbb85ac74810c5b6"}
78
+ {"index":77,"prev":"db2f6c7615925547b9d72ec5925436ac51af78003f0a2ff7dbb85ac74810c5b6","kind":"confirm","source":"manifest+registry","at":"2026-10-03T16:41:14.613Z","name":"pajama_happy_v2","skin":"pajama","mood":"happy","registry":{"tool":"generate_image","createdAt":"2026-10-03T16:31:14.532Z","localPath":"assets/image/pajama_happy_v2_20261003163114.png"},"master":{"path":"E:\\github\\wisp-art\\assets\\image\\pajama_happy_v2_20261003163114.png","sha256":"b2ba0ad41b9898d72010f41039ffaee137270ac7a2778f1d0ed35e32360cd407"},"output":{"path":"assets/pajama/happy.webp","sha256":"2cc63154f05424c119634ec0cccf98a03eb85f14ab5614f9414fe0d1584b2a8f","bytes":144350},"promptMatchesRegistry":true,"hash":"0fe82d1a3a683cb89f44b5d87e738cf0b5899bfff87957f5541bde5cac24a467"}
79
+ {"index":78,"prev":"0fe82d1a3a683cb89f44b5d87e738cf0b5899bfff87957f5541bde5cac24a467","kind":"confirm","source":"manifest+registry","at":"2026-10-03T16:41:14.613Z","name":"pajama_sleepy_v2","skin":"pajama","mood":"sleepy","registry":{"tool":"generate_image","createdAt":"2026-10-03T16:31:43.942Z","localPath":"assets/image/pajama_sleepy_v2_20261003163143.png"},"master":{"path":"E:\\github\\wisp-art\\assets\\image\\pajama_sleepy_v2_20261003163143.png","sha256":"6d2eef6fba63ca0f67bb82a1f09ed889e4c80fa949e230a79b7c148e2cd80434"},"output":{"path":"assets/pajama/sleepy.webp","sha256":"a25e3d97e2e4e9c3b9c864db41c3781e93f7d890476381eb9e7554246c589d63","bytes":116924},"promptMatchesRegistry":true,"hash":"c1b5a73b01b8a0ec346179e8098ae59810a81aa2d992f34117dbc5d1f417c3c2"}
80
+ {"index":79,"prev":"c1b5a73b01b8a0ec346179e8098ae59810a81aa2d992f34117dbc5d1f417c3c2","kind":"confirm","source":"manifest+registry","at":"2026-10-03T16:41:14.613Z","name":"pajama_work_v2","skin":"pajama","mood":"work","registry":{"tool":"generate_image","createdAt":"2026-10-03T16:32:21.018Z","localPath":"assets/image/pajama_work_v2_20261003163221.png"},"master":{"path":"E:\\github\\wisp-art\\assets\\image\\pajama_work_v2_20261003163221.png","sha256":"791c29b4344191dff42ba42596e5baddeace7e65ce2b3de75251a6a5a8f88b69"},"output":{"path":"assets/pajama/work.webp","sha256":"ab0d301d22909d22de87a596bc5ea88f510910d085573d1a3a3987bbfbf79d7e","bytes":115560},"promptMatchesRegistry":true,"hash":"6b5de25b4169f002ecb4c5a3e5935601eaea7c63123c063ca24d2872503708e6"}
81
+ {"index":80,"prev":"6b5de25b4169f002ecb4c5a3e5935601eaea7c63123c063ca24d2872503708e6","kind":"confirm","source":"manifest+registry","at":"2026-10-03T16:41:14.613Z","name":"pajama_attn_v2","skin":"pajama","mood":"attn","registry":{"tool":"generate_image","createdAt":"2026-10-03T16:33:11.405Z","localPath":"assets/image/pajama_attn_v2_20261003163311.png"},"master":{"path":"E:\\github\\wisp-art\\assets\\image\\pajama_attn_v2_20261003163311.png","sha256":"d54266727f5e01dcc02b74031e907430daa8616e0fe6d51d284f406946931e05"},"output":{"path":"assets/pajama/attn.webp","sha256":"8a926dfa392867ce3332e1cf919bf5e9d43c6f52fdd19a0566e88035dc1fa59a","bytes":120392},"promptMatchesRegistry":true,"hash":"33915b71ce7ef8457c44ed363f0f0db6c2446a1ef83ee07bacfae4e7eb691117"}
82
+ {"index":81,"prev":"33915b71ce7ef8457c44ed363f0f0db6c2446a1ef83ee07bacfae4e7eb691117","kind":"confirm","source":"manifest+registry","at":"2026-10-03T16:41:14.613Z","name":"pajama_poked_v2","skin":"pajama","mood":"poked","registry":{"tool":"generate_image","createdAt":"2026-10-03T16:33:50.743Z","localPath":"assets/image/pajama_poked_v2_20261003163350.png"},"master":{"path":"E:\\github\\wisp-art\\assets\\image\\pajama_poked_v2_20261003163350.png","sha256":"6670292882be18c8734c1bf9e42a61a51bbc09f5dad2feefbeeaedd5e2eb7432"},"output":{"path":"assets/pajama/poked.webp","sha256":"b8555dcd9f63d42c46146d5aa36faf7b4d6cf9fae63a9c2ef641babd04393b72","bytes":122020},"promptMatchesRegistry":true,"hash":"61ab263779ba71e61a6bae61bcb55216dc44b0e1d3b8d0ed2829f595fbaec11d"}
83
+ {"index":82,"prev":"61ab263779ba71e61a6bae61bcb55216dc44b0e1d3b8d0ed2829f595fbaec11d","kind":"confirm","source":"manifest+registry","at":"2026-10-03T16:41:14.613Z","name":"pajama_proud_v2","skin":"pajama","mood":"proud","registry":{"tool":"generate_image","createdAt":"2026-10-03T16:34:32.917Z","localPath":"assets/image/pajama_proud_v2_20261003163432.png"},"master":{"path":"E:\\github\\wisp-art\\assets\\image\\pajama_proud_v2_20261003163432.png","sha256":"a768144bd0cfc9c2e4d89975a5ef2ff5d0362209194581e25099d8fd9fab0882"},"output":{"path":"assets/pajama/proud.webp","sha256":"d3ea878ca25322f5a7d0972cc6093069ba424cfac3f33d97f1181157ecd68c9e","bytes":133904},"promptMatchesRegistry":true,"hash":"06e332372f56c6004366b3be1c5b8f54a08fb52f687d2e79f8860b0f559e71ed"}
84
+ {"index":83,"prev":"06e332372f56c6004366b3be1c5b8f54a08fb52f687d2e79f8860b0f559e71ed","kind":"confirm","source":"manifest+registry","at":"2026-10-03T16:41:14.613Z","name":"pajama_eat_v2","skin":"pajama","mood":"eat","registry":{"tool":"generate_image","createdAt":"2026-10-03T16:35:04.733Z","localPath":"assets/image/pajama_eat_v2_20261003163504.png"},"master":{"path":"E:\\github\\wisp-art\\assets\\image\\pajama_eat_v2_20261003163504.png","sha256":"be58911cadeab8d1802edd15860537c1220336161a0b46c498f0c787e45c2770"},"output":{"path":"assets/pajama/eat.webp","sha256":"36de3b11e9d0787fe58320ae90368c75950e2b5af3d90cd72d9b2fa169e45c26","bytes":115012},"promptMatchesRegistry":true,"hash":"50cf9084b96e0d15e9d4018f6635d0ca7694b66e4b605cb770529ccfc9743981"}
85
+ {"index":84,"prev":"50cf9084b96e0d15e9d4018f6635d0ca7694b66e4b605cb770529ccfc9743981","kind":"confirm","source":"manifest+registry","at":"2026-10-03T16:41:14.808Z","name":"night_attn_v3","skin":"night","mood":"attn","registry":{"tool":"generate_image","createdAt":"2026-10-03T16:14:09.723Z","localPath":"assets/image/night_attn_v3_20261003161409.png"},"master":{"path":"E:\\github\\wisp-art\\assets\\image\\night_attn_v3_20261003161409.png","sha256":"ca4620dfbeb128adda7545a7191077504d0403a2211a66b9a3ffb8858c88e71b"},"output":{"path":"assets/night/attn.webp","sha256":"d2a0881ae465be8161e904406eb36bb87cd4f2ca8a90c2b6f1111c93f88a3299","bytes":126352},"promptMatchesRegistry":true,"hash":"bbf361a33cc7ef5dad9dcd8790be1a830bb5043294f272d86584c20073fc5605"}
86
+ {"index":85,"prev":"bbf361a33cc7ef5dad9dcd8790be1a830bb5043294f272d86584c20073fc5605","kind":"confirm","source":"manifest+registry","at":"2026-10-04T02:00:58.785Z","name":"classic_attn_v2","skin":"classic","mood":"attn","registry":{"tool":"generate_image","createdAt":"2026-10-04T01:59:37.355Z","localPath":"assets/image/classic_attn_v2_20261004015937.png"},"master":{"path":"E:\\github\\wisp-art\\assets\\image\\classic_attn_v2_20261004015937.png","sha256":"4fd647ce8d9bf92ead5a58e257fc1179a82c169218f992a1b7c87223002b92f9"},"output":{"path":"assets/classic/attn.webp","sha256":"f7eced59d293ef0c0859fec2e83551b9e31d52e46e146e525d4f2285e8aac3ea","bytes":117904},"promptMatchesRegistry":true,"hash":"cf936b466e164f84554aae41e663ae326d43006b25504b30bd5cfa1baa052c88"}
87
+ {"index":86,"prev":"cf936b466e164f84554aae41e663ae326d43006b25504b30bd5cfa1baa052c88","kind":"confirm","source":"manifest+registry","at":"2026-10-04T02:00:58.785Z","name":"classic_sleepy_v2","skin":"classic","mood":"sleepy","registry":{"tool":"generate_image","createdAt":"2026-10-04T02:00:28.223Z","localPath":"assets/image/classic_sleepy_v2_20261004020028.png"},"master":{"path":"E:\\github\\wisp-art\\assets\\image\\classic_sleepy_v2_20261004020028.png","sha256":"1a46e2f9b51644d8946e3d282b0b19cc10d6eaf9b1fd4c8efe51b462473c2216"},"output":{"path":"assets/classic/sleepy.webp","sha256":"95f7bd8ea5b2151cb7480c9730fd9de6c3018a59f13346a225d7b73bc3bb445e","bytes":90450},"promptMatchesRegistry":true,"hash":"fbdbc2be6e4ca979d137ad9e5b9417f3bf067afb6d7d63d11acf70440848ebe3"}
88
+ {"index":87,"prev":"fbdbc2be6e4ca979d137ad9e5b9417f3bf067afb6d7d63d11acf70440848ebe3","kind":"confirm","source":"manifest+registry","at":"2026-10-04T02:03:11.884Z","name":"classic_sleepy_restore","skin":"classic","mood":"sleepy","registry":{"tool":null,"createdAt":null,"localPath":null,"note":"登记表里没找到这次调用"},"master":null,"output":{"path":"assets/classic/sleepy.webp","sha256":"706b718e4ea9fcaa882c41e21721d1ea1bdcb70de4015621946db6b8b9c7a5a8","bytes":99548},"promptMatchesRegistry":null,"hash":"d5fb324e49c38cbe01708b62d1deade3e4b9fb21b08b8ad19f2e8e21c546b205"}
89
+ {"index":88,"prev":"d5fb324e49c38cbe01708b62d1deade3e4b9fb21b08b8ad19f2e8e21c546b205","kind":"confirm","source":"manifest+registry","at":"2026-10-04T04:48:13.851Z","name":"canon_eat_v2","skin":"canon","mood":"eat","registry":{"tool":"generate_image","createdAt":"2026-10-04T04:47:29.389Z","localPath":"assets/image/canon_eat_v2_20261004044729.png"},"master":{"path":"E:\\github\\wisp-art\\assets\\image\\canon_eat_v2_20261004044729.png","sha256":"b23946fba3b9e0038afd50ba9e3c6bb3a13f02ff2a5bb1d71a9457ff6d80214a"},"output":{"path":"assets/canon/eat.webp","sha256":"cfaba26c33207a9c238185fe378873d6aba6a0e757fb6cdafdc8c314454219ff","bytes":142804},"promptMatchesRegistry":true,"hash":"852b517022616841cf067d9e6817adc44e929aec67bdab406e1391a46a945ebe"}
90
+ {"index":89,"prev":"852b517022616841cf067d9e6817adc44e929aec67bdab406e1391a46a945ebe","kind":"confirm","source":"manifest+registry","at":"2026-10-04T04:48:13.851Z","name":"canon_proud_v2","skin":"canon","mood":"proud","registry":{"tool":"generate_image","createdAt":"2026-10-04T04:45:04.812Z","localPath":"assets/image/canon_proud_v2_20261004044504.png"},"master":{"path":"E:\\github\\wisp-art\\assets\\image\\canon_proud_v2_20261004044504.png","sha256":"21705230dab1cbd0c0c79a0ed4eae88965b3a5da068db3b67c726c2b73110240"},"output":{"path":"assets/canon/proud.webp","sha256":"dda34cdfc15a978d22f8510c60ac77776f0369607ed27ee943c634628c441ecc","bytes":155564},"promptMatchesRegistry":true,"hash":"1c16a355db3e865cd15f9382e9d22d8ae8477e3ab7cc37042d19a29ab608ebcb"}
91
+ {"index":90,"prev":"1c16a355db3e865cd15f9382e9d22d8ae8477e3ab7cc37042d19a29ab608ebcb","kind":"confirm","source":"manifest+registry","at":"2026-10-04T04:48:13.851Z","name":"night_attn_v2","skin":"night","mood":"attn","registry":{"tool":"generate_image","createdAt":"2026-10-04T04:45:42.398Z","localPath":"assets/image/night_attn_v2_20261004044542.png"},"master":{"path":"E:\\github\\wisp-art\\assets\\image\\night_attn_v2_20261004044542.png","sha256":"311785107cce171a0a45d91b88393e15843790e3e8afe9c1e966a8939ca9ddf8"},"output":{"path":"assets/night/attn.webp","sha256":"0201cd3efa497cb930677fcb492cec8dd3d4b23908aecbb2dd1972126fc79efd","bytes":127434},"promptMatchesRegistry":true,"hash":"c4ee657040eba4a48b5dfa003badf2f846bdddfbe62f12272ae1cf68f9791c3a"}
92
+ {"index":91,"prev":"c4ee657040eba4a48b5dfa003badf2f846bdddfbe62f12272ae1cf68f9791c3a","kind":"confirm","source":"manifest+registry","at":"2026-10-04T04:48:13.851Z","name":"deepsea_poked_v2","skin":"deepsea","mood":"poked","registry":{"tool":"generate_image","createdAt":"2026-10-04T04:46:22.297Z","localPath":"assets/image/deepsea_poked_v2_20261004044622.png"},"master":{"path":"E:\\github\\wisp-art\\assets\\image\\deepsea_poked_v2_20261004044622.png","sha256":"d20269b8b0d5171dd25bdd21408ac18221b3ebc8f67c2dc23a9720f3392b2c95"},"output":{"path":"assets/deepsea/poked.webp","sha256":"78bb0e20ce3a7e7c26f7ea3b29b6d96e9ec11ab44b88661d02f20f19abc09d22","bytes":135252},"promptMatchesRegistry":true,"hash":"512a9a044efa6b316f4245d557a64b3471a2187d5e71e59a77d4445249471b43"}
package/build.mjs CHANGED
@@ -1,14 +1,27 @@
1
1
  /* ============================================================================
2
2
  build.mjs — inline the sprites into lib/client.js.
3
3
 
4
- lib/client.template.js holds the whole browser half with one placeholder,
5
- __SPRITES__. This script replaces it with a small object of data URIs:
4
+ lib/client.template.js holds the whole browser half with two placeholders.
5
+ __SPRITES_LITERAL__ is replaced with a small object of data URIs:
6
6
 
7
7
  { idle: "data:image/webp;base64,…", happy: …, sleepy: …, work: … }
8
8
 
9
- Embedding rather than shipping asset files is deliberate: the delivered
10
- plugin is a single self-contained file, so a share carries no path, no
11
- extra route, and no missing-asset failure mode.
9
+ …and __MOTION_LITERAL__ with the frame-animation **manifest** — v1.47.0: a small
10
+ table of clip file names, NOT the bytes. The bytes stay in assets/motion/
11
+ and are served to the page by the host half (lib/index.js registers
12
+ `/wisp-motion/` on the platform's HTTP carrier); the client half resolves
13
+ `new URL('wisp-motion/<file>', document.baseURI)`. Two 720p clips
14
+ base64-inlined to 7.83 MB of lib/client.js and the eight swimsuit clips
15
+ would have added ~30 MB more — multi-megabyte clips belong on disk, not
16
+ inside a single-file bundle:
17
+
18
+ { idle: "idle.webp", sleepy: "sleepy.webp", swim_idle: "swim_idle.webp", ... }
19
+
20
+ Embedding the SPRITES stays deliberate: the delivered plugin is a single
21
+ self-contained client file, so a share carries no path, no extra route, and
22
+ no missing-asset failure mode — for ~120 KB sprites that trade is a clear
23
+ win. The clips are the one asset class where it goes the other way, and they
24
+ degrade silently back to the static sprite when the route is absent.
12
25
 
13
26
  RUN
14
27
  node build.mjs # default tier: 1024x1536 —— 这一档进包,也是唯一被显示的
@@ -53,11 +66,13 @@ const OPTIONAL_MOODS = ['report']
53
66
  /* 皮肤 = assets/ 下的一个子目录,里面是这套皮肤的 <mood>[_tier].webp。
54
67
  如果没有子目录含精灵图,就把 assets/ 本身当作一个名为 default 的皮肤 ——
55
68
  这样 --from <任意目录> 的单套素材用法仍然成立。 */
56
- const SKIN_LABELS = { deepsea: '深海女仆', canon: '原版女仆', classic: '素绘女仆', default: '默认' }
69
+ /* 这份只用于构建日志(菜单用的是客户端半包里那份)。原来它漏了 night / pajama,
70
+ 构建时显示的是裸 id —— 顺手补齐,免得下一次又以为"名字没生效"。 */
71
+ const SKIN_LABELS = { deepsea: '深海女仆', canon: '原版女仆', classic: '素绘女仆', night: '宵蓝礼服', pajama: '宵眠睡衣', swim: '碧海泳装', default: '默认' }
57
72
  const skinLabel = (id) => SKIN_LABELS[id] ?? id
58
73
  /* 顺序即优先级:列表里第一个就是默认皮肤。不这么写的话默认值会由目录名的字母序
59
74
  决定 —— 那是构建实现的偶然,不该变成产品行为。未列出的排在后面。 */
60
- const SKIN_PRIORITY = ['deepsea', 'canon', 'classic', 'night', 'pajama']
75
+ const SKIN_PRIORITY = ['deepsea', 'canon', 'classic', 'night', 'pajama', 'swim']
61
76
  const skinRank = (id) => {
62
77
  const at = SKIN_PRIORITY.indexOf(id)
63
78
  return at < 0 ? SKIN_PRIORITY.length : at
@@ -93,9 +108,16 @@ const pickFile = (dir, mood) => {
93
108
  }
94
109
  const hasSprite = (dir) => MOODS.some((mood) => pickFile(dir, mood) !== null)
95
110
 
111
+ /* assets/ 下的两个保留目录不是皮肤:audio/ 是音效,motion/ 是帧动画素材。
112
+ v1.46.1 必须显式排除 motion/ —— 动图叫 sleepy.webp,正好和"sleepy 这个心情的
113
+ 精灵图"同名,于是 hasSprite() 会把整个 motion/ 当成一套皮肤,然后在缺 idle 的
114
+ 那一刻把构建打红。名字撞车不是素材的错,是这里的发现规则漏了一条。 */
115
+ const RESERVED_DIRS = ['audio', 'motion']
116
+
96
117
  const skinIds = readdirSync(assetsDir, { withFileTypes: true })
97
118
  .filter((e) => e.isDirectory())
98
119
  .map((e) => e.name)
120
+ .filter((name) => !RESERVED_DIRS.includes(name))
99
121
  .filter((name) => hasSprite(join(assetsDir, name)))
100
122
  .sort((a, b) => skinRank(a) - skinRank(b) || a.localeCompare(b))
101
123
  const legacySingleSkin = skinIds.length === 0 && hasSprite(assetsDir)
@@ -119,6 +141,44 @@ if (existsSync(audioDir)) {
119
141
  }
120
142
  if (Object.keys(sounds).length > 0) console.log(` audio: ${Object.keys(sounds).join(', ')}`)
121
143
 
144
+ /* ---- 帧动画(motion):assets/motion/<皮肤>_<状态>.webp -> { <素材名>: "<文件名>.webp" }。
145
+
146
+ v1.47.0 起这里是**清单,不是字节**。表里存的是文件名,字节留在
147
+ assets/motion/ 里,由宿主半包(lib/index.js)注册的 `/wisp-motion/` 路由
148
+ 发到页面上;客户端半包拿到的是 `new URL('wisp-motion/<文件>', baseURI)`。
149
+ 为什么必须这样:720p 的动图是 MB 级素材 —— 通用那两条内联就是 7.83 MB,
150
+ 八条泳装再加约 30 MB,浏览器半包会到 ~45 MB。素材放哪儿是"投递"要回答的
151
+ 问题,不是"再压一压"能解决的;把 ~30 MB 从单文件里挪到十几个静态文件,
152
+ 客户端半包回到 ~7 MB,而她现在还是那一个她。
153
+
154
+ 和音效同一档待遇:**可选**。没有文件就是空对象,客户端据此连 <img> 都不建 ——
155
+ 一个"永远不播的空盒子"比没有它更糟(它会占位、会吃内存、还要有人去解释它)。
156
+
157
+ 为什么只认 .webp:这一档素材是**动图 WebP**(VP8X + 一串 ANMF,alpha 写在
158
+ 格式里)。v1.46.1 之前这里是 alpha 视频(.webm / VP9 + alpha 平面),换掉的
159
+ 原因是**这个壳不还原 VP9 的 alpha** —— 同一段素材她在暗色主题下渲染成黑色
160
+ 剪影、亮色主题下白色剪影(用户确认过)。图片路径的 alpha 是硬的:<img> 播
161
+ 动图时浏览器直接按 alpha 合成。收别的格式进来,透明处会变成一块黑底。
162
+ 扩展名之外还要验 RIFF/WEBP 魔数:名字对了、内容不是 WebP 的失败是**静默**的
163
+ (<img> 加载失败、画面回到立绘),只有构建能拦。 */
164
+ const motionDir = join(assetsDir, 'motion')
165
+ const motion = {}
166
+ let motionRaw = 0
167
+ for (const name of existsSync(motionDir) ? readdirSync(motionDir).sort() : []) {
168
+ if (!name.toLowerCase().endsWith('.webp')) continue
169
+ const file = join(motionDir, name)
170
+ const bytes = readFileSync(file)
171
+ const riff = bytes.length > 12 && bytes.toString('latin1', 0, 4) === 'RIFF' && bytes.toString('latin1', 8, 12) === 'WEBP'
172
+ if (!riff) {
173
+ console.error(`build: assets/motion/${name} is not a WebP (RIFF….WEBP) — the page would show a broken image and silently fall back`)
174
+ process.exit(1)
175
+ }
176
+ const key = name.slice(0, -'.webp'.length)
177
+ motion[key] = name
178
+ motionRaw += bytes.length
179
+ console.log(` motion: ${key} ${(bytes.length / 1024).toFixed(1)} KB on disk -> /wisp-motion/${name}`)
180
+ }
181
+
122
182
  const sprites = {}
123
183
  let total = 0
124
184
  for (const skin of skins) {
@@ -146,6 +206,7 @@ for (const skin of skins) {
146
206
  }
147
207
 
148
208
  const PLACEHOLDER = '__SPRITES_LITERAL__'
209
+ const MOTION_PLACEHOLDER = '__MOTION_LITERAL__'
149
210
  const template = readFileSync(templatePath, 'utf8')
150
211
  const placeholderCount = template.split(PLACEHOLDER).length - 1
151
212
  if (placeholderCount !== 1) {
@@ -156,22 +217,39 @@ if (placeholderCount !== 1) {
156
217
  console.error(`build: template must contain ${PLACEHOLDER} exactly once (found ${placeholderCount})`)
157
218
  process.exit(1)
158
219
  }
220
+ const motionPlaceholderCount = template.split(MOTION_PLACEHOLDER).length - 1
221
+ if (motionPlaceholderCount !== 1) {
222
+ console.error(`build: template must contain ${MOTION_PLACEHOLDER} exactly once (found ${motionPlaceholderCount})`)
223
+ process.exit(1)
224
+ }
159
225
 
160
226
  const literal = '{\n' + skins.map((skin) => (
161
227
  ` ${JSON.stringify(skin)}: {\n`
162
228
  + MOODS.map((m) => ` ${m}: '${sprites[skin][m]}',`).join('\n')
163
229
  + '\n },'
164
230
  )).join('\n') + '\n }'
231
+ /* 空表也要是**合法的空对象**:没有 motion 素材的包照样能构建(客户端会连 <img> 都不建)。 */
232
+ const motionLiteral = '{\n' + Object.keys(motion).map((key) => (
233
+ ` ${JSON.stringify(key)}: '${motion[key]}',`
234
+ )).join('\n') + '\n }'
165
235
  const soundsInlined = template.replace(
166
236
  "const SOUNDS = (typeof __WISP_SOUNDS__",
167
237
  `const __WISP_SOUNDS__ = ${JSON.stringify(sounds)}\nconst SOUNDS = (typeof __WISP_SOUNDS__`,
168
238
  )
169
- const out = soundsInlined.replace(PLACEHOLDER, literal)
239
+ /* 用函数形式替换:base64 里不会有 `$`,但把替换值当**值**传递是唯一不用去想
240
+ `$&`/`$1` 转义问题的写法,而这两张表将来都可能换个编码。 */
241
+ const out = soundsInlined
242
+ .replace(MOTION_PLACEHOLDER, () => motionLiteral)
243
+ .replace(PLACEHOLDER, () => literal)
170
244
 
171
245
  if (out.includes(PLACEHOLDER)) {
172
246
  console.error('build: placeholder survived the substitution; refusing to write a broken bundle')
173
247
  process.exit(1)
174
248
  }
249
+ if (out.includes(MOTION_PLACEHOLDER)) {
250
+ console.error('build: the motion placeholder survived the substitution; refusing to write a broken bundle')
251
+ process.exit(1)
252
+ }
175
253
 
176
254
  /* ---- guard: never call a global the dynamic client runner traps ----------
177
255
  setTimeout/setInterval/clearTimeout/clearInterval/fetch/require are shadowed
@@ -233,11 +311,55 @@ try {
233
311
  process.exit(1)
234
312
  }
235
313
 
314
+ /* 同一道防线给 MOTION:表必须真的存在、真的能求值,而且每个值都必须是
315
+ assets/motion/ 下真实存在的 <名字>.webp(v1.47.0:是**文件名**,不是 data URI)。
316
+ 写坏一个 key(例如把 .webp 之外的素材塞进 assets/motion/、或者构建退回内联却
317
+ 只写了一半个表)时,客户端会建一个永远不动/一加载就报错的 <img>,而失败是
318
+ **静默**的 —— 只有这里能拦。 */
319
+ const motionTable = out.match(/const MOTION = \{([\s\S]*?)\n {4}\}/)
320
+ if (!motionTable) {
321
+ console.error('build: the injected MOTION table is missing; aborting')
322
+ process.exit(1)
323
+ }
324
+ try {
325
+ const value = new Function(`${motionTable[0]}\nreturn MOTION`)()
326
+ const broken = Object.keys(value).filter((key) => {
327
+ const file = value[key]
328
+ if (typeof file !== 'string' || !/^[A-Za-z0-9][A-Za-z0-9._-]*\.webp$/.test(file)) return true
329
+ return !existsSync(join(motionDir, file))
330
+ })
331
+ if (broken.length > 0) {
332
+ console.error(`build: MOTION entries are not clips that exist under assets/motion/: ${broken.join(', ')}; aborting`)
333
+ process.exit(1)
334
+ }
335
+ if (Object.keys(value).length !== Object.keys(motion).length) {
336
+ console.error(`build: MOTION holds ${Object.keys(value).length} clips, expected ${Object.keys(motion).length}; aborting`)
337
+ process.exit(1)
338
+ }
339
+ /* 内联的那一份必须**小**:它就是一张文件名清单(每条几十字节)。哪天有人
340
+ 把字节塞回表里,这一条会当场红 —— 那正是 1.47.0 要解决的事。 */
341
+ const inlineBytes = Object.entries(value).reduce((n, [k, v]) => n + String(k).length + String(v).length + 8, 0)
342
+ if (inlineBytes > 2048) {
343
+ console.error(`build: the MOTION manifest is ${inlineBytes} bytes — it must stay a name list (${Object.keys(value).length} clips); aborting`)
344
+ process.exit(1)
345
+ }
346
+ } catch (error) {
347
+ console.error(`build: injected MOTION table does not evaluate (${error.message}); aborting`)
348
+ process.exit(1)
349
+ }
350
+
236
351
  writeFileSync(outPath, out, 'utf8')
237
352
 
238
353
  const kb = (n) => (n / 1024).toFixed(1)
239
354
  console.log(`\n sprites total ${kb(total)} KB`)
240
355
  console.log(` base64 inlined ${kb(out.length)} KB`)
356
+ if (Object.keys(motion).length > 0) {
357
+ /* 帧动画的体积账单独打两行(v1.47.0):素材字节**不进包**,进包的只有一张
358
+ 文件名清单。预算(verify-wisp.mjs)盯的是这两件事分开的两个数:磁盘上
359
+ 有多少素材、单文件里为它多花了多少字节。 */
360
+ console.log(` motion clips ${kb(motionRaw)} KB on disk (${Object.keys(motion).join(', ')})`)
361
+ console.log(` motion manifest ${Object.values(motion).join('').length + Object.keys(motion).join('').length} B inlined base64 none — served by the host half at /wisp-motion/`)
362
+ }
241
363
  console.log(` wrote lib/client.js`)
242
364
 
243
365
  /* 体积与锐度是同一个决定的两面,所以把账算在构建输出里,而不是只写在文档里: