@linxin666/dsh-pet 0.2.4 → 0.2.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.
Files changed (45) hide show
  1. package/README.i18n.yaml +2 -2
  2. package/README.md +1 -1
  3. package/README.zh.md +1 -1
  4. package/lib/client.js +110 -28
  5. package/lib/client.js.map +1 -1
  6. package/lib/index.js +164 -34
  7. package/lib/types/access.d.ts +16 -0
  8. package/lib/types/access.d.ts.map +1 -0
  9. package/lib/types/access.js +20 -0
  10. package/lib/types/client/PetSettingsCard.d.ts.map +1 -1
  11. package/lib/types/client/PetSettingsCard.js +8 -2
  12. package/lib/types/client/PetSprite.d.ts.map +1 -1
  13. package/lib/types/client/PetSprite.js +10 -2
  14. package/lib/types/client/renderers/live2d/Live2dVisualMount.d.ts.map +1 -1
  15. package/lib/types/client/renderers/live2d/Live2dVisualMount.js +1 -0
  16. package/lib/types/client/renderers/live2d/runtime.d.ts +13 -1
  17. package/lib/types/client/renderers/live2d/runtime.d.ts.map +1 -1
  18. package/lib/types/client/renderers/live2d.d.ts.map +1 -1
  19. package/lib/types/client/renderers/live2d.js +120 -24
  20. package/lib/types/image-dimensions.d.ts +26 -0
  21. package/lib/types/image-dimensions.d.ts.map +1 -0
  22. package/lib/types/image-dimensions.js +77 -0
  23. package/lib/types/index.js +1 -1
  24. package/lib/types/registry.d.ts.map +1 -1
  25. package/lib/types/registry.js +43 -1
  26. package/lib/types/routes.d.ts +6 -1
  27. package/lib/types/routes.d.ts.map +1 -1
  28. package/lib/types/routes.js +36 -33
  29. package/package.json +1 -1
  30. package/src/access.ts +40 -0
  31. package/src/client/PetSettingsCard.tsx +8 -2
  32. package/src/client/PetSprite.test.tsx +71 -0
  33. package/src/client/PetSprite.tsx +10 -2
  34. package/src/client/renderers/live2d/Live2dVisualMount.test.tsx +72 -0
  35. package/src/client/renderers/live2d/Live2dVisualMount.tsx +1 -0
  36. package/src/client/renderers/live2d/runtime.ts +8 -2
  37. package/src/client/renderers/live2d.test.ts +211 -8
  38. package/src/client/renderers/live2d.ts +129 -29
  39. package/src/client/settings-card.module.css +2 -0
  40. package/src/image-dimensions.test.ts +85 -0
  41. package/src/image-dimensions.ts +76 -0
  42. package/src/index.ts +1 -1
  43. package/src/registry.test.ts +58 -5
  44. package/src/registry.ts +40 -1
  45. package/src/routes.ts +38 -34
package/lib/index.js CHANGED
@@ -2,7 +2,7 @@ import { _ as RemarkPicker, a as AFFINITY_MAX, c as applyInteraction, d as empty
2
2
  import { installSettingsSection, settingsNamespace } from "@deepseek-ai/dsh-settings";
3
3
  import z from "schemastery";
4
4
  import { Service } from "@deepseek-ai/cordis";
5
- import { existsSync, mkdirSync, readFileSync, readdirSync, realpathSync, renameSync, statSync, writeFileSync } from "node:fs";
5
+ import { closeSync, existsSync, mkdirSync, openSync, readFileSync, readSync, readdirSync, realpathSync, renameSync, statSync, writeFileSync } from "node:fs";
6
6
  import { basename, dirname, isAbsolute, join, resolve, sep } from "node:path";
7
7
  import { homedir } from "node:os";
8
8
  import { fileURLToPath } from "node:url";
@@ -2252,6 +2252,81 @@ function parseDecorationManifest(raw, source = "decoration.json") {
2252
2252
  };
2253
2253
  }
2254
2254
  //#endregion
2255
+ //#region src/image-dimensions.ts
2256
+ /**
2257
+ * Minimal PNG/WebP dimension reader — header-only, no decoding, no
2258
+ * dependencies. Used by the decoration registry to verify a strip's actual
2259
+ * pixel geometry matches its descriptor (single-row sprite strip; the client
2260
+ * renders by frame-column offsets, so a mismatched strip silently shows the
2261
+ * wrong frames). Parsing is best-effort: an unrecognized or truncated header
2262
+ * returns undefined (the caller decides whether to warn).
2263
+ *
2264
+ * PNG: signature (8) + IHDR chunk — length (4) + 'IHDR' (4) + width (4) +
2265
+ * height (4), both big-endian uint32 at fixed offsets 16/20.
2266
+ * WebP: RIFF header (12) + chunk — 'VP8X' extended (width-1/height-1 as
2267
+ * little-endian uint24 at 24/27), 'VP8L' lossless (packed 14-bit dims at
2268
+ * 21), or 'VP8 ' lossy (frame header, low 14 bits of the uint16 at 26/28).
2269
+ * @module @linxin666/dsh-pet/image-dimensions
2270
+ */
2271
+ const PNG_SIGNATURE = Buffer.from([
2272
+ 137,
2273
+ 80,
2274
+ 78,
2275
+ 71,
2276
+ 13,
2277
+ 10,
2278
+ 26,
2279
+ 10
2280
+ ]);
2281
+ /** Read the pixel size of a PNG buffer, or undefined when unrecognized. */
2282
+ function pngDimensions(buf) {
2283
+ if (buf.length < 24) return void 0;
2284
+ if (!buf.subarray(0, 8).equals(PNG_SIGNATURE)) return void 0;
2285
+ if (buf.toString("ascii", 12, 16) !== "IHDR") return void 0;
2286
+ return {
2287
+ width: buf.readUInt32BE(16),
2288
+ height: buf.readUInt32BE(20)
2289
+ };
2290
+ }
2291
+ /** Read the pixel size of a WebP buffer, or undefined when unrecognized. */
2292
+ function webpDimensions(buf) {
2293
+ if (buf.length < 21) return void 0;
2294
+ if (buf.toString("ascii", 0, 4) !== "RIFF") return void 0;
2295
+ if (buf.toString("ascii", 8, 12) !== "WEBP") return void 0;
2296
+ const fourcc = buf.toString("ascii", 12, 16);
2297
+ if (fourcc === "VP8X") {
2298
+ if (buf.length < 30) return void 0;
2299
+ return {
2300
+ width: 1 + buf.readUIntLE(24, 3),
2301
+ height: 1 + buf.readUIntLE(27, 3)
2302
+ };
2303
+ }
2304
+ if (fourcc === "VP8L") {
2305
+ if (buf.length < 25) return void 0;
2306
+ const bits = buf.readUInt32LE(21);
2307
+ return {
2308
+ width: 1 + (bits & 16383),
2309
+ height: 1 + (bits >>> 14 & 16383)
2310
+ };
2311
+ }
2312
+ if (fourcc === "VP8 ") {
2313
+ if (buf.length < 30) return void 0;
2314
+ return {
2315
+ width: buf.readUInt16LE(26) & 16383,
2316
+ height: buf.readUInt16LE(28) & 16383
2317
+ };
2318
+ }
2319
+ }
2320
+ /**
2321
+ * Read image pixel dimensions from a PNG or WebP buffer. Returns undefined
2322
+ * for formats this reader does not recognize (never throws). Callers treat
2323
+ * undefined as "cannot verify", not as an error.
2324
+ */
2325
+ function imageDimensions(buf) {
2326
+ if (buf.length >= 12 && buf.toString("ascii", 0, 4) === "RIFF") return webpDimensions(buf);
2327
+ return pngDimensions(buf);
2328
+ }
2329
+ //#endregion
2255
2330
  //#region src/contracts/status-decoration.ts
2256
2331
  /** Contract version decorations declare against (independent of manifests). */
2257
2332
  const PET_DECORATION_API_VERSION = "x-org.linxin666.pet-center/status-decoration-v1";
@@ -2859,6 +2934,24 @@ function loadVoicePackFile(file, options) {
2859
2934
  }
2860
2935
  /** Decoration asset URL prefix (served by the decoration route, M5). */
2861
2936
  const DECORATION_ASSET_PREFIX = "/api/pet/decoration";
2937
+ /** Read the pixel dimensions of a decoration strip (PNG/WebP), if decodable. */
2938
+ function readImageDimensions(file) {
2939
+ let header;
2940
+ try {
2941
+ const fd = openSync(file, "r");
2942
+ try {
2943
+ header = Buffer.alloc(64);
2944
+ const read = readSync(fd, header, 0, header.length, 0);
2945
+ if (read < 0) return void 0;
2946
+ header = header.subarray(0, read);
2947
+ } finally {
2948
+ closeSync(fd);
2949
+ }
2950
+ } catch {
2951
+ return;
2952
+ }
2953
+ return imageDimensions(header);
2954
+ }
2862
2955
  /**
2863
2956
  * Scan one directory of decoration folders ('decoration.json' + strip).
2864
2957
  * Later scans override earlier ones on id collision; a bad descriptor warns
@@ -2911,6 +3004,20 @@ function scanDecorationDir(dir, options) {
2911
3004
  source: entryDir,
2912
3005
  message
2913
3006
  });
3007
+ } else {
3008
+ const actual = readImageDimensions(join(entryDir, manifest.entry));
3009
+ if (actual !== void 0) {
3010
+ const expectedWidth = manifest.cell.width * manifest.columns;
3011
+ if (actual.width !== expectedWidth || actual.height !== manifest.cell.height) {
3012
+ const message = "decoration " + manifest.id + ": strip " + actual.width + "x" + actual.height + " does not match cell " + manifest.cell.width + "x" + manifest.cell.height + " x " + manifest.columns + " columns (expected " + expectedWidth + "x" + manifest.cell.height + "); frames will render wrong";
3013
+ options.warnings?.push(message);
3014
+ options.diagnostics?.push({
3015
+ level: "warning",
3016
+ source: entryDir,
3017
+ message
3018
+ });
3019
+ }
3020
+ }
2914
3021
  }
2915
3022
  entries.push({
2916
3023
  apiVersion: PET_DECORATION_API_VERSION,
@@ -3476,6 +3583,23 @@ function isLoopbackRequest(request) {
3476
3583
  }
3477
3584
  }
3478
3585
  //#endregion
3586
+ //#region src/access.ts
3587
+ /**
3588
+ * Whether this request may enter any /api/pet or /pet asset route.
3589
+ * @param ctx - host context; may expose remoteWebUiPairing.
3590
+ * @param request - the incoming HTTP request.
3591
+ * @returns true for loopback, or a live paired-device cookie.
3592
+ */
3593
+ function isPetAllowed(ctx, request) {
3594
+ if (isLoopbackRequest(request)) return true;
3595
+ const bag = ctx;
3596
+ const fromGet = typeof bag.get === "function" ? bag.get("remoteWebUiPairing", false) : void 0;
3597
+ return (isPairingAccess(fromGet) ? fromGet : bag.remoteWebUiPairing)?.isPairedDevice(request) === true;
3598
+ }
3599
+ function isPairingAccess(value) {
3600
+ return value !== void 0 && value !== null && typeof value.isPairedDevice === "function";
3601
+ }
3602
+ //#endregion
3479
3603
  //#region src/routes.ts
3480
3604
  /**
3481
3605
  * Pet HTTP routes — the browser half talks to the host through plain
@@ -3484,7 +3608,10 @@ function isLoopbackRequest(request) {
3484
3608
  * domains are platform-registered, so the pet serves its own API and media —
3485
3609
  * the same pattern as dsh-remote-web-ui's '/api/pair' family. The asset route
3486
3610
  * is one prefix registration serving every registry entry (manifest, atlas,
3487
- * optional previews), so adding a pet never touches route wiring.
3611
+ * optional previews), so adding a pet never touches route wiring. Both the
3612
+ * JSON API, the asset prefix, and the Live2D runtime prefix are loopback-only
3613
+ * by default; a live paired-device cookie is an extra allow path when
3614
+ * remote-web-ui is loaded.
3488
3615
  * @module @linxin666/dsh-pet/routes
3489
3616
  */
3490
3617
  /** Browser-facing base path of the pet API. */
@@ -3590,9 +3717,9 @@ function readJsonBody(req) {
3590
3717
  req.on("error", reject);
3591
3718
  });
3592
3719
  }
3593
- /** Shared route fence: the browser UI is a loopback client; LAN hosts stay out. */
3594
- function guard(req, res) {
3595
- if (isLoopbackRequest(req)) return true;
3720
+ /** Shared route fence: loopback always passes; a live paired-device cookie is an extra allow path. */
3721
+ function guard(ctx, req, res) {
3722
+ if (isPetAllowed(ctx, req)) return true;
3596
3723
  json(res, 403, {
3597
3724
  ok: false,
3598
3725
  error: "forbidden: loopback-only"
@@ -3600,12 +3727,12 @@ function guard(req, res) {
3600
3727
  return false;
3601
3728
  }
3602
3729
  /** Wrap one async service call as a GET JSON route. */
3603
- function getRoute(path, run) {
3730
+ function getRoute(ctx, path, run) {
3604
3731
  return {
3605
3732
  kind: "exact",
3606
3733
  path,
3607
3734
  handler: (req, res) => {
3608
- if (!guard(req, res)) return;
3735
+ if (!guard(ctx, req, res)) return;
3609
3736
  if (!requireMethod(req, res, "GET")) return;
3610
3737
  run().then((value) => json(res, 200, value), (error) => {
3611
3738
  json(res, 500, {
@@ -3617,12 +3744,12 @@ function getRoute(path, run) {
3617
3744
  };
3618
3745
  }
3619
3746
  /** Wrap one async service call as a POST JSON route (body passed through). */
3620
- function postRoute(path, run) {
3747
+ function postRoute(ctx, path, run) {
3621
3748
  return {
3622
3749
  kind: "exact",
3623
3750
  path,
3624
3751
  handler: (req, res) => {
3625
- if (!guard(req, res)) return Promise.resolve();
3752
+ if (!guard(ctx, req, res)) return Promise.resolve();
3626
3753
  if (!requireMethod(req, res, "POST")) return Promise.resolve();
3627
3754
  return readJsonBody(req).then((body) => {
3628
3755
  return run(typeof body === "object" && body !== null ? body : {}).then((value) => json(res, 200, value), (error) => {
@@ -3659,10 +3786,10 @@ function dirAliases(registry) {
3659
3786
  * match; containedRealpath stays as the second layer. Composed pets without
3660
3787
  * a manifest file get a synthesized pet.json.
3661
3788
  */
3662
- function assetHandler(registry, caps) {
3789
+ function assetHandler(ctx, registry, caps) {
3663
3790
  const aliases = dirAliases(registry);
3664
- return (req, res) => {
3665
- if (!guard(req, res)) return;
3791
+ return ((req, res) => {
3792
+ if (!guard(ctx, req, res)) return;
3666
3793
  if (req.method !== "GET" && req.method !== "HEAD") {
3667
3794
  res.writeHead(405);
3668
3795
  res.end();
@@ -3757,7 +3884,7 @@ function assetHandler(registry, caps) {
3757
3884
  res.end();
3758
3885
  return;
3759
3886
  }
3760
- readFile(resolved).then((body) => {
3887
+ return readFile(resolved).then((body) => {
3761
3888
  res.writeHead(200, {
3762
3889
  "content-type": mimeFor(resolved),
3763
3890
  "content-length": String(body.byteLength),
@@ -3772,7 +3899,7 @@ function assetHandler(registry, caps) {
3772
3899
  res.writeHead(404);
3773
3900
  res.end();
3774
3901
  });
3775
- };
3902
+ });
3776
3903
  }
3777
3904
  /** Browser-facing base path of the plugin runtime files (pet-center M3). */
3778
3905
  const PET_RUNTIME_PREFIX = "/api/pet/runtime";
@@ -3794,9 +3921,9 @@ const RUNTIME_FILES = {
3794
3921
  * guidance (the Cubism Core is user-supplied, so its absence is a normal
3795
3922
  * state, not an error).
3796
3923
  */
3797
- function runtimeHandler(roots) {
3798
- return (req, res) => {
3799
- if (!guard(req, res)) return;
3924
+ function runtimeHandler(ctx, roots) {
3925
+ return ((req, res) => {
3926
+ if (!guard(ctx, req, res)) return;
3800
3927
  if (req.method !== "GET" && req.method !== "HEAD") {
3801
3928
  res.writeHead(405);
3802
3929
  res.end();
@@ -3852,7 +3979,7 @@ function runtimeHandler(roots) {
3852
3979
  res.end();
3853
3980
  return;
3854
3981
  }
3855
- readFile(resolved).then((body) => {
3982
+ return readFile(resolved).then((body) => {
3856
3983
  res.writeHead(200, {
3857
3984
  "content-type": name.endsWith(".map") ? "application/json" : "application/javascript; charset=utf-8",
3858
3985
  "content-length": String(body.byteLength),
@@ -3867,7 +3994,7 @@ function runtimeHandler(roots) {
3867
3994
  res.writeHead(404);
3868
3995
  res.end();
3869
3996
  });
3870
- };
3997
+ });
3871
3998
  }
3872
3999
  /**
3873
4000
  * The decoration asset handler behind '/api/pet/decoration/<id>/<file>'
@@ -3876,9 +4003,9 @@ function runtimeHandler(roots) {
3876
4003
  * match, with realpath containment and the same size ceilings as pet
3877
4004
  * assets. Crafted '..' or '.' segments never match the normalized closure.
3878
4005
  */
3879
- function decorationHandler(registry, caps) {
4006
+ function decorationHandler(ctx, registry, caps) {
3880
4007
  return (req, res) => {
3881
- if (!guard(req, res)) return;
4008
+ if (!guard(ctx, req, res)) return;
3882
4009
  if (req.method !== "GET" && req.method !== "HEAD") {
3883
4010
  res.writeHead(405);
3884
4011
  res.end();
@@ -3986,33 +4113,33 @@ function decorationHandler(registry, caps) {
3986
4113
  }
3987
4114
  /** Build the full route family (API + assets + runtime) for one service. */
3988
4115
  function makePetRoutes(deps) {
3989
- const { service } = deps;
4116
+ const { service, ctx } = deps;
3990
4117
  const apiRoutes = [
3991
- getRoute("/api/pet/state", () => service.state()),
3992
- getRoute("/api/pet/pets", () => service.pets()),
3993
- getRoute("/api/pet/diagnostics", () => service.diagnostics()),
3994
- postRoute("/api/pet/interact", (body) => {
4118
+ getRoute(ctx, "/api/pet/state", () => service.state()),
4119
+ getRoute(ctx, "/api/pet/pets", () => service.pets()),
4120
+ getRoute(ctx, "/api/pet/diagnostics", () => service.diagnostics()),
4121
+ postRoute(ctx, "/api/pet/interact", (body) => {
3995
4122
  const kind = body.kind;
3996
4123
  if (kind !== "pet" && kind !== "feed") return Promise.reject(/* @__PURE__ */ new Error("invalid-kind"));
3997
4124
  return service.interact(kind);
3998
4125
  }),
3999
- postRoute("/api/pet/set-visible", (body) => {
4126
+ postRoute(ctx, "/api/pet/set-visible", (body) => {
4000
4127
  const visible = body.visible;
4001
4128
  if (typeof visible !== "boolean") return Promise.reject(/* @__PURE__ */ new Error("invalid-visible"));
4002
4129
  return service.setVisible(visible);
4003
4130
  }),
4004
- postRoute("/api/pet/set-config", (body) => service.setConfig({
4131
+ postRoute(ctx, "/api/pet/set-config", (body) => service.setConfig({
4005
4132
  ...typeof body.size === "number" ? { size: body.size } : {},
4006
4133
  ...typeof body.right === "number" ? { right: body.right } : {},
4007
4134
  ...typeof body.bottom === "number" ? { bottom: body.bottom } : {},
4008
4135
  ...typeof body.visible === "boolean" ? { visible: body.visible } : {}
4009
4136
  })),
4010
- postRoute("/api/pet/set-name", (body) => {
4137
+ postRoute(ctx, "/api/pet/set-name", (body) => {
4011
4138
  const name = body.name;
4012
4139
  if (typeof name !== "string") return Promise.reject(/* @__PURE__ */ new Error("invalid-name"));
4013
4140
  return service.setName(name);
4014
4141
  }),
4015
- postRoute("/api/pet/set-pet", (body) => {
4142
+ postRoute(ctx, "/api/pet/set-pet", (body) => {
4016
4143
  const petId = body.petId;
4017
4144
  if (typeof petId !== "string") return Promise.reject(/* @__PURE__ */ new Error("invalid-pet"));
4018
4145
  return service.setPetId(petId);
@@ -4021,12 +4148,12 @@ function makePetRoutes(deps) {
4021
4148
  const assetRoute = {
4022
4149
  kind: "prefix",
4023
4150
  path: PET_ASSET_PREFIX,
4024
- handler: assetHandler(service.registrySnapshot(), deps.assetCaps ?? PET_ASSET_CAPS)
4151
+ handler: assetHandler(ctx, service.registrySnapshot(), deps.assetCaps ?? PET_ASSET_CAPS)
4025
4152
  };
4026
4153
  const runtimeRoute = {
4027
4154
  kind: "prefix",
4028
4155
  path: PET_RUNTIME_PREFIX,
4029
- handler: runtimeHandler({
4156
+ handler: runtimeHandler(ctx, {
4030
4157
  runtimeDir: deps.runtimeDir ?? join(dshHome(), "pets", ".runtime"),
4031
4158
  vendorDir: deps.vendorDir ?? join(petPackageRoot(import.meta.url), "lib")
4032
4159
  })
@@ -4034,7 +4161,7 @@ function makePetRoutes(deps) {
4034
4161
  const decorationRoute = {
4035
4162
  kind: "prefix",
4036
4163
  path: DECORATION_ASSET_PREFIX,
4037
- handler: decorationHandler(service.registrySnapshot(), deps.assetCaps ?? PET_ASSET_CAPS)
4164
+ handler: decorationHandler(ctx, service.registrySnapshot(), deps.assetCaps ?? PET_ASSET_CAPS)
4038
4165
  };
4039
4166
  return [
4040
4167
  ...apiRoutes,
@@ -4130,7 +4257,10 @@ function applyImpl(ctx, config = {}) {
4130
4257
  enabled: config.enabled ?? true,
4131
4258
  decorationEnabled: config.decorationEnabled ?? true
4132
4259
  };
4133
- const routes = makePetRoutes({ service });
4260
+ const routes = makePetRoutes({
4261
+ service,
4262
+ ctx
4263
+ });
4134
4264
  let disposeRoutes;
4135
4265
  const syncRoutes = () => {
4136
4266
  const enabled = current().enabled ?? true;
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Pet trust fence: loopback (the desktop) always passes; a live paired-device
3
+ * cookie is an additional allow path when remote-web-ui is loaded. The pet
4
+ * never depends on that plugin — without the service the fence stays
5
+ * loopback-only (same pattern as skill-explorer / aionui-panel).
6
+ */
7
+ import type { IncomingMessage } from 'node:http';
8
+ import type { Context } from '@deepseek-ai/cordis';
9
+ /**
10
+ * Whether this request may enter any /api/pet or /pet asset route.
11
+ * @param ctx - host context; may expose remoteWebUiPairing.
12
+ * @param request - the incoming HTTP request.
13
+ * @returns true for loopback, or a live paired-device cookie.
14
+ */
15
+ export declare function isPetAllowed(ctx: Context, request: IncomingMessage): boolean;
16
+ //# sourceMappingURL=access.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"access.d.ts","sourceRoot":"","sources":["../../src/access.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAA;AAChD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAclD;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,eAAe,GAAG,OAAO,CAM5E"}
@@ -0,0 +1,20 @@
1
+ import { isLoopbackRequest } from './loopback.js';
2
+ /**
3
+ * Whether this request may enter any /api/pet or /pet asset route.
4
+ * @param ctx - host context; may expose remoteWebUiPairing.
5
+ * @param request - the incoming HTTP request.
6
+ * @returns true for loopback, or a live paired-device cookie.
7
+ */
8
+ export function isPetAllowed(ctx, request) {
9
+ if (isLoopbackRequest(request))
10
+ return true;
11
+ const bag = ctx;
12
+ const fromGet = typeof bag.get === 'function' ? bag.get('remoteWebUiPairing', false) : undefined;
13
+ const pairing = (isPairingAccess(fromGet) ? fromGet : bag.remoteWebUiPairing);
14
+ return pairing?.isPairedDevice(request) === true;
15
+ }
16
+ function isPairingAccess(value) {
17
+ return value !== undefined
18
+ && value !== null
19
+ && typeof value.isPairedDevice === 'function';
20
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"PetSettingsCard.d.ts","sourceRoot":"","sources":["../../../src/client/PetSettingsCard.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"PetSettingsCard.d.ts","sourceRoot":"","sources":["../../../src/client/PetSettingsCard.tsx"],"names":[],"mappings":"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"}
@@ -41,8 +41,14 @@ export class PetSettingsCardController {
41
41
  choiceField('petId', this.petChoices),
42
42
  ]);
43
43
  this.store = this.form.bind(() => this.projection());
44
- void this.loadPets();
45
- void this.loadDiagnostics();
44
+ // Client plugins are applied synchronously during shell startup. Defer
45
+ // the first registry request until that pass completes so transport
46
+ // plugins (notably remote-web-ui on a paired non-loopback origin) can
47
+ // install their fetch channel before /api/pet/pets is issued.
48
+ window.setTimeout(() => {
49
+ void this.loadPets();
50
+ void this.loadDiagnostics();
51
+ }, 0);
46
52
  }
47
53
  /** Fetch registry diagnostics once (soft-fail: an empty list on error). */
48
54
  async loadDiagnostics() {
@@ -1 +1 @@
1
- {"version":3,"file":"PetSprite.d.ts","sourceRoot":"","sources":["../../../src/client/PetSprite.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,KAAK,EAAkE,SAAS,EAAE,WAAW,EAAE,MAAM,OAAO,CAAA;AAGnH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAA;AACnE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AACrD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AACjD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAEnD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAIjD,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAA;AAGjC,wEAAwE;AACxE,MAAM,WAAW,cAAc;IAC7B,gDAAgD;IAChD,QAAQ,EAAE,YAAY,GAAG,IAAI,CAAA;IAC7B,8EAA8E;IAC9E,UAAU,EAAE,aAAa,CAAA;IACzB,qDAAqD;IACrD,OAAO,EAAE,gBAAgB,CAAA;IACzB,sCAAsC;IACtC,QAAQ,EAAE,WAAW,GAAG,IAAI,CAAA;IAC5B,8BAA8B;IAC9B,KAAK,EAAE,MAAM,IAAI,CAAA;IACjB,sCAAsC;IACtC,MAAM,EAAE,MAAM,IAAI,CAAA;IAClB,sCAAsC;IACtC,MAAM,EAAE,MAAM,IAAI,CAAA;IAClB,+BAA+B;IAC/B,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAA;IAClD,uDAAuD;IACvD,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IAChC,4DAA4D;IAC5D,aAAa,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAA;IAC1C,2DAA2D;IAC3D,cAAc,EAAE,MAAM,IAAI,CAAA;IAC1B;;;;OAIG;IACH,MAAM,CAAC,EAAE,SAAS,CAAA;IAClB,+CAA+C;IAC/C,CAAC,EAAE,WAAW,CAAC,OAAO,EAAE,CAAC,CAAA;CAC1B;AAkFD;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,cAAc,GAAG,WAAW,CAygB5D"}
1
+ {"version":3,"file":"PetSprite.d.ts","sourceRoot":"","sources":["../../../src/client/PetSprite.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,KAAK,EAAkE,SAAS,EAAE,WAAW,EAAE,MAAM,OAAO,CAAA;AAGnH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAA;AACnE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AACrD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AACjD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAEnD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAIjD,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAA;AAGjC,wEAAwE;AACxE,MAAM,WAAW,cAAc;IAC7B,gDAAgD;IAChD,QAAQ,EAAE,YAAY,GAAG,IAAI,CAAA;IAC7B,8EAA8E;IAC9E,UAAU,EAAE,aAAa,CAAA;IACzB,qDAAqD;IACrD,OAAO,EAAE,gBAAgB,CAAA;IACzB,sCAAsC;IACtC,QAAQ,EAAE,WAAW,GAAG,IAAI,CAAA;IAC5B,8BAA8B;IAC9B,KAAK,EAAE,MAAM,IAAI,CAAA;IACjB,sCAAsC;IACtC,MAAM,EAAE,MAAM,IAAI,CAAA;IAClB,sCAAsC;IACtC,MAAM,EAAE,MAAM,IAAI,CAAA;IAClB,+BAA+B;IAC/B,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAA;IAClD,uDAAuD;IACvD,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IAChC,4DAA4D;IAC5D,aAAa,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAA;IAC1C,2DAA2D;IAC3D,cAAc,EAAE,MAAM,IAAI,CAAA;IAC1B;;;;OAIG;IACH,MAAM,CAAC,EAAE,SAAS,CAAA;IAClB,+CAA+C;IAC/C,CAAC,EAAE,WAAW,CAAC,OAAO,EAAE,CAAC,CAAA;CAC1B;AA0FD;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,cAAc,GAAG,WAAW,CAygB5D"}
@@ -51,7 +51,11 @@ function StatusOrnament(props) {
51
51
  const position = (index) => (-index * frameWidth) + 'px 0px';
52
52
  const reduceMotion = window.matchMedia?.('(prefers-reduced-motion: reduce)')?.matches === true;
53
53
  el.style.backgroundPosition = position(segment.from);
54
- if (reduceMotion)
54
+ // A single-frame segment (from === to) has nothing to animate: with
55
+ // loop=true the wrap branch would reset index to the same frame and the
56
+ // tick would keep rescheduling a no-op rAF forever. Settle on the one
57
+ // frame instead — same as the reduced-motion static hold.
58
+ if (reduceMotion || segment.from === segment.to)
55
59
  return;
56
60
  let raf = 0;
57
61
  let index = segment.from;
@@ -68,8 +72,12 @@ function StatusOrnament(props) {
68
72
  index += 1;
69
73
  else if (decoration.loop)
70
74
  index = segment.from;
75
+ // Only advance the background when the frame actually changes:
76
+ // the segment's frame rate (duration ms, typically 90-160) is far
77
+ // below the rAF cadence, so writing the same position every frame
78
+ // would churn style recalculations for no visual change.
79
+ el.style.backgroundPosition = position(index);
71
80
  }
72
- el.style.backgroundPosition = position(index);
73
81
  // A non-looping segment settles on its last frame; stop scheduling
74
82
  // instead of repainting the same position every frame.
75
83
  if (!decoration.loop && index === segment.to)
@@ -1 +1 @@
1
- {"version":3,"file":"Live2dVisualMount.d.ts","sourceRoot":"","sources":["../../../../../src/client/renderers/live2d/Live2dVisualMount.tsx"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAA+B,KAAK,YAAY,EAAE,MAAM,OAAO,CAAA;AACtE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAA;AACnE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AACzD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAKtD,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAA;AAE1C,4EAA4E;AAC5E,wBAAgB,iBAAiB,CAAC,KAAK,EAAE;IACvC,UAAU,EAAE,aAAa,CAAA;IACzB,KAAK,EAAE,aAAa,CAAA;IACpB,KAAK,EAAE,MAAM,IAAI,CAAA;IACjB,CAAC,EAAE,WAAW,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC,CAAA;CAC/B,GAAG,YAAY,CAuEf"}
1
+ {"version":3,"file":"Live2dVisualMount.d.ts","sourceRoot":"","sources":["../../../../../src/client/renderers/live2d/Live2dVisualMount.tsx"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAA+B,KAAK,YAAY,EAAE,MAAM,OAAO,CAAA;AACtE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAA;AACnE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AACzD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAKtD,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAA;AAE1C,4EAA4E;AAC5E,wBAAgB,iBAAiB,CAAC,KAAK,EAAE;IACvC,UAAU,EAAE,aAAa,CAAA;IACzB,KAAK,EAAE,aAAa,CAAA;IACpB,KAAK,EAAE,MAAM,IAAI,CAAA;IACjB,CAAC,EAAE,WAAW,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC,CAAA;CAC/B,GAAG,YAAY,CAwEf"}
@@ -20,6 +20,7 @@ export function Live2dVisualMount(props) {
20
20
  const [error, setError] = useState(null);
21
21
  // One activation per pet definition: build the contract context and mount.
22
22
  useEffect(() => {
23
+ setError(null);
23
24
  const container = containerRef.current;
24
25
  const live2d = props.definition.live2d;
25
26
  if (container === null || live2d === undefined)
@@ -21,12 +21,19 @@ export interface Live2dVendorApp {
21
21
  renderer: {
22
22
  readonly width: number;
23
23
  readonly height: number;
24
+ resize(width: number, height: number): void;
24
25
  };
25
26
  init(options: Record<string, unknown>): Promise<void>;
26
- destroy(removeView?: boolean, options?: Record<string, unknown>): void;
27
+ destroy(rendererOptions?: boolean | {
28
+ removeView?: boolean;
29
+ releaseGlobalResources?: boolean;
30
+ }, options?: Record<string, unknown>): void;
27
31
  }
28
32
  /** The Live2DModel slice the renderer uses. */
29
33
  export interface Live2dVendorModel {
34
+ automator: {
35
+ autoUpdate: boolean;
36
+ };
30
37
  anchor: {
31
38
  set(x: number, y?: number): void;
32
39
  };
@@ -50,6 +57,11 @@ export interface Live2dVendorModel {
50
57
  expression(name?: string): unknown;
51
58
  hitTest(x: number, y: number): string[];
52
59
  on(event: string, fn: () => void): unknown;
60
+ destroy(options?: {
61
+ children?: boolean;
62
+ texture?: boolean;
63
+ baseTexture?: boolean;
64
+ }): void;
53
65
  }
54
66
  /** The vendor bundle global (window.__dshPetLive2d). */
55
67
  export interface Live2dVendor {
@@ -1 +1 @@
1
- {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../../../../src/client/renderers/live2d/runtime.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../../../../src/client/renderers/live2d/runtime.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"live2d.d.ts","sourceRoot":"","sources":["../../../../src/client/renderers/live2d.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AACnD,OAAO,EAEL,KAAK,WAAW,EAEhB,KAAK,iBAAiB,EACvB,MAAM,6BAA6B,CAAA;AASpC,gFAAgF;AAChF,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,SAAS,CAAC,EAAE;QAAE,CAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IACtC,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC,GAAG;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;IAClE,WAAW,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC,CAAA;IACpD,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;CACpB;AAED,sDAAsD;AACtD,MAAM,MAAM,eAAe,GAAG,cAAc,GAAG,gBAAgB,GAAG,aAAa,CAAA;AAE/E,4EAA4E;AAC5E,MAAM,WAAW,oBAAqB,SAAQ,iBAAiB;IAC7D,2EAA2E;IAC3E,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/B,0EAA0E;IAC1E,OAAO,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,eAAe,KAAK,IAAI,GAAG,IAAI,CAAA;CACzD;AAwBD,kCAAkC;AAClC,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C;AAcD,0CAA0C;AAC1C,eAAO,MAAM,cAAc,EAAE,WAAW,CAAC,eAAe,CAmIvD,CAAA"}
1
+ {"version":3,"file":"live2d.d.ts","sourceRoot":"","sources":["../../../../src/client/renderers/live2d.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AACnD,OAAO,EAEL,KAAK,WAAW,EAEhB,KAAK,iBAAiB,EACvB,MAAM,6BAA6B,CAAA;AASpC,gFAAgF;AAChF,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,SAAS,CAAC,EAAE;QAAE,CAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IACtC,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC,GAAG;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;IAClE,WAAW,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC,CAAA;IACpD,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;CACpB;AAED,sDAAsD;AACtD,MAAM,MAAM,eAAe,GAAG,cAAc,GAAG,gBAAgB,GAAG,aAAa,CAAA;AAE/E,4EAA4E;AAC5E,MAAM,WAAW,oBAAqB,SAAQ,iBAAiB;IAC7D,2EAA2E;IAC3E,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/B,0EAA0E;IAC1E,OAAO,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,eAAe,KAAK,IAAI,GAAG,IAAI,CAAA;CACzD;AA6DD,kCAAkC;AAClC,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C;AAcD,0CAA0C;AAC1C,eAAO,MAAM,cAAc,EAAE,WAAW,CAAC,eAAe,CAkMvD,CAAA"}