@camstack/addon-pipeline-orchestrator 1.2.156 → 1.2.158

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 (37) hide show
  1. package/assets/viewer/.viewer-current-files.json +5 -5
  2. package/assets/viewer/.viewer-version +1 -1
  3. package/assets/viewer/_expo/static/js/web/Clipboard-700253b10f1602fda8cd5c60ac3d7311.js +8 -0
  4. package/assets/viewer/_expo/static/js/web/Haptics-a829136f781602b8b2248edf2e67baf2.js +3 -0
  5. package/assets/viewer/_expo/static/js/web/index-43c7609c306a7b586fc77cf5827ad74c.js +3680 -0
  6. package/assets/viewer/_expo/static/js/web/node-fs-19704d0a42999fb99ae05019d5ec6dec.js +1 -0
  7. package/assets/viewer/_expo/static/js/web/node-path-1f6ca301c0f4fde8a4e14648e9008fb6.js +1 -0
  8. package/assets/viewer/assets/node_modules/expo-router/assets/arrow_down.017bc6ba3fc25503e5eb5e53826d48a8.png +0 -0
  9. package/assets/viewer/assets/node_modules/expo-router/assets/error.d1ea1496f9057eb392d5bbf3732a61b7.png +0 -0
  10. package/assets/viewer/assets/node_modules/expo-router/assets/file.19eeb73b9593a38f8e9f418337fc7d10.png +0 -0
  11. package/assets/viewer/assets/node_modules/expo-router/assets/forward.d8b800c443b8972542883e0b9de2bdc6.png +0 -0
  12. package/assets/viewer/assets/node_modules/expo-router/assets/pkg.ab19f4cbc543357183a20571f68380a3.png +0 -0
  13. package/assets/viewer/assets/node_modules/expo-router/assets/react-navigation/elements/back-icon-mask.0a328cd9c1afd0afe8e3b1ec5165b1b4.png +0 -0
  14. package/assets/viewer/assets/node_modules/expo-router/assets/react-navigation/elements/back-icon.35ba0eaec5a4f5ed12ca16fabeae451d.png +0 -0
  15. package/assets/viewer/assets/node_modules/expo-router/assets/react-navigation/elements/clear-icon.c94f6478e7ae0cdd9f15de1fcb9e5e55.png +0 -0
  16. package/assets/viewer/assets/node_modules/expo-router/assets/react-navigation/elements/clear-icon.c94f6478e7ae0cdd9f15de1fcb9e5e55@2x.png +0 -0
  17. package/assets/viewer/assets/node_modules/expo-router/assets/react-navigation/elements/clear-icon.c94f6478e7ae0cdd9f15de1fcb9e5e55@3x.png +0 -0
  18. package/assets/viewer/assets/node_modules/expo-router/assets/react-navigation/elements/clear-icon.c94f6478e7ae0cdd9f15de1fcb9e5e55@4x.png +0 -0
  19. package/assets/viewer/assets/node_modules/expo-router/assets/react-navigation/elements/close-icon.808e1b1b9b53114ec2838071a7e6daa7.png +0 -0
  20. package/assets/viewer/assets/node_modules/expo-router/assets/react-navigation/elements/close-icon.808e1b1b9b53114ec2838071a7e6daa7@2x.png +0 -0
  21. package/assets/viewer/assets/node_modules/expo-router/assets/react-navigation/elements/close-icon.808e1b1b9b53114ec2838071a7e6daa7@3x.png +0 -0
  22. package/assets/viewer/assets/node_modules/expo-router/assets/react-navigation/elements/close-icon.808e1b1b9b53114ec2838071a7e6daa7@4x.png +0 -0
  23. package/assets/viewer/assets/node_modules/expo-router/assets/react-navigation/elements/search-icon.286d67d3f74808a60a78d3ebf1a5fb57.png +0 -0
  24. package/assets/viewer/assets/node_modules/expo-router/assets/sitemap.412dd9275b6b48ad28f5e3d81bb1f626.png +0 -0
  25. package/assets/viewer/assets/node_modules/expo-router/assets/unmatched.20e71bdf79e3a97bf55fd9e164041578.png +0 -0
  26. package/assets/viewer/index.html +1 -1
  27. package/dist/_stub.js +2 -2
  28. package/dist/{_virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_orchestrator_widgets-BqAXr9_9.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_orchestrator_widgets-CB1Jzhdp.mjs} +3 -3
  29. package/dist/_virtual_mf___mfe_internal__addon_pipeline_orchestrator_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-BeFrCpMD.mjs +26 -0
  30. package/dist/_virtual_mf___mfe_internal__addon_pipeline_orchestrator_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-CPl8KXva.mjs +26 -0
  31. package/dist/{hostInit-nP4_yUtc.mjs → hostInit-LWkwV19U.mjs} +3 -3
  32. package/dist/index.js +313 -0
  33. package/dist/index.mjs +313 -0
  34. package/dist/remoteEntry.js +1 -1
  35. package/package.json +1 -1
  36. package/dist/_virtual_mf___mfe_internal__addon_pipeline_orchestrator_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-C0S-3PxD.mjs +0 -26
  37. package/dist/_virtual_mf___mfe_internal__addon_pipeline_orchestrator_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-Cv1F4RhF.mjs +0 -26
package/dist/index.js CHANGED
@@ -5437,6 +5437,12 @@ Object.fromEntries([
5437
5437
  icon: "move",
5438
5438
  order: 40
5439
5439
  },
5440
+ {
5441
+ id: "navigation",
5442
+ label: "Navigation",
5443
+ icon: "compass",
5444
+ order: 41
5445
+ },
5440
5446
  {
5441
5447
  id: "consumables",
5442
5448
  label: "Consumables",
@@ -28482,6 +28488,203 @@ DeviceType.Camera, method(object({ deviceId: number() }), PtzAutotrackStatusSche
28482
28488
  deviceId: number(),
28483
28489
  status: PtzAutotrackStatusSchema
28484
28490
  });
28491
+ /**
28492
+ * `navigation` — a device-scoped capability that natively expresses the FULL
28493
+ * navigation / action surface of a robot that DRIVES ITSELF and carries an
28494
+ * on-board camera (the Dreame robot-vacuum camera is the first provider).
28495
+ *
28496
+ * Why a NEW cap rather than overloading `ptz`:
28497
+ * - `ptz` moves a *gimbal* on a fixed camera (pan/tilt/zoom of the lens). A
28498
+ * robot vacuum has no gimbal — the whole chassis drives, turns and spins.
28499
+ * The two are different physical models: PTZ is absolute-position + presets,
28500
+ * navigation is momentary drive nudges + discrete robot ACTIONS
28501
+ * (dock / spot-clean / follow-pet / go-to-point / …).
28502
+ * - This cap is the SOURCE OF TRUTH. Two consumers adapt from it rather than
28503
+ * the reverse:
28504
+ * 1. a native CamStack navigation panel (data-driven from `listActions`
28505
+ * / `getOptions`), and
28506
+ * 2. the PTZ surface — a thin adapter mimics `ptz` from `navigation` so a
28507
+ * robot camera shows up in the existing PTZ control path without every
28508
+ * PTZ provider learning about robots. The mapping lives in the adapter,
28509
+ * not here (see the addon design note):
28510
+ * ptz.continuousMove({pan,tilt}) → navigation.move({pan,tilt})
28511
+ * ptz.stop() → navigation.stop()
28512
+ * ptz.goHome() → navigation.runAction('goHome')
28513
+ * ptz.getPresets() → navigation.listActions() (id→preset)
28514
+ * ptz.goToPreset(id) → navigation.runAction(id)
28515
+ *
28516
+ * ## Continuous drive
28517
+ *
28518
+ * `move` is MOMENTARY. Fluid navigation comes from the UI (or the PTZ adapter)
28519
+ * sending `move({pan,tilt})` REPEATEDLY at ~1 Hz while a direction is held, and
28520
+ * one `stop()` on release — exactly like the robot app's remote-drive joystick.
28521
+ * The provider forwards EACH `move` to one drive write; it must NOT debounce or
28522
+ * coalesce them. The UI owns the cadence.
28523
+ *
28524
+ * ## The action dictionary
28525
+ *
28526
+ * The discrete controls (dock / locate / spot-clean / follow / flash / sounds)
28527
+ * are a DATA-DRIVEN dictionary the cap exposes via `listActions()`. Each entry
28528
+ * carries `{ id, kind, label, icon }` (plus `soundId` for sound entries) so the
28529
+ * native panel AND the PTZ mimic render buttons WITHOUT hardcoding a
28530
+ * vendor-specific list. `kind: 'action'` entries are triggered with
28531
+ * `runAction({ actionId })`; `kind: 'sound'` entries with `playSound({ soundId })`
28532
+ * (the entry carries the `soundId` to pass). The general primitives — `move`,
28533
+ * `stop`, `goToPoint` — stay as first-class methods, not dictionary entries.
28534
+ *
28535
+ * NOTE (provider wiring): the first provider (Dreame) drives this with the RAW
28536
+ * `callAction(siid,aiid,in)` / `setProperty({siid,piid,value})` MIoT primitives
28537
+ * that the currently-published `@apocaliss92/nodedreame` already exposes on
28538
+ * every device handle. A future nodedreame publish adds a typed
28539
+ * `DreameCameraController` (drive / playPetSound / spotClean / findPet / …); the
28540
+ * provider can then swap the raw calls for the typed methods with no change to
28541
+ * THIS contract.
28542
+ */
28543
+ /**
28544
+ * A momentary drive nudge. The robot MOVES (no gimbal) for as long as the caller
28545
+ * keeps sending nudges (~1 Hz); an explicit `stop` (or letting the nudges lapse)
28546
+ * halts it.
28547
+ *
28548
+ * - `pan` — turn: negative = left, positive = right, 0 = straight.
28549
+ * - `tilt` — throttle: positive = forward, negative = spin / turn-around.
28550
+ * - `speed` — optional intensity hint [0, 1]; the provider may scale the drive
28551
+ * vector by it (drivers without proportional drive ignore it).
28552
+ *
28553
+ * `pan` / `tilt` are normalized [-1, 1]. Both optional so a caller can nudge one
28554
+ * axis alone; an all-undefined nudge is a no-op.
28555
+ */
28556
+ var NavigationMoveCommandSchema = object({
28557
+ pan: number().min(-1).max(1).optional(),
28558
+ tilt: number().min(-1).max(1).optional(),
28559
+ speed: number().min(0).max(1).optional()
28560
+ });
28561
+ /**
28562
+ * The enumerated discrete actions a navigation-capable robot can perform via
28563
+ * `runAction`. This is the CLOSED vocabulary; a given device advertises the
28564
+ * subset it supports through `listActions`. Sounds are NOT here — they go through
28565
+ * `playSound` (see the `sound` dictionary entries).
28566
+ */
28567
+ var NavigationActionIdSchema = _enum([
28568
+ "goHome",
28569
+ "locate",
28570
+ "spotClean",
28571
+ "findPet",
28572
+ "personFollow",
28573
+ "stop",
28574
+ "startClean",
28575
+ "pauseClean",
28576
+ "dockWash",
28577
+ "autoEmpty",
28578
+ "flashOn",
28579
+ "flashOff"
28580
+ ]);
28581
+ /** Whether a dictionary entry is a `runAction` action or a `playSound` sound. */
28582
+ var NavigationEntryKindSchema = _enum(["action", "sound"]);
28583
+ /**
28584
+ * One entry in the navigation action dictionary — the DATA-DRIVEN unit both the
28585
+ * native panel and the PTZ mimic render as a button.
28586
+ *
28587
+ * - `id` — stable id. For `kind:'action'` it is a {@link NavigationActionId}
28588
+ * (pass to `runAction`); for `kind:'sound'` it is a namespaced id
28589
+ * (`sound:meow`) whose `soundId` is passed to `playSound`.
28590
+ * - `icon` — icon HINT (lucide-style name; the UI maps it to its own set).
28591
+ * - `label` — operator-facing English label.
28592
+ * - `soundId` — wire sound id, present only on `kind:'sound'` entries.
28593
+ * - `enabled` — per-device FEATURE FLAG. `listActions` reports it so the UI /
28594
+ * PTZ render ONLY enabled entries. Data-driven: the provider
28595
+ * flips it from config, never by editing code.
28596
+ */
28597
+ var NavigationActionEntrySchema = object({
28598
+ id: string(),
28599
+ kind: NavigationEntryKindSchema,
28600
+ label: string(),
28601
+ icon: string(),
28602
+ /** Present only on `kind:'sound'` entries — the id to pass to `playSound`. */
28603
+ soundId: number().int().optional(),
28604
+ /** Per-device feature flag — render this entry only when true. */
28605
+ enabled: boolean()
28606
+ });
28607
+ /** Coordinates for `goToPoint` — a point on the robot's live map. */
28608
+ var NavigationPointSchema = object({
28609
+ x: number(),
28610
+ y: number()
28611
+ });
28612
+ /**
28613
+ * Per-device FEATURE-FLAG report for the general (non-dictionary) primitives.
28614
+ * The cap reports which are enabled so the UI / PTZ render only the controls
28615
+ * that are turned on for THIS device. Data-driven: the provider derives these
28616
+ * from config + probe, never hardcoded in the UI. The per-DICTIONARY-entry flags
28617
+ * live on {@link NavigationActionEntrySchema.enabled}; these gate the primitives
28618
+ * that are not dictionary entries.
28619
+ *
28620
+ * - `move` / `stop` — the momentary drive joystick.
28621
+ * - `goToPoint` — send-to-map-coordinate. Ships OFF on Dreame until the
28622
+ * map-coordinate plumbing is wired.
28623
+ * - `runAction` — the discrete action buttons (dictionary `kind:'action'`).
28624
+ * - `playSound` — the sound buttons (dictionary `kind:'sound'`).
28625
+ * - `light` — the on/off fill-light toggle (works anytime).
28626
+ * - `lightMode` — the auto/manual selector + manual level slider (a
28627
+ * camera-service control; needs an active stream).
28628
+ */
28629
+ var NavigationFeaturesSchema = object({
28630
+ move: boolean(),
28631
+ stop: boolean(),
28632
+ goToPoint: boolean(),
28633
+ runAction: boolean(),
28634
+ playSound: boolean(),
28635
+ light: boolean(),
28636
+ lightMode: boolean()
28637
+ });
28638
+ /** Light mode: `auto` lets the camera choose brightness; `manual` uses `level`. */
28639
+ var NavigationLightModeSchema = _enum(["auto", "manual"]);
28640
+ /**
28641
+ * Live navigation state so the UI can reflect what the robot is doing:
28642
+ * - `mode` — coarse activity (idle / cleaning / following / …).
28643
+ * - `following` — person/pet follow is currently armed.
28644
+ * - `flash` — the on-camera fill light is on.
28645
+ * - `lightMode` — auto vs manual fill-light mode.
28646
+ * - `lightLevel` — manual fill-light level (40..100); meaningful when
28647
+ * `lightMode === 'manual'`.
28648
+ */
28649
+ var NavigationStatusSchema = object({
28650
+ mode: _enum([
28651
+ "idle",
28652
+ "cleaning",
28653
+ "spot",
28654
+ "following",
28655
+ "goto",
28656
+ "returning",
28657
+ "paused",
28658
+ "unknown"
28659
+ ]),
28660
+ following: boolean(),
28661
+ flash: boolean(),
28662
+ lightMode: NavigationLightModeSchema,
28663
+ lightLevel: number().min(40).max(100),
28664
+ /** Ms epoch when the slice was last updated. */
28665
+ lastChangedAt: number()
28666
+ });
28667
+ NavigationStatusSchema.extend({ lastFetchedAt: number() });
28668
+ DeviceType.Camera, method(NavigationMoveCommandSchema.extend({ deviceId: number() }), _void(), { kind: "mutation" }), method(object({ deviceId: number() }), _void(), { kind: "mutation" }), method(NavigationPointSchema.extend({ deviceId: number() }), _void(), { kind: "mutation" }), method(object({ deviceId: number() }), array(NavigationActionEntrySchema)), method(object({
28669
+ deviceId: number(),
28670
+ actionId: NavigationActionIdSchema
28671
+ }), _void(), { kind: "mutation" }), method(object({
28672
+ deviceId: number(),
28673
+ soundId: number().int()
28674
+ }), _void(), { kind: "mutation" }), method(object({
28675
+ deviceId: number(),
28676
+ on: boolean()
28677
+ }), _void(), { kind: "mutation" }), method(object({
28678
+ deviceId: number(),
28679
+ mode: NavigationLightModeSchema,
28680
+ level: number().min(40).max(100).optional()
28681
+ }), _void(), { kind: "mutation" }), method(object({
28682
+ deviceId: number(),
28683
+ level: number().min(40).max(100)
28684
+ }), _void(), { kind: "mutation" }), method(object({ deviceId: number() }), NavigationFeaturesSchema), object({
28685
+ deviceId: number(),
28686
+ status: NavigationStatusSchema
28687
+ });
28485
28688
  DeviceType.Camera, DeviceType.Sensor, DeviceType.Switch, method(object({ deviceId: number().int().nonnegative() }), object({ success: literal(true) }), {
28486
28689
  kind: "mutation",
28487
28690
  auth: "admin"
@@ -33630,6 +33833,66 @@ Object.freeze({
33630
33833
  addonId: null,
33631
33834
  access: "create"
33632
33835
  },
33836
+ "navigation.getFeatures": {
33837
+ capName: "navigation",
33838
+ capScope: "device",
33839
+ addonId: null,
33840
+ access: "view"
33841
+ },
33842
+ "navigation.goToPoint": {
33843
+ capName: "navigation",
33844
+ capScope: "device",
33845
+ addonId: null,
33846
+ access: "create"
33847
+ },
33848
+ "navigation.listActions": {
33849
+ capName: "navigation",
33850
+ capScope: "device",
33851
+ addonId: null,
33852
+ access: "view"
33853
+ },
33854
+ "navigation.move": {
33855
+ capName: "navigation",
33856
+ capScope: "device",
33857
+ addonId: null,
33858
+ access: "create"
33859
+ },
33860
+ "navigation.playSound": {
33861
+ capName: "navigation",
33862
+ capScope: "device",
33863
+ addonId: null,
33864
+ access: "create"
33865
+ },
33866
+ "navigation.runAction": {
33867
+ capName: "navigation",
33868
+ capScope: "device",
33869
+ addonId: null,
33870
+ access: "create"
33871
+ },
33872
+ "navigation.setLightLevel": {
33873
+ capName: "navigation",
33874
+ capScope: "device",
33875
+ addonId: null,
33876
+ access: "create"
33877
+ },
33878
+ "navigation.setLightMode": {
33879
+ capName: "navigation",
33880
+ capScope: "device",
33881
+ addonId: null,
33882
+ access: "create"
33883
+ },
33884
+ "navigation.setLightOn": {
33885
+ capName: "navigation",
33886
+ capScope: "device",
33887
+ addonId: null,
33888
+ access: "create"
33889
+ },
33890
+ "navigation.stop": {
33891
+ capName: "navigation",
33892
+ capScope: "device",
33893
+ addonId: null,
33894
+ access: "create"
33895
+ },
33633
33896
  "networkAccess.getEndpoint": {
33634
33897
  capName: "network-access",
33635
33898
  capScope: "system",
@@ -37725,6 +37988,56 @@ Object.freeze({
37725
37988
  form: "single",
37726
37989
  optional: false
37727
37990
  }],
37991
+ "navigation.getFeatures": [{
37992
+ name: "deviceId",
37993
+ form: "single",
37994
+ optional: false
37995
+ }],
37996
+ "navigation.goToPoint": [{
37997
+ name: "deviceId",
37998
+ form: "single",
37999
+ optional: false
38000
+ }],
38001
+ "navigation.listActions": [{
38002
+ name: "deviceId",
38003
+ form: "single",
38004
+ optional: false
38005
+ }],
38006
+ "navigation.move": [{
38007
+ name: "deviceId",
38008
+ form: "single",
38009
+ optional: false
38010
+ }],
38011
+ "navigation.playSound": [{
38012
+ name: "deviceId",
38013
+ form: "single",
38014
+ optional: false
38015
+ }],
38016
+ "navigation.runAction": [{
38017
+ name: "deviceId",
38018
+ form: "single",
38019
+ optional: false
38020
+ }],
38021
+ "navigation.setLightLevel": [{
38022
+ name: "deviceId",
38023
+ form: "single",
38024
+ optional: false
38025
+ }],
38026
+ "navigation.setLightMode": [{
38027
+ name: "deviceId",
38028
+ form: "single",
38029
+ optional: false
38030
+ }],
38031
+ "navigation.setLightOn": [{
38032
+ name: "deviceId",
38033
+ form: "single",
38034
+ optional: false
38035
+ }],
38036
+ "navigation.stop": [{
38037
+ name: "deviceId",
38038
+ form: "single",
38039
+ optional: false
38040
+ }],
37728
38041
  "networkQuality.getDeviceStats": [{
37729
38042
  name: "deviceId",
37730
38043
  form: "single",
package/dist/index.mjs CHANGED
@@ -5409,6 +5409,12 @@ Object.fromEntries([
5409
5409
  icon: "move",
5410
5410
  order: 40
5411
5411
  },
5412
+ {
5413
+ id: "navigation",
5414
+ label: "Navigation",
5415
+ icon: "compass",
5416
+ order: 41
5417
+ },
5412
5418
  {
5413
5419
  id: "consumables",
5414
5420
  label: "Consumables",
@@ -28454,6 +28460,203 @@ DeviceType.Camera, method(object({ deviceId: number() }), PtzAutotrackStatusSche
28454
28460
  deviceId: number(),
28455
28461
  status: PtzAutotrackStatusSchema
28456
28462
  });
28463
+ /**
28464
+ * `navigation` — a device-scoped capability that natively expresses the FULL
28465
+ * navigation / action surface of a robot that DRIVES ITSELF and carries an
28466
+ * on-board camera (the Dreame robot-vacuum camera is the first provider).
28467
+ *
28468
+ * Why a NEW cap rather than overloading `ptz`:
28469
+ * - `ptz` moves a *gimbal* on a fixed camera (pan/tilt/zoom of the lens). A
28470
+ * robot vacuum has no gimbal — the whole chassis drives, turns and spins.
28471
+ * The two are different physical models: PTZ is absolute-position + presets,
28472
+ * navigation is momentary drive nudges + discrete robot ACTIONS
28473
+ * (dock / spot-clean / follow-pet / go-to-point / …).
28474
+ * - This cap is the SOURCE OF TRUTH. Two consumers adapt from it rather than
28475
+ * the reverse:
28476
+ * 1. a native CamStack navigation panel (data-driven from `listActions`
28477
+ * / `getOptions`), and
28478
+ * 2. the PTZ surface — a thin adapter mimics `ptz` from `navigation` so a
28479
+ * robot camera shows up in the existing PTZ control path without every
28480
+ * PTZ provider learning about robots. The mapping lives in the adapter,
28481
+ * not here (see the addon design note):
28482
+ * ptz.continuousMove({pan,tilt}) → navigation.move({pan,tilt})
28483
+ * ptz.stop() → navigation.stop()
28484
+ * ptz.goHome() → navigation.runAction('goHome')
28485
+ * ptz.getPresets() → navigation.listActions() (id→preset)
28486
+ * ptz.goToPreset(id) → navigation.runAction(id)
28487
+ *
28488
+ * ## Continuous drive
28489
+ *
28490
+ * `move` is MOMENTARY. Fluid navigation comes from the UI (or the PTZ adapter)
28491
+ * sending `move({pan,tilt})` REPEATEDLY at ~1 Hz while a direction is held, and
28492
+ * one `stop()` on release — exactly like the robot app's remote-drive joystick.
28493
+ * The provider forwards EACH `move` to one drive write; it must NOT debounce or
28494
+ * coalesce them. The UI owns the cadence.
28495
+ *
28496
+ * ## The action dictionary
28497
+ *
28498
+ * The discrete controls (dock / locate / spot-clean / follow / flash / sounds)
28499
+ * are a DATA-DRIVEN dictionary the cap exposes via `listActions()`. Each entry
28500
+ * carries `{ id, kind, label, icon }` (plus `soundId` for sound entries) so the
28501
+ * native panel AND the PTZ mimic render buttons WITHOUT hardcoding a
28502
+ * vendor-specific list. `kind: 'action'` entries are triggered with
28503
+ * `runAction({ actionId })`; `kind: 'sound'` entries with `playSound({ soundId })`
28504
+ * (the entry carries the `soundId` to pass). The general primitives — `move`,
28505
+ * `stop`, `goToPoint` — stay as first-class methods, not dictionary entries.
28506
+ *
28507
+ * NOTE (provider wiring): the first provider (Dreame) drives this with the RAW
28508
+ * `callAction(siid,aiid,in)` / `setProperty({siid,piid,value})` MIoT primitives
28509
+ * that the currently-published `@apocaliss92/nodedreame` already exposes on
28510
+ * every device handle. A future nodedreame publish adds a typed
28511
+ * `DreameCameraController` (drive / playPetSound / spotClean / findPet / …); the
28512
+ * provider can then swap the raw calls for the typed methods with no change to
28513
+ * THIS contract.
28514
+ */
28515
+ /**
28516
+ * A momentary drive nudge. The robot MOVES (no gimbal) for as long as the caller
28517
+ * keeps sending nudges (~1 Hz); an explicit `stop` (or letting the nudges lapse)
28518
+ * halts it.
28519
+ *
28520
+ * - `pan` — turn: negative = left, positive = right, 0 = straight.
28521
+ * - `tilt` — throttle: positive = forward, negative = spin / turn-around.
28522
+ * - `speed` — optional intensity hint [0, 1]; the provider may scale the drive
28523
+ * vector by it (drivers without proportional drive ignore it).
28524
+ *
28525
+ * `pan` / `tilt` are normalized [-1, 1]. Both optional so a caller can nudge one
28526
+ * axis alone; an all-undefined nudge is a no-op.
28527
+ */
28528
+ var NavigationMoveCommandSchema = object({
28529
+ pan: number().min(-1).max(1).optional(),
28530
+ tilt: number().min(-1).max(1).optional(),
28531
+ speed: number().min(0).max(1).optional()
28532
+ });
28533
+ /**
28534
+ * The enumerated discrete actions a navigation-capable robot can perform via
28535
+ * `runAction`. This is the CLOSED vocabulary; a given device advertises the
28536
+ * subset it supports through `listActions`. Sounds are NOT here — they go through
28537
+ * `playSound` (see the `sound` dictionary entries).
28538
+ */
28539
+ var NavigationActionIdSchema = _enum([
28540
+ "goHome",
28541
+ "locate",
28542
+ "spotClean",
28543
+ "findPet",
28544
+ "personFollow",
28545
+ "stop",
28546
+ "startClean",
28547
+ "pauseClean",
28548
+ "dockWash",
28549
+ "autoEmpty",
28550
+ "flashOn",
28551
+ "flashOff"
28552
+ ]);
28553
+ /** Whether a dictionary entry is a `runAction` action or a `playSound` sound. */
28554
+ var NavigationEntryKindSchema = _enum(["action", "sound"]);
28555
+ /**
28556
+ * One entry in the navigation action dictionary — the DATA-DRIVEN unit both the
28557
+ * native panel and the PTZ mimic render as a button.
28558
+ *
28559
+ * - `id` — stable id. For `kind:'action'` it is a {@link NavigationActionId}
28560
+ * (pass to `runAction`); for `kind:'sound'` it is a namespaced id
28561
+ * (`sound:meow`) whose `soundId` is passed to `playSound`.
28562
+ * - `icon` — icon HINT (lucide-style name; the UI maps it to its own set).
28563
+ * - `label` — operator-facing English label.
28564
+ * - `soundId` — wire sound id, present only on `kind:'sound'` entries.
28565
+ * - `enabled` — per-device FEATURE FLAG. `listActions` reports it so the UI /
28566
+ * PTZ render ONLY enabled entries. Data-driven: the provider
28567
+ * flips it from config, never by editing code.
28568
+ */
28569
+ var NavigationActionEntrySchema = object({
28570
+ id: string(),
28571
+ kind: NavigationEntryKindSchema,
28572
+ label: string(),
28573
+ icon: string(),
28574
+ /** Present only on `kind:'sound'` entries — the id to pass to `playSound`. */
28575
+ soundId: number().int().optional(),
28576
+ /** Per-device feature flag — render this entry only when true. */
28577
+ enabled: boolean()
28578
+ });
28579
+ /** Coordinates for `goToPoint` — a point on the robot's live map. */
28580
+ var NavigationPointSchema = object({
28581
+ x: number(),
28582
+ y: number()
28583
+ });
28584
+ /**
28585
+ * Per-device FEATURE-FLAG report for the general (non-dictionary) primitives.
28586
+ * The cap reports which are enabled so the UI / PTZ render only the controls
28587
+ * that are turned on for THIS device. Data-driven: the provider derives these
28588
+ * from config + probe, never hardcoded in the UI. The per-DICTIONARY-entry flags
28589
+ * live on {@link NavigationActionEntrySchema.enabled}; these gate the primitives
28590
+ * that are not dictionary entries.
28591
+ *
28592
+ * - `move` / `stop` — the momentary drive joystick.
28593
+ * - `goToPoint` — send-to-map-coordinate. Ships OFF on Dreame until the
28594
+ * map-coordinate plumbing is wired.
28595
+ * - `runAction` — the discrete action buttons (dictionary `kind:'action'`).
28596
+ * - `playSound` — the sound buttons (dictionary `kind:'sound'`).
28597
+ * - `light` — the on/off fill-light toggle (works anytime).
28598
+ * - `lightMode` — the auto/manual selector + manual level slider (a
28599
+ * camera-service control; needs an active stream).
28600
+ */
28601
+ var NavigationFeaturesSchema = object({
28602
+ move: boolean(),
28603
+ stop: boolean(),
28604
+ goToPoint: boolean(),
28605
+ runAction: boolean(),
28606
+ playSound: boolean(),
28607
+ light: boolean(),
28608
+ lightMode: boolean()
28609
+ });
28610
+ /** Light mode: `auto` lets the camera choose brightness; `manual` uses `level`. */
28611
+ var NavigationLightModeSchema = _enum(["auto", "manual"]);
28612
+ /**
28613
+ * Live navigation state so the UI can reflect what the robot is doing:
28614
+ * - `mode` — coarse activity (idle / cleaning / following / …).
28615
+ * - `following` — person/pet follow is currently armed.
28616
+ * - `flash` — the on-camera fill light is on.
28617
+ * - `lightMode` — auto vs manual fill-light mode.
28618
+ * - `lightLevel` — manual fill-light level (40..100); meaningful when
28619
+ * `lightMode === 'manual'`.
28620
+ */
28621
+ var NavigationStatusSchema = object({
28622
+ mode: _enum([
28623
+ "idle",
28624
+ "cleaning",
28625
+ "spot",
28626
+ "following",
28627
+ "goto",
28628
+ "returning",
28629
+ "paused",
28630
+ "unknown"
28631
+ ]),
28632
+ following: boolean(),
28633
+ flash: boolean(),
28634
+ lightMode: NavigationLightModeSchema,
28635
+ lightLevel: number().min(40).max(100),
28636
+ /** Ms epoch when the slice was last updated. */
28637
+ lastChangedAt: number()
28638
+ });
28639
+ NavigationStatusSchema.extend({ lastFetchedAt: number() });
28640
+ DeviceType.Camera, method(NavigationMoveCommandSchema.extend({ deviceId: number() }), _void(), { kind: "mutation" }), method(object({ deviceId: number() }), _void(), { kind: "mutation" }), method(NavigationPointSchema.extend({ deviceId: number() }), _void(), { kind: "mutation" }), method(object({ deviceId: number() }), array(NavigationActionEntrySchema)), method(object({
28641
+ deviceId: number(),
28642
+ actionId: NavigationActionIdSchema
28643
+ }), _void(), { kind: "mutation" }), method(object({
28644
+ deviceId: number(),
28645
+ soundId: number().int()
28646
+ }), _void(), { kind: "mutation" }), method(object({
28647
+ deviceId: number(),
28648
+ on: boolean()
28649
+ }), _void(), { kind: "mutation" }), method(object({
28650
+ deviceId: number(),
28651
+ mode: NavigationLightModeSchema,
28652
+ level: number().min(40).max(100).optional()
28653
+ }), _void(), { kind: "mutation" }), method(object({
28654
+ deviceId: number(),
28655
+ level: number().min(40).max(100)
28656
+ }), _void(), { kind: "mutation" }), method(object({ deviceId: number() }), NavigationFeaturesSchema), object({
28657
+ deviceId: number(),
28658
+ status: NavigationStatusSchema
28659
+ });
28457
28660
  DeviceType.Camera, DeviceType.Sensor, DeviceType.Switch, method(object({ deviceId: number().int().nonnegative() }), object({ success: literal(true) }), {
28458
28661
  kind: "mutation",
28459
28662
  auth: "admin"
@@ -33602,6 +33805,66 @@ Object.freeze({
33602
33805
  addonId: null,
33603
33806
  access: "create"
33604
33807
  },
33808
+ "navigation.getFeatures": {
33809
+ capName: "navigation",
33810
+ capScope: "device",
33811
+ addonId: null,
33812
+ access: "view"
33813
+ },
33814
+ "navigation.goToPoint": {
33815
+ capName: "navigation",
33816
+ capScope: "device",
33817
+ addonId: null,
33818
+ access: "create"
33819
+ },
33820
+ "navigation.listActions": {
33821
+ capName: "navigation",
33822
+ capScope: "device",
33823
+ addonId: null,
33824
+ access: "view"
33825
+ },
33826
+ "navigation.move": {
33827
+ capName: "navigation",
33828
+ capScope: "device",
33829
+ addonId: null,
33830
+ access: "create"
33831
+ },
33832
+ "navigation.playSound": {
33833
+ capName: "navigation",
33834
+ capScope: "device",
33835
+ addonId: null,
33836
+ access: "create"
33837
+ },
33838
+ "navigation.runAction": {
33839
+ capName: "navigation",
33840
+ capScope: "device",
33841
+ addonId: null,
33842
+ access: "create"
33843
+ },
33844
+ "navigation.setLightLevel": {
33845
+ capName: "navigation",
33846
+ capScope: "device",
33847
+ addonId: null,
33848
+ access: "create"
33849
+ },
33850
+ "navigation.setLightMode": {
33851
+ capName: "navigation",
33852
+ capScope: "device",
33853
+ addonId: null,
33854
+ access: "create"
33855
+ },
33856
+ "navigation.setLightOn": {
33857
+ capName: "navigation",
33858
+ capScope: "device",
33859
+ addonId: null,
33860
+ access: "create"
33861
+ },
33862
+ "navigation.stop": {
33863
+ capName: "navigation",
33864
+ capScope: "device",
33865
+ addonId: null,
33866
+ access: "create"
33867
+ },
33605
33868
  "networkAccess.getEndpoint": {
33606
33869
  capName: "network-access",
33607
33870
  capScope: "system",
@@ -37697,6 +37960,56 @@ Object.freeze({
37697
37960
  form: "single",
37698
37961
  optional: false
37699
37962
  }],
37963
+ "navigation.getFeatures": [{
37964
+ name: "deviceId",
37965
+ form: "single",
37966
+ optional: false
37967
+ }],
37968
+ "navigation.goToPoint": [{
37969
+ name: "deviceId",
37970
+ form: "single",
37971
+ optional: false
37972
+ }],
37973
+ "navigation.listActions": [{
37974
+ name: "deviceId",
37975
+ form: "single",
37976
+ optional: false
37977
+ }],
37978
+ "navigation.move": [{
37979
+ name: "deviceId",
37980
+ form: "single",
37981
+ optional: false
37982
+ }],
37983
+ "navigation.playSound": [{
37984
+ name: "deviceId",
37985
+ form: "single",
37986
+ optional: false
37987
+ }],
37988
+ "navigation.runAction": [{
37989
+ name: "deviceId",
37990
+ form: "single",
37991
+ optional: false
37992
+ }],
37993
+ "navigation.setLightLevel": [{
37994
+ name: "deviceId",
37995
+ form: "single",
37996
+ optional: false
37997
+ }],
37998
+ "navigation.setLightMode": [{
37999
+ name: "deviceId",
38000
+ form: "single",
38001
+ optional: false
38002
+ }],
38003
+ "navigation.setLightOn": [{
38004
+ name: "deviceId",
38005
+ form: "single",
38006
+ optional: false
38007
+ }],
38008
+ "navigation.stop": [{
38009
+ name: "deviceId",
38010
+ form: "single",
38011
+ optional: false
38012
+ }],
37700
38013
  "networkQuality.getDeviceStats": [{
37701
38014
  name: "deviceId",
37702
38015
  form: "single",
@@ -30,7 +30,7 @@ async function d(e) {
30
30
  }
31
31
  }
32
32
  async function f() {
33
- return l ||= d(() => import("./_virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_orchestrator_widgets-BqAXr9_9.mjs")).catch((e) => {
33
+ return l ||= d(() => import("./_virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_orchestrator_widgets-CB1Jzhdp.mjs")).catch((e) => {
34
34
  throw l = void 0, e;
35
35
  }), l;
36
36
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-pipeline-orchestrator",
3
- "version": "1.2.156",
3
+ "version": "1.2.158",
4
4
  "description": "Hub-side camera-to-agent load balancer — tracks runner capacity and dispatches attachCamera calls to the optimal pipeline-runner instance",
5
5
  "keywords": [
6
6
  "camstack",