camstack 1.2.101 → 1.2.103

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.
@@ -14522,7 +14522,7 @@ function date4(params) {
14522
14522
  // ../../node_modules/zod/v4/classic/external.js
14523
14523
  config(en_default());
14524
14524
 
14525
- // ../types/dist/sleep-Db7MvrdS.mjs
14525
+ // ../types/dist/sleep-CgijQHtG.mjs
14526
14526
  var WELL_KNOWN_TABS = [
14527
14527
  {
14528
14528
  id: "overview",
@@ -32150,6 +32150,85 @@ var batteryCapability = {
32150
32150
  * whether persisting is worth a SQLite commit. */
32151
32151
  volatileStateFields: ["lastUpdated"]
32152
32152
  };
32153
+ var NETWORK_LINK_TYPES = [
32154
+ "wifi",
32155
+ "ethernet",
32156
+ "cellular",
32157
+ "unknown"
32158
+ ];
32159
+ var NetworkLinkStatusSchema = external_exports.object({
32160
+ /** The link the device is on. `'unknown'` = not read yet, not "no link". */
32161
+ type: external_exports.enum(NETWORK_LINK_TYPES),
32162
+ /**
32163
+ * Link quality, 0..100 inclusive, normalised by the provider from whatever
32164
+ * the firmware reports (bars, RSSI, a vendor scale). **`null` means NOT
32165
+ * KNOWN or NOT APPLICABLE** — a wired link has no signal, and a wireless
32166
+ * one whose reading has not landed must not be drawn at 0 %. Consumers
32167
+ * SKIP a null rather than coerce it.
32168
+ */
32169
+ signalPercent: external_exports.number().min(0).max(100).nullable(),
32170
+ /** Raw received signal strength in dBm, when the firmware reports one. */
32171
+ rssiDbm: external_exports.number().optional(),
32172
+ /** Network name of a wireless link, when the firmware reports it. */
32173
+ ssid: external_exports.string().optional(),
32174
+ /** Ms epoch of the last observation. Lets consumers reason about freshness. */
32175
+ lastUpdated: external_exports.number()
32176
+ });
32177
+ var NETWORK_LINK_UNKNOWN = {
32178
+ type: "unknown",
32179
+ signalPercent: null,
32180
+ lastUpdated: 0
32181
+ };
32182
+ var networkLinkCapability = {
32183
+ name: "network-link",
32184
+ scope: "device",
32185
+ deviceNative: true,
32186
+ mode: "singleton",
32187
+ deviceTypes: [
32188
+ DeviceType.Camera,
32189
+ DeviceType.Sensor,
32190
+ DeviceType.Button,
32191
+ DeviceType.Switch,
32192
+ DeviceType.Light,
32193
+ DeviceType.Lock,
32194
+ DeviceType.Siren
32195
+ ],
32196
+ methods: {},
32197
+ events: {
32198
+ /**
32199
+ * Emitted whenever the cached status changes (a link switch, a signal
32200
+ * reading that moved). Mirrored on the parent chain by the
32201
+ * DeviceEventPropagator like `battery.onStatusChanged`.
32202
+ */
32203
+ onStatusChanged: { data: external_exports.object({
32204
+ deviceId: external_exports.number(),
32205
+ status: NetworkLinkStatusSchema
32206
+ }) }
32207
+ },
32208
+ status: {
32209
+ schema: NetworkLinkStatusSchema,
32210
+ kind: "push",
32211
+ empty: NETWORK_LINK_UNKNOWN
32212
+ },
32213
+ /**
32214
+ * Runtime-state slice — every provider stores the same shape under
32215
+ * `device.runtimeState['network-link']`, read once by the badge and the
32216
+ * Home Assistant projector regardless of the driver.
32217
+ */
32218
+ runtimeState: NetworkLinkStatusSchema,
32219
+ /**
32220
+ * Runtime-state durability: **restored** — a link reading is slow to
32221
+ * change and a sleeping battery camera may not report for hours; the
32222
+ * restored slice is what the badge shows until the next read.
32223
+ *
32224
+ * See `RuntimeStateDurability`. Enforced by
32225
+ * `scripts/check-runtime-state-durability.ts`.
32226
+ */
32227
+ durability: "restored",
32228
+ /** Clock fields: written, but excluded from the compare that decides
32229
+ * whether persisting is worth a SQLite commit. */
32230
+ volatileStateFields: ["lastUpdated"]
32231
+ };
32153
32232
  var BinaryStatusSchema = external_exports.object({
32154
32233
  on: external_exports.boolean(),
32155
32234
  /** Ms epoch of the last transition. 0 if never observed. */
@@ -36855,6 +36934,169 @@ var ptzAutotrackCapability = {
36855
36934
  */
36856
36935
  durability: "session"
36857
36936
  };
36937
+ var NavigationMoveCommandSchema = external_exports.object({
36938
+ pan: external_exports.number().min(-1).max(1).optional(),
36939
+ tilt: external_exports.number().min(-1).max(1).optional(),
36940
+ speed: external_exports.number().min(0).max(1).optional()
36941
+ });
36942
+ var NavigationActionIdSchema = external_exports.enum([
36943
+ "goHome",
36944
+ "locate",
36945
+ "spotClean",
36946
+ "findPet",
36947
+ "personFollow",
36948
+ "stop",
36949
+ "startClean",
36950
+ "pauseClean",
36951
+ "dockWash",
36952
+ "autoEmpty",
36953
+ "flashOn",
36954
+ "flashOff"
36955
+ ]);
36956
+ var NavigationEntryKindSchema = external_exports.enum(["action", "sound"]);
36957
+ var NavigationActionEntrySchema = external_exports.object({
36958
+ id: external_exports.string(),
36959
+ kind: NavigationEntryKindSchema,
36960
+ label: external_exports.string(),
36961
+ icon: external_exports.string(),
36962
+ /** Present only on `kind:'sound'` entries — the id to pass to `playSound`. */
36963
+ soundId: external_exports.number().int().optional(),
36964
+ /** Per-device feature flag — render this entry only when true. */
36965
+ enabled: external_exports.boolean()
36966
+ });
36967
+ var NavigationPointSchema = external_exports.object({
36968
+ x: external_exports.number(),
36969
+ y: external_exports.number()
36970
+ });
36971
+ var NavigationFeaturesSchema = external_exports.object({
36972
+ move: external_exports.boolean(),
36973
+ stop: external_exports.boolean(),
36974
+ goToPoint: external_exports.boolean(),
36975
+ runAction: external_exports.boolean(),
36976
+ playSound: external_exports.boolean(),
36977
+ light: external_exports.boolean(),
36978
+ lightMode: external_exports.boolean()
36979
+ });
36980
+ var NavigationLightModeSchema = external_exports.enum(["auto", "manual"]);
36981
+ var NavigationModeSchema = external_exports.enum([
36982
+ "idle",
36983
+ "cleaning",
36984
+ "spot",
36985
+ "following",
36986
+ "goto",
36987
+ "returning",
36988
+ "paused",
36989
+ "unknown"
36990
+ ]);
36991
+ var NavigationStatusSchema = external_exports.object({
36992
+ mode: NavigationModeSchema,
36993
+ following: external_exports.boolean(),
36994
+ flash: external_exports.boolean(),
36995
+ lightMode: NavigationLightModeSchema,
36996
+ lightLevel: external_exports.number().min(40).max(100),
36997
+ /** Ms epoch when the slice was last updated. */
36998
+ lastChangedAt: external_exports.number()
36999
+ });
37000
+ var NavigationRuntimeStateSchema = NavigationStatusSchema.extend({ lastFetchedAt: external_exports.number() });
37001
+ var navigationCapability = {
37002
+ name: "navigation",
37003
+ scope: "device",
37004
+ deviceNative: true,
37005
+ mode: "singleton",
37006
+ deviceTypes: [DeviceType.Camera],
37007
+ deviceConfig: { ui: {
37008
+ kind: "widget",
37009
+ widgetId: "host/navigation-panel",
37010
+ tab: "navigation",
37011
+ topTab: true,
37012
+ label: "Navigation",
37013
+ order: 0
37014
+ } },
37015
+ methods: {
37016
+ /**
37017
+ * Momentary drive nudge (the robot moves). `protected` — mirrors
37018
+ * `ptz.continuousMove` so the Viewer navigation panel (and the PTZ-mimic
37019
+ * path) works for any authenticated user, not admin-only. The UI sends
37020
+ * these at ~1 Hz while a control is held; the provider forwards each one to
37021
+ * a single drive write WITHOUT debouncing.
37022
+ */
37023
+ move: method(NavigationMoveCommandSchema.extend({ deviceId: external_exports.number() }), external_exports.void(), { kind: "mutation" }),
37024
+ /** Halt all motion immediately (zero drive vector). */
37025
+ stop: method(external_exports.object({ deviceId: external_exports.number() }), external_exports.void(), { kind: "mutation" }),
37026
+ /** Send the robot to a point on its live map. */
37027
+ goToPoint: method(NavigationPointSchema.extend({ deviceId: external_exports.number() }), external_exports.void(), { kind: "mutation" }),
37028
+ /**
37029
+ * Enumerate the discrete controls THIS device supports (data-driven UI +
37030
+ * PTZ mimic). Camera-probed subset of {@link NAVIGATION_ACTION_CATALOG}.
37031
+ */
37032
+ listActions: method(external_exports.object({ deviceId: external_exports.number() }), external_exports.array(NavigationActionEntrySchema)),
37033
+ /**
37034
+ * Run one discrete action (a `kind:'action'` dictionary entry). Invalid /
37035
+ * unsupported action ids are rejected by the provider.
37036
+ */
37037
+ runAction: method(external_exports.object({
37038
+ deviceId: external_exports.number(),
37039
+ actionId: NavigationActionIdSchema
37040
+ }), external_exports.void(), { kind: "mutation" }),
37041
+ /** Play a sound by its wire id (the `soundId` of a `kind:'sound'` entry). */
37042
+ playSound: method(external_exports.object({
37043
+ deviceId: external_exports.number(),
37044
+ soundId: external_exports.number().int()
37045
+ }), external_exports.void(), { kind: "mutation" }),
37046
+ /**
37047
+ * Turn the on-camera fill light on / off (the `OpenFullLight` control —
37048
+ * works anytime, no active stream required).
37049
+ */
37050
+ setLightOn: method(external_exports.object({
37051
+ deviceId: external_exports.number(),
37052
+ on: external_exports.boolean()
37053
+ }), external_exports.void(), { kind: "mutation" }),
37054
+ /**
37055
+ * Set the fill-light mode (auto vs manual). `manual` optionally carries the
37056
+ * initial `level`. The auto/manual + level control is a CAMERA-service
37057
+ * action that generally needs an active camera stream/monitor session — the
37058
+ * UI shows the manual level slider ONLY when `mode === 'manual'`.
37059
+ */
37060
+ setLightMode: method(external_exports.object({
37061
+ deviceId: external_exports.number(),
37062
+ mode: NavigationLightModeSchema,
37063
+ level: external_exports.number().min(40).max(100).optional()
37064
+ }), external_exports.void(), { kind: "mutation" }),
37065
+ /** Set the MANUAL fill-light level (40..100). Implies `manual` mode. */
37066
+ setLightLevel: method(external_exports.object({
37067
+ deviceId: external_exports.number(),
37068
+ level: external_exports.number().min(40).max(100)
37069
+ }), external_exports.void(), { kind: "mutation" }),
37070
+ /**
37071
+ * Per-device FEATURE-FLAG report for the general primitives — drives which
37072
+ * controls the UI shows (the per-entry flags for the dictionary come back on
37073
+ * `listActions`).
37074
+ */
37075
+ getFeatures: method(external_exports.object({ deviceId: external_exports.number() }), NavigationFeaturesSchema)
37076
+ },
37077
+ events: { onStatusChanged: { data: external_exports.object({
37078
+ deviceId: external_exports.number(),
37079
+ status: NavigationStatusSchema
37080
+ }) } },
37081
+ status: {
37082
+ schema: NavigationStatusSchema,
37083
+ kind: "push"
37084
+ },
37085
+ /**
37086
+ * Runtime-state slice mirrored by the kernel. The navigation panel watches it
37087
+ * for live mode / follow / flash changes.
37088
+ */
37089
+ runtimeState: NavigationRuntimeStateSchema,
37090
+ /**
37091
+ * Runtime-state durability: **session** — like `vacuum-control`, a restored
37092
+ * `mode: cleaning` / `following: true` is a robot that is not actually doing
37093
+ * that. The live handle re-publishes on connect.
37094
+ *
37095
+ * See `RuntimeStateDurability`. Enforced by
37096
+ * `scripts/check-runtime-state-durability.ts`.
37097
+ */
37098
+ durability: "session"
37099
+ };
36858
37100
  var rebootCapability = {
36859
37101
  name: "reboot",
36860
37102
  scope: "device",
@@ -42270,6 +42512,66 @@ var METHOD_ACCESS_MAP = Object.freeze({
42270
42512
  addonId: null,
42271
42513
  access: "create"
42272
42514
  },
42515
+ "navigation.getFeatures": {
42516
+ capName: "navigation",
42517
+ capScope: "device",
42518
+ addonId: null,
42519
+ access: "view"
42520
+ },
42521
+ "navigation.goToPoint": {
42522
+ capName: "navigation",
42523
+ capScope: "device",
42524
+ addonId: null,
42525
+ access: "create"
42526
+ },
42527
+ "navigation.listActions": {
42528
+ capName: "navigation",
42529
+ capScope: "device",
42530
+ addonId: null,
42531
+ access: "view"
42532
+ },
42533
+ "navigation.move": {
42534
+ capName: "navigation",
42535
+ capScope: "device",
42536
+ addonId: null,
42537
+ access: "create"
42538
+ },
42539
+ "navigation.playSound": {
42540
+ capName: "navigation",
42541
+ capScope: "device",
42542
+ addonId: null,
42543
+ access: "create"
42544
+ },
42545
+ "navigation.runAction": {
42546
+ capName: "navigation",
42547
+ capScope: "device",
42548
+ addonId: null,
42549
+ access: "create"
42550
+ },
42551
+ "navigation.setLightLevel": {
42552
+ capName: "navigation",
42553
+ capScope: "device",
42554
+ addonId: null,
42555
+ access: "create"
42556
+ },
42557
+ "navigation.setLightMode": {
42558
+ capName: "navigation",
42559
+ capScope: "device",
42560
+ addonId: null,
42561
+ access: "create"
42562
+ },
42563
+ "navigation.setLightOn": {
42564
+ capName: "navigation",
42565
+ capScope: "device",
42566
+ addonId: null,
42567
+ access: "create"
42568
+ },
42569
+ "navigation.stop": {
42570
+ capName: "navigation",
42571
+ capScope: "device",
42572
+ addonId: null,
42573
+ access: "create"
42574
+ },
42273
42575
  "networkAccess.getEndpoint": {
42274
42576
  capName: "network-access",
42275
42577
  capScope: "system",
@@ -46365,6 +46667,56 @@ var METHOD_DEVICE_SELECTORS = Object.freeze({
46365
46667
  form: "single",
46366
46668
  optional: false
46367
46669
  }],
46670
+ "navigation.getFeatures": [{
46671
+ name: "deviceId",
46672
+ form: "single",
46673
+ optional: false
46674
+ }],
46675
+ "navigation.goToPoint": [{
46676
+ name: "deviceId",
46677
+ form: "single",
46678
+ optional: false
46679
+ }],
46680
+ "navigation.listActions": [{
46681
+ name: "deviceId",
46682
+ form: "single",
46683
+ optional: false
46684
+ }],
46685
+ "navigation.move": [{
46686
+ name: "deviceId",
46687
+ form: "single",
46688
+ optional: false
46689
+ }],
46690
+ "navigation.playSound": [{
46691
+ name: "deviceId",
46692
+ form: "single",
46693
+ optional: false
46694
+ }],
46695
+ "navigation.runAction": [{
46696
+ name: "deviceId",
46697
+ form: "single",
46698
+ optional: false
46699
+ }],
46700
+ "navigation.setLightLevel": [{
46701
+ name: "deviceId",
46702
+ form: "single",
46703
+ optional: false
46704
+ }],
46705
+ "navigation.setLightMode": [{
46706
+ name: "deviceId",
46707
+ form: "single",
46708
+ optional: false
46709
+ }],
46710
+ "navigation.setLightOn": [{
46711
+ name: "deviceId",
46712
+ form: "single",
46713
+ optional: false
46714
+ }],
46715
+ "navigation.stop": [{
46716
+ name: "deviceId",
46717
+ form: "single",
46718
+ optional: false
46719
+ }],
46368
46720
  "networkQuality.getDeviceStats": [{
46369
46721
  name: "deviceId",
46370
46722
  form: "single",
package/dist/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  runDiscover
4
- } from "./chunk-7N7KEXGL.js";
4
+ } from "./chunk-IAJ7W6M6.js";
5
5
  import "./chunk-LMMQX4CK.js";
6
6
 
7
7
  // src/cli.ts
@@ -38,7 +38,7 @@ async function runServe(args) {
38
38
  ...typeof values.data === "string" ? { data: values.data } : {}
39
39
  };
40
40
  Object.assign(process.env, buildServeEnv(opts));
41
- await import("./launcher-Q6SAJY4R.js");
41
+ await import("./launcher-WOJX4MSL.js");
42
42
  }
43
43
 
44
44
  // src/commands/agent.ts
@@ -83,7 +83,7 @@ async function runAgent(args) {
83
83
  ...typeof values.port === "string" ? { port: values.port } : {}
84
84
  };
85
85
  Object.assign(process.env, buildAgentEnv(opts));
86
- await import("./launcher-Q6SAJY4R.js");
86
+ await import("./launcher-WOJX4MSL.js");
87
87
  }
88
88
 
89
89
  // src/commands/setup.ts
@@ -1130,7 +1130,7 @@ function isUnknown(_value) {
1130
1130
  return true;
1131
1131
  }
1132
1132
  async function resolveServerInteractive(presetNamespace) {
1133
- const { discoverNodes, resolveHubFromDiscovered, filterHubNodes, DEFAULT_HUB_HTTPS_PORT } = await import("./discover-3TATRQOW.js");
1133
+ const { discoverNodes, resolveHubFromDiscovered, filterHubNodes, DEFAULT_HUB_HTTPS_PORT } = await import("./discover-LBZ4OABF.js");
1134
1134
  if (presetNamespace) {
1135
1135
  const spinner4 = clack.spinner();
1136
1136
  spinner4.start(`Discovering hub on LAN (namespace "${presetNamespace}")`);
@@ -5,7 +5,7 @@ import {
5
5
  filterHubNodes,
6
6
  resolveHubFromDiscovered,
7
7
  runDiscover
8
- } from "./chunk-7N7KEXGL.js";
8
+ } from "./chunk-IAJ7W6M6.js";
9
9
  import "./chunk-LMMQX4CK.js";
10
10
  export {
11
11
  DEFAULT_HUB_HTTPS_PORT,