@camstack/addon-tailscale 1.2.84 → 1.2.86

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.
@@ -24,7 +24,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
24
24
  enumerable: true
25
25
  }) : target, mod));
26
26
  //#endregion
27
- const require_dist = require("../dist-DUqXeckw.js");
27
+ const require_dist = require("../dist-BHHoYHmH.js");
28
28
  let node_child_process = require("node:child_process");
29
29
  let node_util = require("node:util");
30
30
  let node_fs = require("node:fs");
@@ -1,4 +1,4 @@
1
- import { a as EventCategory, i as BaseAddon, n as networkAccessCapability, r as BOOT_RECOVERY_BACKOFF_MS, t as meshNetworkCapability } from "../dist-C9fQsDBf.mjs";
1
+ import { a as EventCategory, i as BaseAddon, n as networkAccessCapability, r as BOOT_RECOVERY_BACKOFF_MS, t as meshNetworkCapability } from "../dist-DQnICiSH.mjs";
2
2
  import { execFile, spawn } from "node:child_process";
3
3
  import { promisify } from "node:util";
4
4
  import * as fs from "node:fs";
@@ -15845,16 +15845,16 @@ DeviceType.AlarmPanel, method(object({
15845
15845
  code: string().min(1).optional()
15846
15846
  }), _void(), {
15847
15847
  kind: "mutation",
15848
- auth: "admin"
15848
+ auth: "protected"
15849
15849
  }), method(object({
15850
15850
  deviceId: number().int().nonnegative(),
15851
15851
  code: string().min(1).optional()
15852
15852
  }), _void(), {
15853
15853
  kind: "mutation",
15854
- auth: "admin"
15854
+ auth: "protected"
15855
15855
  }), method(object({ deviceId: number().int().nonnegative() }), _void(), {
15856
15856
  kind: "mutation",
15857
- auth: "admin"
15857
+ auth: "protected"
15858
15858
  });
15859
15859
  /**
15860
15860
  * Shared geometry vocabulary for on-frame shape caps — privacy-mask,
@@ -23509,7 +23509,7 @@ DeviceType.Light, method(object({
23509
23509
  percentage: number().min(0).max(100)
23510
23510
  }), _void(), {
23511
23511
  kind: "mutation",
23512
- auth: "admin"
23512
+ auth: "protected"
23513
23513
  }), object({
23514
23514
  deviceId: number(),
23515
23515
  percentage: number().min(0).max(100),
@@ -23517,7 +23517,7 @@ DeviceType.Light, method(object({
23517
23517
  });
23518
23518
  DeviceType.Button, method(object({ deviceId: number().int().nonnegative() }), _void(), {
23519
23519
  kind: "mutation",
23520
- auth: "admin"
23520
+ auth: "protected"
23521
23521
  });
23522
23522
  /**
23523
23523
  * camera-credentials — device-scoped cap exposing the camera's network
@@ -23676,50 +23676,50 @@ DeviceType.Thermostat, DeviceType.Climate, method(object({
23676
23676
  mode: HvacModeSchema
23677
23677
  }), _void(), {
23678
23678
  kind: "mutation",
23679
- auth: "admin"
23679
+ auth: "protected"
23680
23680
  }), method(object({
23681
23681
  deviceId: number().int().nonnegative(),
23682
23682
  fanMode: string().min(1)
23683
23683
  }), _void(), {
23684
23684
  kind: "mutation",
23685
- auth: "admin"
23685
+ auth: "protected"
23686
23686
  }), method(object({
23687
23687
  deviceId: number().int().nonnegative(),
23688
23688
  preset: string().min(1)
23689
23689
  }), _void(), {
23690
23690
  kind: "mutation",
23691
- auth: "admin"
23691
+ auth: "protected"
23692
23692
  }), method(object({
23693
23693
  deviceId: number().int().nonnegative(),
23694
23694
  target: number()
23695
23695
  }), _void(), {
23696
23696
  kind: "mutation",
23697
- auth: "admin"
23697
+ auth: "protected"
23698
23698
  }), method(object({
23699
23699
  deviceId: number().int().nonnegative(),
23700
23700
  targetLow: number(),
23701
23701
  targetHigh: number()
23702
23702
  }), _void(), {
23703
23703
  kind: "mutation",
23704
- auth: "admin"
23704
+ auth: "protected"
23705
23705
  }), method(object({
23706
23706
  deviceId: number().int().nonnegative(),
23707
23707
  targetHumidity: number().min(0).max(100)
23708
23708
  }), _void(), {
23709
23709
  kind: "mutation",
23710
- auth: "admin"
23710
+ auth: "protected"
23711
23711
  }), method(object({
23712
23712
  deviceId: number().int().nonnegative(),
23713
23713
  on: boolean()
23714
23714
  }), _void(), {
23715
23715
  kind: "mutation",
23716
- auth: "admin"
23716
+ auth: "protected"
23717
23717
  }), method(object({
23718
23718
  deviceId: number().int().nonnegative(),
23719
23719
  on: boolean()
23720
23720
  }), _void(), {
23721
23721
  kind: "mutation",
23722
- auth: "admin"
23722
+ auth: "protected"
23723
23723
  });
23724
23724
  /**
23725
23725
  * Color-light cap. Coexists with `switch` (on/off) and `brightness`
@@ -23794,7 +23794,7 @@ DeviceType.Light, method(object({
23794
23794
  color: ColorInputSchema
23795
23795
  }), _void(), {
23796
23796
  kind: "mutation",
23797
- auth: "admin"
23797
+ auth: "protected"
23798
23798
  }), object({
23799
23799
  deviceId: number(),
23800
23800
  mode: _enum([
@@ -23943,7 +23943,7 @@ DeviceType.Control, method(object({
23943
23943
  control: ControlSetValueInputSchema
23944
23944
  }), _void(), {
23945
23945
  kind: "mutation",
23946
- auth: "admin"
23946
+ auth: "protected"
23947
23947
  });
23948
23948
  object({
23949
23949
  /** Lifecycle state of the cover. */
@@ -23964,25 +23964,25 @@ object({
23964
23964
  });
23965
23965
  DeviceType.Cover, method(object({ deviceId: number().int().nonnegative() }), _void(), {
23966
23966
  kind: "mutation",
23967
- auth: "admin"
23967
+ auth: "protected"
23968
23968
  }), method(object({ deviceId: number().int().nonnegative() }), _void(), {
23969
23969
  kind: "mutation",
23970
- auth: "admin"
23970
+ auth: "protected"
23971
23971
  }), method(object({ deviceId: number().int().nonnegative() }), _void(), {
23972
23972
  kind: "mutation",
23973
- auth: "admin"
23973
+ auth: "protected"
23974
23974
  }), method(object({
23975
23975
  deviceId: number().int().nonnegative(),
23976
23976
  position: number().min(0).max(100)
23977
23977
  }), _void(), {
23978
23978
  kind: "mutation",
23979
- auth: "admin"
23979
+ auth: "protected"
23980
23980
  }), method(object({
23981
23981
  deviceId: number().int().nonnegative(),
23982
23982
  tiltPosition: number().min(0).max(100)
23983
23983
  }), _void(), {
23984
23984
  kind: "mutation",
23985
- auth: "admin"
23985
+ auth: "protected"
23986
23986
  });
23987
23987
  /**
23988
23988
  * Vendor-neutral day/night (IR-cut) control — the per-camera config cap
@@ -24187,6 +24187,59 @@ var IdentitySampleInfoSchema = object({
24187
24187
  deviceId: number().int().optional(),
24188
24188
  base64: string().optional()
24189
24189
  });
24190
+ /**
24191
+ * One enrolled sample, judged against the gallery it lives in.
24192
+ *
24193
+ * The gallery is the one input to recognition nobody re-reads: a sample
24194
+ * enrolled from the wrong face keeps voting forever, and because the matches it
24195
+ * pulls then look confident, nobody goes back. The 2026-09-08 audit found
24196
+ * exactly one such pair on this cluster — a sample scoring 0.61 against three
24197
+ * samples of ANOTHER person, enrolled from the same camera in the same minute,
24198
+ * where every other cross-identity pair sits under 0.50.
24199
+ */
24200
+ var IdentitySampleAuditRowSchema = object({
24201
+ sampleId: string(),
24202
+ enrolledAt: number().int(),
24203
+ deviceId: number().int().optional(),
24204
+ source: _enum(["detected", "photo"]),
24205
+ /** The enrolled crop's media key, so the panel can show the evidence. */
24206
+ mediaKey: string().optional(),
24207
+ /**
24208
+ * False = the sample is stamped with a DIFFERENT face model, and a cosine
24209
+ * across feature spaces is a well-formed float with no meaning. Every number
24210
+ * below then says nothing — it must read as "cannot say", never as an
24211
+ * accusation and never as a clean bill: this list ends in a Remove button.
24212
+ */
24213
+ comparable: boolean(),
24214
+ /** Mean cosine against this person's other samples. Null when there are none
24215
+ * to compare with — never 0, which would read as "opposite". */
24216
+ selfMean: number().nullable(),
24217
+ /** The other person this sample looks most like, when it looks like one.
24218
+ * This is the half that convicts: not looking like yourself can be a hard
24219
+ * angle; looking like someone the gallery can NAME is a mis-enrolment. */
24220
+ bestForeign: object({
24221
+ identityId: string(),
24222
+ name: string(),
24223
+ score: number()
24224
+ }).optional(),
24225
+ /** 0 = nothing to say. Higher = look at this one sooner. */
24226
+ suspicion: number()
24227
+ });
24228
+ var IdentitySampleAuditSchema = object({
24229
+ identityId: string(),
24230
+ name: string(),
24231
+ /** The cluster face model every comparison was made in. */
24232
+ modelId: string(),
24233
+ totalSamples: number().int(),
24234
+ comparableSamples: number().int(),
24235
+ flagged: number().int(),
24236
+ /** The bar `flagged` counts against, so the panel states the RULE and not
24237
+ * only its current result. */
24238
+ flagThreshold: number(),
24239
+ /** Worst first. A row with nothing to say still appears, at the bottom: the
24240
+ * operator asked to see the gallery, not only its accusations. */
24241
+ rows: array(IdentitySampleAuditRowSchema).readonly()
24242
+ });
24190
24243
  var FaceInfoSchema = object({
24191
24244
  faceId: string(),
24192
24245
  deviceId: number().int(),
@@ -24338,7 +24391,7 @@ includeCrops: boolean().optional() }).optional(), array(IdentitySchema).readonly
24338
24391
  }), method(object({ id: string() }), _void(), {
24339
24392
  kind: "mutation",
24340
24393
  auth: "admin"
24341
- }), method(object({ identityId: string() }), array(IdentitySampleInfoSchema).readonly()), method(object({
24394
+ }), method(object({ identityId: string() }), array(IdentitySampleInfoSchema).readonly()), method(object({ identityId: string().min(1) }), IdentitySampleAuditSchema, { auth: "admin" }), method(object({
24342
24395
  identityId: string(),
24343
24396
  sampleId: string()
24344
24397
  }), _void(), {
@@ -24524,25 +24577,25 @@ DeviceType.Fan, method(object({
24524
24577
  percentage: number().min(0).max(100)
24525
24578
  }), _void(), {
24526
24579
  kind: "mutation",
24527
- auth: "admin"
24580
+ auth: "protected"
24528
24581
  }), method(object({
24529
24582
  deviceId: number().int().nonnegative(),
24530
24583
  preset: string().min(1)
24531
24584
  }), _void(), {
24532
24585
  kind: "mutation",
24533
- auth: "admin"
24586
+ auth: "protected"
24534
24587
  }), method(object({
24535
24588
  deviceId: number().int().nonnegative(),
24536
24589
  direction: FanDirectionSchema
24537
24590
  }), _void(), {
24538
24591
  kind: "mutation",
24539
- auth: "admin"
24592
+ auth: "protected"
24540
24593
  }), method(object({
24541
24594
  deviceId: number().int().nonnegative(),
24542
24595
  oscillating: boolean()
24543
24596
  }), _void(), {
24544
24597
  kind: "mutation",
24545
- auth: "admin"
24598
+ auth: "protected"
24546
24599
  });
24547
24600
  /**
24548
24601
  * Per-device feature/identity probe slice. Holds the runtime-resolved
@@ -24645,19 +24698,19 @@ DeviceType.Humidifier, method(object({
24645
24698
  on: boolean()
24646
24699
  }), _void(), {
24647
24700
  kind: "mutation",
24648
- auth: "admin"
24701
+ auth: "protected"
24649
24702
  }), method(object({
24650
24703
  deviceId: number().int().nonnegative(),
24651
24704
  humidity: number().min(0).max(100)
24652
24705
  }), _void(), {
24653
24706
  kind: "mutation",
24654
- auth: "admin"
24707
+ auth: "protected"
24655
24708
  }), method(object({
24656
24709
  deviceId: number().int().nonnegative(),
24657
24710
  mode: string().min(1)
24658
24711
  }), _void(), {
24659
24712
  kind: "mutation",
24660
- auth: "admin"
24713
+ auth: "protected"
24661
24714
  });
24662
24715
  object({
24663
24716
  /** Current relative humidity, 0..100. */
@@ -25119,13 +25172,13 @@ object({
25119
25172
  });
25120
25173
  DeviceType.LawnMower, method(object({ deviceId: number().int().nonnegative() }), _void(), {
25121
25174
  kind: "mutation",
25122
- auth: "admin"
25175
+ auth: "protected"
25123
25176
  }), method(object({ deviceId: number().int().nonnegative() }), _void(), {
25124
25177
  kind: "mutation",
25125
- auth: "admin"
25178
+ auth: "protected"
25126
25179
  }), method(object({ deviceId: number().int().nonnegative() }), _void(), {
25127
25180
  kind: "mutation",
25128
- auth: "admin"
25181
+ auth: "protected"
25129
25182
  });
25130
25183
  /**
25131
25184
  * local-network — hub-only singleton.
@@ -25385,16 +25438,16 @@ DeviceType.Lock, method(object({
25385
25438
  code: string().min(1).optional()
25386
25439
  }), _void(), {
25387
25440
  kind: "mutation",
25388
- auth: "admin"
25441
+ auth: "protected"
25389
25442
  }), method(object({
25390
25443
  deviceId: number().int().nonnegative(),
25391
25444
  code: string().min(1).optional()
25392
25445
  }), _void(), {
25393
25446
  kind: "mutation",
25394
- auth: "admin"
25447
+ auth: "protected"
25395
25448
  }), method(object({ deviceId: number().int().nonnegative() }), _void(), {
25396
25449
  kind: "mutation",
25397
- auth: "admin"
25450
+ auth: "protected"
25398
25451
  });
25399
25452
  /**
25400
25453
  * Media-player cap. Models HA `media_player.*` (Sonos, Chromecast,
@@ -25468,55 +25521,55 @@ object({
25468
25521
  });
25469
25522
  DeviceType.MediaPlayer, method(object({ deviceId: number().int().nonnegative() }), _void(), {
25470
25523
  kind: "mutation",
25471
- auth: "admin"
25524
+ auth: "protected"
25472
25525
  }), method(object({ deviceId: number().int().nonnegative() }), _void(), {
25473
25526
  kind: "mutation",
25474
- auth: "admin"
25527
+ auth: "protected"
25475
25528
  }), method(object({ deviceId: number().int().nonnegative() }), _void(), {
25476
25529
  kind: "mutation",
25477
- auth: "admin"
25530
+ auth: "protected"
25478
25531
  }), method(object({ deviceId: number().int().nonnegative() }), _void(), {
25479
25532
  kind: "mutation",
25480
- auth: "admin"
25533
+ auth: "protected"
25481
25534
  }), method(object({ deviceId: number().int().nonnegative() }), _void(), {
25482
25535
  kind: "mutation",
25483
- auth: "admin"
25536
+ auth: "protected"
25484
25537
  }), method(object({
25485
25538
  deviceId: number().int().nonnegative(),
25486
25539
  positionMs: number().int().nonnegative()
25487
25540
  }), _void(), {
25488
25541
  kind: "mutation",
25489
- auth: "admin"
25542
+ auth: "protected"
25490
25543
  }), method(object({
25491
25544
  deviceId: number().int().nonnegative(),
25492
25545
  volumeLevel: number().min(0).max(100)
25493
25546
  }), _void(), {
25494
25547
  kind: "mutation",
25495
- auth: "admin"
25548
+ auth: "protected"
25496
25549
  }), method(object({
25497
25550
  deviceId: number().int().nonnegative(),
25498
25551
  muted: boolean()
25499
25552
  }), _void(), {
25500
25553
  kind: "mutation",
25501
- auth: "admin"
25554
+ auth: "protected"
25502
25555
  }), method(object({
25503
25556
  deviceId: number().int().nonnegative(),
25504
25557
  shuffle: boolean()
25505
25558
  }), _void(), {
25506
25559
  kind: "mutation",
25507
- auth: "admin"
25560
+ auth: "protected"
25508
25561
  }), method(object({
25509
25562
  deviceId: number().int().nonnegative(),
25510
25563
  repeat: MediaPlayerRepeatSchema
25511
25564
  }), _void(), {
25512
25565
  kind: "mutation",
25513
- auth: "admin"
25566
+ auth: "protected"
25514
25567
  }), method(object({
25515
25568
  deviceId: number().int().nonnegative(),
25516
25569
  source: string().min(1)
25517
25570
  }), _void(), {
25518
25571
  kind: "mutation",
25519
- auth: "admin"
25572
+ auth: "protected"
25520
25573
  }), method(object({
25521
25574
  deviceId: number().int().nonnegative(),
25522
25575
  /** Media identifier / URL. */
@@ -25526,7 +25579,7 @@ DeviceType.MediaPlayer, method(object({ deviceId: number().int().nonnegative() }
25526
25579
  mediaType: string().min(1)
25527
25580
  }), _void(), {
25528
25581
  kind: "mutation",
25529
- auth: "admin"
25582
+ auth: "protected"
25530
25583
  });
25531
25584
  /**
25532
25585
  * mesh-network — collection cap for mesh-VPN providers.
@@ -26753,49 +26806,49 @@ DeviceType.PetFeeder, method(object({
26753
26806
  hopper2: gramsPortion.optional()
26754
26807
  }), _void(), {
26755
26808
  kind: "mutation",
26756
- auth: "admin"
26809
+ auth: "protected"
26757
26810
  }), method(object({ deviceId: number().int().nonnegative() }), _void(), {
26758
26811
  kind: "mutation",
26759
- auth: "admin"
26812
+ auth: "protected"
26760
26813
  }), method(object({ deviceId: number().int().nonnegative() }), _void(), {
26761
26814
  kind: "mutation",
26762
- auth: "admin"
26815
+ auth: "protected"
26763
26816
  }), method(object({ deviceId: number().int().nonnegative() }), _void(), {
26764
26817
  kind: "mutation",
26765
- auth: "admin"
26818
+ auth: "protected"
26766
26819
  }), method(object({ deviceId: number().int().nonnegative() }), _void(), {
26767
26820
  kind: "mutation",
26768
- auth: "admin"
26821
+ auth: "protected"
26769
26822
  }), method(object({
26770
26823
  deviceId: number().int().nonnegative(),
26771
26824
  soundId: number().int().nonnegative()
26772
26825
  }), _void(), {
26773
26826
  kind: "mutation",
26774
- auth: "admin"
26827
+ auth: "protected"
26775
26828
  }), method(object({
26776
26829
  deviceId: number().int().nonnegative(),
26777
26830
  on: boolean()
26778
26831
  }), _void(), {
26779
26832
  kind: "mutation",
26780
- auth: "admin"
26833
+ auth: "protected"
26781
26834
  }), method(object({
26782
26835
  deviceId: number().int().nonnegative(),
26783
26836
  on: boolean()
26784
26837
  }), _void(), {
26785
26838
  kind: "mutation",
26786
- auth: "admin"
26839
+ auth: "protected"
26787
26840
  }), method(object({
26788
26841
  deviceId: number().int().nonnegative(),
26789
26842
  on: boolean()
26790
26843
  }), _void(), {
26791
26844
  kind: "mutation",
26792
- auth: "admin"
26845
+ auth: "protected"
26793
26846
  }), method(object({
26794
26847
  deviceId: number().int().nonnegative(),
26795
26848
  level: number().int().nonnegative()
26796
26849
  }), _void(), {
26797
26850
  kind: "mutation",
26798
- auth: "admin"
26851
+ auth: "protected"
26799
26852
  });
26800
26853
  var VehicleSchema = object({
26801
26854
  id: string(),
@@ -28582,7 +28635,7 @@ DeviceType.Switch, DeviceType.Siren, DeviceType.Light, method(object({
28582
28635
  on: boolean()
28583
28636
  }), _void(), {
28584
28637
  kind: "mutation",
28585
- auth: "admin"
28638
+ auth: "protected"
28586
28639
  }), object({
28587
28640
  deviceId: number(),
28588
28641
  on: boolean(),
@@ -29439,25 +29492,25 @@ object({
29439
29492
  });
29440
29493
  DeviceType.Vacuum, method(object({ deviceId: number().int().nonnegative() }), _void(), {
29441
29494
  kind: "mutation",
29442
- auth: "admin"
29495
+ auth: "protected"
29443
29496
  }), method(object({ deviceId: number().int().nonnegative() }), _void(), {
29444
29497
  kind: "mutation",
29445
- auth: "admin"
29498
+ auth: "protected"
29446
29499
  }), method(object({ deviceId: number().int().nonnegative() }), _void(), {
29447
29500
  kind: "mutation",
29448
- auth: "admin"
29501
+ auth: "protected"
29449
29502
  }), method(object({ deviceId: number().int().nonnegative() }), _void(), {
29450
29503
  kind: "mutation",
29451
- auth: "admin"
29504
+ auth: "protected"
29452
29505
  }), method(object({ deviceId: number().int().nonnegative() }), _void(), {
29453
29506
  kind: "mutation",
29454
- auth: "admin"
29507
+ auth: "protected"
29455
29508
  }), method(object({
29456
29509
  deviceId: number().int().nonnegative(),
29457
29510
  speed: string().min(1)
29458
29511
  }), _void(), {
29459
29512
  kind: "mutation",
29460
- auth: "admin"
29513
+ auth: "protected"
29461
29514
  });
29462
29515
  object({
29463
29516
  /** Lifecycle state of the valve. */
@@ -29476,19 +29529,19 @@ object({
29476
29529
  });
29477
29530
  DeviceType.Valve, method(object({ deviceId: number().int().nonnegative() }), _void(), {
29478
29531
  kind: "mutation",
29479
- auth: "admin"
29532
+ auth: "protected"
29480
29533
  }), method(object({ deviceId: number().int().nonnegative() }), _void(), {
29481
29534
  kind: "mutation",
29482
- auth: "admin"
29535
+ auth: "protected"
29483
29536
  }), method(object({ deviceId: number().int().nonnegative() }), _void(), {
29484
29537
  kind: "mutation",
29485
- auth: "admin"
29538
+ auth: "protected"
29486
29539
  }), method(object({
29487
29540
  deviceId: number().int().nonnegative(),
29488
29541
  position: number().min(0).max(100)
29489
29542
  }), _void(), {
29490
29543
  kind: "mutation",
29491
- auth: "admin"
29544
+ auth: "protected"
29492
29545
  });
29493
29546
  object({
29494
29547
  detected: boolean(),
@@ -29522,19 +29575,19 @@ DeviceType.WaterHeater, method(object({
29522
29575
  temp: number().finite()
29523
29576
  }), _void(), {
29524
29577
  kind: "mutation",
29525
- auth: "admin"
29578
+ auth: "protected"
29526
29579
  }), method(object({
29527
29580
  deviceId: number().int().nonnegative(),
29528
29581
  mode: string().min(1)
29529
29582
  }), _void(), {
29530
29583
  kind: "mutation",
29531
- auth: "admin"
29584
+ auth: "protected"
29532
29585
  }), method(object({
29533
29586
  deviceId: number().int().nonnegative(),
29534
29587
  on: boolean()
29535
29588
  }), _void(), {
29536
29589
  kind: "mutation",
29537
- auth: "admin"
29590
+ auth: "protected"
29538
29591
  });
29539
29592
  object({
29540
29593
  /** Verbatim HA condition state (`sunny`, `cloudy`, `rainy`, …). Null
@@ -31626,6 +31679,12 @@ Object.freeze({
31626
31679
  addonId: null,
31627
31680
  access: "create"
31628
31681
  },
31682
+ "faceGallery.auditIdentitySamples": {
31683
+ capName: "face-gallery",
31684
+ capScope: "system",
31685
+ addonId: null,
31686
+ access: "view"
31687
+ },
31629
31688
  "faceGallery.createIdentity": {
31630
31689
  capName: "face-gallery",
31631
31690
  capScope: "system",
@@ -15845,16 +15845,16 @@ DeviceType.AlarmPanel, method(object({
15845
15845
  code: string().min(1).optional()
15846
15846
  }), _void(), {
15847
15847
  kind: "mutation",
15848
- auth: "admin"
15848
+ auth: "protected"
15849
15849
  }), method(object({
15850
15850
  deviceId: number().int().nonnegative(),
15851
15851
  code: string().min(1).optional()
15852
15852
  }), _void(), {
15853
15853
  kind: "mutation",
15854
- auth: "admin"
15854
+ auth: "protected"
15855
15855
  }), method(object({ deviceId: number().int().nonnegative() }), _void(), {
15856
15856
  kind: "mutation",
15857
- auth: "admin"
15857
+ auth: "protected"
15858
15858
  });
15859
15859
  /**
15860
15860
  * Shared geometry vocabulary for on-frame shape caps — privacy-mask,
@@ -23509,7 +23509,7 @@ DeviceType.Light, method(object({
23509
23509
  percentage: number().min(0).max(100)
23510
23510
  }), _void(), {
23511
23511
  kind: "mutation",
23512
- auth: "admin"
23512
+ auth: "protected"
23513
23513
  }), object({
23514
23514
  deviceId: number(),
23515
23515
  percentage: number().min(0).max(100),
@@ -23517,7 +23517,7 @@ DeviceType.Light, method(object({
23517
23517
  });
23518
23518
  DeviceType.Button, method(object({ deviceId: number().int().nonnegative() }), _void(), {
23519
23519
  kind: "mutation",
23520
- auth: "admin"
23520
+ auth: "protected"
23521
23521
  });
23522
23522
  /**
23523
23523
  * camera-credentials — device-scoped cap exposing the camera's network
@@ -23676,50 +23676,50 @@ DeviceType.Thermostat, DeviceType.Climate, method(object({
23676
23676
  mode: HvacModeSchema
23677
23677
  }), _void(), {
23678
23678
  kind: "mutation",
23679
- auth: "admin"
23679
+ auth: "protected"
23680
23680
  }), method(object({
23681
23681
  deviceId: number().int().nonnegative(),
23682
23682
  fanMode: string().min(1)
23683
23683
  }), _void(), {
23684
23684
  kind: "mutation",
23685
- auth: "admin"
23685
+ auth: "protected"
23686
23686
  }), method(object({
23687
23687
  deviceId: number().int().nonnegative(),
23688
23688
  preset: string().min(1)
23689
23689
  }), _void(), {
23690
23690
  kind: "mutation",
23691
- auth: "admin"
23691
+ auth: "protected"
23692
23692
  }), method(object({
23693
23693
  deviceId: number().int().nonnegative(),
23694
23694
  target: number()
23695
23695
  }), _void(), {
23696
23696
  kind: "mutation",
23697
- auth: "admin"
23697
+ auth: "protected"
23698
23698
  }), method(object({
23699
23699
  deviceId: number().int().nonnegative(),
23700
23700
  targetLow: number(),
23701
23701
  targetHigh: number()
23702
23702
  }), _void(), {
23703
23703
  kind: "mutation",
23704
- auth: "admin"
23704
+ auth: "protected"
23705
23705
  }), method(object({
23706
23706
  deviceId: number().int().nonnegative(),
23707
23707
  targetHumidity: number().min(0).max(100)
23708
23708
  }), _void(), {
23709
23709
  kind: "mutation",
23710
- auth: "admin"
23710
+ auth: "protected"
23711
23711
  }), method(object({
23712
23712
  deviceId: number().int().nonnegative(),
23713
23713
  on: boolean()
23714
23714
  }), _void(), {
23715
23715
  kind: "mutation",
23716
- auth: "admin"
23716
+ auth: "protected"
23717
23717
  }), method(object({
23718
23718
  deviceId: number().int().nonnegative(),
23719
23719
  on: boolean()
23720
23720
  }), _void(), {
23721
23721
  kind: "mutation",
23722
- auth: "admin"
23722
+ auth: "protected"
23723
23723
  });
23724
23724
  /**
23725
23725
  * Color-light cap. Coexists with `switch` (on/off) and `brightness`
@@ -23794,7 +23794,7 @@ DeviceType.Light, method(object({
23794
23794
  color: ColorInputSchema
23795
23795
  }), _void(), {
23796
23796
  kind: "mutation",
23797
- auth: "admin"
23797
+ auth: "protected"
23798
23798
  }), object({
23799
23799
  deviceId: number(),
23800
23800
  mode: _enum([
@@ -23943,7 +23943,7 @@ DeviceType.Control, method(object({
23943
23943
  control: ControlSetValueInputSchema
23944
23944
  }), _void(), {
23945
23945
  kind: "mutation",
23946
- auth: "admin"
23946
+ auth: "protected"
23947
23947
  });
23948
23948
  object({
23949
23949
  /** Lifecycle state of the cover. */
@@ -23964,25 +23964,25 @@ object({
23964
23964
  });
23965
23965
  DeviceType.Cover, method(object({ deviceId: number().int().nonnegative() }), _void(), {
23966
23966
  kind: "mutation",
23967
- auth: "admin"
23967
+ auth: "protected"
23968
23968
  }), method(object({ deviceId: number().int().nonnegative() }), _void(), {
23969
23969
  kind: "mutation",
23970
- auth: "admin"
23970
+ auth: "protected"
23971
23971
  }), method(object({ deviceId: number().int().nonnegative() }), _void(), {
23972
23972
  kind: "mutation",
23973
- auth: "admin"
23973
+ auth: "protected"
23974
23974
  }), method(object({
23975
23975
  deviceId: number().int().nonnegative(),
23976
23976
  position: number().min(0).max(100)
23977
23977
  }), _void(), {
23978
23978
  kind: "mutation",
23979
- auth: "admin"
23979
+ auth: "protected"
23980
23980
  }), method(object({
23981
23981
  deviceId: number().int().nonnegative(),
23982
23982
  tiltPosition: number().min(0).max(100)
23983
23983
  }), _void(), {
23984
23984
  kind: "mutation",
23985
- auth: "admin"
23985
+ auth: "protected"
23986
23986
  });
23987
23987
  /**
23988
23988
  * Vendor-neutral day/night (IR-cut) control — the per-camera config cap
@@ -24187,6 +24187,59 @@ var IdentitySampleInfoSchema = object({
24187
24187
  deviceId: number().int().optional(),
24188
24188
  base64: string().optional()
24189
24189
  });
24190
+ /**
24191
+ * One enrolled sample, judged against the gallery it lives in.
24192
+ *
24193
+ * The gallery is the one input to recognition nobody re-reads: a sample
24194
+ * enrolled from the wrong face keeps voting forever, and because the matches it
24195
+ * pulls then look confident, nobody goes back. The 2026-09-08 audit found
24196
+ * exactly one such pair on this cluster — a sample scoring 0.61 against three
24197
+ * samples of ANOTHER person, enrolled from the same camera in the same minute,
24198
+ * where every other cross-identity pair sits under 0.50.
24199
+ */
24200
+ var IdentitySampleAuditRowSchema = object({
24201
+ sampleId: string(),
24202
+ enrolledAt: number().int(),
24203
+ deviceId: number().int().optional(),
24204
+ source: _enum(["detected", "photo"]),
24205
+ /** The enrolled crop's media key, so the panel can show the evidence. */
24206
+ mediaKey: string().optional(),
24207
+ /**
24208
+ * False = the sample is stamped with a DIFFERENT face model, and a cosine
24209
+ * across feature spaces is a well-formed float with no meaning. Every number
24210
+ * below then says nothing — it must read as "cannot say", never as an
24211
+ * accusation and never as a clean bill: this list ends in a Remove button.
24212
+ */
24213
+ comparable: boolean(),
24214
+ /** Mean cosine against this person's other samples. Null when there are none
24215
+ * to compare with — never 0, which would read as "opposite". */
24216
+ selfMean: number().nullable(),
24217
+ /** The other person this sample looks most like, when it looks like one.
24218
+ * This is the half that convicts: not looking like yourself can be a hard
24219
+ * angle; looking like someone the gallery can NAME is a mis-enrolment. */
24220
+ bestForeign: object({
24221
+ identityId: string(),
24222
+ name: string(),
24223
+ score: number()
24224
+ }).optional(),
24225
+ /** 0 = nothing to say. Higher = look at this one sooner. */
24226
+ suspicion: number()
24227
+ });
24228
+ var IdentitySampleAuditSchema = object({
24229
+ identityId: string(),
24230
+ name: string(),
24231
+ /** The cluster face model every comparison was made in. */
24232
+ modelId: string(),
24233
+ totalSamples: number().int(),
24234
+ comparableSamples: number().int(),
24235
+ flagged: number().int(),
24236
+ /** The bar `flagged` counts against, so the panel states the RULE and not
24237
+ * only its current result. */
24238
+ flagThreshold: number(),
24239
+ /** Worst first. A row with nothing to say still appears, at the bottom: the
24240
+ * operator asked to see the gallery, not only its accusations. */
24241
+ rows: array(IdentitySampleAuditRowSchema).readonly()
24242
+ });
24190
24243
  var FaceInfoSchema = object({
24191
24244
  faceId: string(),
24192
24245
  deviceId: number().int(),
@@ -24338,7 +24391,7 @@ includeCrops: boolean().optional() }).optional(), array(IdentitySchema).readonly
24338
24391
  }), method(object({ id: string() }), _void(), {
24339
24392
  kind: "mutation",
24340
24393
  auth: "admin"
24341
- }), method(object({ identityId: string() }), array(IdentitySampleInfoSchema).readonly()), method(object({
24394
+ }), method(object({ identityId: string() }), array(IdentitySampleInfoSchema).readonly()), method(object({ identityId: string().min(1) }), IdentitySampleAuditSchema, { auth: "admin" }), method(object({
24342
24395
  identityId: string(),
24343
24396
  sampleId: string()
24344
24397
  }), _void(), {
@@ -24524,25 +24577,25 @@ DeviceType.Fan, method(object({
24524
24577
  percentage: number().min(0).max(100)
24525
24578
  }), _void(), {
24526
24579
  kind: "mutation",
24527
- auth: "admin"
24580
+ auth: "protected"
24528
24581
  }), method(object({
24529
24582
  deviceId: number().int().nonnegative(),
24530
24583
  preset: string().min(1)
24531
24584
  }), _void(), {
24532
24585
  kind: "mutation",
24533
- auth: "admin"
24586
+ auth: "protected"
24534
24587
  }), method(object({
24535
24588
  deviceId: number().int().nonnegative(),
24536
24589
  direction: FanDirectionSchema
24537
24590
  }), _void(), {
24538
24591
  kind: "mutation",
24539
- auth: "admin"
24592
+ auth: "protected"
24540
24593
  }), method(object({
24541
24594
  deviceId: number().int().nonnegative(),
24542
24595
  oscillating: boolean()
24543
24596
  }), _void(), {
24544
24597
  kind: "mutation",
24545
- auth: "admin"
24598
+ auth: "protected"
24546
24599
  });
24547
24600
  /**
24548
24601
  * Per-device feature/identity probe slice. Holds the runtime-resolved
@@ -24645,19 +24698,19 @@ DeviceType.Humidifier, method(object({
24645
24698
  on: boolean()
24646
24699
  }), _void(), {
24647
24700
  kind: "mutation",
24648
- auth: "admin"
24701
+ auth: "protected"
24649
24702
  }), method(object({
24650
24703
  deviceId: number().int().nonnegative(),
24651
24704
  humidity: number().min(0).max(100)
24652
24705
  }), _void(), {
24653
24706
  kind: "mutation",
24654
- auth: "admin"
24707
+ auth: "protected"
24655
24708
  }), method(object({
24656
24709
  deviceId: number().int().nonnegative(),
24657
24710
  mode: string().min(1)
24658
24711
  }), _void(), {
24659
24712
  kind: "mutation",
24660
- auth: "admin"
24713
+ auth: "protected"
24661
24714
  });
24662
24715
  object({
24663
24716
  /** Current relative humidity, 0..100. */
@@ -25119,13 +25172,13 @@ object({
25119
25172
  });
25120
25173
  DeviceType.LawnMower, method(object({ deviceId: number().int().nonnegative() }), _void(), {
25121
25174
  kind: "mutation",
25122
- auth: "admin"
25175
+ auth: "protected"
25123
25176
  }), method(object({ deviceId: number().int().nonnegative() }), _void(), {
25124
25177
  kind: "mutation",
25125
- auth: "admin"
25178
+ auth: "protected"
25126
25179
  }), method(object({ deviceId: number().int().nonnegative() }), _void(), {
25127
25180
  kind: "mutation",
25128
- auth: "admin"
25181
+ auth: "protected"
25129
25182
  });
25130
25183
  /**
25131
25184
  * local-network — hub-only singleton.
@@ -25385,16 +25438,16 @@ DeviceType.Lock, method(object({
25385
25438
  code: string().min(1).optional()
25386
25439
  }), _void(), {
25387
25440
  kind: "mutation",
25388
- auth: "admin"
25441
+ auth: "protected"
25389
25442
  }), method(object({
25390
25443
  deviceId: number().int().nonnegative(),
25391
25444
  code: string().min(1).optional()
25392
25445
  }), _void(), {
25393
25446
  kind: "mutation",
25394
- auth: "admin"
25447
+ auth: "protected"
25395
25448
  }), method(object({ deviceId: number().int().nonnegative() }), _void(), {
25396
25449
  kind: "mutation",
25397
- auth: "admin"
25450
+ auth: "protected"
25398
25451
  });
25399
25452
  /**
25400
25453
  * Media-player cap. Models HA `media_player.*` (Sonos, Chromecast,
@@ -25468,55 +25521,55 @@ object({
25468
25521
  });
25469
25522
  DeviceType.MediaPlayer, method(object({ deviceId: number().int().nonnegative() }), _void(), {
25470
25523
  kind: "mutation",
25471
- auth: "admin"
25524
+ auth: "protected"
25472
25525
  }), method(object({ deviceId: number().int().nonnegative() }), _void(), {
25473
25526
  kind: "mutation",
25474
- auth: "admin"
25527
+ auth: "protected"
25475
25528
  }), method(object({ deviceId: number().int().nonnegative() }), _void(), {
25476
25529
  kind: "mutation",
25477
- auth: "admin"
25530
+ auth: "protected"
25478
25531
  }), method(object({ deviceId: number().int().nonnegative() }), _void(), {
25479
25532
  kind: "mutation",
25480
- auth: "admin"
25533
+ auth: "protected"
25481
25534
  }), method(object({ deviceId: number().int().nonnegative() }), _void(), {
25482
25535
  kind: "mutation",
25483
- auth: "admin"
25536
+ auth: "protected"
25484
25537
  }), method(object({
25485
25538
  deviceId: number().int().nonnegative(),
25486
25539
  positionMs: number().int().nonnegative()
25487
25540
  }), _void(), {
25488
25541
  kind: "mutation",
25489
- auth: "admin"
25542
+ auth: "protected"
25490
25543
  }), method(object({
25491
25544
  deviceId: number().int().nonnegative(),
25492
25545
  volumeLevel: number().min(0).max(100)
25493
25546
  }), _void(), {
25494
25547
  kind: "mutation",
25495
- auth: "admin"
25548
+ auth: "protected"
25496
25549
  }), method(object({
25497
25550
  deviceId: number().int().nonnegative(),
25498
25551
  muted: boolean()
25499
25552
  }), _void(), {
25500
25553
  kind: "mutation",
25501
- auth: "admin"
25554
+ auth: "protected"
25502
25555
  }), method(object({
25503
25556
  deviceId: number().int().nonnegative(),
25504
25557
  shuffle: boolean()
25505
25558
  }), _void(), {
25506
25559
  kind: "mutation",
25507
- auth: "admin"
25560
+ auth: "protected"
25508
25561
  }), method(object({
25509
25562
  deviceId: number().int().nonnegative(),
25510
25563
  repeat: MediaPlayerRepeatSchema
25511
25564
  }), _void(), {
25512
25565
  kind: "mutation",
25513
- auth: "admin"
25566
+ auth: "protected"
25514
25567
  }), method(object({
25515
25568
  deviceId: number().int().nonnegative(),
25516
25569
  source: string().min(1)
25517
25570
  }), _void(), {
25518
25571
  kind: "mutation",
25519
- auth: "admin"
25572
+ auth: "protected"
25520
25573
  }), method(object({
25521
25574
  deviceId: number().int().nonnegative(),
25522
25575
  /** Media identifier / URL. */
@@ -25526,7 +25579,7 @@ DeviceType.MediaPlayer, method(object({ deviceId: number().int().nonnegative() }
25526
25579
  mediaType: string().min(1)
25527
25580
  }), _void(), {
25528
25581
  kind: "mutation",
25529
- auth: "admin"
25582
+ auth: "protected"
25530
25583
  });
25531
25584
  /**
25532
25585
  * mesh-network — collection cap for mesh-VPN providers.
@@ -26753,49 +26806,49 @@ DeviceType.PetFeeder, method(object({
26753
26806
  hopper2: gramsPortion.optional()
26754
26807
  }), _void(), {
26755
26808
  kind: "mutation",
26756
- auth: "admin"
26809
+ auth: "protected"
26757
26810
  }), method(object({ deviceId: number().int().nonnegative() }), _void(), {
26758
26811
  kind: "mutation",
26759
- auth: "admin"
26812
+ auth: "protected"
26760
26813
  }), method(object({ deviceId: number().int().nonnegative() }), _void(), {
26761
26814
  kind: "mutation",
26762
- auth: "admin"
26815
+ auth: "protected"
26763
26816
  }), method(object({ deviceId: number().int().nonnegative() }), _void(), {
26764
26817
  kind: "mutation",
26765
- auth: "admin"
26818
+ auth: "protected"
26766
26819
  }), method(object({ deviceId: number().int().nonnegative() }), _void(), {
26767
26820
  kind: "mutation",
26768
- auth: "admin"
26821
+ auth: "protected"
26769
26822
  }), method(object({
26770
26823
  deviceId: number().int().nonnegative(),
26771
26824
  soundId: number().int().nonnegative()
26772
26825
  }), _void(), {
26773
26826
  kind: "mutation",
26774
- auth: "admin"
26827
+ auth: "protected"
26775
26828
  }), method(object({
26776
26829
  deviceId: number().int().nonnegative(),
26777
26830
  on: boolean()
26778
26831
  }), _void(), {
26779
26832
  kind: "mutation",
26780
- auth: "admin"
26833
+ auth: "protected"
26781
26834
  }), method(object({
26782
26835
  deviceId: number().int().nonnegative(),
26783
26836
  on: boolean()
26784
26837
  }), _void(), {
26785
26838
  kind: "mutation",
26786
- auth: "admin"
26839
+ auth: "protected"
26787
26840
  }), method(object({
26788
26841
  deviceId: number().int().nonnegative(),
26789
26842
  on: boolean()
26790
26843
  }), _void(), {
26791
26844
  kind: "mutation",
26792
- auth: "admin"
26845
+ auth: "protected"
26793
26846
  }), method(object({
26794
26847
  deviceId: number().int().nonnegative(),
26795
26848
  level: number().int().nonnegative()
26796
26849
  }), _void(), {
26797
26850
  kind: "mutation",
26798
- auth: "admin"
26851
+ auth: "protected"
26799
26852
  });
26800
26853
  var VehicleSchema = object({
26801
26854
  id: string(),
@@ -28582,7 +28635,7 @@ DeviceType.Switch, DeviceType.Siren, DeviceType.Light, method(object({
28582
28635
  on: boolean()
28583
28636
  }), _void(), {
28584
28637
  kind: "mutation",
28585
- auth: "admin"
28638
+ auth: "protected"
28586
28639
  }), object({
28587
28640
  deviceId: number(),
28588
28641
  on: boolean(),
@@ -29439,25 +29492,25 @@ object({
29439
29492
  });
29440
29493
  DeviceType.Vacuum, method(object({ deviceId: number().int().nonnegative() }), _void(), {
29441
29494
  kind: "mutation",
29442
- auth: "admin"
29495
+ auth: "protected"
29443
29496
  }), method(object({ deviceId: number().int().nonnegative() }), _void(), {
29444
29497
  kind: "mutation",
29445
- auth: "admin"
29498
+ auth: "protected"
29446
29499
  }), method(object({ deviceId: number().int().nonnegative() }), _void(), {
29447
29500
  kind: "mutation",
29448
- auth: "admin"
29501
+ auth: "protected"
29449
29502
  }), method(object({ deviceId: number().int().nonnegative() }), _void(), {
29450
29503
  kind: "mutation",
29451
- auth: "admin"
29504
+ auth: "protected"
29452
29505
  }), method(object({ deviceId: number().int().nonnegative() }), _void(), {
29453
29506
  kind: "mutation",
29454
- auth: "admin"
29507
+ auth: "protected"
29455
29508
  }), method(object({
29456
29509
  deviceId: number().int().nonnegative(),
29457
29510
  speed: string().min(1)
29458
29511
  }), _void(), {
29459
29512
  kind: "mutation",
29460
- auth: "admin"
29513
+ auth: "protected"
29461
29514
  });
29462
29515
  object({
29463
29516
  /** Lifecycle state of the valve. */
@@ -29476,19 +29529,19 @@ object({
29476
29529
  });
29477
29530
  DeviceType.Valve, method(object({ deviceId: number().int().nonnegative() }), _void(), {
29478
29531
  kind: "mutation",
29479
- auth: "admin"
29532
+ auth: "protected"
29480
29533
  }), method(object({ deviceId: number().int().nonnegative() }), _void(), {
29481
29534
  kind: "mutation",
29482
- auth: "admin"
29535
+ auth: "protected"
29483
29536
  }), method(object({ deviceId: number().int().nonnegative() }), _void(), {
29484
29537
  kind: "mutation",
29485
- auth: "admin"
29538
+ auth: "protected"
29486
29539
  }), method(object({
29487
29540
  deviceId: number().int().nonnegative(),
29488
29541
  position: number().min(0).max(100)
29489
29542
  }), _void(), {
29490
29543
  kind: "mutation",
29491
- auth: "admin"
29544
+ auth: "protected"
29492
29545
  });
29493
29546
  object({
29494
29547
  detected: boolean(),
@@ -29522,19 +29575,19 @@ DeviceType.WaterHeater, method(object({
29522
29575
  temp: number().finite()
29523
29576
  }), _void(), {
29524
29577
  kind: "mutation",
29525
- auth: "admin"
29578
+ auth: "protected"
29526
29579
  }), method(object({
29527
29580
  deviceId: number().int().nonnegative(),
29528
29581
  mode: string().min(1)
29529
29582
  }), _void(), {
29530
29583
  kind: "mutation",
29531
- auth: "admin"
29584
+ auth: "protected"
29532
29585
  }), method(object({
29533
29586
  deviceId: number().int().nonnegative(),
29534
29587
  on: boolean()
29535
29588
  }), _void(), {
29536
29589
  kind: "mutation",
29537
- auth: "admin"
29590
+ auth: "protected"
29538
29591
  });
29539
29592
  object({
29540
29593
  /** Verbatim HA condition state (`sunny`, `cloudy`, `rainy`, …). Null
@@ -31626,6 +31679,12 @@ Object.freeze({
31626
31679
  addonId: null,
31627
31680
  access: "create"
31628
31681
  },
31682
+ "faceGallery.auditIdentitySamples": {
31683
+ capName: "face-gallery",
31684
+ capScope: "system",
31685
+ addonId: null,
31686
+ access: "view"
31687
+ },
31629
31688
  "faceGallery.createIdentity": {
31630
31689
  capName: "face-gallery",
31631
31690
  capScope: "system",
@@ -2,7 +2,7 @@ Object.defineProperties(exports, {
2
2
  __esModule: { value: true },
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
- const require_dist = require("../dist-DUqXeckw.js");
5
+ const require_dist = require("../dist-BHHoYHmH.js");
6
6
  let node_crypto = require("node:crypto");
7
7
  let node_child_process = require("node:child_process");
8
8
  //#region src/ingress/tailscale-cli.ts
@@ -1,4 +1,4 @@
1
- import { a as EventCategory, i as BaseAddon, n as networkAccessCapability } from "../dist-C9fQsDBf.mjs";
1
+ import { a as EventCategory, i as BaseAddon, n as networkAccessCapability } from "../dist-DQnICiSH.mjs";
2
2
  import { randomUUID } from "node:crypto";
3
3
  import { execFile } from "node:child_process";
4
4
  import { promisify } from "node:util";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-tailscale",
3
- "version": "1.2.84",
3
+ "version": "1.2.86",
4
4
  "description": "Tailscale bundle for CamStack — joins the host to a tailnet (client) and exposes the hub via Serve/Funnel (ingress). Multi-entry npm package shipping 2 addons under a single bundle.",
5
5
  "keywords": [
6
6
  "camstack",