oomi-ai 0.2.50 → 0.3.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.
Files changed (88) hide show
  1. package/README.md +203 -507
  2. package/agent_instructions.md +244 -253
  3. package/bin/oomi-ai.js +4026 -5795
  4. package/bin/sessionBridgeState.js +78 -78
  5. package/lib/openclawPaths.js +70 -71
  6. package/lib/openclawProfile.js +216 -216
  7. package/lib/personaApiClient.js +133 -303
  8. package/lib/spokenMetadata.js +137 -137
  9. package/openclaw.extension.js +341 -341
  10. package/openclaw.plugin.json +17 -17
  11. package/package.json +59 -59
  12. package/persona-app/README.md +27 -0
  13. package/persona-app/registry/v1.json +63 -0
  14. package/persona-app/schema/persona-app.v1.schema.json +90 -0
  15. package/skills/oomi/SKILL.md +165 -182
  16. package/skills/oomi/agent_instructions.md +99 -80
  17. package/lib/channelPluginClient.js +0 -119
  18. package/lib/openclawDevGateway.js +0 -384
  19. package/lib/personaJobExecutor.js +0 -139
  20. package/lib/personaJobPoller.js +0 -112
  21. package/lib/personaPortAllocator.js +0 -36
  22. package/lib/personaRuntimeManager.js +0 -496
  23. package/lib/personaRuntimeProcess.js +0 -924
  24. package/lib/personaRuntimeRegistry.js +0 -67
  25. package/lib/personaRuntimeSupervisor.js +0 -330
  26. package/lib/scaffold.js +0 -108
  27. package/lib/template.js +0 -45
  28. package/skills/oomi/config.json +0 -3
  29. package/skills/oomi/scripts/get_avatar_capabilities.py +0 -40
  30. package/skills/oomi/scripts/get_data.py +0 -49
  31. package/skills/oomi/scripts/install_agent_instructions.py +0 -78
  32. package/skills/oomi/scripts/send_goal.py +0 -53
  33. package/skills/oomi/scripts/sync.py +0 -46
  34. package/skills/oomi/setup.py +0 -41
  35. package/templates/persona-app/.env.example +0 -8
  36. package/templates/persona-app/README.md +0 -58
  37. package/templates/persona-app/eslint.config.js +0 -28
  38. package/templates/persona-app/index.html +0 -18
  39. package/templates/persona-app/oomi.runtime.json +0 -13
  40. package/templates/persona-app/package.json +0 -44
  41. package/templates/persona-app/persona/brief.md +0 -14
  42. package/templates/persona-app/persona.json +0 -14
  43. package/templates/persona-app/public/manifest.webmanifest +0 -8
  44. package/templates/persona-app/public/oomi.health.json +0 -6
  45. package/templates/persona-app/src/App.css +0 -379
  46. package/templates/persona-app/src/App.tsx +0 -17
  47. package/templates/persona-app/src/index.css +0 -53
  48. package/templates/persona-app/src/main.tsx +0 -23
  49. package/templates/persona-app/src/pages/HomePage.tsx +0 -127
  50. package/templates/persona-app/src/pages/ScenePage.tsx +0 -158
  51. package/templates/persona-app/src/persona/config.ts +0 -6
  52. package/templates/persona-app/src/persona/notes.ts +0 -10
  53. package/templates/persona-app/src/spatial.ts +0 -82
  54. package/templates/persona-app/src/vite-env.d.ts +0 -3
  55. package/templates/persona-app/template.json +0 -13
  56. package/templates/persona-app/tsconfig.app.json +0 -23
  57. package/templates/persona-app/tsconfig.json +0 -7
  58. package/templates/persona-app/tsconfig.node.json +0 -21
  59. package/templates/persona-app/vendor/webspatial/FORK.md +0 -6
  60. package/templates/persona-app/vendor/webspatial/core-sdk/LICENSE +0 -21
  61. package/templates/persona-app/vendor/webspatial/core-sdk/dist/iife/index.d.ts +0 -906
  62. package/templates/persona-app/vendor/webspatial/core-sdk/dist/iife/index.global.js +0 -75
  63. package/templates/persona-app/vendor/webspatial/core-sdk/dist/iife/index.global.js.map +0 -1
  64. package/templates/persona-app/vendor/webspatial/core-sdk/dist/index.d.ts +0 -906
  65. package/templates/persona-app/vendor/webspatial/core-sdk/dist/index.js +0 -3131
  66. package/templates/persona-app/vendor/webspatial/core-sdk/dist/index.js.map +0 -1
  67. package/templates/persona-app/vendor/webspatial/core-sdk/package.json +0 -45
  68. package/templates/persona-app/vendor/webspatial/react-sdk/LICENSE +0 -21
  69. package/templates/persona-app/vendor/webspatial/react-sdk/dist/default/index.d.ts +0 -365
  70. package/templates/persona-app/vendor/webspatial/react-sdk/dist/default/index.js +0 -4167
  71. package/templates/persona-app/vendor/webspatial/react-sdk/dist/default/index.js.map +0 -1
  72. package/templates/persona-app/vendor/webspatial/react-sdk/dist/jsx/jsx-dev-runtime.d.ts +0 -82
  73. package/templates/persona-app/vendor/webspatial/react-sdk/dist/jsx/jsx-dev-runtime.js +0 -66
  74. package/templates/persona-app/vendor/webspatial/react-sdk/dist/jsx/jsx-dev-runtime.js.map +0 -1
  75. package/templates/persona-app/vendor/webspatial/react-sdk/dist/jsx/jsx-dev-runtime.web.d.ts +0 -2
  76. package/templates/persona-app/vendor/webspatial/react-sdk/dist/jsx/jsx-dev-runtime.web.js +0 -18
  77. package/templates/persona-app/vendor/webspatial/react-sdk/dist/jsx/jsx-dev-runtime.web.js.map +0 -1
  78. package/templates/persona-app/vendor/webspatial/react-sdk/dist/jsx/jsx-runtime.d.ts +0 -5
  79. package/templates/persona-app/vendor/webspatial/react-sdk/dist/jsx/jsx-runtime.js +0 -66
  80. package/templates/persona-app/vendor/webspatial/react-sdk/dist/jsx/jsx-runtime.js.map +0 -1
  81. package/templates/persona-app/vendor/webspatial/react-sdk/dist/jsx/jsx-runtime.web.d.ts +0 -1
  82. package/templates/persona-app/vendor/webspatial/react-sdk/dist/jsx/jsx-runtime.web.js +0 -18
  83. package/templates/persona-app/vendor/webspatial/react-sdk/dist/jsx/jsx-runtime.web.js.map +0 -1
  84. package/templates/persona-app/vendor/webspatial/react-sdk/dist/web/index.d.ts +0 -365
  85. package/templates/persona-app/vendor/webspatial/react-sdk/dist/web/index.js +0 -4207
  86. package/templates/persona-app/vendor/webspatial/react-sdk/dist/web/index.js.map +0 -1
  87. package/templates/persona-app/vendor/webspatial/react-sdk/package.json +0 -94
  88. package/templates/persona-app/vite.config.ts +0 -31
package/README.md CHANGED
@@ -1,554 +1,250 @@
1
1
  # oomi-ai
2
2
 
3
- Managed Oomi chat, voice bridge, and XR-first persona scaffolding for OpenClaw.
3
+ Managed Oomi channel, bridge, voice, and persona app API tooling for OpenClaw.
4
4
 
5
- ## At A Glance
5
+ `oomi-ai` connects an OpenClaw machine to Oomi. Persona UI creation and rendering happen inside Oomi-managed systems. The OpenClaw machine uses API actions only.
6
6
 
7
- - managed OpenClaw channel extension for Oomi text chat
8
- - local bridge and pairing tooling for device-backed chat and voice
9
- - XR-first WebSpatial persona scaffolding for generated Oomi work surfaces
10
- - vendored AndroidXR WebSpatial fork sync and scaffold repair for managed persona runtimes
11
- - managed persona launch, register, stop, delete, and queued persona-job execution flows
12
- - repo-local runtime and TTS validation loops for package developers
7
+ The current model is:
13
8
 
14
- This package is for two audiences:
15
- - OpenClaw operators who need to connect a machine to Oomi and keep chat or voice healthy
16
- - Developers evaluating the plugin on npm and deciding whether it matches their OpenClaw + Oomi setup
17
-
18
- ## Current Package Focus
19
-
20
- The current package is centered on three operational contracts:
21
-
22
- 1. managed Oomi text transport inside OpenClaw
23
- 2. device-backed chat and voice through the local bridge
24
- 3. XR-first persona runtime generation and repair for Oomi work surfaces
9
+ - OpenClaw talks to Oomi through managed channel and bridge APIs.
10
+ - Oomi clients render persona apps from approved templates, components, data bindings, actions, and permissions.
11
+ - The agent may inspect and update persona app state through approved Oomi API actions.
12
+ - The user adds persona apps from the Oomi client so platform permissions and data hydration happen in the right place.
25
13
 
26
14
  ## What This Package Ships
27
15
 
28
- The npm package contains three Oomi integration surfaces:
29
-
30
16
  1. OpenClaw channel extension
17
+
31
18
  - File: `openclaw.extension.js`
32
- - Purpose: stable managed text transport through the Oomi backend channel API
33
- - This is the preferred integration surface for normal chat
34
-
35
- 2. Local bridge + CLI
19
+ - Purpose: managed text transport through the Oomi backend channel API.
20
+
21
+ 2. Local bridge and CLI
22
+
36
23
  - Files: `bin/oomi-ai.js`, `bin/sessionBridgeState.js`
37
- - Purpose: pair a device, manage the OpenClaw bridge worker, and support managed gateway traffic needed by device-backed chat and voice
38
- - This is the part that deals with broker sockets, local gateway sessions, challenge auth, and bridge health
39
-
40
- 3. Persona scaffold + runtime helpers
41
- - Files: `templates/persona-app/*`, `lib/scaffold.js`, `lib/personaRuntime*.js`
42
- - Purpose: create, launch, repair, and register XR-first managed persona apps for Oomi
43
- - This is the part that matters when Oomi or an agent generates a specialist work surface
44
-
45
- In practical terms:
46
- - If you only need a clean managed chat channel, the extension is the main reason to install this package
47
- - If you need Oomi device-backed chat or voice on an OpenClaw machine, you also need the bridge tooling in this package
48
- - If you need Oomi-managed personas that open as real XR work surfaces, you also need the scaffold and runtime helpers in this package
49
-
50
- ## When To Install It
51
-
52
- Install `oomi-ai` if all of the following are true:
53
- - you use OpenClaw
54
- - you want Oomi as a managed channel, bridge-backed voice surface, or persona runtime inside OpenClaw
55
- - you want device-backed Oomi chat, Oomi voice, generated personas, or some combination of those
56
-
57
- Do not install it just to use the Oomi web app by itself.
58
-
59
- ## Install And Upgrade
60
-
61
- Global install:
62
-
63
- ```bash
64
- pnpm add -g oomi-ai@latest
65
- ```
66
-
67
- Fallback:
68
-
69
- ```bash
70
- npm install -g oomi-ai@latest
71
- ```
72
-
73
- Install the OpenClaw plugin:
74
-
75
- ```bash
76
- openclaw plugins install oomi-ai@latest
77
- ```
78
-
79
- Upgrade an existing machine:
80
-
81
- ```bash
82
- pnpm add -g oomi-ai@latest
83
- openclaw plugins install oomi-ai@latest
84
- ```
85
-
86
- ## Operator Quick Start
87
-
88
- The packaged operator instructions live in [agent_instructions.md](./agent_instructions.md).
89
- That is the primary reference for:
90
- - pairing a device
91
- - installing the plugin
92
- - configuring `channels.oomi.accounts.default`
93
- - running or supervising the bridge
94
- - checking whether the system is healthy
95
- - troubleshooting chat and voice failures
96
- - generating or repairing XR-first managed persona apps
97
-
98
- Fast-path install flow:
99
-
100
- ```bash
101
- oomi openclaw pair --app-url https://www.oomi.ai --no-start
102
- openclaw plugins install oomi-ai@latest
103
- oomi openclaw plugin --show-secrets --backend-url https://api.oomi.ai
104
- ```
105
-
106
- Then apply the printed `channels.oomi.accounts.default` config and restart OpenClaw.
107
-
108
- ## Configuration
109
-
110
- OpenClaw channel config lives under:
111
-
112
- ```json
113
- {
114
- "channels": {
115
- "oomi": {
116
- "defaultAccountId": "default",
117
- "accounts": {
118
- "default": {
119
- "backendUrl": "https://api.oomi.ai",
120
- "deviceToken": "...",
121
- "defaultSessionKey": "agent:main:webchat:channel:oomi",
122
- "requestTimeoutMs": 15000
123
- }
124
- }
125
- }
126
- }
127
- }
128
- ```
129
-
130
- Required fields:
131
- - `backendUrl`
132
- - `deviceToken`
133
-
134
- Optional fields:
135
- - `defaultSessionKey`
136
- - `requestTimeoutMs`
137
-
138
- ## Runtime Model
139
-
140
- There are two runtime contracts worth understanding.
141
-
142
- ### Managed Text Chat
143
-
144
- Managed text chat uses the OpenClaw channel extension and the Oomi backend channel API.
145
- This path is the more stable contract and should be preferred when evaluating the plugin for normal chat.
146
-
147
- ### Device-Backed Chat And Voice
148
-
149
- Device-backed chat and voice use the local bridge.
150
- That bridge:
151
- - keeps a broker socket open to Oomi
152
- - opens local gateway sessions on demand
153
- - enforces `connect`-first request ordering
154
- - preserves or synthesizes `idempotencyKey` for `chat.send`
155
- - keeps voice-session faults from poisoning normal provider health where possible
156
-
157
- This is the part of the package most likely to matter when debugging voice turn failures.
158
-
159
- For managed cloned-voice replies, the canonical contract is:
160
- - visible assistant `content` stays user-facing
161
- - hidden `metadata.spoken` carries the backend TTS payload
162
- - the shared helper in `lib/spokenMetadata.js` is used by both the extension and the local bridge to preserve or normalize that sidecar before it reaches the backend
163
-
164
- The backend cloned-voice path is intentionally strict. If `metadata.spoken` does not reach Oomi, backend TTS fails instead of speaking a flat fallback voice.
165
-
166
- ## Bridge Logging
167
-
168
- The bridge is intentionally quiet by default in production so normal deploys do not spam logs with frame-level transport noise.
169
-
170
- To enable verbose bridge tracing temporarily, set:
171
-
172
- ```bash
173
- OOMI_BRIDGE_DEBUG=1
174
- ```
175
-
176
- With that flag enabled, the bridge will emit low-level session, frame, and spoken-metadata debug logs again.
177
-
178
- ## Local TTS Validation
179
-
180
- If you are developing this package inside the Oomi repo, you can now validate the managed voice path locally before publishing.
181
-
182
- This local gate does three things:
183
- - replays an assistant `chat.final` frame through the same spoken-metadata normalization path used by the OpenClaw extension and the bridge
184
- - feeds that normalized frame into the Rails backend replay harness
185
- - optionally calls the real Qwen cloned-voice provider and confirms that audio deltas come back
186
-
187
- Important:
188
- - this is a repo developer workflow, not a generic npm-only operator command
189
- - it expects the Oomi repo checkout, the Rails backend, and local provider env vars
190
- - the real-provider replay can auto-enroll a disposable default sample voice profile from `assets/voice/source/nemu-enrollment-sample.mp3`
191
-
192
- Assistant-final contract only:
193
-
194
- ```bash
195
- oomi openclaw debug assistant-final --text "Hey Justin! How is the testing going?" --json
196
- ```
197
-
198
- Full local backend replay:
199
-
200
- ```bash
201
- oomi openclaw debug tts-pipeline --text "When your voice reaches me, it gets turned into text, I read it and think about it, then I speak back through the managed chat session." --json
202
- ```
203
-
204
- Real Qwen provider replay:
205
-
206
- ```bash
207
- oomi openclaw debug tts-pipeline --text "When your voice reaches me, it gets turned into text, I read it and think about it, then I speak back through the managed chat session." --live-provider --env-file .env.local --provider-timeout-ms 20000 --json
208
- ```
209
-
210
- What a good result looks like:
211
- - `backend.success = true`
212
- - `managed.assistantSpeechFinal.present = true`
213
- - `qwen.errorCode = null`
214
- - `qwen.audioDeltaCount > 0` when `--live-provider` is used
215
-
216
- This is the preferred pre-publish gate for managed voice regressions, because it is much faster than publishing to npm and testing through a live OpenClaw machine first.
217
-
218
- ## Local OpenClaw Dev Harness
219
-
220
- For plugin/runtime work, the preferred pre-publish loop is:
221
-
222
- 1. run the repo-local CLI directly from source
223
- 2. run the same flow inside the Dockerized OpenClaw dev harness using a local packed tarball
224
- 3. only then update a real OpenClaw machine
225
-
226
- Fast source smoke from the repo checkout:
227
-
228
- ```bash
229
- node packages/oomi-ai/bin/oomi-ai.js openclaw debug persona-runtime --name "Chef Dev" --json
230
- ```
231
-
232
- Containerized real-runtime smoke:
233
-
234
- ```bash
235
- docker compose -f docker/openclaw-dev/compose.yml build openclaw-dev
236
- docker compose -f docker/openclaw-dev/compose.yml up -d openclaw-dev
237
- docker compose -f docker/openclaw-dev/compose.yml exec -T openclaw-dev openclaw gateway health --url ws://127.0.0.1:18789 --token dev-gateway-token --json
238
- docker compose -f docker/openclaw-dev/compose.yml exec -T openclaw-dev oomi-local openclaw debug persona-runtime --name "Chef Dev" --json
24
+ - Purpose: pair a device, manage the OpenClaw bridge worker, and support managed gateway traffic for device-backed chat and voice.
25
+
26
+ 3. Persona app API tools
27
+
28
+ - Files: `persona-app/*`, `lib/personaApiClient.js`, `bin/oomi-ai.js`
29
+ - Purpose: inspect account-linked component-composed persona apps and apply approved backend actions.
30
+
31
+ 4. Agent/operator instructions
32
+
33
+ - Files: `agent_instructions.md`, `skills/oomi/*`
34
+ - Purpose: tell OpenClaw agents how to connect, repair, and use Oomi without local UI code generation.
35
+
36
+ ## Boundary
37
+
38
+ Persona UI is an Oomi-managed client capability, not an OpenClaw-machine responsibility.
39
+
40
+ This package exposes connection, bridge, voice, and persona app state APIs. It does not include a local persona app workspace, local persona runtime manager, queued UI job runner, or app framework bundle.
41
+
42
+ ## Install And Upgrade
43
+
44
+ Global install:
45
+
46
+ ```bash
47
+ pnpm add -g oomi-ai@latest
239
48
  ```
240
49
 
241
- The local managed-chat smoke uses a dedicated session key separate from the browser shell so repeated sentinel prompts do not leak into the interactive conversation history.
242
-
243
- `oomi-local` is a deterministic container wrapper that executes the installed packed `oomi-ai` artifact directly with Node. In the Docker harness, it is only the package wrapper. The agent itself is the real OpenClaw runtime running in the foreground.
244
-
245
- Shared profile contract smoke:
246
-
247
- ```bash
248
- node packages/oomi-ai/bin/oomi-ai.js openclaw profile init --profile-id oomi-dev-local --label "Oomi Local Dev" --backend-url http://127.0.0.1:3001 --device-token dev-device-token --json
249
- node packages/oomi-ai/bin/oomi-ai.js openclaw profile apply --profile ~/.openclaw/oomi-openclaw-profile.json --openclaw-home ~/.openclaw --json
250
- ```
251
-
252
- What the harness does:
253
-
254
- - bootstraps an isolated OpenClaw home rooted at `HOME/.openclaw`
255
- - runs `openclaw onboard --non-interactive ...`
256
- - writes and applies `HOME/.openclaw/oomi-dev-profile.json` using the same shared profile contract the future onboarding UI and hosted-agent bootstrap should use
257
- - enables the Oomi channel account through that applied profile and relies on local OpenClaw plugin auto-discovery for the installed `oomi-ai` plugin
258
- - writes device identity material used by the `oomi-ai` bridge tooling
259
- - packs the local `packages/oomi-ai` checkout into a `.tgz`
260
- - installs that tarball globally in the container
261
- - installs the same tarball as a real OpenClaw plugin
262
- - defaults model auth to `oomi-managed` so onboarding/bootstrap does not require end-user provider keys
263
- - runs `openclaw gateway` as the foreground container process
264
-
265
- Useful env overrides for local integration:
266
-
267
- - `OOMI_DEV_BACKEND_URL`
268
- - `OOMI_DEV_DEVICE_TOKEN`
269
- - `OOMI_DEV_MODEL_AUTH_MODE`
270
- - `OPENCLAW_GATEWAY_TOKEN`
271
- - `OPENCLAW_GATEWAY_PASSWORD`
272
-
273
- Recommended local modes:
274
-
275
- - onboarding/runtime checks without provider keys
276
- - `OOMI_DEV_MODEL_AUTH_MODE=oomi-managed`
277
- - internal real-response smoke before publish
278
- - `OPENROUTER_API_KEY=...`
279
- - optional explicit override: `OOMI_DEV_MODEL_AUTH_MODE=provider-env`
280
-
281
- The default container config is intentionally safe for onboarding and runtime testing. It does not require a published npm version, and it does not require end-user provider keys.
282
-
283
- To make the Dockerized OpenClaw runtime actually answer managed chat locally today, add this to the repo `.env.local`:
50
+ Fallback:
284
51
 
285
52
  ```bash
286
- OOMI_DEV_MODEL_AUTH_MODE=provider-env
287
- OPENROUTER_API_KEY=<your-openrouter-key>
53
+ npm install -g oomi-ai@latest
288
54
  ```
289
55
 
290
- The local harness uses the `openrouter-free` preset for direct-provider smoke. If `OPENROUTER_API_KEY` is present in `.env.local`, `pnpm run dev:openclaw-local` automatically uses the provider-backed testing path. Without that key, it boots in `oomi-managed` mode and waits on a future Oomi-managed provider relay.
291
-
292
- ## Persona Scaffolding
56
+ Install or update the OpenClaw plugin:
293
57
 
294
- Use the scaffold flow when OpenClaw needs to build a managed persona app that will live inside Oomi:
295
-
296
- ```bash
297
- oomi personas scaffold market-analyst --name "Market Analyst" --description "Private app for reviewing my broker positions and risk." --out ~/.openclaw/workspace/personas/market-analyst
298
- ```
299
-
300
- Use:
301
- - `oomi personas create <id>` only for repo-local manifest work, not for the normal managed Oomi persona flow
302
- - `oomi personas create-managed <slug>` to create the backend managed persona record before launch or runtime registration
303
- - `oomi personas scaffold <slug>` for an XR-first WebSpatial Oomi app shell with runtime metadata and health documents
304
- - `oomi persona-jobs execute --message-file <job.json>` when OpenClaw receives a structured persona orchestration job from Oomi
58
+ ```bash
59
+ openclaw plugins install oomi-ai@latest
60
+ ```
305
61
 
306
- Managed runtime and recovery commands:
62
+ After upgrading, refresh the running bridge so stale gateway connections do not keep using the previous package:
307
63
 
308
64
  ```bash
309
- oomi personas launch-managed market-analyst --workspace-root ~/.openclaw/workspace/personas --force-install --json
310
- oomi personas status market-analyst
311
- oomi personas stop market-analyst
312
- oomi personas delete market-analyst
313
- # recovery only, after create-managed already exists
314
- oomi personas runtime-register market-analyst --local-port 4789
315
- oomi personas heartbeat market-analyst --local-port 4789
316
- oomi persona-jobs start pj_123
317
- oomi persona-jobs succeed pj_123 --workspace-path ~/.openclaw/workspace/personas/market-analyst --local-port 4789
318
- oomi persona-jobs fail pj_123 --code JOB_FAILED --message "Scaffold generation failed."
65
+ oomi openclaw refresh --skip-version-check
66
+ oomi openclaw bridge ps
319
67
  ```
320
68
 
321
- Notes:
69
+ If the bridge still looks stale, restart it explicitly:
322
70
 
323
- - For remote Oomi clients such as web and Android XR, do not manually register `http://127.0.0.1:<port>` as the persona `entryUrl`.
324
- - When you pass only `--local-port`, `oomi-ai` derives a LAN-reachable endpoint automatically and keeps the healthcheck on loopback.
325
- - If you pass `--endpoint` explicitly, it should be a LAN or relay URL that the client can actually open.
326
- - The scaffolded XR route should default directly into a mounted scene component that calls `configurePersonaScene()`, logs `detectSpatialEnvironment()`, and renders multiple authored `enable-xr` panels.
327
- - The browser route should remain valid, but the XR entry path should not fall back to a flat marketing or home page.
328
- - Do not use manual `npm run dev` as the first-time persona launch path for managed Oomi personas.
71
+ ```bash
72
+ oomi openclaw bridge restart --detach
73
+ oomi openclaw bridge ps
74
+ ```
329
75
 
330
- Exact managed persona creation order:
76
+ On macOS supervised installs:
331
77
 
332
78
  ```bash
333
- export WORKSPACE_ROOT="$HOME/.openclaw/workspace/personas"
334
- export SLUG="tokyo-guide"
335
- export NAME="Tokyo Guide"
336
- export DESCRIPTION="Personal travel assistant for Tokyo trip planning - itineraries, food, culture, and summer tips for July"
337
-
338
- # 1. Scaffold the local app workspace
339
- oomi personas scaffold "$SLUG" \
340
- --name "$NAME" \
341
- --description "$DESCRIPTION" \
342
- --out "$WORKSPACE_ROOT/$SLUG" \
343
- --force
344
-
345
- # 2. Verify scaffold actually wrote files
346
- test -f "$WORKSPACE_ROOT/$SLUG/persona.json"
347
- test -f "$WORKSPACE_ROOT/$SLUG/oomi.runtime.json"
348
- test -f "$WORKSPACE_ROOT/$SLUG/package.json"
349
-
350
- # 3. Create the backend persona record first
351
- oomi personas create-managed "$SLUG" \
352
- --name "$NAME" \
353
- --description "$DESCRIPTION" \
354
- --json
355
-
356
- # 4. Launch the managed runtime and register it with Oomi
357
- oomi personas launch-managed "$SLUG" \
358
- --workspace-root "$WORKSPACE_ROOT" \
359
- --force-install \
360
- --json
361
-
362
- # 5. Verify local runtime state exists
363
- test -f "$WORKSPACE_ROOT/$SLUG/.oomi/runtime.json"
364
- cat "$WORKSPACE_ROOT/$SLUG/.oomi/runtime.json"
365
-
366
- # 6. Verify Oomi-local status
367
- oomi personas status "$SLUG" --json
368
-
369
- # 7. Send a heartbeat using the actual assigned port
370
- PORT="$(jq -r '.localPort' "$WORKSPACE_ROOT/$SLUG/.oomi/runtime.json")"
371
- oomi personas heartbeat "$SLUG" \
372
- --local-port "$PORT" \
373
- --json
79
+ oomi openclaw bridge service restart
80
+ oomi openclaw bridge service status
374
81
  ```
375
82
 
376
- Rules for that flow:
83
+ Healthy update expectation:
84
+
85
+ - exactly one bridge worker is active
86
+ - the worker reports the newly installed package version
87
+ - bridge status reaches `connected`
88
+
89
+ ## Standard Connect Flow
90
+
91
+ Pair the machine:
377
92
 
378
- - scaffold first
379
- - verify scaffold wrote files before backend creation
380
- - create-managed before any runtime registration or heartbeat
381
- - launch-managed instead of manual `npm run dev`
382
- - heartbeat only after `.oomi/runtime.json` exists
383
- - fail fast if any `--json` command does not return success
384
- - never treat local runtime success as backend registration success
93
+ ```bash
94
+ oomi openclaw pair --app-url https://www.oomi.ai --no-start
95
+ ```
385
96
 
386
- Do not do this for first-time creation:
97
+ Print the OpenClaw config:
387
98
 
388
99
  ```bash
389
- oomi personas runtime-register "$SLUG" --local-port 4791
390
- oomi personas launch-managed "$SLUG"
391
- npm run dev &
100
+ oomi openclaw plugin --show-secrets --backend-url https://api.oomi.ai
392
101
  ```
393
102
 
394
- That sequence is wrong because `runtime-register` and `heartbeat` assume the backend persona already exists, `launch-managed` only auto-creates when the persona is missing and `--name` is present, and manual `npm run dev` bypasses the managed runtime state contract.
103
+ Apply the printed `channels.oomi.accounts.default` config and restart OpenClaw.
395
104
 
396
- Queued-job shortcut:
105
+ Start or repair the bridge:
397
106
 
398
107
  ```bash
399
- oomi personas create-managed cooking-persona --name "Cooking Persona" --description "Private cooking workspace for recipes, meal planning, and kitchen notes."
108
+ oomi openclaw bridge ensure --detach
109
+ ```
110
+
111
+ ## Configuration
112
+
113
+ OpenClaw channel config lives under:
114
+
115
+ ```json
116
+ {
117
+ "channels": {
118
+ "oomi": {
119
+ "defaultAccountId": "default",
120
+ "accounts": {
121
+ "default": {
122
+ "backendUrl": "https://api.oomi.ai",
123
+ "deviceToken": "...",
124
+ "defaultSessionKey": "agent:main:webchat:channel:oomi",
125
+ "requestTimeoutMs": 15000
126
+ }
127
+ }
128
+ }
129
+ }
130
+ }
400
131
  ```
401
132
 
402
- Use that shortcut only when the backend and running bridge are already set up to consume the queued `persona_job` automatically. Do not confuse it with the explicit scaffold + launch flow above.
133
+ Required fields:
134
+
135
+ - `backendUrl`
136
+ - `deviceToken`
137
+
138
+ Optional fields:
139
+
140
+ - `defaultSessionKey`
141
+ - `requestTimeoutMs`
142
+
143
+ ## Persona App API Tools
144
+
145
+ Component-composed persona apps are the default Oomi mini-app path. Use these commands when the user asks about or updates an existing Oomi persona app such as Fitness Today:
146
+
147
+ ```bash
148
+ oomi persona-apps list --json
149
+ oomi persona-apps show fitness-today --json
150
+ oomi persona-apps apply-action fitness-today --action fitness.complete_workout --payload-json '{"goalId":"easy-run","minutes":20}' --json
151
+ ```
152
+
153
+ Rules for agents:
154
+
155
+ - Answer from returned `appState.bindings`, not from memory.
156
+ - Apply updates only through approved `persona-apps apply-action` actions.
157
+ - If the persona app does not exist, tell the user to add it from the Oomi client first.
158
+ - Do not create local persona UI projects.
159
+
160
+ For the Fitness v0 slice:
161
+
162
+ ```bash
163
+ oomi persona-apps apply-action fitness-today --action fitness.complete_goal --payload-json '{"goalId":"easy-run"}' --json
164
+ oomi persona-apps apply-action fitness-today --action fitness.complete_workout --payload-json '{"goalId":"easy-run","minutes":20}' --json
165
+ ```
166
+
167
+ ## Voice Contract
168
+
169
+ Managed voice uses the same Oomi plugin and bridge layer as managed chat.
170
+
171
+ For assistant replies, visible chat text stays user-facing. Optional hidden TTS metadata may live at `metadata.spoken`:
172
+
173
+ ```json
174
+ {
175
+ "metadata": {
176
+ "spoken": {
177
+ "text": "Speech-optimized text for TTS only.",
178
+ "language": "English",
179
+ "instructions": "Speak with warm, upbeat conversational energy and natural pacing."
180
+ }
181
+ }
182
+ }
183
+ ```
184
+
185
+ Rules:
186
+
187
+ - visible `content` is the source of truth for chat rendering
188
+ - `metadata.spoken.text` is backend TTS input only
189
+ - visible chat text should not contain raw speaking tags
190
+ - the package preserves valid `metadata.spoken`
191
+ - if omitted, the package may synthesize a bounded fallback from visible assistant text
192
+
193
+ ## Health Checks
194
+
195
+ Use these when chat or voice is failing:
196
+
197
+ ```bash
198
+ oomi openclaw bridge ps
199
+ oomi openclaw bridge service status
200
+ oomi openclaw status
201
+ tail -f ~/.openclaw/logs/oomi-bridge-live.log
202
+ tail -f ~/.openclaw/logs/gateway.log
203
+ tail -f ~/.openclaw/logs/gateway.err.log
204
+ ```
205
+
206
+ Bridge status meanings:
207
+
208
+ - `starting`: bridge booting or waiting for managed subscription
209
+ - `connected`: ready for managed chat and voice traffic
210
+ - `reconnecting`: transport dropped and retry is scheduled
211
+ - `degraded`: bridge caught a runtime fault but is still alive
212
+ - `error`: startup or auth failure blocked useful operation
213
+ - `stopped`: not running or intentionally stopped
214
+
215
+ ## Troubleshooting
216
+
217
+ Duplicate plugin id warning:
218
+
219
+ - Cause: multiple discoverable `oomi-ai` installs.
220
+ - Action: remove stale extension copies and reinstall once.
221
+
222
+ `invalid handshake: first request must be connect`:
223
+
224
+ - Cause: a gateway request was sent before `connect` had been accepted.
225
+ - Action: update `oomi-ai`, restart the bridge, and confirm only one bridge worker is running.
226
+
227
+ STT works but the assistant does not reply:
228
+
229
+ - Cause: the voice turn likely reached Oomi, but the managed gateway or OpenClaw run failed later.
230
+ - Action: inspect `gateway.log`, `gateway.err.log`, and the session JSONL for auth, network, or bridge restart errors.
231
+
232
+ Bridge keeps using an old package after update:
403
233
 
404
- If you want to explicitly host or reuse the persona app on the OpenClaw machine outside the queued-job path, use:
405
-
406
- ```bash
407
- oomi personas launch-managed cooking-persona --entry-url https://your-relay.example/oomi/cooking-persona
408
- ```
409
-
410
- This command:
234
+ - Action: run `oomi openclaw refresh --skip-version-check`.
235
+ - If still stale: run `oomi openclaw bridge restart --detach`.
236
+ - On macOS service installs: run `oomi openclaw bridge service restart`.
237
+ - Confirm with `oomi openclaw bridge ps`.
411
238
 
412
- - reuses `OPENCLAW_WORKSPACE/personas/<slug>` as the stable workspace
413
- - scaffolds only when the workspace is missing
414
- - installs dependencies only when needed or forced
415
- - allocates or reuses a free local port
416
- - starts or reuses the local runtime
417
- - registers the runtime URL back to Oomi unless `--no-register` is set
239
+ ## Developer Verification
418
240
 
419
- For existing managed personas that are already open in Oomi, the safe edit flow is:
241
+ From `packages/oomi-ai`:
420
242
 
421
243
  ```bash
422
- oomi personas status <slug> --json
244
+ npm run check
245
+ npm test
246
+ npm pack --dry-run
247
+ npm publish --dry-run --no-git-checks --access public
423
248
  ```
424
249
 
425
- The agent should use `editableWorkspacePath` from that output as the authoritative directory for reads, edits, and verification. `compatibilityWorkspacePath` is only a fallback for older installs.
426
-
427
- ## Bridge Health States
428
-
429
- The bridge status file is written locally and should roughly be interpreted as:
430
- - `starting`: process booting or waiting for managed subscription
431
- - `connected`: broker connected and managed subscription confirmed
432
- - `reconnecting`: broker or gateway transport dropped and reconnect is scheduled
433
- - `degraded`: bridge is still alive but hit a runtime fault that needs attention
434
- - `error`: startup or auth-level failure that prevents useful operation
435
- - `stopped`: bridge is not running or was intentionally stopped
436
-
437
- For voice support, a `voice_session_*` failure should be treated as narrower than a full provider outage.
438
-
439
- ## Troubleshooting
440
-
441
- ### `invalid handshake: first request must be connect`
442
-
443
- Meaning:
444
- - a gateway request was forwarded before the session had accepted `connect`
445
-
446
- What to check:
447
- - update to the latest `oomi-ai`
448
- - restart the bridge worker
449
- - confirm only one active bridge worker exists for the device
450
-
451
- ### `duplicate plugin id detected`
452
-
453
- Meaning:
454
- - OpenClaw can see more than one `oomi-ai` plugin source
455
-
456
- What to check:
457
- - ensure there is only one active install under OpenClaw plugin discovery paths
458
- - remove stale local extension copies before reinstalling
459
-
460
- ### Bridge keeps flipping between `reconnecting`, `degraded`, or `stopped`
461
-
462
- What to check:
463
- - `oomi openclaw bridge ps`
464
- - `oomi openclaw bridge service status`
465
- - `tail -f ~/.openclaw/logs/oomi-bridge-live.log`
466
- - `tail -f ~/.openclaw/logs/gateway.log`
467
-
468
- If the process is alive but runtime faults are being caught, expect `degraded` rather than an immediate hard stop.
469
-
470
- ### Voice STT works but the agent does not answer
471
-
472
- This usually means one of these:
473
- - the managed gateway/device side is not actually ready
474
- - the bridge or agent run failed after delivery
475
- - the OpenClaw run stopped with an upstream provider `network_error`
476
-
477
- In that situation, inspect:
478
- - `~/.openclaw/logs/gateway.log`
479
- - `~/.openclaw/logs/gateway.err.log`
480
- - the relevant session JSONL in `~/.openclaw/agents/main/sessions/`
481
-
482
- ### Voice text works but cloned TTS fails with `MISSING_SPOKEN_METADATA`
483
-
484
- Meaning:
485
- - the assistant text arrived
486
- - the backend voice relay never received valid hidden `metadata.spoken`
487
-
488
- What to check:
489
- - run the local replay gate before publishing:
490
- - `oomi openclaw debug assistant-final --text "..."`
491
- - `oomi openclaw debug tts-pipeline --text "..."`
492
- - if the package local replay succeeds but the live machine fails, verify the OpenClaw machine is actually running the updated bridge binary
493
- - if the local replay fails, fix the assistant-final contract first instead of debugging the browser or backend deployment
494
-
495
- ## Developer Notes
496
-
497
- If you are inspecting this package on npm, the main architectural points are:
498
- - the extension path is the stable managed text contract
499
- - the local bridge exists because Oomi also needs device-backed and voice-capable flows
500
- - the persona scaffold exists because Oomi specialist personas can surface as scoped XR/web work surfaces, not just chat tabs
501
- - the bridge has been hardened for:
502
- - strict `connect`-first forwarding
503
- - method-specific request shaping
504
- - `idempotencyKey` handling
505
- - bridge status that does not report `connected` before managed subscription is ready
506
- - runtime fault isolation so local session failures are less likely to crash the whole provider
507
- - one shared hidden managed-voice speech metadata helper used by both the extension and the local bridge
508
-
509
- For generated WebSpatial persona apps, the intended scaffold contract is:
510
- - XR mode defaults directly into the mounted scene route
511
- - `configurePersonaScene()` runs from that scene component
512
- - runtime diagnostics are logged on scene boot
513
- - multiple meaningful UI surfaces use `enable-xr` and `xrStyle()`
514
- - `html.is-spatial` keeps the host shell transparent
515
-
516
- If you are developing the plugin, test the packaged surface with:
517
-
518
- ```bash
519
- cd packages/oomi-ai
520
- node --test test/*.test.mjs
521
- npm pack --dry-run
522
- ```
523
-
524
- For managed voice changes, do not stop at the package tests. Run the local replay gate from the repo root as well, especially before publishing:
525
-
526
- ```bash
527
- oomi openclaw debug tts-pipeline --text "Local managed voice validation text." --json
528
- oomi openclaw debug tts-pipeline --text "Local managed voice validation text." --live-provider --env-file .env.local --provider-timeout-ms 20000 --json
529
- ```
530
-
531
- ## Release Process
532
-
533
- Before publishing:
534
-
535
- ```bash
536
- cd packages/oomi-ai
537
- node --test test/*.test.mjs
538
- npm pack --dry-run
539
- ```
540
-
541
- For voice-related changes, also run the repo-backed local replay gate before publish:
542
-
543
- ```bash
544
- oomi openclaw debug tts-pipeline --text "Local managed voice validation text." --json
545
- oomi openclaw debug tts-pipeline --text "Local managed voice validation text." --live-provider --env-file .env.local --provider-timeout-ms 20000 --json
546
- ```
547
-
548
- Then publish the bumped version:
549
-
550
- ```bash
551
- pnpm check
552
- pnpm publish --dry-run --no-git-checks --access public
553
- pnpm publish --access public
554
- ```
250
+ Expected package contents are restricted by the `files` allowlist in `package.json`.