@laplace.live/persona-sdk 0.8.0 → 0.9.0

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.
@@ -1,6 +1,11 @@
1
+ import type { ShortcutInfo } from '../wire/types.ts';
1
2
  /**
2
3
  * Display label for a model-relative motion/expression/animation file: the
3
4
  * basename with its format extension stripped. Cubism entries carry no `Name`,
4
5
  * so the basename is the only identifier there is.
5
6
  */
6
7
  export declare function motionLabel(file: string): string;
8
+ /** English label for one shortcut action kind; kinds newer than this SDK read `Action`. */
9
+ export declare function shortcutActionLabel(kind: string): string;
10
+ /** Display label for an app shortcut: its title, else its action-kind labels joined with ` + `. */
11
+ export declare function shortcutLabel(shortcut: Pick<ShortcutInfo, 'title' | 'actionKinds'>): string;
@@ -7,3 +7,20 @@ export function motionLabel(file) {
7
7
  const base = file.split(/[\\/]/).pop() ?? file;
8
8
  return base.replace(/\.motion3\.json$|\.exp3\.json$|\.vrma$|\.json$/i, '') || base;
9
9
  }
10
+ // English fallbacks; localizing clients keep their own map and use these for unknown kinds.
11
+ const SHORTCUT_ACTION_KIND_LABELS = {
12
+ 'effect-toggle': 'Toggle Effect',
13
+ 'effect-params': 'Effect Settings',
14
+ 'camera-pose': 'Camera Position',
15
+ 'layer-visibility': 'Layer Visibility',
16
+ };
17
+ /** English label for one shortcut action kind; kinds newer than this SDK read `Action`. */
18
+ export function shortcutActionLabel(kind) {
19
+ return SHORTCUT_ACTION_KIND_LABELS[kind] ?? 'Action';
20
+ }
21
+ /** Display label for an app shortcut: its title, else its action-kind labels joined with ` + `. */
22
+ export function shortcutLabel(shortcut) {
23
+ if (shortcut.title !== null && shortcut.title !== '')
24
+ return shortcut.title;
25
+ return shortcut.actionKinds.map(shortcutActionLabel).join(' + ') || 'Shortcut';
26
+ }
@@ -4,7 +4,7 @@ export const API_ERROR_CODES = [
4
4
  'invalid-request',
5
5
  'unknown-method',
6
6
  'invalid-params',
7
- /** A referenced id (scene, instance, model, asset, hotkey) resolves to nothing. */
7
+ /** A referenced id (scene, instance, model, asset, hotkey, shortcut, expression) resolves to nothing. */
8
8
  'not-found',
9
9
  /** The instance's model format cannot perform this method (e.g. MToon on Live2D). */
10
10
  'unsupported-for-format',
@@ -1,4 +1,4 @@
1
- import type { ExpressionPersistence, HotkeyState, ModelFormat, PoseStatus, SceneState, Settings, TrackingStatus } from './types.ts';
1
+ import type { ExpressionPersistence, HotkeyState, ModelFormat, PoseStatus, SceneState, Settings, ShortcutInfo, TrackingStatus } from './types.ts';
2
2
  /** Every push event a session can subscribe to, with its payload. */
3
3
  export interface EventMap {
4
4
  /** Any scene mutation: create/delete/rename/activate/shortcut and persisted scene edits. */
@@ -10,6 +10,10 @@ export interface EventMap {
10
10
  modelId: string | null;
11
11
  config: HotkeyState;
12
12
  };
13
+ /** The app-shortcut list, its names, or its OS registrations changed. */
14
+ 'shortcut.state': {
15
+ shortcuts: ShortcutInfo[];
16
+ };
13
17
  /** `sources` maps source id → status; optional so pre-multi-source servers still parse. */
14
18
  'tracking.status': {
15
19
  tracking: TrackingStatus;
@@ -4,6 +4,7 @@ export const EVENT_NAMES = Object.keys({
4
4
  'scene.changed': true,
5
5
  'settings.changed': true,
6
6
  'hotkey.state': true,
7
+ 'shortcut.state': true,
7
8
  'tracking.status': true,
8
9
  'instance.loaded': true,
9
10
  'expression.changed': true,
@@ -1,5 +1,5 @@
1
1
  import type { EventName } from './events.ts';
2
- import type { AnchorOption, AppCapability, AssetKind, AssetRef, Attach, Expression, ExpressionPersistence, HotkeyConfig, HotkeyState, InjectEntry, InjectTarget, InstanceRuntime, JsonValue, ModelInfo, ModelRef, MotionGroup, MToonTuning, ObjectContent, ObjectLightOverride, ObjectSpace, Place2D, Place3D, PlayingMotion, PoseSourceId, PoseStatus, Scene, SceneItem, ScenePatch, SceneState, ScreenPlacement, Settings, SettingsPatch, TrackingSourceConfig, TrackingSourceId, TrackingSourceKind, TrackingStatus, VrmPlacement } from './types.ts';
2
+ import type { AnchorOption, AppCapability, AssetKind, AssetRef, Attach, Expression, ExpressionPersistence, HotkeyConfig, HotkeyState, InjectEntry, InjectTarget, InstanceRuntime, JsonValue, ModelInfo, ModelRef, MotionGroup, MToonTuning, ObjectContent, ObjectLightOverride, ObjectSpace, Place2D, Place3D, PlayingMotion, PoseSourceId, PoseStatus, Scene, SceneItem, ScenePatch, SceneState, ScreenPlacement, Settings, SettingsPatch, ShortcutInfo, TrackingSourceConfig, TrackingSourceId, TrackingSourceKind, TrackingStatus, VrmPlacement } from './types.ts';
3
3
  /** Marker for methods that take no parameters; the client lets you omit the argument. */
4
4
  export type EmptyRequest = Record<never, never>;
5
5
  /** Marker for methods whose success response carries no data. */
@@ -241,6 +241,14 @@ export interface HotkeyTriggerRequest {
241
241
  hotkeyId: string;
242
242
  }
243
243
  export type HotkeyTriggerResponse = EmptyResponse;
244
+ export type ShortcutListRequest = EmptyRequest;
245
+ export interface ShortcutListResponse {
246
+ shortcuts: ShortcutInfo[];
247
+ }
248
+ export interface ShortcutTriggerRequest {
249
+ shortcutId: string;
250
+ }
251
+ export type ShortcutTriggerResponse = EmptyResponse;
244
252
  export type ModelListRequest = EmptyRequest;
245
253
  export interface ModelListResponse {
246
254
  models: ModelRef[];
@@ -612,6 +620,14 @@ export interface MethodMap {
612
620
  request: HotkeyTriggerRequest;
613
621
  response: HotkeyTriggerResponse;
614
622
  };
623
+ 'shortcut.list': {
624
+ request: ShortcutListRequest;
625
+ response: ShortcutListResponse;
626
+ };
627
+ 'shortcut.trigger': {
628
+ request: ShortcutTriggerRequest;
629
+ response: ShortcutTriggerResponse;
630
+ };
615
631
  'model.list': {
616
632
  request: ModelListRequest;
617
633
  response: ModelListResponse;
@@ -93,6 +93,9 @@ export declare const requestSchemas: {
93
93
  'hotkey.trigger': z.ZodObject<{
94
94
  hotkeyId: z.ZodString;
95
95
  }, z.core.$strip>;
96
+ 'shortcut.trigger': z.ZodObject<{
97
+ shortcutId: z.ZodString;
98
+ }, z.core.$strip>;
96
99
  'tracking.addSource': z.ZodObject<{
97
100
  kind: z.ZodEnum<{
98
101
  "vts-ios": "vts-ios";
@@ -76,6 +76,7 @@ export const requestSchemas = {
76
76
  config: z.custom(isRecord, 'config must be a hotkey config'),
77
77
  }),
78
78
  'hotkey.trigger': z.object({ hotkeyId: nonEmpty }),
79
+ 'shortcut.trigger': z.object({ shortcutId: nonEmpty }),
79
80
  'tracking.addSource': z.object({
80
81
  kind: z.enum(['vts-ios', 'vts-ios-native', 'ifacialmocap', 'vmc']),
81
82
  name: z.string().optional(),
@@ -435,7 +435,7 @@ export interface Scene {
435
435
  name: string;
436
436
  /** Models and objects in one list; array order = z-order (bottom to top) within each space. */
437
437
  items: SceneItem[];
438
- /** Tracking/pose/hotkey/expression target. null only when `items` holds no model. */
438
+ /** Hotkey target and the default instance for model-scoped methods. null only when `items` holds no model. */
439
439
  primaryInstanceId: string | null;
440
440
  background: SceneBackground;
441
441
  behavior: SceneBehavior;
@@ -468,7 +468,7 @@ export interface ScenePatch {
468
468
  * App-level features a client gates on (never version-sniff): `hello` and
469
469
  * `app.info` report them — the per-app mirror of {@link InstanceRuntime.capabilities}.
470
470
  */
471
- export declare const APP_CAPABILITIES: readonly ["storage", "speech"];
471
+ export declare const APP_CAPABILITIES: readonly ["storage", "speech", "shortcuts"];
472
472
  export type AppCapability = (typeof APP_CAPABILITIES)[number];
473
473
  export declare function isAppCapability(v: unknown): v is AppCapability;
474
474
  /** What a loaded model instance can do; absent capabilities answer `unsupported-for-format`. */
@@ -533,6 +533,24 @@ export interface HotkeyState extends HotkeyConfig {
533
533
  /** Hotkey ids currently registered with the OS (active model only). */
534
534
  registered: string[];
535
535
  }
536
+ /** Action kinds an app shortcut can carry today; servers may send kinds newer than this list. */
537
+ export declare const SHORTCUT_ACTION_KINDS: readonly ["effect-toggle", "effect-params", "camera-pose", "layer-visibility"];
538
+ export type ShortcutActionKind = (typeof SHORTCUT_ACTION_KINDS)[number];
539
+ /**
540
+ * One app-level global shortcut (a multi-action macro) as clients see it. Action
541
+ * payloads stay app-side — `actionKinds` is what drives derived labels.
542
+ */
543
+ export interface ShortcutInfo {
544
+ id: string;
545
+ /** User-given name, or null — derive a label from `actionKinds` (see `shortcutLabel`). */
546
+ title: string | null;
547
+ /** Bound key combo, or null for a trigger-only shortcut (`shortcut.trigger` still fires it). */
548
+ accelerator: string | null;
549
+ /** May include kinds newer than this SDK; label those generically. */
550
+ actionKinds: string[];
551
+ /** Whether the combo is currently registered with the OS. */
552
+ registered: boolean;
553
+ }
536
554
  export interface ExpressionPersistence {
537
555
  supported: boolean;
538
556
  enabled: boolean;
@@ -12,10 +12,13 @@ export const SHADOW_QUALITY_LEVELS = ['off', 'low', 'medium', 'high', 'extra'];
12
12
  * App-level features a client gates on (never version-sniff): `hello` and
13
13
  * `app.info` report them — the per-app mirror of {@link InstanceRuntime.capabilities}.
14
14
  */
15
- export const APP_CAPABILITIES = ['storage', 'speech'];
15
+ export const APP_CAPABILITIES = ['storage', 'speech', 'shortcuts'];
16
16
  export function isAppCapability(v) {
17
17
  return typeof v === 'string' && APP_CAPABILITIES.includes(v);
18
18
  }
19
+ // ---- App shortcuts --------------------------------------------------------------
20
+ /** Action kinds an app shortcut can carry today; servers may send kinds newer than this list. */
21
+ export const SHORTCUT_ACTION_KINDS = ['effect-toggle', 'effect-params', 'camera-pose', 'layer-visibility'];
19
22
  // ---- Settings ------------------------------------------------------------------
20
23
  export const TRACKING_SOURCE_IDS = ['vts-ios', 'vts-ios-native', 'ifacialmocap'];
21
24
  /** Body-pose protocols. Every one so far is UDP with a configurable port. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@laplace.live/persona-sdk",
3
- "version": "0.8.0",
3
+ "version": "0.9.0",
4
4
  "description": "TypeScript SDK and wire schema for the LAPLACE Persona plugin API",
5
5
  "license": "MIT",
6
6
  "type": "module",