oomi-ai 0.2.48 → 0.2.50

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.
package/README.md CHANGED
@@ -1,57 +1,60 @@
1
- # oomi-ai
2
-
3
- OpenClaw channel plugin and bridge tooling for Oomi managed chat and voice.
4
-
5
- ## Current Focus
6
-
7
- `0.2.40` keeps the persona automation lane, adds a stable local persona runtime manager, upgrades the Docker dev harness from a package simulator to a real OpenClaw runtime, and introduces a shared OpenClaw profile contract so local onboarding, Docker bootstrap, and future hosted agents use the same setup model:
8
- - WebSpatial-based persona scaffolding for generated Oomi apps
9
- - vendored AndroidXR WebSpatial fork sync for persona runtimes, including the npm-safe package metadata needed by OpenClaw installs
10
- - managed persona runtime installs now detect vendored WebSpatial drift and reinstall automatically so existing workspaces pick up XR runtime fixes
11
- - a high-level `oomi personas create-managed` command for agent-driven persona creation
12
- - a stable `oomi personas launch-managed` flow for local persona hosting under `OPENCLAW_WORKSPACE/personas`
13
- - a matching `oomi personas delete` flow that stops managed runtimes and removes the persona workspace from the OpenClaw machine
14
- - shared OpenClaw path handling for isolated local or containerized dev roots
15
- - versioned `oomi openclaw profile init|apply` commands for deterministic local/dev or hosted setup flows
16
- - explicit model auth modes so onboarding can default to `oomi-managed` while internal testing can still opt into direct provider auth
17
- - a repo-local `openclaw debug persona-runtime` smoke test for managed persona runtime launch/reuse/stop
18
- - a Docker-based OpenClaw dev harness that runs a real `openclaw gateway` inside an isolated container
19
- - device-authenticated persona runtime registration and job callbacks
20
- - automatic bridge-side polling for queued `persona_job` control messages
21
- - one shared spoken-metadata normalizer used by both the extension and the bridge
22
- - a repo-backed local `tts-pipeline` replay that can validate assistant-final -> backend -> real Qwen TTS before publishing
23
- - spoken-metadata handling that preserves natural pauses like `...` and keeps the managed voice contract valid on the real chat session path
24
-
25
- This package is for two audiences:
26
- - OpenClaw operators who need to connect a machine to Oomi and keep chat or voice healthy
27
- - Developers evaluating the plugin on npm and deciding whether it matches their OpenClaw + Oomi setup
28
-
29
- ## What This Package Ships
30
-
31
- The npm package contains two Oomi integration surfaces:
32
-
33
- 1. OpenClaw channel extension
34
- - File: `openclaw.extension.js`
35
- - Purpose: stable managed text transport through the Oomi backend channel API
36
- - This is the preferred integration surface for normal chat
37
-
38
- 2. Local bridge + CLI
39
- - Files: `bin/oomi-ai.js`, `bin/sessionBridgeState.js`
40
- - Purpose: pair a device, manage the OpenClaw bridge worker, and support managed gateway traffic needed by device-backed chat and voice
41
- - This is the part that deals with broker sockets, local gateway sessions, challenge auth, and bridge health
42
-
43
- In practical terms:
44
- - If you only need a clean managed chat channel, the extension is the main reason to install this package
45
- - If you need Oomi device-backed chat or voice on an OpenClaw machine, you also need the bridge tooling in this package
1
+ # oomi-ai
2
+
3
+ Managed Oomi chat, voice bridge, and XR-first persona scaffolding for OpenClaw.
4
+
5
+ ## At A Glance
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
13
+
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
25
+
26
+ ## What This Package Ships
27
+
28
+ The npm package contains three Oomi integration surfaces:
29
+
30
+ 1. OpenClaw channel extension
31
+ - 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
36
+ - 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
46
49
 
47
50
  ## When To Install It
48
51
 
49
- Install `oomi-ai` if all of the following are true:
50
- - you use OpenClaw
51
- - you want Oomi as a managed channel inside OpenClaw
52
- - you want device-backed Oomi chat, Oomi voice, or both
53
-
54
- Do not install it just to use the Oomi web app by itself.
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.
55
58
 
56
59
  ## Install And Upgrade
57
60
 
@@ -82,14 +85,15 @@ openclaw plugins install oomi-ai@latest
82
85
 
83
86
  ## Operator Quick Start
84
87
 
85
- The packaged operator instructions live in [agent_instructions.md](./agent_instructions.md).
86
- That is the primary reference for:
87
- - pairing a device
88
- - installing the plugin
89
- - configuring `channels.oomi.accounts.default`
90
- - running or supervising the bridge
91
- - checking whether the system is healthy
92
- - troubleshooting chat and voice failures
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
93
97
 
94
98
  Fast-path install flow:
95
99
 
@@ -285,43 +289,119 @@ OPENROUTER_API_KEY=<your-openrouter-key>
285
289
 
286
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.
287
291
 
288
- ## Persona Scaffolding
289
-
290
- Use the scaffold flow when OpenClaw needs to build a managed persona app that will live inside Oomi:
292
+ ## Persona Scaffolding
293
+
294
+ Use the scaffold flow when OpenClaw needs to build a managed persona app that will live inside Oomi:
291
295
 
292
296
  ```bash
293
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
294
298
  ```
295
299
 
296
- Use:
297
- - `oomi personas create <id>` for repo-local manifest work
298
- - `oomi personas create-managed --name "Cooking Persona" --description "Private cooking workspace"` for the end-to-end Oomi-managed persona flow
299
- - `oomi personas scaffold <slug>` for a WebSpatial-based Oomi app shell with runtime metadata and health documents
300
- - `oomi persona-jobs execute --message-file <job.json>` when OpenClaw receives a structured persona orchestration job from Oomi
301
-
302
- Additional persona runtime commands:
303
-
304
- ```bash
305
- oomi personas launch-managed market-analyst --name "Market Analyst" --description "Private app for reviewing my broker positions and risk."
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
305
+
306
+ Managed runtime and recovery commands:
307
+
308
+ ```bash
309
+ oomi personas launch-managed market-analyst --workspace-root ~/.openclaw/workspace/personas --force-install --json
306
310
  oomi personas status market-analyst
307
311
  oomi personas stop market-analyst
308
312
  oomi personas delete market-analyst
313
+ # recovery only, after create-managed already exists
309
314
  oomi personas runtime-register market-analyst --local-port 4789
310
- oomi personas heartbeat market-analyst --local-port 4789
311
- oomi persona-jobs start pj_123
315
+ oomi personas heartbeat market-analyst --local-port 4789
316
+ oomi persona-jobs start pj_123
312
317
  oomi persona-jobs succeed pj_123 --workspace-path ~/.openclaw/workspace/personas/market-analyst --local-port 4789
313
- oomi persona-jobs fail pj_123 --code JOB_FAILED --message "Scaffold generation failed."
314
- ```
315
-
316
- Recommended agent flow:
317
-
318
- ```bash
319
- oomi personas create-managed --name "Cooking Persona" --description "Private cooking workspace for recipes, meal planning, and kitchen notes."
320
- ```
321
-
322
- That command creates the managed persona record in Oomi using the linked device identity. The backend then enqueues the `persona_job`, and the running bridge consumes that job automatically. The poll path is filtered to `metadata.type = persona_job`, so it does not consume normal queued chat traffic.
323
-
324
- If you want to explicitly host or reuse the persona app on the OpenClaw machine outside the queued-job path, use:
318
+ oomi persona-jobs fail pj_123 --code JOB_FAILED --message "Scaffold generation failed."
319
+ ```
320
+
321
+ Notes:
322
+
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.
329
+
330
+ Exact managed persona creation order:
331
+
332
+ ```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
374
+ ```
375
+
376
+ Rules for that flow:
377
+
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
385
+
386
+ Do not do this for first-time creation:
387
+
388
+ ```bash
389
+ oomi personas runtime-register "$SLUG" --local-port 4791
390
+ oomi personas launch-managed "$SLUG"
391
+ npm run dev &
392
+ ```
393
+
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.
395
+
396
+ Queued-job shortcut:
397
+
398
+ ```bash
399
+ oomi personas create-managed cooking-persona --name "Cooking Persona" --description "Private cooking workspace for recipes, meal planning, and kitchen notes."
400
+ ```
401
+
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.
403
+
404
+ If you want to explicitly host or reuse the persona app on the OpenClaw machine outside the queued-job path, use:
325
405
 
326
406
  ```bash
327
407
  oomi personas launch-managed cooking-persona --entry-url https://your-relay.example/oomi/cooking-persona
@@ -412,18 +492,26 @@ What to check:
412
492
  - if the package local replay succeeds but the live machine fails, verify the OpenClaw machine is actually running the updated bridge binary
413
493
  - if the local replay fails, fix the assistant-final contract first instead of debugging the browser or backend deployment
414
494
 
415
- ## Developer Notes
416
-
417
- If you are inspecting this package on npm, the main architectural points are:
418
- - the extension path is the stable managed text contract
419
- - the local bridge exists because Oomi also needs device-backed and voice-capable flows
420
- - the bridge has been hardened for:
421
- - strict `connect`-first forwarding
422
- - method-specific request shaping
423
- - `idempotencyKey` handling
424
- - bridge status that does not report `connected` before managed subscription is ready
425
- - runtime fault isolation so local session failures are less likely to crash the whole provider
426
- - one shared hidden managed-voice speech metadata helper used by both the extension and the local bridge
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
427
515
 
428
516
  If you are developing the plugin, test the packaged surface with:
429
517
 
@@ -1,6 +1,11 @@
1
- # Oomi OpenClaw Operator Guide
2
-
3
- Use these instructions when you need to connect, repair, or verify an OpenClaw machine that should talk to Oomi.
1
+ # Oomi OpenClaw Operator Guide
2
+
3
+ Use these instructions when you need to connect, repair, or verify an OpenClaw machine that should talk to Oomi.
4
+
5
+ This is the packaged agent-facing reference for:
6
+ - managed OpenClaw connect and repair flows
7
+ - device-backed chat and voice bridge recovery
8
+ - XR-first persona generation and persona runtime repair
4
9
 
5
10
  ## Primary Goal
6
11
 
@@ -194,20 +199,51 @@ Aliases allowed if needed:
194
199
 
195
200
  ## Persona App Generation
196
201
 
202
+ For persona app work, treat the scaffold as a runtime contract, not a disposable starting point.
203
+
197
204
  When a user asks you in chat to create a new persona for Oomi:
198
205
 
199
- 1. Prefer `oomi personas create-managed --name "<name>" --description "<description>"`.
200
- 2. That is the primary end-to-end command for agent-driven persona creation.
201
- 3. It creates the managed persona record in Oomi and relies on the running bridge to consume the queued `persona_job` automatically.
202
- 4. Do not manually scaffold first unless you are recovering a failed persona job or working outside the queued Oomi flow.
206
+ 1. First clarify the persona `name`, `slug`, `description`, permissions, tools, and the ideal work surface.
207
+ 2. After that, use this exact manual creation order on the OpenClaw machine:
208
+ - `export WORKSPACE_ROOT="$HOME/.openclaw/workspace/personas"`
209
+ - `export SLUG="<persona-slug>"`
210
+ - `export NAME="<persona-name>"`
211
+ - `export DESCRIPTION="<persona-description>"`
212
+ - `oomi personas scaffold "$SLUG" --name "$NAME" --description "$DESCRIPTION" --out "$WORKSPACE_ROOT/$SLUG" --force`
213
+ - `test -f "$WORKSPACE_ROOT/$SLUG/persona.json"`
214
+ - `test -f "$WORKSPACE_ROOT/$SLUG/oomi.runtime.json"`
215
+ - `test -f "$WORKSPACE_ROOT/$SLUG/package.json"`
216
+ - `oomi personas create-managed "$SLUG" --name "$NAME" --description "$DESCRIPTION" --json`
217
+ - `oomi personas launch-managed "$SLUG" --workspace-root "$WORKSPACE_ROOT" --force-install --json`
218
+ - `test -f "$WORKSPACE_ROOT/$SLUG/.oomi/runtime.json"`
219
+ - `cat "$WORKSPACE_ROOT/$SLUG/.oomi/runtime.json"`
220
+ - `oomi personas status "$SLUG" --json`
221
+ - `PORT="$(jq -r '.localPort' "$WORKSPACE_ROOT/$SLUG/.oomi/runtime.json")"`
222
+ - `oomi personas heartbeat "$SLUG" --local-port "$PORT" --json`
223
+ 3. Fail fast if scaffold verification fails or if any `--json` command does not return success.
224
+ 4. Treat backend registration as incomplete until `create-managed`, `launch-managed`, `status`, and `heartbeat` all succeed.
225
+ 5. Do not present a localhost URL like `http://127.0.0.1:4789` as the final persona runtime URL for Oomi clients.
226
+ 6. Do not rely on `launch-managed` auto-creating the backend persona record. Run `create-managed` explicitly first.
227
+ 7. Do not use `oomi personas runtime-register <slug>` or `oomi personas heartbeat <slug>` before `create-managed` succeeds.
228
+ 8. Do not use manual `npm run dev` or any unmanaged dev server as the persona launch path.
203
229
 
204
230
  When generating a managed persona app for Oomi:
205
231
 
206
232
  1. Do not build the app shell from scratch.
207
233
  2. Always run `oomi personas scaffold <slug> --name "<name>" --description "<description>" --out <path>` first.
208
234
  3. Only customize persona-specific files inside `src/persona/` and `persona/` unless Oomi explicitly instructs otherwise.
209
- 4. Preserve the scaffolded WebSpatial/Vite shell, `public/oomi.health.json`, `oomi.runtime.json`, and `public/manifest.webmanifest`.
210
- 5. After customization, start the app and register the runtime with Oomi using the current runtime contract.
235
+ 4. Preserve the scaffolded WebSpatial/Vite shell, `public/oomi.health.json`, `oomi.runtime.json`, `public/manifest.webmanifest`, and the vendored WebSpatial fork.
236
+ 5. Keep the browser route and the XR route split. In XR mode, the index route should open directly into the mounted scene component, not a flat homepage.
237
+ 6. Call `configurePersonaScene()` from that mounted scene component and log `detectSpatialEnvironment()` on scene boot so the runtime can be verified in headset.
238
+ 7. Author multiple meaningful XR surfaces with `enable-xr`, `--xr-back`, and `--xr-background-material` values instead of putting one outer `enable-xr` wrapper around the whole page.
239
+ 8. Keep `html.is-spatial` shell styles transparent so the host recedes and the authored panels carry the spatial material.
240
+ 9. Keep `snapdom` and `html2canvas` exposed from `main.tsx` because AndroidXR DOM capture depends on them.
241
+ 10. After customization, bring the persona online through `oomi personas launch-managed <slug> --workspace-root <root> --force-install --json`, then verify `oomi personas status <slug> --json`, then heartbeat using the assigned local port from `.oomi/runtime.json`.
242
+ 11. For normal OpenClaw-hosted persona apps on the same LAN, the managed runtime registration contract is:
243
+ - backend `entryUrl`: LAN-reachable host such as `http://192.168.x.x:<port>`
244
+ - backend `healthcheckUrl`: local loopback such as `http://127.0.0.1:<port>/webspatial/avp/oomi.health.json`
245
+ 12. Do not override `--endpoint` with `127.0.0.1` unless the persona is intentionally local-only and not meant to open from Oomi web/XR.
246
+ 13. Do not replace the managed runtime flow with manual `npm run dev`, ad hoc `runtime-register`, or ad hoc `heartbeat` commands during first-time creation.
211
247
 
212
248
  When editing an existing managed persona that is already open in Oomi:
213
249
 
@@ -215,7 +251,7 @@ When editing an existing managed persona that is already open in Oomi:
215
251
  2. First run `oomi personas status <slug> --json`.
216
252
  3. Use `editableWorkspacePath` from that command as the authoritative directory for reads, edits, and verification.
217
253
  4. Treat `compatibilityWorkspacePath` only as a fallback or migration clue.
218
- 5. Preserve the scaffolded WebSpatial shell and runtime health files unless the user explicitly asks for a deeper structural change.
254
+ 5. Preserve the scaffolded WebSpatial shell and runtime health files unless the user explicitly asks for a deeper structural change, and do not regress the XR route back into a flat home page.
219
255
  6. Do not claim the persona changed unless you have verified the file contents changed in `editableWorkspacePath` or the runtime reflects the update.
220
256
 
221
257
  When executing a structured persona job from Oomi:
@@ -228,5 +264,8 @@ When executing a structured persona job from Oomi:
228
264
  - `oomi persona-jobs start <jobId>`
229
265
  - `oomi persona-jobs succeed <jobId> --workspace-path <path> --local-port 4789`
230
266
  - `oomi persona-jobs fail <jobId> --code <code> --message "<text>"`
267
+ 4. Before any low-level `runtime-register` or `heartbeat` recovery command, make sure the backend persona already exists via `create-managed`.
268
+ 5. If you use the low-level `runtime-register` or `heartbeat` commands, prefer `--local-port` by itself and let `oomi-ai` derive the LAN-reachable endpoint automatically.
269
+ 6. If you must pass `--endpoint` explicitly, it must be the LAN-reachable host or a relay URL, not `127.0.0.1`.
231
270
 
232
271
  When the Oomi bridge is running on the machine, queued persona jobs from Oomi are now polled and executed automatically through the filtered control-message lane. You should still use the explicit commands above for manual retries, recovery, or direct operator workflows.
package/bin/oomi-ai.js CHANGED
@@ -259,14 +259,14 @@ Commands:
259
259
  personas sync
260
260
  Sync personas from the repo into the Oomi backend registry.
261
261
 
262
- personas create <id>
263
- Create a new persona manifest and optionally sync it to the backend.
264
- personas create-managed [slug]
265
- Create a managed persona in Oomi and enqueue its build job for the linked device.
266
- personas launch-managed [slug]
267
- Launch or reuse a managed persona runtime on this OpenClaw machine.
268
- personas scaffold <slug>
269
- Create an Oomi-managed persona app scaffold for agent customization.
262
+ personas create <id>
263
+ Create a new persona manifest for local or repo work. For managed Oomi personas prefer create-managed.
264
+ personas create-managed [slug]
265
+ Create the managed persona record in Oomi. Run this before manual launch-managed, runtime-register, or heartbeat flows.
266
+ personas launch-managed [slug]
267
+ Launch or reuse a managed persona runtime on this OpenClaw machine and register a client-reachable runtime URL. Prefer scaffold + create-managed first.
268
+ personas scaffold <slug>
269
+ Create an Oomi-managed persona app scaffold for agent customization.
270
270
  personas status <slug>
271
271
  Show local managed persona runtime state for a persona slug.
272
272
  personas stop <slug>
@@ -274,9 +274,9 @@ Commands:
274
274
  personas delete <slug>
275
275
  Stop a managed persona runtime and remove its workspace from this OpenClaw machine.
276
276
  personas runtime-register <slug>
277
- Register a running persona runtime with the Oomi backend.
278
- personas heartbeat <slug>
279
- Send a persona runtime heartbeat to the Oomi backend.
277
+ Register a running persona runtime with the Oomi backend. Recovery-only after create-managed. Prefer --local-port so the CLI can derive a reachable endpoint.
278
+ personas heartbeat <slug>
279
+ Send a persona runtime heartbeat to the Oomi backend. Recovery-only after launch-managed wrote .oomi/runtime.json.
280
280
  personas runtime-fail <slug>
281
281
  Report persona runtime failure to the Oomi backend.
282
282
  persona-jobs start <jobId>
@@ -1579,21 +1579,21 @@ async function handlePersonaLaunchManagedCommand(flags = {}, positionalSlug = ''
1579
1579
  const client = createCliPersonaApiClient(flags);
1580
1580
  const safeName = String(flags.name || '').trim();
1581
1581
  const safeDescription = String(flags.description || '').trim() || safeName;
1582
- const safeSlug = String(flags.slug || positionalSlug || (safeName ? slugifyPersonaName(safeName) : '')).trim();
1583
- if (!safeSlug) {
1584
- throw new Error('Persona slug or name is required. Usage: oomi personas launch-managed [slug] --name "<name>"');
1585
- }
1582
+ const safeSlug = String(flags.slug || positionalSlug || (safeName ? slugifyPersonaName(safeName) : '')).trim();
1583
+ if (!safeSlug) {
1584
+ throw new Error('Persona slug or name is required. Usage: oomi personas launch-managed [slug] --name "<name>". Prefer `oomi personas create-managed <slug> --name "<name>" --description "<description>"` first.');
1585
+ }
1586
1586
 
1587
1587
  const shouldCreate = !isTruthyFlag(flags['no-create']);
1588
1588
  let createdPersona = false;
1589
1589
  let personaPayload = await findExistingManagedPersona(client, safeSlug);
1590
- if (!personaPayload) {
1591
- if (!shouldCreate) {
1592
- throw new Error(`Managed persona ${safeSlug} does not exist in Oomi. Remove --no-create or create it first.`);
1593
- }
1594
- if (!safeName) {
1595
- throw new Error('Persona name is required when creating a new managed persona.');
1596
- }
1590
+ if (!personaPayload) {
1591
+ if (!shouldCreate) {
1592
+ throw new Error(`Managed persona ${safeSlug} does not exist in Oomi. Remove --no-create or create it first with \`oomi personas create-managed ${safeSlug} --name "<name>" --description "<description>"\`.`);
1593
+ }
1594
+ if (!safeName) {
1595
+ throw new Error('Persona name is required when creating a new managed persona implicitly. Prefer running `oomi personas create-managed <slug> --name "<name>" --description "<description>"` first instead of relying on launch-managed auto-create.');
1596
+ }
1597
1597
  personaPayload = await client.createManagedPersona({
1598
1598
  slug: safeSlug,
1599
1599
  name: safeName,
@@ -54,6 +54,7 @@ const LEGACY_WEBSPATIAL_TEMPLATE_FILE_RULES = [
54
54
  shouldReplace: (content) =>
55
55
  !content.includes('WEBSPATIAL_FORK_REPOSITORY') ||
56
56
  !content.includes('configurePersonaScene') ||
57
+ !content.includes('"--xr-back": String(back)') ||
57
58
  content.includes('WEBSPATIAL_FORK_COMMIT = "b2746721e4fe6b4f86dac0ea55938074eea00cda"') ||
58
59
  content.includes('WEBSPATIAL_FORK_COMMIT = "8904ac8fec48fe49ee14d1739237bd1afb2894fe"'),
59
60
  },
@@ -67,20 +68,22 @@ const LEGACY_WEBSPATIAL_TEMPLATE_FILE_RULES = [
67
68
  {
68
69
  relativePath: path.join('src', 'App.tsx'),
69
70
  shouldReplace: (content) =>
71
+ !content.includes('const isSpatialRuntime = __XR_ENV_BASE__.startsWith("/webspatial/avp");') ||
72
+ !content.includes('<Route path="home" element={<HomePage />} />') ||
70
73
  content.includes('<Route path="/" element={<HomePage />} />') ||
71
- content.includes('<Route path="/scene" element={<ScenePage />} />'),
74
+ content.includes('<Route path="/scene" element={<ScenePage />} />') ||
75
+ content.includes('<Route index element={<HomePage />} />'),
72
76
  },
73
77
  {
74
78
  relativePath: path.join('src', 'pages', 'HomePage.tsx'),
75
79
  shouldReplace: (content) =>
76
80
  (content.includes('Open Spatial Scene') &&
77
81
  content.includes('Open Scene Route')) ||
78
- (content.includes('Launch Spatial Surface') &&
79
- content.includes('Open Browser Preview') &&
80
- content.includes('Focused surface') &&
81
- !content.includes('sceneMode')) ||
82
- content.includes('enable-xr-monitor={sceneMode || undefined}') ||
83
- content.includes('enable-xr={sceneMode || undefined}') ||
82
+ content.includes('sceneMode') ||
83
+ content.includes('configurePersonaScene();') ||
84
+ content.includes('persona-preview-card') ||
85
+ content.includes('Launch Spatial Surface') ||
86
+ content.includes('Open Spatial Preview') ||
84
87
  (
85
88
  content.includes('persona-panel persona-runtime" enable-xr') ||
86
89
  content.includes('persona-button" onClick={openPersonaScene} enable-xr') ||
@@ -91,6 +94,7 @@ const LEGACY_WEBSPATIAL_TEMPLATE_FILE_RULES = [
91
94
  {
92
95
  relativePath: path.join('src', 'pages', 'ScenePage.tsx'),
93
96
  shouldReplace: (content) =>
97
+ content.includes('sceneMode') ||
94
98
  (
95
99
  !content.includes('enable-xr-monitor') &&
96
100
  content.includes(
@@ -103,14 +107,23 @@ const LEGACY_WEBSPATIAL_TEMPLATE_FILE_RULES = [
103
107
  content.includes('Fork-backed proof points')
104
108
  ),
105
109
  },
110
+ {
111
+ relativePath: path.join('src', 'index.css'),
112
+ shouldReplace: (content) =>
113
+ !content.includes('html.is-spatial #root') ||
114
+ content.includes('radial-gradient(circle at top, rgba(205, 183, 143, 0.32), transparent 36%)'),
115
+ },
106
116
  {
107
117
  relativePath: path.join('src', 'App.css'),
108
118
  shouldReplace: (content) =>
119
+ content.includes('.persona-shell') ||
109
120
  (content.includes('.scene-panel') && !content.includes('.scene-interaction-grid')) ||
110
121
  content.includes('html.is-spatial .persona-runtime {') ||
111
122
  content.includes('html.is-spatial .persona-scene-root {') ||
112
123
  content.includes('html.is-spatial .persona-button,') ||
113
- content.includes('html.is-spatial .persona-card,'),
124
+ content.includes('html.is-spatial .persona-card,') ||
125
+ !content.includes('.scene-workspace-grid') ||
126
+ !content.includes('.home-grid'),
114
127
  },
115
128
  {
116
129
  relativePath: 'vite.config.ts',
@@ -2,7 +2,7 @@
2
2
  "id": "oomi-ai",
3
3
  "name": "Oomi Channel Plugin",
4
4
  "description": "Managed Oomi channel integration for OpenClaw.",
5
- "version": "0.2.48",
5
+ "version": "0.2.50",
6
6
  "author": "Oomi",
7
7
  "license": "MIT",
8
8
  "openclawVersion": ">=0.5.0",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "oomi-ai",
3
- "version": "0.2.48",
4
- "description": "Oomi OpenClaw channel plugin and bridge tooling",
3
+ "version": "0.2.50",
4
+ "description": "Managed Oomi chat, voice bridge, and XR-first persona scaffolding for OpenClaw",
5
5
  "bin": {
6
6
  "oomi": "bin/oomi-ai.js"
7
7
  },
@@ -29,14 +29,19 @@
29
29
  "defaultChoice": "npm"
30
30
  }
31
31
  },
32
- "keywords": [
33
- "oomi",
34
- "openclaw",
35
- "cli",
36
- "voice",
37
- "agent"
38
- ],
39
- "homepage": "https://oomi.ai",
32
+ "keywords": [
33
+ "oomi",
34
+ "openclaw",
35
+ "cli",
36
+ "plugin",
37
+ "voice",
38
+ "agent",
39
+ "persona",
40
+ "webspatial",
41
+ "xr",
42
+ "androidxr"
43
+ ],
44
+ "homepage": "https://www.oomi.ai",
40
45
  "repository": {
41
46
  "type": "git",
42
47
  "url": "git+https://github.com/crispcode-io/oomi.git",