camstack 1.2.82 → 1.2.84

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-C1mz-ocE.mjs
14525
+ // ../types/dist/sleep-Cwo3fRlv.mjs
14526
14526
  var WELL_KNOWN_TABS = [
14527
14527
  {
14528
14528
  id: "overview",
@@ -17875,6 +17875,68 @@ var LocationStatSchema = external_exports.object({
17875
17875
  fileCount: external_exports.number(),
17876
17876
  present: external_exports.boolean()
17877
17877
  });
17878
+ var BackupRunStateSchema = external_exports.enum([
17879
+ "queued",
17880
+ "running",
17881
+ "succeeded",
17882
+ "failed",
17883
+ "cancelled"
17884
+ ]);
17885
+ var BackupRunPhaseSchema = external_exports.enum([
17886
+ "queued",
17887
+ "building",
17888
+ "uploading",
17889
+ "done"
17890
+ ]);
17891
+ var BackupRunSchema = external_exports.object({
17892
+ /** Stable run id — the handle `backup.cancel` takes. */
17893
+ id: external_exports.string(),
17894
+ state: BackupRunStateSchema,
17895
+ phase: BackupRunPhaseSchema,
17896
+ /**
17897
+ * Resolved destination location ids. Empty while queued (targets are
17898
+ * resolved when the run starts, against the then-current policies).
17899
+ */
17900
+ destinationIds: external_exports.array(external_exports.string()).readonly(),
17901
+ label: external_exports.string().optional(),
17902
+ /** ms-epoch when the run was submitted (trigger call / schedule fire). */
17903
+ requestedAt: external_exports.number(),
17904
+ /** ms-epoch when the run left the queue and started building. */
17905
+ startedAt: external_exports.number().optional(),
17906
+ /** ms-epoch when the run reached a terminal state. */
17907
+ finishedAt: external_exports.number().optional(),
17908
+ /** Compressed bytes of the staging archive written so far. */
17909
+ stagedBytes: external_exports.number(),
17910
+ /** Final staged archive size, once the build phase completes. */
17911
+ archiveSizeBytes: external_exports.number().optional(),
17912
+ /** Bytes pushed to the destination currently uploading. */
17913
+ uploadedBytes: external_exports.number(),
17914
+ /** Destinations where the archive fully landed (uploaded + indexed). */
17915
+ completedDestinationIds: external_exports.array(external_exports.string()).readonly(),
17916
+ /** Destinations that failed during the fan-out. */
17917
+ failedDestinationIds: external_exports.array(external_exports.string()).readonly(),
17918
+ /** Failure message when `state === 'failed'`. */
17919
+ error: external_exports.string().optional(),
17920
+ /**
17921
+ * 1-based place in the execution queue — 1 = runs next. Present only
17922
+ * while `state === 'queued'`. Stamped by the orchestrator from the
17923
+ * queue's OWN pending order, never derived from timestamps, so the
17924
+ * UI cannot show an order the executor will not honour.
17925
+ */
17926
+ queuePosition: external_exports.number().int().min(1).optional()
17927
+ });
17928
+ var BackupTriggerResultSchema = external_exports.object({
17929
+ /** The run this trigger mapped to — poll it via `listRuns`, stop it via `cancel`. */
17930
+ runId: external_exports.string(),
17931
+ /** True when the run waited behind an in-flight run instead of starting immediately. */
17932
+ queued: external_exports.boolean(),
17933
+ /** True when this trigger was coalesced onto an identical already-queued run. */
17934
+ joined: external_exports.boolean(),
17935
+ /** True when the run was cancelled before completing every destination. */
17936
+ cancelled: external_exports.boolean(),
17937
+ /** One entry per destination the archive landed at (partial on cancel). */
17938
+ entries: external_exports.array(BackupEntrySchema).readonly()
17939
+ });
17878
17940
  var BackupScheduleSchema = external_exports.object({
17879
17941
  /** Stable id. Generated by the orchestrator on first upsert if absent. */
17880
17942
  id: external_exports.string(),
@@ -17911,6 +17973,11 @@ var backupCapability = {
17911
17973
  * Trigger a backup. Without `destinations` the orchestrator fans
17912
17974
  * out to every destination flagged as enabled in the routing
17913
17975
  * config; with it, only the listed addons receive the archive.
17976
+ *
17977
+ * At most ONE backup run executes at a time — the source tree and
17978
+ * the staging disk are shared by every run, so a second trigger
17979
+ * while one is in flight is enqueued (or joined onto an identical
17980
+ * queued run) and the result says so. See D342.
17914
17981
  */
17915
17982
  trigger: method(external_exports.object({
17916
17983
  /** Subset of registered `backup-destination` addon ids to write to. */
@@ -17924,7 +17991,30 @@ var backupCapability = {
17924
17991
  * retention (manual runs).
17925
17992
  */
17926
17993
  retentionCount: external_exports.number().int().min(1).max(1e3).optional()
17927
- }).optional(), external_exports.array(BackupEntrySchema).readonly(), {
17994
+ }).optional(), BackupTriggerResultSchema, {
17995
+ kind: "mutation",
17996
+ auth: "admin"
17997
+ }),
17998
+ /**
17999
+ * Every run the orchestrator knows about, in EXECUTION order: the
18000
+ * running run first, then queued runs in the exact order they will
18001
+ * execute (each with `queuePosition`, 1 = next), then the bounded
18002
+ * finished history newest-first. Only one run executes at a time
18003
+ * (D342) — the queued section IS the line. Each run carries live
18004
+ * phase + byte counters so a runaway build is visible in seconds,
18005
+ * not via `du`.
18006
+ */
18007
+ listRuns: method(external_exports.void(), external_exports.array(BackupRunSchema).readonly(), { auth: "admin" }),
18008
+ /**
18009
+ * Stop a backup run. Mirrors `storage-migration.cancel` semantics:
18010
+ * id in, `{ cancelled }` out — `false` when the run is unknown or
18011
+ * already terminal. A QUEUED run is removed before it ever starts;
18012
+ * the RUNNING run has its tar/upload stream actually aborted, the
18013
+ * half-written staging archive is deleted, and the in-flight
18014
+ * destination upload is aborted server-side (partial discarded).
18015
+ * Destinations that already completed keep their archive.
18016
+ */
18017
+ cancel: method(external_exports.object({ runId: external_exports.string() }), external_exports.object({ cancelled: external_exports.boolean() }), {
17928
18018
  kind: "mutation",
17929
18019
  auth: "admin"
17930
18020
  }),
@@ -18664,6 +18754,38 @@ var streamBrokerCapability = {
18664
18754
  auth: "admin"
18665
18755
  }),
18666
18756
  /**
18757
+ * The HARDWARE behind a device number was replaced
18758
+ * (`deviceManager.migrateDevice`). Forget every piece of broker state that
18759
+ * described the old box, so the next catalog pull derives everything from
18760
+ * the camera that is actually there:
18761
+ *
18762
+ * - every `derived:*` stream definition — a derived is authored against a
18763
+ * specific profile layout, and against the wrong hardware its feeder
18764
+ * respawns forever (observed at attempt 2732 on the live hub,
18765
+ * 2026-09-01);
18766
+ * - the profile-slot assignment entry, PURGED (not unassigned — unassign
18767
+ * marks the slot manual, which would pin the stale choice instead of
18768
+ * letting `computeInitialAssignment` re-derive it);
18769
+ * - the probe snapshots (`<deviceId>/…` — probed codec/resolution of the
18770
+ * old hardware);
18771
+ * - the persisted RTSP token rows for the device's brokers (keyed
18772
+ * `<deviceId>/<camStreamId>`; the stream ids change with the hardware,
18773
+ * so the rows are dead URLs).
18774
+ *
18775
+ * An RPC, deliberately — an event is telemetry and may be dropped (D8),
18776
+ * and a dropped forget leaves a feeder respawning against a stream that
18777
+ * does not exist.
18778
+ */
18779
+ forgetDeviceHardware: method(external_exports.object({ deviceId: external_exports.number().int().nonnegative() }), external_exports.object({
18780
+ derivedStreamsDeleted: external_exports.array(external_exports.string()).readonly(),
18781
+ assignmentsPurged: external_exports.boolean(),
18782
+ probeSnapshotsDropped: external_exports.number().int().nonnegative(),
18783
+ rtspTokenRowsDeleted: external_exports.number().int().nonnegative()
18784
+ }), {
18785
+ kind: "mutation",
18786
+ auth: "admin"
18787
+ }),
18788
+ /**
18667
18789
  * Render a short GIF or MP4 from the broker's PRE-BUFFER around an instant.
18668
18790
  *
18669
18791
  * The pre-buffer is the only source that already holds the seconds BEFORE
@@ -26454,7 +26576,20 @@ var RecentTracksQueryInput = external_exports.object({
26454
26576
  projection: TrackProjectionSchema.optional(),
26455
26577
  /** Include stationary-promoted rows (parked objects). Default false: the
26456
26578
  * feed lists passages; parking records live on the stationary registry. */
26457
- includeStationary: external_exports.boolean().optional()
26579
+ includeStationary: external_exports.boolean().optional(),
26580
+ /**
26581
+ * Restrict to these track classes. ABSENT or EMPTY means no filter.
26582
+ *
26583
+ * The same filter `listTracks` takes, because the timeline's class chips must
26584
+ * mean the same thing whether the scope is one camera or twelve. Until this
26585
+ * existed the scoped feed downloaded a page and narrowed it on the phone
26586
+ * while the single-camera path narrowed the read — one filter, two costs.
26587
+ *
26588
+ * A SUPERSET prefilter on `classes[]`, like its single-camera twin: rows
26589
+ * whose class list is unreadable are kept, and the client's rule stays the
26590
+ * exact one.
26591
+ */
26592
+ classes: external_exports.array(external_exports.string()).optional()
26458
26593
  });
26459
26594
  var RecentTracksPageSchema = external_exports.object({
26460
26595
  /** Merged page, ordered by (`lastSeen` DESC, `trackId` DESC). */
@@ -31730,8 +31865,22 @@ var automationControlCapability = {
31730
31865
  durability: "session"
31731
31866
  };
31732
31867
  var BatteryStatusSchema = external_exports.object({
31733
- /** 0..100 inclusive. Firmware-reported. */
31734
- percentage: external_exports.number().min(0).max(100),
31868
+ /**
31869
+ * 0..100 inclusive, firmware-reported. **`null` means NOT YET KNOWN** — the
31870
+ * provider has registered the capability but no reading has landed.
31871
+ *
31872
+ * It is nullable because it was not, and the only value a provider could
31873
+ * seed with was `0`. A battery camera behind an NVR therefore announced
31874
+ * itself at 0% on every start and corrected itself a moment later, which is
31875
+ * indistinguishable from a real flat battery: it fires the low-battery alert
31876
+ * every time the hub restarts. Unknown is not empty (D315), and on a battery
31877
+ * reading the difference is an alarm.
31878
+ *
31879
+ * `vacuum-control` and `lawn-mower-control` already model it this way.
31880
+ * Consumers must SKIP a null rather than coerce it — `battery-band` already
31881
+ * declines to band a non-finite reading, which is the correct shape.
31882
+ */
31883
+ percentage: external_exports.number().min(0).max(100).nullable(),
31735
31884
  /**
31736
31885
  * Charging source. `'dc'` covers wall/USB adapters; `'solar'` is
31737
31886
  * Reolink-specific for the Solar Panel 2 accessory (will become
@@ -39741,6 +39890,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
39741
39890
  addonId: null,
39742
39891
  access: "create"
39743
39892
  },
39893
+ "backup.cancel": {
39894
+ capName: "backup",
39895
+ capScope: "system",
39896
+ addonId: null,
39897
+ access: "create"
39898
+ },
39744
39899
  "backup.delete": {
39745
39900
  capName: "backup",
39746
39901
  capScope: "system",
@@ -39783,6 +39938,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
39783
39938
  addonId: null,
39784
39939
  access: "view"
39785
39940
  },
39941
+ "backup.listRuns": {
39942
+ capName: "backup",
39943
+ capScope: "system",
39944
+ addonId: null,
39945
+ access: "view"
39946
+ },
39786
39947
  "backup.listSchedules": {
39787
39948
  capName: "backup",
39788
39949
  capScope: "system",
@@ -44349,6 +44510,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
44349
44510
  addonId: null,
44350
44511
  access: "create"
44351
44512
  },
44513
+ "streamBroker.forgetDeviceHardware": {
44514
+ capName: "stream-broker",
44515
+ capScope: "system",
44516
+ addonId: null,
44517
+ access: "delete"
44518
+ },
44352
44519
  "streamBroker.getAllRtspEntries": {
44353
44520
  capName: "stream-broker",
44354
44521
  capScope: "system",
@@ -46807,6 +46974,11 @@ var METHOD_DEVICE_SELECTORS = Object.freeze({
46807
46974
  form: "single",
46808
46975
  optional: false
46809
46976
  }],
46977
+ "streamBroker.forgetDeviceHardware": [{
46978
+ name: "deviceId",
46979
+ form: "single",
46980
+ optional: false
46981
+ }],
46810
46982
  "streamBroker.getDeviceAudioMute": [{
46811
46983
  name: "deviceId",
46812
46984
  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-GLXEXFJW.js";
4
+ } from "./chunk-O7PXXZZ7.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-DD66RRLG.js");
41
+ await import("./launcher-EQ3SI35Z.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-DD66RRLG.js");
86
+ await import("./launcher-EQ3SI35Z.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-JZRN6RUI.js");
1133
+ const { discoverNodes, resolveHubFromDiscovered, filterHubNodes, DEFAULT_HUB_HTTPS_PORT } = await import("./discover-E5HX2QAP.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-GLXEXFJW.js";
8
+ } from "./chunk-O7PXXZZ7.js";
9
9
  import "./chunk-LMMQX4CK.js";
10
10
  export {
11
11
  DEFAULT_HUB_HTTPS_PORT,