@pollen-robotics/reachy-mini-sdk 1.7.3-main.5cd69ad

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 (85) hide show
  1. package/CHANGELOG.md +188 -0
  2. package/LICENSE +201 -0
  3. package/README.md +129 -0
  4. package/host/APP_AUTHOR_GUIDE.md +646 -0
  5. package/host/README.md +155 -0
  6. package/host/SPEC.md +618 -0
  7. package/host/dist/ReachyHost.d.ts +39 -0
  8. package/host/dist/ReachyHost.d.ts.map +1 -0
  9. package/host/dist/assets/index.d.ts +16 -0
  10. package/host/dist/assets/index.d.ts.map +1 -0
  11. package/host/dist/chunks/index-CyLPysJS.js +401 -0
  12. package/host/dist/chunks/index-CyLPysJS.js.map +1 -0
  13. package/host/dist/chunks/mountHost-8f-laxwI.js +48280 -0
  14. package/host/dist/chunks/mountHost-8f-laxwI.js.map +1 -0
  15. package/host/dist/chunks/reachy-mini-sdk-eBYlC77N.js +1719 -0
  16. package/host/dist/chunks/reachy-mini-sdk-eBYlC77N.js.map +1 -0
  17. package/host/dist/components/ConnectingView.d.ts +13 -0
  18. package/host/dist/components/ConnectingView.d.ts.map +1 -0
  19. package/host/dist/components/EmbedFrame.d.ts +16 -0
  20. package/host/dist/components/EmbedFrame.d.ts.map +1 -0
  21. package/host/dist/components/ErrorView.d.ts +21 -0
  22. package/host/dist/components/ErrorView.d.ts.map +1 -0
  23. package/host/dist/components/LeavingView.d.ts +33 -0
  24. package/host/dist/components/LeavingView.d.ts.map +1 -0
  25. package/host/dist/components/PickerView.d.ts +51 -0
  26. package/host/dist/components/PickerView.d.ts.map +1 -0
  27. package/host/dist/components/ReachyHostShell.d.ts +21 -0
  28. package/host/dist/components/ReachyHostShell.d.ts.map +1 -0
  29. package/host/dist/components/SignInView.d.ts +32 -0
  30. package/host/dist/components/SignInView.d.ts.map +1 -0
  31. package/host/dist/components/StepsProgressIndicator.d.ts +41 -0
  32. package/host/dist/components/StepsProgressIndicator.d.ts.map +1 -0
  33. package/host/dist/components/TopBar.d.ts +52 -0
  34. package/host/dist/components/TopBar.d.ts.map +1 -0
  35. package/host/dist/components/WelcomeBackOverlay.d.ts +28 -0
  36. package/host/dist/components/WelcomeBackOverlay.d.ts.map +1 -0
  37. package/host/dist/embed/index.d.ts +151 -0
  38. package/host/dist/embed/index.d.ts.map +1 -0
  39. package/host/dist/entry/auto.d.ts +12 -0
  40. package/host/dist/entry/auto.d.ts.map +1 -0
  41. package/host/dist/entry/auto.js +7 -0
  42. package/host/dist/entry/auto.js.map +1 -0
  43. package/host/dist/entry/embed.d.ts +12 -0
  44. package/host/dist/entry/embed.d.ts.map +1 -0
  45. package/host/dist/entry/embed.js +7 -0
  46. package/host/dist/entry/embed.js.map +1 -0
  47. package/host/dist/hooks/useHfProfile.d.ts +7 -0
  48. package/host/dist/hooks/useHfProfile.d.ts.map +1 -0
  49. package/host/dist/hooks/useHostBridge.d.ts +37 -0
  50. package/host/dist/hooks/useHostBridge.d.ts.map +1 -0
  51. package/host/dist/hooks/useOAuth.d.ts +16 -0
  52. package/host/dist/hooks/useOAuth.d.ts.map +1 -0
  53. package/host/dist/hooks/useRobots.d.ts +17 -0
  54. package/host/dist/hooks/useRobots.d.ts.map +1 -0
  55. package/host/dist/hooks/useSdk.d.ts +16 -0
  56. package/host/dist/hooks/useSdk.d.ts.map +1 -0
  57. package/host/dist/index.d.ts +25 -0
  58. package/host/dist/index.d.ts.map +1 -0
  59. package/host/dist/index.js +15 -0
  60. package/host/dist/index.js.map +1 -0
  61. package/host/dist/lib/centralListener.d.ts +73 -0
  62. package/host/dist/lib/centralListener.d.ts.map +1 -0
  63. package/host/dist/lib/centralRest.d.ts +35 -0
  64. package/host/dist/lib/centralRest.d.ts.map +1 -0
  65. package/host/dist/lib/protocol.d.ts +230 -0
  66. package/host/dist/lib/protocol.d.ts.map +1 -0
  67. package/host/dist/lib/protocol.js +48 -0
  68. package/host/dist/lib/protocol.js.map +1 -0
  69. package/host/dist/lib/sdk-types.d.ts +46 -0
  70. package/host/dist/lib/sdk-types.d.ts.map +1 -0
  71. package/host/dist/lib/settings.d.ts +69 -0
  72. package/host/dist/lib/settings.d.ts.map +1 -0
  73. package/host/dist/lib/signalingUrl.d.ts +28 -0
  74. package/host/dist/lib/signalingUrl.d.ts.map +1 -0
  75. package/host/dist/lib/theme.d.ts +4 -0
  76. package/host/dist/lib/theme.d.ts.map +1 -0
  77. package/host/dist/lib/themeMode.d.ts +9 -0
  78. package/host/dist/lib/themeMode.d.ts.map +1 -0
  79. package/host/dist/lib/tokens.d.ts +64 -0
  80. package/host/dist/lib/tokens.d.ts.map +1 -0
  81. package/host/dist/mountHost.d.ts +36 -0
  82. package/host/dist/mountHost.d.ts.map +1 -0
  83. package/package.json +109 -0
  84. package/reachy-mini-sdk.d.ts +294 -0
  85. package/reachy-mini-sdk.js +2618 -0
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Settings + auth helpers for the host shell.
3
+ *
4
+ * Three concerns live here:
5
+ * 1. OAuth client ID resolution (HF Spaces injection > caller-
6
+ * supplied > `localStorage`).
7
+ * 2. Dev token seeding: skips the OAuth dance entirely when the
8
+ * app author passes `devToken` to `mountHost()`.
9
+ * 3. Inter-load flags (`oauth-pending` for the "welcome back"
10
+ * animation; `signed-out` so we don't auto-relogin after a
11
+ * user-initiated logout).
12
+ *
13
+ * Storage rules (SPEC §8.2):
14
+ * - HF token + user name live in `sessionStorage` (tab-scoped,
15
+ * wiped on close). The Reachy Mini SDK reads them from
16
+ * `hf_token` / `hf_username` / `hf_token_expires`.
17
+ * - Persistent flags (`hf_oauth_client_id`, `oauth-pending`,
18
+ * `signed-out`) live in `localStorage`.
19
+ * - Tokens have a 15 min TTL by default; the SDK refreshes
20
+ * on demand if a real OAuth refresh flow is wired.
21
+ */
22
+ export type ClientIdSource = 'none' | 'caller' | 'space' | 'localStorage';
23
+ export interface DevTokenConfig {
24
+ token: string;
25
+ userName: string;
26
+ }
27
+ /** Resolve the OAuth client ID from all known sources. */
28
+ export declare function resolveClientId(callerSupplied?: string): string | undefined;
29
+ /** Same as `resolveClientId` but reports which source won.
30
+ * Useful for the SignInView's "you're using…" hint. */
31
+ export declare function resolveClientIdSource(callerSupplied?: string): {
32
+ clientId: string | undefined;
33
+ source: ClientIdSource;
34
+ };
35
+ /** Persist an OAuth client ID for future sessions. */
36
+ export declare function storeClientId(clientId: string): void;
37
+ /** Pre-seed the SDK's auth cache with a personal access token.
38
+ * Used in dev to skip the OAuth redirect. */
39
+ export declare function seedDevToken(config: DevTokenConfig): void;
40
+ /** `true` if a dev token was passed to `mountHost()` this page
41
+ * load, regardless of whether the session storage was later
42
+ * wiped by a sign-out. */
43
+ export declare function hasCachedDevToken(): boolean;
44
+ /** Re-seed the session storage from the cached dev token. No-op
45
+ * if no dev token was provided to `mountHost()`. Returns `true`
46
+ * iff a token was re-seeded. */
47
+ export declare function rehydrateDevToken(): boolean;
48
+ /** Mark that we're about to start an OAuth redirect. The host
49
+ * reads this on the next boot to show the "welcome back" view. */
50
+ export declare function markOAuthPending(): void;
51
+ /** Read and clear the `oauth-pending` flag in one call. Returns
52
+ * `true` iff this boot is the result of an OAuth redirect. */
53
+ export declare function consumeOAuthPending(): boolean;
54
+ /** Mark the user as explicitly signed out so the SDK doesn't
55
+ * silently re-authenticate from a leftover session cookie. */
56
+ export declare function markUserSignedOut(): void;
57
+ /** Clear the signed-out flag (called when the user clicks
58
+ * "Sign in" after a logout). */
59
+ export declare function clearSignedOutFlag(): void;
60
+ /** Returns `true` if the user explicitly signed out earlier. */
61
+ export declare function isUserSignedOut(): boolean;
62
+ /** Wipe HF token keys from sessionStorage. Called by the embed
63
+ * on `host:leaving` before the iframe unmounts (SPEC §8.2). */
64
+ export declare function wipeHfSessionStorage(): void;
65
+ /** Decode a base64 JSON `?config=` URL parameter into a typed
66
+ * value. Returns `null` on missing / malformed input. The
67
+ * caller is responsible for validating the shape. */
68
+ export declare function readUrlConfig<T = unknown>(): T | null;
69
+ //# sourceMappingURL=settings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../../src/lib/settings.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAYH,MAAM,MAAM,cAAc,GACtB,MAAM,GACN,QAAQ,GACR,OAAO,GACP,cAAc,CAAC;AAEnB,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB;AAID,0DAA0D;AAC1D,wBAAgB,eAAe,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAW3E;AAED;wDACwD;AACxD,wBAAgB,qBAAqB,CACnC,cAAc,CAAC,EAAE,MAAM,GACtB;IAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,MAAM,EAAE,cAAc,CAAA;CAAE,CAW1D;AAED,sDAAsD;AACtD,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAMpD;AAWD;8CAC8C;AAC9C,wBAAgB,YAAY,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI,CAYzD;AAED;;2BAE2B;AAC3B,wBAAgB,iBAAiB,IAAI,OAAO,CAE3C;AAED;;iCAEiC;AACjC,wBAAgB,iBAAiB,IAAI,OAAO,CAI3C;AAID;mEACmE;AACnE,wBAAgB,gBAAgB,IAAI,IAAI,CAMvC;AAED;+DAC+D;AAC/D,wBAAgB,mBAAmB,IAAI,OAAO,CAQ7C;AAID;+DAC+D;AAC/D,wBAAgB,iBAAiB,IAAI,IAAI,CAMxC;AAED;iCACiC;AACjC,wBAAgB,kBAAkB,IAAI,IAAI,CAMzC;AAED,gEAAgE;AAChE,wBAAgB,eAAe,IAAI,OAAO,CAMzC;AAID;gEACgE;AAChE,wBAAgB,oBAAoB,IAAI,IAAI,CAQ3C;AAID;;sDAEsD;AACtD,wBAAgB,aAAa,CAAC,CAAC,GAAG,OAAO,KAAK,CAAC,GAAG,IAAI,CAUrD"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Resolve the signaling URL for the ReachyMini SDK.
3
+ *
4
+ * Priority:
5
+ * 1. `?signaling_url=<url>` URL parameter (override for
6
+ * staging / self-hosted central).
7
+ * 2. `window.huggingface.variables.SIGNALING_URL` if injected
8
+ * by the HF Spaces frontmatter (rare).
9
+ * 3. The canonical Pollen-Robotics central
10
+ * (`https://pollen-robotics-reachy-mini-central.hf.space`).
11
+ *
12
+ * Why we don't fall back to the SDK's bundled default
13
+ * ───────────────────────────────────────────────────
14
+ * The SDK shipped with `tfrere-reachy-mini-central.hf.space`
15
+ * baked in for legacy reasons. Reachies registered through the
16
+ * mobile app (the canonical onboarding path) sit on the
17
+ * `pollen-robotics-...` Space, so a host that lets the SDK fall
18
+ * back to the legacy URL ends up showing an empty list even when
19
+ * the user owns one of those robots. We override the default
20
+ * here so the host and the mobile app talk to the same central
21
+ * out of the box.
22
+ *
23
+ * Never throws. A malformed override just falls back to the
24
+ * canonical default.
25
+ */
26
+ export declare const DEFAULT_CENTRAL_SIGNALING_URL = "https://pollen-robotics-reachy-mini-central.hf.space";
27
+ export declare function resolveSignalingUrl(): string;
28
+ //# sourceMappingURL=signalingUrl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signalingUrl.d.ts","sourceRoot":"","sources":["../../src/lib/signalingUrl.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,eAAO,MAAM,6BAA6B,yDACc,CAAC;AAEzD,wBAAgB,mBAAmB,IAAI,MAAM,CAsB5C"}
@@ -0,0 +1,4 @@
1
+ import type { Theme } from '@mui/material/styles';
2
+ export declare const lightTheme: Theme;
3
+ export declare const darkTheme: Theme;
4
+ //# sourceMappingURL=theme.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme.d.ts","sourceRoot":"","sources":["../../src/lib/theme.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AA2FlD,eAAO,MAAM,UAAU,EAAE,KAA2B,CAAC;AACrD,eAAO,MAAM,SAAS,EAAE,KAA0B,CAAC"}
@@ -0,0 +1,9 @@
1
+ import type { ThemeMode } from './protocol';
2
+ /**
3
+ * React hook returning the current theme mode and reacting to OS
4
+ * palette changes. Stable across React StrictMode double-mounts:
5
+ * the `matchMedia` listener is registered in an effect with a
6
+ * proper cleanup.
7
+ */
8
+ export declare function useThemeMode(): ThemeMode;
9
+ //# sourceMappingURL=themeMode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"themeMode.d.ts","sourceRoot":"","sources":["../../src/lib/themeMode.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AA6B5C;;;;;GAKG;AACH,wBAAgB,YAAY,IAAI,SAAS,CAqBxC"}
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Shared design tokens.
3
+ *
4
+ * Mirrors `reachy_mini_mobile_app/src/ui/design/tokens.ts` so the
5
+ * host shell, the mobile shell, and the desktop app share one
6
+ * visual vocabulary (typography scale, weight scale, radii,
7
+ * status colours, motion durations). Keep this file in lockstep
8
+ * with the mobile one - drift is what gets flagged at design
9
+ * review.
10
+ *
11
+ * Safe-area insets are NOT exposed here: the host shell ships on
12
+ * desktop browsers and HF Spaces, where notch / home-indicator
13
+ * insets are not a concern. The mobile shell keeps that layer in
14
+ * its own tokens module.
15
+ */
16
+ export declare const TYPO: {
17
+ readonly micro: "0.65rem";
18
+ readonly tiny: "0.7rem";
19
+ readonly xs: "0.75rem";
20
+ readonly sm: "0.8rem";
21
+ readonly body: "0.85rem";
22
+ readonly md: "0.9rem";
23
+ readonly lg: "1rem";
24
+ readonly xl: "1.1rem";
25
+ readonly xxl: "1.25rem";
26
+ readonly hero: "1.5rem";
27
+ readonly display: "1.625rem";
28
+ };
29
+ export declare const FONT_WEIGHT: {
30
+ readonly regular: 400;
31
+ readonly medium: 500;
32
+ readonly semibold: 600;
33
+ readonly bold: 700;
34
+ };
35
+ export declare const RADIUS: {
36
+ readonly xs: 4;
37
+ readonly sm: 6;
38
+ readonly md: 8;
39
+ readonly lg: 12;
40
+ readonly xl: 16;
41
+ readonly xxl: 20;
42
+ readonly pill: 9999;
43
+ readonly circle: "50%";
44
+ };
45
+ export declare const STATUS: {
46
+ readonly success: "#22c55e";
47
+ readonly successSoft: "#16a34a";
48
+ readonly error: "#ef4444";
49
+ readonly warning: "#f59e0b";
50
+ readonly info: "#6366f1";
51
+ };
52
+ export declare const DURATION: {
53
+ readonly fast: 150;
54
+ readonly base: 250;
55
+ readonly slow: 400;
56
+ };
57
+ export declare const LAYOUT: {
58
+ /** Max width of any centred "card-in-screen" content (sign-in,
59
+ * picker, error). Matches the mobile shell. */
60
+ readonly contentMaxWidth: 420;
61
+ readonly heroSize: 160;
62
+ readonly heroSizeSmall: 120;
63
+ };
64
+ //# sourceMappingURL=tokens.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../../src/lib/tokens.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,eAAO,MAAM,IAAI;;;;;;;;;;;;CAYP,CAAC;AAEX,eAAO,MAAM,WAAW;;;;;CAKd,CAAC;AAEX,eAAO,MAAM,MAAM;;;;;;;;;CAST,CAAC;AAEX,eAAO,MAAM,MAAM;;;;;;CAMT,CAAC;AAEX,eAAO,MAAM,QAAQ;;;;CAIX,CAAC;AAEX,eAAO,MAAM,MAAM;IACjB;oDACgD;;;;CAIxC,CAAC"}
@@ -0,0 +1,36 @@
1
+ import type { ConfigPayload } from './lib/protocol';
2
+ export interface MountHostOptions {
3
+ /** REQUIRED. Passed to the SDK + shown in the top bar. */
4
+ appName: string;
5
+ /** Optional top-bar logo. Recommended PNG/SVG, 32×32. */
6
+ appIconUrl?: string;
7
+ /** Optional emoji fallback (used when no icon URL). */
8
+ appEmoji?: string;
9
+ /** Allow microphone capture inside the iframe. */
10
+ enableMicrophone?: boolean;
11
+ /** HF OAuth client ID override; falls back to HF Spaces
12
+ * injection then localStorage. */
13
+ clientId?: string;
14
+ /** Dev shortcut: seed a personal access token so the host
15
+ * skips the OAuth dance. Strip this before deploying. */
16
+ devToken?: {
17
+ token: string;
18
+ userName: string;
19
+ };
20
+ /** Mount target: an HTMLElement or a CSS selector. Defaults
21
+ * to `#root` (auto-created if missing). */
22
+ target?: HTMLElement | string;
23
+ /** Embed path within the same origin. Defaults to
24
+ * `/?embedded=1`. */
25
+ embedPath?: string;
26
+ /** Override the host display name in the top bar. */
27
+ hostName?: string;
28
+ /** Pre-set the initial config (mostly for tests; production
29
+ * reads `?config=` automatically). */
30
+ initialConfig?: ConfigPayload;
31
+ }
32
+ export interface MountedHost {
33
+ unmount(): void;
34
+ }
35
+ export declare function mountHost(options: MountHostOptions): MountedHost;
36
+ //# sourceMappingURL=mountHost.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mountHost.d.ts","sourceRoot":"","sources":["../src/mountHost.tsx"],"names":[],"mappings":"AA4BA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEpD,MAAM,WAAW,gBAAgB;IAC/B,0DAA0D;IAC1D,OAAO,EAAE,MAAM,CAAC;IAChB,yDAAyD;IACzD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,uDAAuD;IACvD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kDAAkD;IAClD,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B;uCACmC;IACnC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;8DAC0D;IAC1D,QAAQ,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IAC/C;gDAC4C;IAC5C,MAAM,CAAC,EAAE,WAAW,GAAG,MAAM,CAAC;IAC9B;0BACsB;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qDAAqD;IACrD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;2CACuC;IACvC,aAAa,CAAC,EAAE,aAAa,CAAC;CAC/B;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,IAAI,IAAI,CAAC;CACjB;AAED,wBAAgB,SAAS,CAAC,OAAO,EAAE,gBAAgB,GAAG,WAAW,CA6ChE"}
package/package.json ADDED
@@ -0,0 +1,109 @@
1
+ {
2
+ "name": "@pollen-robotics/reachy-mini-sdk",
3
+ "version": "1.7.3-main.5cd69ad",
4
+ "description": "Browser SDK for controlling a Reachy Mini robot over WebRTC, plus an optional Hugging Face Spaces host shell (OAuth + robot picker + iframe bridge) exposed via the ./host subpath.",
5
+ "type": "module",
6
+ "main": "./reachy-mini-sdk.js",
7
+ "module": "./reachy-mini-sdk.js",
8
+ "types": "./reachy-mini-sdk.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./reachy-mini-sdk.d.ts",
12
+ "import": "./reachy-mini-sdk.js",
13
+ "default": "./reachy-mini-sdk.js"
14
+ },
15
+ "./host": {
16
+ "types": "./host/dist/index.d.ts",
17
+ "import": "./host/dist/index.js"
18
+ },
19
+ "./host/auto": {
20
+ "types": "./host/dist/entry/auto.d.ts",
21
+ "import": "./host/dist/entry/auto.js"
22
+ },
23
+ "./host/embed": {
24
+ "types": "./host/dist/entry/embed.d.ts",
25
+ "import": "./host/dist/entry/embed.js"
26
+ },
27
+ "./host/protocol": {
28
+ "types": "./host/dist/lib/protocol.d.ts",
29
+ "import": "./host/dist/lib/protocol.js"
30
+ },
31
+ "./package.json": "./package.json"
32
+ },
33
+ "files": [
34
+ "reachy-mini-sdk.js",
35
+ "reachy-mini-sdk.d.ts",
36
+ "host/dist",
37
+ "host/README.md",
38
+ "host/SPEC.md",
39
+ "host/APP_AUTHOR_GUIDE.md",
40
+ "README.md",
41
+ "CHANGELOG.md",
42
+ "LICENSE"
43
+ ],
44
+ "sideEffects": false,
45
+ "scripts": {
46
+ "build": "cd host && vite build && tsc -p tsconfig.build.json",
47
+ "build:watch": "cd host && vite build --watch",
48
+ "typecheck": "cd host && tsc --noEmit",
49
+ "dev": "cd host && vite",
50
+ "clean": "rm -rf host/dist"
51
+ },
52
+ "dependencies": {
53
+ "@emotion/react": "^11.14.0",
54
+ "@emotion/styled": "^11.14.1",
55
+ "@huggingface/hub": "^0.15.2",
56
+ "@mui/icons-material": "^7.3.5",
57
+ "@mui/material": "^7.3.5"
58
+ },
59
+ "peerDependencies": {
60
+ "react": "^18.0.0 || ^19.0.0",
61
+ "react-dom": "^18.0.0 || ^19.0.0"
62
+ },
63
+ "peerDependenciesMeta": {
64
+ "react": {
65
+ "optional": true
66
+ },
67
+ "react-dom": {
68
+ "optional": true
69
+ }
70
+ },
71
+ "devDependencies": {
72
+ "@types/node": "^25.7.0",
73
+ "@types/react": "^19.2.14",
74
+ "@types/react-dom": "^19.2.3",
75
+ "@vitejs/plugin-react-swc": "^4.0.0",
76
+ "react": "^19.2.5",
77
+ "react-dom": "^19.2.5",
78
+ "typescript": "^5.7.3",
79
+ "vite": "^7.2.1"
80
+ },
81
+ "keywords": [
82
+ "reachy",
83
+ "reachy-mini",
84
+ "pollen-robotics",
85
+ "robot",
86
+ "robotics",
87
+ "webrtc",
88
+ "sdk",
89
+ "browser",
90
+ "huggingface-spaces",
91
+ "host",
92
+ "iframe",
93
+ "shell"
94
+ ],
95
+ "author": "Pollen Robotics",
96
+ "license": "Apache-2.0",
97
+ "homepage": "https://github.com/pollen-robotics/reachy_mini#readme",
98
+ "bugs": {
99
+ "url": "https://github.com/pollen-robotics/reachy_mini/issues"
100
+ },
101
+ "repository": {
102
+ "type": "git",
103
+ "url": "git+https://github.com/pollen-robotics/reachy_mini.git",
104
+ "directory": "js"
105
+ },
106
+ "publishConfig": {
107
+ "access": "public"
108
+ }
109
+ }
@@ -0,0 +1,294 @@
1
+ /**
2
+ * Type declarations for the ReachyMini browser SDK. These are the
3
+ * canonical types shipped with the npm package — the host shell
4
+ * (`./host` subpath) re-exports them via `host/src/lib/sdk-types.ts`
5
+ * so React components, hooks, and the embed client all see exactly
6
+ * the same surface.
7
+ *
8
+ * The runtime lives in `reachy-mini-sdk.js`; this `.d.ts` only
9
+ * declares the public types. We hand-maintain it (rather than
10
+ * generating from the JSDoc) so consumers get rich types without an
11
+ * extra build step on our side.
12
+ *
13
+ * Legacy CDN consumers can still expose the constructor on
14
+ * `window.ReachyMini` themselves; the global declaration at the
15
+ * bottom keeps that shape typed.
16
+ */
17
+
18
+ /** Robot summary returned by the central via `robots`/`robotsChanged`. */
19
+ export interface RobotInfo {
20
+ id: string;
21
+ meta?: { name?: string };
22
+ /**
23
+ * `true` when the central reports an active session held by
24
+ * another consumer. Older centrals omit it; default `false`.
25
+ */
26
+ busy?: boolean;
27
+ /**
28
+ * Friendly name of the app currently holding the session, when
29
+ * the busy consumer advertised one. Pure UX hint, never trust
30
+ * for security decisions. `null` / undefined when the robot is
31
+ * free.
32
+ */
33
+ activeApp?: string | null;
34
+ /**
35
+ * Network transport reported by the daemon (`wifi` / `usb` /
36
+ * arbitrary string). Surfaced as a chip on the discovery card.
37
+ * Older centrals or non-conformant daemons may omit it.
38
+ */
39
+ transport?: string | null;
40
+ /**
41
+ * Hardware id reported by the daemon (e.g. serial number).
42
+ * When present, the picker shows it in place of the (longer,
43
+ * less human-friendly) peer id. Optional.
44
+ */
45
+ hardwareId?: string | null;
46
+ }
47
+
48
+ /** Latest robot telemetry mirrored on `robot.robotState` (wire shape). */
49
+ export interface RobotState {
50
+ /** Flat row-major 4×4 head pose (16 numbers). */
51
+ head?: number[];
52
+ /** [rightRad, leftRad]. */
53
+ antennas?: number[];
54
+ /** Radians. */
55
+ body_yaw?: number;
56
+ motor_mode?: 'enabled' | 'disabled' | 'gravity_compensation';
57
+ is_move_running?: boolean;
58
+ }
59
+
60
+ /** SDK constructor options. */
61
+ export interface ReachyMiniOptions {
62
+ signalingUrl?: string;
63
+ /**
64
+ * @deprecated The SDK no longer acquires the user's microphone. A silent
65
+ * placeholder audio sender is always set up so apps can `replaceTrack`
66
+ * their own audio (TTS, files, or — for teleop — the user's mic) onto
67
+ * it. This option is parsed for backward compatibility but has no
68
+ * effect.
69
+ */
70
+ enableMicrophone?: boolean;
71
+ clientId?: string;
72
+ appName?: string;
73
+ /**
74
+ * Hint to the receiver's WebRTC jitter buffer (ms). 0 = "render
75
+ * ASAP", appropriate for teleop. Spec range [0, 4000]. Browsers
76
+ * that don't implement `RTCRtpReceiver.jitterBufferTarget` fall
77
+ * back to default buffering (~150-200 ms).
78
+ */
79
+ videoJitterBufferTargetMs?: number;
80
+ /**
81
+ * When true AND the URL carries a `robot_peer_id` hint, the SDK
82
+ * auto-calls `startSession(preselectedRobotId)` once that robot
83
+ * appears in the central's list after `connect()` resolves. One-shot
84
+ * per page load; the host iframe relies on this to skip the picker.
85
+ */
86
+ autoStartFromUrl?: boolean;
87
+ }
88
+
89
+ /** Options accepted by `autoConnect()`. */
90
+ export interface AutoConnectOptions {
91
+ /** Skip `authenticate()`; use this raw HF token. */
92
+ token?: string;
93
+ /**
94
+ * Called in the standalone, multi-robot case to let the consumer
95
+ * pick a robot from the live list. Return the robot id, or `null`
96
+ * to cancel.
97
+ */
98
+ pickRobot?: (robots: AutoConnectRobotChoice[]) => Promise<string | null>;
99
+ /** Skip `pickRobot` when exactly one robot is free. Default `true`. */
100
+ autoPickIfSingle?: boolean;
101
+ /** Hide busy robots from the picker. Default `true`. */
102
+ filterBusy?: boolean;
103
+ /** Call `ensureAwake()` after `startSession()`. Default `true`. */
104
+ wakeOnConnect?: boolean;
105
+ }
106
+
107
+ /** Robot row passed to `pickRobot` callback (richer than `RobotInfo`). */
108
+ export interface AutoConnectRobotChoice {
109
+ id: string;
110
+ name: string | null;
111
+ busy: boolean;
112
+ activeApp: string | null;
113
+ meta: Record<string, unknown>;
114
+ lastSeenAgeSeconds: number | null;
115
+ }
116
+
117
+ /** Resolution payload of `autoConnect()`. */
118
+ export interface AutoConnectResult {
119
+ robotId: string;
120
+ robotName: string | null;
121
+ isEmbedded: boolean;
122
+ /** Set when `autoConnect()` short-circuited on an already-streaming session. */
123
+ alreadyStreaming?: boolean;
124
+ }
125
+
126
+ /** Options for the awaitable motion helpers (`wakeUp`, `gotoSleep`). */
127
+ export interface MotionAwaitOptions {
128
+ /**
129
+ * Hard upper bound for the trajectory completion response from the
130
+ * daemon. Defaults to 8000 ms (typical wake_up is ~1-3 s, but
131
+ * deeply offset poses can take longer). The returned promise
132
+ * rejects with a `${command} timed out after ${timeoutMs}ms` error
133
+ * if the daemon goes silent.
134
+ */
135
+ timeoutMs?: number;
136
+ }
137
+
138
+ /** `subscribeLogs()` argument. */
139
+ export interface SubscribeLogsOptions {
140
+ onLine: (entry: { timestamp: string; line: string }) => void;
141
+ onError?: (error: string) => void;
142
+ }
143
+
144
+ /** Public surface of a ReachyMini SDK instance. */
145
+ export interface ReachyMiniInstance extends EventTarget {
146
+ readonly state: 'disconnected' | 'connected' | 'streaming';
147
+ readonly robots: RobotInfo[];
148
+ /**
149
+ * Mirror of the latest "state" event detail. Fields appear only once
150
+ * the daemon has sent the corresponding source field.
151
+ */
152
+ readonly robotState: RobotState;
153
+ readonly username: string | null;
154
+ readonly isAuthenticated: boolean;
155
+ readonly micSupported: boolean;
156
+ readonly micMuted: boolean;
157
+ readonly audioMuted: boolean;
158
+ /** Set by the SDK from `?robot_peer_id=` / `#robot_peer_id=`. */
159
+ readonly preselectedRobotId: string | null;
160
+ /** `true` iff `preselectedRobotId !== null`. UX branching helper. */
161
+ readonly isEmbedded: boolean;
162
+
163
+ /** Underlying RTCPeerConnection. Apps can read it to inspect
164
+ * audio / video transceivers. */
165
+ _pc: RTCPeerConnection | null;
166
+ /** Silent placeholder MediaStream the SDK feeds the WebRTC audio
167
+ * sender so robot-speaker output can negotiate sendrecv. Apps inject
168
+ * their own audio (TTS, files, the user's mic for teleop) by calling
169
+ * `replaceTrack()` on the audio sender from `_pc.getSenders()`. */
170
+ _micStream: MediaStream | null;
171
+
172
+ authenticate(): Promise<boolean>;
173
+ login(): Promise<void>;
174
+ logout(): void;
175
+
176
+ connect(token?: string): Promise<void>;
177
+ /**
178
+ * One-shot bring-up: auth → SSE connect → robot selection → session →
179
+ * wake up. The all-in-one entry point that captures the common
180
+ * "embed *or* standalone, just get me streaming" flow.
181
+ */
182
+ autoConnect(options?: AutoConnectOptions): Promise<AutoConnectResult>;
183
+ disconnect(): void;
184
+
185
+ startSession(robotId: string): Promise<void>;
186
+ stopSession(): Promise<void>;
187
+
188
+ attachVideo(el: HTMLVideoElement): () => void;
189
+
190
+ setHeadRpyDeg(roll: number, pitch: number, yaw: number): boolean;
191
+ setAntennasDeg(right: number, left: number): boolean;
192
+ setBodyYawDeg(yawDeg: number): boolean;
193
+ /**
194
+ * Streaming variant for the trajectory player: sets the full
195
+ * target frame at 50-100 Hz. Unspecified joints keep their
196
+ * previous target. Returns `false` if the data channel is not
197
+ * open.
198
+ */
199
+ setTarget(args: {
200
+ head?: number[];
201
+ antennas?: number[];
202
+ body_yaw?: number;
203
+ }): boolean;
204
+ /**
205
+ * Smooth daemon-side interpolation to a target pose over `duration`
206
+ * seconds. Mirrors `setTarget`'s wire shape and adds a required
207
+ * `duration` field. Throws `TypeError` on invalid input.
208
+ */
209
+ gotoTarget(args: {
210
+ head?: number[];
211
+ antennas?: number[];
212
+ body_yaw?: number;
213
+ duration: number;
214
+ }): boolean;
215
+ /** Send an arbitrary JSON message on the data channel. */
216
+ sendRaw(data: unknown): boolean;
217
+ /** Play a sound file on the robot's speakers (basename). */
218
+ playSound(file: string): boolean;
219
+
220
+ setAudioMuted(muted: boolean): void;
221
+ setMicMuted(muted: boolean): void;
222
+
223
+ getVolume(): Promise<number | null>;
224
+ setVolume(volume: number): Promise<number | null>;
225
+ getMicrophoneVolume(): Promise<number | null>;
226
+ setMicrophoneVolume(volume: number): Promise<number | null>;
227
+
228
+ /** Daemon version string, or `null` when unavailable. */
229
+ getVersion(): Promise<string | null>;
230
+ /** Hardware ID (USB serial), or `null` on developer machines. */
231
+ getHardwareId(): Promise<string | null>;
232
+ /** Force a `state` event right now (background poll runs at 500 ms). */
233
+ requestState(): boolean;
234
+ /** Subscribe to daemon `journalctl` logs over the data channel. */
235
+ subscribeLogs(options: SubscribeLogsOptions): () => void;
236
+
237
+ /**
238
+ * Motor torque mode: `enabled` (position control), `disabled`
239
+ * (limp), `gravity_compensation` (float-by-hand). Returns
240
+ * `false` if the data channel is not open.
241
+ */
242
+ setMotorMode(
243
+ mode: 'enabled' | 'disabled' | 'gravity_compensation',
244
+ ): boolean;
245
+ /**
246
+ * Per-motor torque toggle. When `ids` is omitted, applies globally
247
+ * (equivalent to `setMotorMode("enabled" | "disabled")`).
248
+ */
249
+ setMotorTorque(on: boolean, ids?: string[] | null): boolean;
250
+ /**
251
+ * Play the wake-up trajectory (enables motors first). Resolves on
252
+ * the daemon's `{command: "wake_up", completed: true}` response,
253
+ * rejects on `timeoutMs` elapsed or on session teardown.
254
+ */
255
+ wakeUp(options?: MotionAwaitOptions): Promise<void>;
256
+ /**
257
+ * Play the goto-sleep trajectory. Resolves when the daemon reports
258
+ * completion. Does NOT touch motor mode; caller manages it.
259
+ */
260
+ gotoSleep(options?: MotionAwaitOptions): Promise<void>;
261
+ /** Read the awake state from the cached `motor_mode`. */
262
+ isAwake(): boolean;
263
+ /**
264
+ * Idempotent wakeUp: noop when already awake. Resolves with
265
+ * the post-call awake state. Does NOT await the trajectory.
266
+ */
267
+ ensureAwake(timeoutMs?: number): Promise<boolean>;
268
+ }
269
+
270
+ export type ReachyMiniConstructor = new (
271
+ options?: ReachyMiniOptions,
272
+ ) => ReachyMiniInstance;
273
+
274
+ /** SDK constructor. */
275
+ export const ReachyMini: ReachyMiniConstructor;
276
+
277
+ /** Degrees → radians. */
278
+ export function degToRad(deg: number): number;
279
+ /** Radians → degrees. */
280
+ export function radToDeg(rad: number): number;
281
+ /** Roll/pitch/yaw (degrees) → 4×4 rotation matrix (ZYX convention). */
282
+ export function rpyToMatrix(
283
+ rollDeg: number,
284
+ pitchDeg: number,
285
+ yawDeg: number,
286
+ ): number[][];
287
+ /** Rotation matrix (3×3 or 4×4) → `{ roll, pitch, yaw }` in degrees. */
288
+ export function matrixToRpy(m: number[][]): {
289
+ roll: number;
290
+ pitch: number;
291
+ yaw: number;
292
+ };
293
+
294
+ export default ReachyMini;