@camstack/addon-tailscale 1.2.116 → 1.2.118
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client/tailscale.addon.js +4 -4
- package/dist/client/tailscale.addon.mjs +4 -4
- package/dist/{dist-jCCe7qVD.js → dist-B5khvoZj.js} +122 -76
- package/dist/{dist-DOnpd-Z8.mjs → dist-CnsQ7vyF.mjs} +122 -76
- package/dist/ingress/tailscale-ingress.addon.js +1 -1
- package/dist/ingress/tailscale-ingress.addon.mjs +1 -1
- package/package.json +1 -1
|
@@ -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-
|
|
27
|
+
const require_dist = require("../dist-B5khvoZj.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");
|
|
@@ -1294,15 +1294,15 @@ var TailscaleClientAddon = class extends require_dist.BaseAddon {
|
|
|
1294
1294
|
type: "boolean",
|
|
1295
1295
|
key: "acceptRoutes",
|
|
1296
1296
|
label: "Accept routes from peers",
|
|
1297
|
-
description: "Install subnet routes other peers advertise (e.g. a peer router exposing `192.168.
|
|
1297
|
+
description: "Install subnet routes other peers advertise (e.g. a peer router exposing `192.168.60.0/24`).",
|
|
1298
1298
|
default: false
|
|
1299
1299
|
}),
|
|
1300
1300
|
this.field({
|
|
1301
1301
|
type: "text",
|
|
1302
1302
|
key: "advertisedRoutes",
|
|
1303
1303
|
label: "Advertise subnet routes",
|
|
1304
|
-
description: "Comma-separated CIDRs this host exposes to peers (e.g. `192.168.
|
|
1305
|
-
placeholder: "192.168.
|
|
1304
|
+
description: "Comma-separated CIDRs this host exposes to peers (e.g. `192.168.10.0/24,10.0.0.0/8`). Requires approval in the Tailscale admin console.",
|
|
1305
|
+
placeholder: "192.168.10.0/24"
|
|
1306
1306
|
}),
|
|
1307
1307
|
this.field({
|
|
1308
1308
|
type: "text",
|
|
@@ -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-
|
|
1
|
+
import { a as EventCategory, i as BaseAddon, n as networkAccessCapability, r as BOOT_RECOVERY_BACKOFF_MS, t as meshNetworkCapability } from "../dist-CnsQ7vyF.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";
|
|
@@ -1266,15 +1266,15 @@ var TailscaleClientAddon = class extends BaseAddon {
|
|
|
1266
1266
|
type: "boolean",
|
|
1267
1267
|
key: "acceptRoutes",
|
|
1268
1268
|
label: "Accept routes from peers",
|
|
1269
|
-
description: "Install subnet routes other peers advertise (e.g. a peer router exposing `192.168.
|
|
1269
|
+
description: "Install subnet routes other peers advertise (e.g. a peer router exposing `192.168.60.0/24`).",
|
|
1270
1270
|
default: false
|
|
1271
1271
|
}),
|
|
1272
1272
|
this.field({
|
|
1273
1273
|
type: "text",
|
|
1274
1274
|
key: "advertisedRoutes",
|
|
1275
1275
|
label: "Advertise subnet routes",
|
|
1276
|
-
description: "Comma-separated CIDRs this host exposes to peers (e.g. `192.168.
|
|
1277
|
-
placeholder: "192.168.
|
|
1276
|
+
description: "Comma-separated CIDRs this host exposes to peers (e.g. `192.168.10.0/24,10.0.0.0/8`). Requires approval in the Tailscale admin console.",
|
|
1277
|
+
placeholder: "192.168.10.0/24"
|
|
1278
1278
|
}),
|
|
1279
1279
|
this.field({
|
|
1280
1280
|
type: "text",
|
|
@@ -10554,11 +10554,11 @@ var ModelVariantGroupSchema = object({
|
|
|
10554
10554
|
/** Quantization axis. Omit ⇒ the fp32 base build. */
|
|
10555
10555
|
precision: _enum(["fp32", "int8"]).optional(),
|
|
10556
10556
|
/**
|
|
10557
|
-
*
|
|
10558
|
-
*
|
|
10559
|
-
*
|
|
10557
|
+
* Training / latency-variant axis. Omit ⇒ the standard build. `test` marks
|
|
10558
|
+
* an alternate training of the same family (Scrypted `relu_test`); chip
|
|
10559
|
+
* label is "Test".
|
|
10560
10560
|
*/
|
|
10561
|
-
optimization: _enum(["standard", "
|
|
10561
|
+
optimization: _enum(["standard", "test"]).optional(),
|
|
10562
10562
|
/**
|
|
10563
10563
|
* Input-resolution axis (square input side, px). Omit ⇒ the family's native
|
|
10564
10564
|
* resolution (640 for yolo26). Reduced-input builds (320 / 256) are a big,
|
|
@@ -10581,9 +10581,10 @@ var ModelProviderIdSchema = _enum([
|
|
|
10581
10581
|
* are per upstream. A persisted custom-model row written when this field was a
|
|
10582
10582
|
* string still parses — the string is lifted into `{ weights }`.
|
|
10583
10583
|
*
|
|
10584
|
-
* Every licence surface (the
|
|
10585
|
-
*
|
|
10586
|
-
*
|
|
10584
|
+
* Every machine licence surface (`THIRD_PARTY_MODELS.md`, the Hugging Face
|
|
10585
|
+
* model table) is GENERATED from these records by
|
|
10586
|
+
* `scripts/gen-model-licenses.ts` (D661). Operator-facing docs live in
|
|
10587
|
+
* `camstack/docs` → `/docs/detection/models`.
|
|
10587
10588
|
*/
|
|
10588
10589
|
var ModelLicenseSchema = preprocess((value) => typeof value === "string" ? { weights: value } : value, object({
|
|
10589
10590
|
/** SPDX id of the WEIGHTS' terms, a `LicenseRef-*` for non-SPDX terms, or `UNKNOWN`. */
|
|
@@ -14112,7 +14113,7 @@ DeviceType.Camera;
|
|
|
14112
14113
|
* This matters here more than anywhere else in the repo, because every provider
|
|
14113
14114
|
* that knows a device's host knows its PASSWORD too: `{ host, port, username,
|
|
14114
14115
|
* password }` sit in one object on Hikvision, Amcrest, Reolink and ONVIF alike,
|
|
14115
|
-
* and `http://admin:hunter2@192.168.
|
|
14116
|
+
* and `http://admin:hunter2@192.168.60.139/` is a URL a browser accepts. The
|
|
14116
14117
|
* camera's own page will ask for its own login. That is correct, and pre-
|
|
14117
14118
|
* filling it is the operator's business, not ours.
|
|
14118
14119
|
*
|
|
@@ -17096,7 +17097,7 @@ method(object({
|
|
|
17096
17097
|
timeoutMs: 6e5
|
|
17097
17098
|
});
|
|
17098
17099
|
method(object({
|
|
17099
|
-
|
|
17100
|
+
targetNodeId: string(),
|
|
17100
17101
|
modelId: string(),
|
|
17101
17102
|
format: _enum(MODEL_FORMATS),
|
|
17102
17103
|
entry: ModelCatalogEntrySchema
|
|
@@ -19579,8 +19580,9 @@ var NcRuleSchema = NcRuleInputSchema.extend({
|
|
|
19579
19580
|
disabledTargetIds: array(string()).default([])
|
|
19580
19581
|
});
|
|
19581
19582
|
/**
|
|
19582
|
-
* The state-summary SECTIONS (D647 / D698): the D637 kind groups that
|
|
19583
|
-
* still-true state. `
|
|
19583
|
+
* The state-summary SECTIONS (D647 / D698 / D708): the D637 kind groups that
|
|
19584
|
+
* report a still-true state. `addons` is the crash-looped addons only and
|
|
19585
|
+
* `addon-updates` the addons that are behind (D708 split them). `backups-exports` and `alarm` are not sections — a completed
|
|
19584
19586
|
* job is not an open state, and the alarm stays instant.
|
|
19585
19587
|
*/
|
|
19586
19588
|
var NcStateSummarySectionIdSchema = _enum([
|
|
@@ -19592,6 +19594,7 @@ var NcStateSummarySectionIdSchema = _enum([
|
|
|
19592
19594
|
"detection-blind",
|
|
19593
19595
|
"nodes",
|
|
19594
19596
|
"addons",
|
|
19597
|
+
"addon-updates",
|
|
19595
19598
|
"updates"
|
|
19596
19599
|
]);
|
|
19597
19600
|
/** One section of a previewed state summary. `unavailable` = its state could not be read. */
|
|
@@ -20072,7 +20075,19 @@ var NcAlarmModeDelaysListSchema = array(object({
|
|
|
20072
20075
|
* When this mode may be armed. Absent / null = always allowed (same as a
|
|
20073
20076
|
* rule with no `schedule`). Evaluated with {@link isScheduleActive}.
|
|
20074
20077
|
*/
|
|
20075
|
-
schedule: NcScheduleSchema.optional()
|
|
20078
|
+
schedule: NcScheduleSchema.optional(),
|
|
20079
|
+
/**
|
|
20080
|
+
* D706: while this mode's ENTRY DELAY runs, do the alarm rules' own pushes go out (as an
|
|
20081
|
+
* intrusion naming the locations)? Absent = false — the entry-delay notification is the
|
|
20082
|
+
* only one, and the matches ride the triggered notification's mosaic (D705).
|
|
20083
|
+
*/
|
|
20084
|
+
notifyDuringEntryDelay: boolean().optional(),
|
|
20085
|
+
/**
|
|
20086
|
+
* D706: notify "watched again" when a sensor this arm bypassed closes and opens again.
|
|
20087
|
+
* Absent = false (logged, not sent). Even when true it is not sent when that same sensor
|
|
20088
|
+
* is the one that starts the entry delay — the entry-delay notification already names it.
|
|
20089
|
+
*/
|
|
20090
|
+
notifySensorRewatched: boolean().optional()
|
|
20076
20091
|
})).max(8).refine(uniqueModes, { message: "modeDelays: at most one entry per arm mode" });
|
|
20077
20092
|
var NcAlarmModeDelaysEditListSchema = array(object({
|
|
20078
20093
|
mode: AlarmArmModeSchema,
|
|
@@ -20081,7 +20096,11 @@ var NcAlarmModeDelaysEditListSchema = array(object({
|
|
|
20081
20096
|
triggeredDurationSec: NcAlarmTriggeredSecSchema.nullable().optional(),
|
|
20082
20097
|
postTriggeredAction: NcAlarmPostTriggeredActionSchema.nullable().optional(),
|
|
20083
20098
|
/** Set a schedule, or `null` to clear (mode always allowed again). */
|
|
20084
|
-
schedule: NcScheduleSchema.nullable().optional()
|
|
20099
|
+
schedule: NcScheduleSchema.nullable().optional(),
|
|
20100
|
+
/** D706: set the switch, or `null` to clear it (back to the default, false). */
|
|
20101
|
+
notifyDuringEntryDelay: boolean().nullable().optional(),
|
|
20102
|
+
/** D706: set the switch, or `null` to clear it (back to the default, false). */
|
|
20103
|
+
notifySensorRewatched: boolean().nullable().optional()
|
|
20085
20104
|
})).max(8).refine(uniqueModes, { message: "modeDelays: at most one edit per arm mode" });
|
|
20086
20105
|
/** One switch of the alarm table: put ONE device on, or take it off, ONE mode's list. */
|
|
20087
20106
|
var NcAlarmNonBlockingEditSchema = object({
|
|
@@ -21042,39 +21061,19 @@ Object.freeze(Object.fromEntries([{
|
|
|
21042
21061
|
label: "Face recognition model",
|
|
21043
21062
|
defaultModelId: "auraface-r100",
|
|
21044
21063
|
indexName: "the enrolled face gallery",
|
|
21045
|
-
options: [
|
|
21046
|
-
|
|
21047
|
-
|
|
21048
|
-
|
|
21049
|
-
},
|
|
21050
|
-
{
|
|
21051
|
-
id: "arcface-r100",
|
|
21052
|
-
label: "ArcFace (ResNet34)"
|
|
21053
|
-
},
|
|
21054
|
-
{
|
|
21055
|
-
id: "inception-resnet-v1",
|
|
21056
|
-
label: "Inception ResNet V1"
|
|
21057
|
-
}
|
|
21058
|
-
]
|
|
21064
|
+
options: [{
|
|
21065
|
+
id: "auraface-r100",
|
|
21066
|
+
label: "AuraFace R100"
|
|
21067
|
+
}]
|
|
21059
21068
|
}, {
|
|
21060
21069
|
stepId: "clip-embedding",
|
|
21061
21070
|
label: "Semantic search model",
|
|
21062
|
-
defaultModelId: "
|
|
21071
|
+
defaultModelId: "siglip2-b16-224",
|
|
21063
21072
|
indexName: "the object semantic-search index",
|
|
21064
|
-
options: [
|
|
21065
|
-
|
|
21066
|
-
|
|
21067
|
-
|
|
21068
|
-
},
|
|
21069
|
-
{
|
|
21070
|
-
id: "mobileclip-s2",
|
|
21071
|
-
label: "MobileCLIP S2"
|
|
21072
|
-
},
|
|
21073
|
-
{
|
|
21074
|
-
id: "siglip2-b16-224",
|
|
21075
|
-
label: "SigLIP2 B/16 (Apache-2.0)"
|
|
21076
|
-
}
|
|
21077
|
-
]
|
|
21073
|
+
options: [{
|
|
21074
|
+
id: "siglip2-b16-224",
|
|
21075
|
+
label: "SigLIP2 B/16 (Apache-2.0)"
|
|
21076
|
+
}]
|
|
21078
21077
|
}].map((s) => [s.stepId, s.defaultModelId])));
|
|
21079
21078
|
var CLUSTER_STEP_SETTING_FIELDS = [{
|
|
21080
21079
|
stepId: "face-embedding",
|
|
@@ -23922,6 +23921,22 @@ var MotionSourceEnum = _enum([
|
|
|
23922
23921
|
"device-activity"
|
|
23923
23922
|
]);
|
|
23924
23923
|
/**
|
|
23924
|
+
* What opened an on-motion detection SESSION: the motion source that passed the
|
|
23925
|
+
* camera's `motionSources` gate, and what raised it (the camera itself, or a
|
|
23926
|
+
* sensor the operator attached — D672). `sensorName` is the attached sensor's
|
|
23927
|
+
* device name as the orchestrator's camera-sensors resolution last read it;
|
|
23928
|
+
* absent when unknown or when the camera itself triggered.
|
|
23929
|
+
*
|
|
23930
|
+
* Carried on the session attach ONLY so the runner's `DetectionPhaseTransition`
|
|
23931
|
+
* can say what started the session (D672 rule 11, amended 2026-10-06). The
|
|
23932
|
+
* runner never decides anything on it.
|
|
23933
|
+
*/
|
|
23934
|
+
var SessionTriggerSchema = object({
|
|
23935
|
+
source: MotionSourceEnum,
|
|
23936
|
+
triggeredBy: MotionTriggeredBySchema,
|
|
23937
|
+
sensorName: string().optional()
|
|
23938
|
+
});
|
|
23939
|
+
/**
|
|
23925
23940
|
* List of motion sources active on a camera. Empty array is valid:
|
|
23926
23941
|
* "no source" — happens for battery cams without firmware motion when
|
|
23927
23942
|
* the operator hasn't opted into the SW analyzer (would hold the
|
|
@@ -24173,6 +24188,14 @@ var RunnerCameraConfigSchema = object({
|
|
|
24173
24188
|
*/
|
|
24174
24189
|
motionSources: MotionSourcesSchema.default(["analyzer"]),
|
|
24175
24190
|
/**
|
|
24191
|
+
* What opened this attach, on a SESSION attach only (see
|
|
24192
|
+
* {@link SessionTriggerSchema}). OPTIONAL with no default: absent on a
|
|
24193
|
+
* standing attach, an occupancy burst, a re-dispatch with no motion event
|
|
24194
|
+
* behind it, and every attach from an orchestrator older than the field — the
|
|
24195
|
+
* runner then names no source on the phase event.
|
|
24196
|
+
*/
|
|
24197
|
+
sessionTrigger: SessionTriggerSchema.optional(),
|
|
24198
|
+
/**
|
|
24176
24199
|
* WHICH root detector runs for this camera. The detection counterpart of
|
|
24177
24200
|
* {@link motionSources}, same shape and same discipline: a per-camera list
|
|
24178
24201
|
* of sources the system understands, vendor-agnostic, owned here.
|
|
@@ -30396,7 +30419,7 @@ var LocalInterfaceSchema = object({
|
|
|
30396
30419
|
name: string(),
|
|
30397
30420
|
family: _enum(["IPv4", "IPv6"]),
|
|
30398
30421
|
address: string(),
|
|
30399
|
-
/** CIDR shorthand (e.g. `192.168.
|
|
30422
|
+
/** CIDR shorthand (e.g. `192.168.10.10/24`). Empty when OS doesn't expose. */
|
|
30400
30423
|
cidr: string(),
|
|
30401
30424
|
/** OS netmask. Stable across calls so the SDK can hash on it. */
|
|
30402
30425
|
netmask: string(),
|
|
@@ -30450,7 +30473,8 @@ var ConnectionEndpointSchema = object({
|
|
|
30450
30473
|
"lan-ipv4",
|
|
30451
30474
|
"lan-ipv6",
|
|
30452
30475
|
"public",
|
|
30453
|
-
"loopback"
|
|
30476
|
+
"loopback",
|
|
30477
|
+
"app-link"
|
|
30454
30478
|
]),
|
|
30455
30479
|
/**
|
|
30456
30480
|
* Originating-interface kind — `lan`/`wifi`/`docker`/`vpn`/`other`/
|
|
@@ -30519,15 +30543,27 @@ var GetConnectionEndpointsResultSchema = object({
|
|
|
30519
30543
|
localPort: AdvertisedLocalPortSchema
|
|
30520
30544
|
});
|
|
30521
30545
|
/**
|
|
30522
|
-
* The
|
|
30523
|
-
*
|
|
30524
|
-
*
|
|
30546
|
+
* The address flagged for notification links. `baseUrl: null` = AUTO, which
|
|
30547
|
+
* since D709 is the CamStack app link; `resolved` reports the effective value,
|
|
30548
|
+
* so the UI can show it either way.
|
|
30525
30549
|
*/
|
|
30526
30550
|
var NotificationEndpointSchema = object({
|
|
30527
30551
|
/** The operator's explicit choice, or null for AUTO. */
|
|
30528
30552
|
baseUrl: string().nullable(),
|
|
30529
|
-
/**
|
|
30530
|
-
|
|
30553
|
+
/**
|
|
30554
|
+
* The effective flagged address: the explicit choice, else (AUTO) the
|
|
30555
|
+
* CamStack app link `https://camstack.zentik.app` (D709). A pre-D709 hub
|
|
30556
|
+
* answered the public tunnel / mesh here, or null.
|
|
30557
|
+
*/
|
|
30558
|
+
resolved: string().nullable(),
|
|
30559
|
+
/**
|
|
30560
|
+
* The hub origin an app link carries as `hub=` (D709): the hub's best
|
|
30561
|
+
* public HTTPS address — the tunnel, then the mesh (Tailscale MagicDNS) —
|
|
30562
|
+
* picked from this cap's own palette by `pickAppLinkHub`. `null` when the
|
|
30563
|
+
* hub advertises neither; the app link is then minted without `hub=`.
|
|
30564
|
+
* Absent on a pre-D709 hub.
|
|
30565
|
+
*/
|
|
30566
|
+
appLinkHub: string().nullable()
|
|
30531
30567
|
});
|
|
30532
30568
|
/**
|
|
30533
30569
|
* The URLs the SDK / viewer should race for API access. `baseUrls` empty =
|
|
@@ -30581,7 +30617,11 @@ method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(obje
|
|
|
30581
30617
|
* Pass `'https'` when the caller is itself loaded over HTTPS
|
|
30582
30618
|
* to avoid mixed-content blocks in the browser. The public
|
|
30583
30619
|
* tunnel always emits `https://` regardless. */
|
|
30584
|
-
scheme: _enum(["http", "https"]).optional()
|
|
30620
|
+
scheme: _enum(["http", "https"]).optional(),
|
|
30621
|
+
/** Append the CamStack app link entry (`kind: 'app-link'`, D709) —
|
|
30622
|
+
* an address notification links can be flagged with, not a hub
|
|
30623
|
+
* route. Default `false`: racers and rankers never see it. */
|
|
30624
|
+
includeAppLink: boolean().optional()
|
|
30585
30625
|
}), GetConnectionEndpointsResultSchema), method(_void(), NotificationEndpointSchema), method(object({ baseUrl: string().nullable() }), NotificationEndpointSchema, { kind: "mutation" }), method(_void(), ViewerEndpointsSchema), method(object({ baseUrls: array(string()).readonly() }), ViewerEndpointsSchema, { kind: "mutation" }), method(_void(), AllowedAddressesSchema), method(AllowedAddressesSchema, object({ success: literal(true) }), { kind: "mutation" }), method(_void(), AllowedAddressesSchema, { kind: "mutation" }), method(_void(), TlsStatusSchema), method(object({ reason: string().optional() }), TlsStatusSchema, {
|
|
30586
30626
|
kind: "mutation",
|
|
30587
30627
|
auth: "admin"
|
|
@@ -30842,7 +30882,7 @@ var MeshPeerSchema = object({
|
|
|
30842
30882
|
tags: array(string()).readonly(),
|
|
30843
30883
|
/** True when the peer advertises itself as an exit-node candidate. */
|
|
30844
30884
|
exitNodeOption: boolean(),
|
|
30845
|
-
/** Subnet routes the peer advertises (e.g. `["192.168.
|
|
30885
|
+
/** Subnet routes the peer advertises (e.g. `["192.168.10.0/24"]`). */
|
|
30846
30886
|
advertisedRoutes: array(string()).readonly(),
|
|
30847
30887
|
/** Owner account login (e.g. `foo@example.com`). Null for tagged peers. */
|
|
30848
30888
|
userLogin: string().nullable(),
|
|
@@ -31847,7 +31887,13 @@ var OsdStatusSchema = object({ overlays: array(object({
|
|
|
31847
31887
|
*/
|
|
31848
31888
|
availablePositions: array(OsdPositionEnum).readonly(),
|
|
31849
31889
|
/** Firmware does not allow editing the `text` field (e.g. timestamp). */
|
|
31850
|
-
readOnly: boolean().optional()
|
|
31890
|
+
readOnly: boolean().optional(),
|
|
31891
|
+
/**
|
|
31892
|
+
* Firmware text ceiling for this overlay. Absent = no known limit.
|
|
31893
|
+
* The OSD manager truncates here on every write — never stores its own
|
|
31894
|
+
* copy on the binding.
|
|
31895
|
+
*/
|
|
31896
|
+
maxCharacters: number().int().positive().optional()
|
|
31851
31897
|
})).readonly() });
|
|
31852
31898
|
var OsdOverlayPatchSchema = object({
|
|
31853
31899
|
enabled: boolean().optional(),
|
|
@@ -31898,7 +31944,9 @@ var OsdTemplateBindingSchema = object({
|
|
|
31898
31944
|
valuePath: string().min(1).max(64),
|
|
31899
31945
|
/** Convert TO this unit at render (`tryConvertUnit`). Absent = source unit. */
|
|
31900
31946
|
displayUnit: string().max(16).optional(),
|
|
31901
|
-
maxDecimals: number().int().min(0).max(4).default(1)
|
|
31947
|
+
maxDecimals: number().int().min(0).max(4).default(1),
|
|
31948
|
+
/** Raw value → display text (same shape as slot binding). Empty string hides. */
|
|
31949
|
+
valueMap: record(string(), string()).optional()
|
|
31902
31950
|
});
|
|
31903
31951
|
/**
|
|
31904
31952
|
* A named template: bindings (alias → leaf field) + a parser that
|
|
@@ -31948,18 +31996,11 @@ var OsdSlotBindingSchema = object({
|
|
|
31948
31996
|
source: OsdSourceSchema,
|
|
31949
31997
|
/** `${value}` and `${unit}` are substituted; every occurrence. */
|
|
31950
31998
|
template: string().max(96).default("${value}"),
|
|
31951
|
-
/** Truncate with an ellipsis past this length. Absent = no limit. */
|
|
31952
|
-
maxCharacters: number().int().min(4).max(64).optional(),
|
|
31953
31999
|
/**
|
|
31954
32000
|
* Decimal places for a numeric value. `0` yields an integer — the
|
|
31955
32001
|
* documented workaround for firmwares that reject `.` in overlay text.
|
|
31956
32002
|
*/
|
|
31957
32003
|
maxDecimals: number().int().min(0).max(4).default(1),
|
|
31958
|
-
/**
|
|
31959
|
-
* Appended via `${unit}` when no unit conversion produces a label.
|
|
31960
|
-
* Prefer `source.displayUnit` for converted device-state values.
|
|
31961
|
-
*/
|
|
31962
|
-
unitLabel: string().max(8).optional(),
|
|
31963
32004
|
/** Raw value → display text, e.g. `{"true":"MOTION","false":""}`. */
|
|
31964
32005
|
valueMap: record(string(), string()).optional(),
|
|
31965
32006
|
/** Time windows in which the slot is shown. Absent = always. */
|
|
@@ -31968,9 +32009,7 @@ var OsdSlotBindingSchema = object({
|
|
|
31968
32009
|
* Display gate, in the notification centre's condition vocabulary.
|
|
31969
32010
|
* Only the keys reported by `getConditionSupport` are accepted.
|
|
31970
32011
|
*/
|
|
31971
|
-
conditions: NcConditionsSchema.optional()
|
|
31972
|
-
/** Rendered when the gate is closed or the value unreadable. Empty = hide. */
|
|
31973
|
-
fallbackText: string().max(64).default("")
|
|
32012
|
+
conditions: NcConditionsSchema.optional()
|
|
31974
32013
|
});
|
|
31975
32014
|
/** One camera slot, as the operator sees it: firmware truth + our binding. */
|
|
31976
32015
|
var OsdSlotViewSchema = object({
|
|
@@ -47647,12 +47686,14 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
|
|
|
47647
47686
|
{
|
|
47648
47687
|
id: "addons",
|
|
47649
47688
|
family: "system",
|
|
47650
|
-
label: "Addons",
|
|
47651
|
-
kinds: [
|
|
47652
|
-
|
|
47653
|
-
|
|
47654
|
-
|
|
47655
|
-
|
|
47689
|
+
label: "Addons stopped",
|
|
47690
|
+
kinds: ["addon-crash-loop"]
|
|
47691
|
+
},
|
|
47692
|
+
{
|
|
47693
|
+
id: "addon-updates",
|
|
47694
|
+
family: "system",
|
|
47695
|
+
label: "Addon updates",
|
|
47696
|
+
kinds: ["addon-update-available", "addon-updated"]
|
|
47656
47697
|
},
|
|
47657
47698
|
{
|
|
47658
47699
|
id: "updates",
|
|
@@ -47812,13 +47853,15 @@ var STATE_SUMMARY_SECTION_VARS = [
|
|
|
47812
47853
|
},
|
|
47813
47854
|
{
|
|
47814
47855
|
name: "summaryAddons",
|
|
47815
|
-
label: "Summary: addons",
|
|
47816
|
-
example: "
|
|
47817
|
-
kinds: [
|
|
47818
|
-
|
|
47819
|
-
|
|
47820
|
-
|
|
47821
|
-
|
|
47856
|
+
label: "Summary: addons stopped",
|
|
47857
|
+
example: "hub — recorder stopped after repeated crashes",
|
|
47858
|
+
kinds: ["addon-crash-loop"]
|
|
47859
|
+
},
|
|
47860
|
+
{
|
|
47861
|
+
name: "summaryAddonUpdates",
|
|
47862
|
+
label: "Summary: addon updates",
|
|
47863
|
+
example: "hub:\n• @camstack/addon-recorder 1.2.3 → 1.2.4",
|
|
47864
|
+
kinds: ["addon-update-available", "addon-updated"]
|
|
47822
47865
|
},
|
|
47823
47866
|
{
|
|
47824
47867
|
name: "summaryUpdates",
|
|
@@ -47902,6 +47945,7 @@ var STATE_SUMMARY_VARS = [
|
|
|
47902
47945
|
[...RULE_BODY_ONLY],
|
|
47903
47946
|
[...RULE_TEXT],
|
|
47904
47947
|
([...RULE_TEXT], [...DEVICE_EVENTS]),
|
|
47948
|
+
([...RULE_TEXT], [...COMBINED_ALARM]),
|
|
47905
47949
|
([...RULE_TEXT], [...DEVICE_EVENTS]),
|
|
47906
47950
|
([...RULE_TEXT], [...BATTERY, ...CONSUMABLE]),
|
|
47907
47951
|
([...RULE_TEXT], [...CONSUMABLE]),
|
|
@@ -47942,6 +47986,8 @@ var STATE_SUMMARY_VARS = [
|
|
|
47942
47986
|
[...RULE_TEXT],
|
|
47943
47987
|
[...RULE_TEXT],
|
|
47944
47988
|
[...RULE_TEXT],
|
|
47989
|
+
[...RULE_TEXT],
|
|
47990
|
+
[...RULE_TEXT],
|
|
47945
47991
|
...STATE_SUMMARY_VARS
|
|
47946
47992
|
];
|
|
47947
47993
|
new Set([
|
|
@@ -10553,11 +10553,11 @@ var ModelVariantGroupSchema = object({
|
|
|
10553
10553
|
/** Quantization axis. Omit ⇒ the fp32 base build. */
|
|
10554
10554
|
precision: _enum(["fp32", "int8"]).optional(),
|
|
10555
10555
|
/**
|
|
10556
|
-
*
|
|
10557
|
-
*
|
|
10558
|
-
*
|
|
10556
|
+
* Training / latency-variant axis. Omit ⇒ the standard build. `test` marks
|
|
10557
|
+
* an alternate training of the same family (Scrypted `relu_test`); chip
|
|
10558
|
+
* label is "Test".
|
|
10559
10559
|
*/
|
|
10560
|
-
optimization: _enum(["standard", "
|
|
10560
|
+
optimization: _enum(["standard", "test"]).optional(),
|
|
10561
10561
|
/**
|
|
10562
10562
|
* Input-resolution axis (square input side, px). Omit ⇒ the family's native
|
|
10563
10563
|
* resolution (640 for yolo26). Reduced-input builds (320 / 256) are a big,
|
|
@@ -10580,9 +10580,10 @@ var ModelProviderIdSchema = _enum([
|
|
|
10580
10580
|
* are per upstream. A persisted custom-model row written when this field was a
|
|
10581
10581
|
* string still parses — the string is lifted into `{ weights }`.
|
|
10582
10582
|
*
|
|
10583
|
-
* Every licence surface (the
|
|
10584
|
-
*
|
|
10585
|
-
*
|
|
10583
|
+
* Every machine licence surface (`THIRD_PARTY_MODELS.md`, the Hugging Face
|
|
10584
|
+
* model table) is GENERATED from these records by
|
|
10585
|
+
* `scripts/gen-model-licenses.ts` (D661). Operator-facing docs live in
|
|
10586
|
+
* `camstack/docs` → `/docs/detection/models`.
|
|
10586
10587
|
*/
|
|
10587
10588
|
var ModelLicenseSchema = preprocess((value) => typeof value === "string" ? { weights: value } : value, object({
|
|
10588
10589
|
/** SPDX id of the WEIGHTS' terms, a `LicenseRef-*` for non-SPDX terms, or `UNKNOWN`. */
|
|
@@ -14111,7 +14112,7 @@ DeviceType.Camera;
|
|
|
14111
14112
|
* This matters here more than anywhere else in the repo, because every provider
|
|
14112
14113
|
* that knows a device's host knows its PASSWORD too: `{ host, port, username,
|
|
14113
14114
|
* password }` sit in one object on Hikvision, Amcrest, Reolink and ONVIF alike,
|
|
14114
|
-
* and `http://admin:hunter2@192.168.
|
|
14115
|
+
* and `http://admin:hunter2@192.168.60.139/` is a URL a browser accepts. The
|
|
14115
14116
|
* camera's own page will ask for its own login. That is correct, and pre-
|
|
14116
14117
|
* filling it is the operator's business, not ours.
|
|
14117
14118
|
*
|
|
@@ -17095,7 +17096,7 @@ method(object({
|
|
|
17095
17096
|
timeoutMs: 6e5
|
|
17096
17097
|
});
|
|
17097
17098
|
method(object({
|
|
17098
|
-
|
|
17099
|
+
targetNodeId: string(),
|
|
17099
17100
|
modelId: string(),
|
|
17100
17101
|
format: _enum(MODEL_FORMATS),
|
|
17101
17102
|
entry: ModelCatalogEntrySchema
|
|
@@ -19578,8 +19579,9 @@ var NcRuleSchema = NcRuleInputSchema.extend({
|
|
|
19578
19579
|
disabledTargetIds: array(string()).default([])
|
|
19579
19580
|
});
|
|
19580
19581
|
/**
|
|
19581
|
-
* The state-summary SECTIONS (D647 / D698): the D637 kind groups that
|
|
19582
|
-
* still-true state. `
|
|
19582
|
+
* The state-summary SECTIONS (D647 / D698 / D708): the D637 kind groups that
|
|
19583
|
+
* report a still-true state. `addons` is the crash-looped addons only and
|
|
19584
|
+
* `addon-updates` the addons that are behind (D708 split them). `backups-exports` and `alarm` are not sections — a completed
|
|
19583
19585
|
* job is not an open state, and the alarm stays instant.
|
|
19584
19586
|
*/
|
|
19585
19587
|
var NcStateSummarySectionIdSchema = _enum([
|
|
@@ -19591,6 +19593,7 @@ var NcStateSummarySectionIdSchema = _enum([
|
|
|
19591
19593
|
"detection-blind",
|
|
19592
19594
|
"nodes",
|
|
19593
19595
|
"addons",
|
|
19596
|
+
"addon-updates",
|
|
19594
19597
|
"updates"
|
|
19595
19598
|
]);
|
|
19596
19599
|
/** One section of a previewed state summary. `unavailable` = its state could not be read. */
|
|
@@ -20071,7 +20074,19 @@ var NcAlarmModeDelaysListSchema = array(object({
|
|
|
20071
20074
|
* When this mode may be armed. Absent / null = always allowed (same as a
|
|
20072
20075
|
* rule with no `schedule`). Evaluated with {@link isScheduleActive}.
|
|
20073
20076
|
*/
|
|
20074
|
-
schedule: NcScheduleSchema.optional()
|
|
20077
|
+
schedule: NcScheduleSchema.optional(),
|
|
20078
|
+
/**
|
|
20079
|
+
* D706: while this mode's ENTRY DELAY runs, do the alarm rules' own pushes go out (as an
|
|
20080
|
+
* intrusion naming the locations)? Absent = false — the entry-delay notification is the
|
|
20081
|
+
* only one, and the matches ride the triggered notification's mosaic (D705).
|
|
20082
|
+
*/
|
|
20083
|
+
notifyDuringEntryDelay: boolean().optional(),
|
|
20084
|
+
/**
|
|
20085
|
+
* D706: notify "watched again" when a sensor this arm bypassed closes and opens again.
|
|
20086
|
+
* Absent = false (logged, not sent). Even when true it is not sent when that same sensor
|
|
20087
|
+
* is the one that starts the entry delay — the entry-delay notification already names it.
|
|
20088
|
+
*/
|
|
20089
|
+
notifySensorRewatched: boolean().optional()
|
|
20075
20090
|
})).max(8).refine(uniqueModes, { message: "modeDelays: at most one entry per arm mode" });
|
|
20076
20091
|
var NcAlarmModeDelaysEditListSchema = array(object({
|
|
20077
20092
|
mode: AlarmArmModeSchema,
|
|
@@ -20080,7 +20095,11 @@ var NcAlarmModeDelaysEditListSchema = array(object({
|
|
|
20080
20095
|
triggeredDurationSec: NcAlarmTriggeredSecSchema.nullable().optional(),
|
|
20081
20096
|
postTriggeredAction: NcAlarmPostTriggeredActionSchema.nullable().optional(),
|
|
20082
20097
|
/** Set a schedule, or `null` to clear (mode always allowed again). */
|
|
20083
|
-
schedule: NcScheduleSchema.nullable().optional()
|
|
20098
|
+
schedule: NcScheduleSchema.nullable().optional(),
|
|
20099
|
+
/** D706: set the switch, or `null` to clear it (back to the default, false). */
|
|
20100
|
+
notifyDuringEntryDelay: boolean().nullable().optional(),
|
|
20101
|
+
/** D706: set the switch, or `null` to clear it (back to the default, false). */
|
|
20102
|
+
notifySensorRewatched: boolean().nullable().optional()
|
|
20084
20103
|
})).max(8).refine(uniqueModes, { message: "modeDelays: at most one edit per arm mode" });
|
|
20085
20104
|
/** One switch of the alarm table: put ONE device on, or take it off, ONE mode's list. */
|
|
20086
20105
|
var NcAlarmNonBlockingEditSchema = object({
|
|
@@ -21041,39 +21060,19 @@ Object.freeze(Object.fromEntries([{
|
|
|
21041
21060
|
label: "Face recognition model",
|
|
21042
21061
|
defaultModelId: "auraface-r100",
|
|
21043
21062
|
indexName: "the enrolled face gallery",
|
|
21044
|
-
options: [
|
|
21045
|
-
|
|
21046
|
-
|
|
21047
|
-
|
|
21048
|
-
},
|
|
21049
|
-
{
|
|
21050
|
-
id: "arcface-r100",
|
|
21051
|
-
label: "ArcFace (ResNet34)"
|
|
21052
|
-
},
|
|
21053
|
-
{
|
|
21054
|
-
id: "inception-resnet-v1",
|
|
21055
|
-
label: "Inception ResNet V1"
|
|
21056
|
-
}
|
|
21057
|
-
]
|
|
21063
|
+
options: [{
|
|
21064
|
+
id: "auraface-r100",
|
|
21065
|
+
label: "AuraFace R100"
|
|
21066
|
+
}]
|
|
21058
21067
|
}, {
|
|
21059
21068
|
stepId: "clip-embedding",
|
|
21060
21069
|
label: "Semantic search model",
|
|
21061
|
-
defaultModelId: "
|
|
21070
|
+
defaultModelId: "siglip2-b16-224",
|
|
21062
21071
|
indexName: "the object semantic-search index",
|
|
21063
|
-
options: [
|
|
21064
|
-
|
|
21065
|
-
|
|
21066
|
-
|
|
21067
|
-
},
|
|
21068
|
-
{
|
|
21069
|
-
id: "mobileclip-s2",
|
|
21070
|
-
label: "MobileCLIP S2"
|
|
21071
|
-
},
|
|
21072
|
-
{
|
|
21073
|
-
id: "siglip2-b16-224",
|
|
21074
|
-
label: "SigLIP2 B/16 (Apache-2.0)"
|
|
21075
|
-
}
|
|
21076
|
-
]
|
|
21072
|
+
options: [{
|
|
21073
|
+
id: "siglip2-b16-224",
|
|
21074
|
+
label: "SigLIP2 B/16 (Apache-2.0)"
|
|
21075
|
+
}]
|
|
21077
21076
|
}].map((s) => [s.stepId, s.defaultModelId])));
|
|
21078
21077
|
var CLUSTER_STEP_SETTING_FIELDS = [{
|
|
21079
21078
|
stepId: "face-embedding",
|
|
@@ -23921,6 +23920,22 @@ var MotionSourceEnum = _enum([
|
|
|
23921
23920
|
"device-activity"
|
|
23922
23921
|
]);
|
|
23923
23922
|
/**
|
|
23923
|
+
* What opened an on-motion detection SESSION: the motion source that passed the
|
|
23924
|
+
* camera's `motionSources` gate, and what raised it (the camera itself, or a
|
|
23925
|
+
* sensor the operator attached — D672). `sensorName` is the attached sensor's
|
|
23926
|
+
* device name as the orchestrator's camera-sensors resolution last read it;
|
|
23927
|
+
* absent when unknown or when the camera itself triggered.
|
|
23928
|
+
*
|
|
23929
|
+
* Carried on the session attach ONLY so the runner's `DetectionPhaseTransition`
|
|
23930
|
+
* can say what started the session (D672 rule 11, amended 2026-10-06). The
|
|
23931
|
+
* runner never decides anything on it.
|
|
23932
|
+
*/
|
|
23933
|
+
var SessionTriggerSchema = object({
|
|
23934
|
+
source: MotionSourceEnum,
|
|
23935
|
+
triggeredBy: MotionTriggeredBySchema,
|
|
23936
|
+
sensorName: string().optional()
|
|
23937
|
+
});
|
|
23938
|
+
/**
|
|
23924
23939
|
* List of motion sources active on a camera. Empty array is valid:
|
|
23925
23940
|
* "no source" — happens for battery cams without firmware motion when
|
|
23926
23941
|
* the operator hasn't opted into the SW analyzer (would hold the
|
|
@@ -24172,6 +24187,14 @@ var RunnerCameraConfigSchema = object({
|
|
|
24172
24187
|
*/
|
|
24173
24188
|
motionSources: MotionSourcesSchema.default(["analyzer"]),
|
|
24174
24189
|
/**
|
|
24190
|
+
* What opened this attach, on a SESSION attach only (see
|
|
24191
|
+
* {@link SessionTriggerSchema}). OPTIONAL with no default: absent on a
|
|
24192
|
+
* standing attach, an occupancy burst, a re-dispatch with no motion event
|
|
24193
|
+
* behind it, and every attach from an orchestrator older than the field — the
|
|
24194
|
+
* runner then names no source on the phase event.
|
|
24195
|
+
*/
|
|
24196
|
+
sessionTrigger: SessionTriggerSchema.optional(),
|
|
24197
|
+
/**
|
|
24175
24198
|
* WHICH root detector runs for this camera. The detection counterpart of
|
|
24176
24199
|
* {@link motionSources}, same shape and same discipline: a per-camera list
|
|
24177
24200
|
* of sources the system understands, vendor-agnostic, owned here.
|
|
@@ -30395,7 +30418,7 @@ var LocalInterfaceSchema = object({
|
|
|
30395
30418
|
name: string(),
|
|
30396
30419
|
family: _enum(["IPv4", "IPv6"]),
|
|
30397
30420
|
address: string(),
|
|
30398
|
-
/** CIDR shorthand (e.g. `192.168.
|
|
30421
|
+
/** CIDR shorthand (e.g. `192.168.10.10/24`). Empty when OS doesn't expose. */
|
|
30399
30422
|
cidr: string(),
|
|
30400
30423
|
/** OS netmask. Stable across calls so the SDK can hash on it. */
|
|
30401
30424
|
netmask: string(),
|
|
@@ -30449,7 +30472,8 @@ var ConnectionEndpointSchema = object({
|
|
|
30449
30472
|
"lan-ipv4",
|
|
30450
30473
|
"lan-ipv6",
|
|
30451
30474
|
"public",
|
|
30452
|
-
"loopback"
|
|
30475
|
+
"loopback",
|
|
30476
|
+
"app-link"
|
|
30453
30477
|
]),
|
|
30454
30478
|
/**
|
|
30455
30479
|
* Originating-interface kind — `lan`/`wifi`/`docker`/`vpn`/`other`/
|
|
@@ -30518,15 +30542,27 @@ var GetConnectionEndpointsResultSchema = object({
|
|
|
30518
30542
|
localPort: AdvertisedLocalPortSchema
|
|
30519
30543
|
});
|
|
30520
30544
|
/**
|
|
30521
|
-
* The
|
|
30522
|
-
*
|
|
30523
|
-
*
|
|
30545
|
+
* The address flagged for notification links. `baseUrl: null` = AUTO, which
|
|
30546
|
+
* since D709 is the CamStack app link; `resolved` reports the effective value,
|
|
30547
|
+
* so the UI can show it either way.
|
|
30524
30548
|
*/
|
|
30525
30549
|
var NotificationEndpointSchema = object({
|
|
30526
30550
|
/** The operator's explicit choice, or null for AUTO. */
|
|
30527
30551
|
baseUrl: string().nullable(),
|
|
30528
|
-
/**
|
|
30529
|
-
|
|
30552
|
+
/**
|
|
30553
|
+
* The effective flagged address: the explicit choice, else (AUTO) the
|
|
30554
|
+
* CamStack app link `https://camstack.zentik.app` (D709). A pre-D709 hub
|
|
30555
|
+
* answered the public tunnel / mesh here, or null.
|
|
30556
|
+
*/
|
|
30557
|
+
resolved: string().nullable(),
|
|
30558
|
+
/**
|
|
30559
|
+
* The hub origin an app link carries as `hub=` (D709): the hub's best
|
|
30560
|
+
* public HTTPS address — the tunnel, then the mesh (Tailscale MagicDNS) —
|
|
30561
|
+
* picked from this cap's own palette by `pickAppLinkHub`. `null` when the
|
|
30562
|
+
* hub advertises neither; the app link is then minted without `hub=`.
|
|
30563
|
+
* Absent on a pre-D709 hub.
|
|
30564
|
+
*/
|
|
30565
|
+
appLinkHub: string().nullable()
|
|
30530
30566
|
});
|
|
30531
30567
|
/**
|
|
30532
30568
|
* The URLs the SDK / viewer should race for API access. `baseUrls` empty =
|
|
@@ -30580,7 +30616,11 @@ method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(obje
|
|
|
30580
30616
|
* Pass `'https'` when the caller is itself loaded over HTTPS
|
|
30581
30617
|
* to avoid mixed-content blocks in the browser. The public
|
|
30582
30618
|
* tunnel always emits `https://` regardless. */
|
|
30583
|
-
scheme: _enum(["http", "https"]).optional()
|
|
30619
|
+
scheme: _enum(["http", "https"]).optional(),
|
|
30620
|
+
/** Append the CamStack app link entry (`kind: 'app-link'`, D709) —
|
|
30621
|
+
* an address notification links can be flagged with, not a hub
|
|
30622
|
+
* route. Default `false`: racers and rankers never see it. */
|
|
30623
|
+
includeAppLink: boolean().optional()
|
|
30584
30624
|
}), GetConnectionEndpointsResultSchema), method(_void(), NotificationEndpointSchema), method(object({ baseUrl: string().nullable() }), NotificationEndpointSchema, { kind: "mutation" }), method(_void(), ViewerEndpointsSchema), method(object({ baseUrls: array(string()).readonly() }), ViewerEndpointsSchema, { kind: "mutation" }), method(_void(), AllowedAddressesSchema), method(AllowedAddressesSchema, object({ success: literal(true) }), { kind: "mutation" }), method(_void(), AllowedAddressesSchema, { kind: "mutation" }), method(_void(), TlsStatusSchema), method(object({ reason: string().optional() }), TlsStatusSchema, {
|
|
30585
30625
|
kind: "mutation",
|
|
30586
30626
|
auth: "admin"
|
|
@@ -30841,7 +30881,7 @@ var MeshPeerSchema = object({
|
|
|
30841
30881
|
tags: array(string()).readonly(),
|
|
30842
30882
|
/** True when the peer advertises itself as an exit-node candidate. */
|
|
30843
30883
|
exitNodeOption: boolean(),
|
|
30844
|
-
/** Subnet routes the peer advertises (e.g. `["192.168.
|
|
30884
|
+
/** Subnet routes the peer advertises (e.g. `["192.168.10.0/24"]`). */
|
|
30845
30885
|
advertisedRoutes: array(string()).readonly(),
|
|
30846
30886
|
/** Owner account login (e.g. `foo@example.com`). Null for tagged peers. */
|
|
30847
30887
|
userLogin: string().nullable(),
|
|
@@ -31846,7 +31886,13 @@ var OsdStatusSchema = object({ overlays: array(object({
|
|
|
31846
31886
|
*/
|
|
31847
31887
|
availablePositions: array(OsdPositionEnum).readonly(),
|
|
31848
31888
|
/** Firmware does not allow editing the `text` field (e.g. timestamp). */
|
|
31849
|
-
readOnly: boolean().optional()
|
|
31889
|
+
readOnly: boolean().optional(),
|
|
31890
|
+
/**
|
|
31891
|
+
* Firmware text ceiling for this overlay. Absent = no known limit.
|
|
31892
|
+
* The OSD manager truncates here on every write — never stores its own
|
|
31893
|
+
* copy on the binding.
|
|
31894
|
+
*/
|
|
31895
|
+
maxCharacters: number().int().positive().optional()
|
|
31850
31896
|
})).readonly() });
|
|
31851
31897
|
var OsdOverlayPatchSchema = object({
|
|
31852
31898
|
enabled: boolean().optional(),
|
|
@@ -31897,7 +31943,9 @@ var OsdTemplateBindingSchema = object({
|
|
|
31897
31943
|
valuePath: string().min(1).max(64),
|
|
31898
31944
|
/** Convert TO this unit at render (`tryConvertUnit`). Absent = source unit. */
|
|
31899
31945
|
displayUnit: string().max(16).optional(),
|
|
31900
|
-
maxDecimals: number().int().min(0).max(4).default(1)
|
|
31946
|
+
maxDecimals: number().int().min(0).max(4).default(1),
|
|
31947
|
+
/** Raw value → display text (same shape as slot binding). Empty string hides. */
|
|
31948
|
+
valueMap: record(string(), string()).optional()
|
|
31901
31949
|
});
|
|
31902
31950
|
/**
|
|
31903
31951
|
* A named template: bindings (alias → leaf field) + a parser that
|
|
@@ -31947,18 +31995,11 @@ var OsdSlotBindingSchema = object({
|
|
|
31947
31995
|
source: OsdSourceSchema,
|
|
31948
31996
|
/** `${value}` and `${unit}` are substituted; every occurrence. */
|
|
31949
31997
|
template: string().max(96).default("${value}"),
|
|
31950
|
-
/** Truncate with an ellipsis past this length. Absent = no limit. */
|
|
31951
|
-
maxCharacters: number().int().min(4).max(64).optional(),
|
|
31952
31998
|
/**
|
|
31953
31999
|
* Decimal places for a numeric value. `0` yields an integer — the
|
|
31954
32000
|
* documented workaround for firmwares that reject `.` in overlay text.
|
|
31955
32001
|
*/
|
|
31956
32002
|
maxDecimals: number().int().min(0).max(4).default(1),
|
|
31957
|
-
/**
|
|
31958
|
-
* Appended via `${unit}` when no unit conversion produces a label.
|
|
31959
|
-
* Prefer `source.displayUnit` for converted device-state values.
|
|
31960
|
-
*/
|
|
31961
|
-
unitLabel: string().max(8).optional(),
|
|
31962
32003
|
/** Raw value → display text, e.g. `{"true":"MOTION","false":""}`. */
|
|
31963
32004
|
valueMap: record(string(), string()).optional(),
|
|
31964
32005
|
/** Time windows in which the slot is shown. Absent = always. */
|
|
@@ -31967,9 +32008,7 @@ var OsdSlotBindingSchema = object({
|
|
|
31967
32008
|
* Display gate, in the notification centre's condition vocabulary.
|
|
31968
32009
|
* Only the keys reported by `getConditionSupport` are accepted.
|
|
31969
32010
|
*/
|
|
31970
|
-
conditions: NcConditionsSchema.optional()
|
|
31971
|
-
/** Rendered when the gate is closed or the value unreadable. Empty = hide. */
|
|
31972
|
-
fallbackText: string().max(64).default("")
|
|
32011
|
+
conditions: NcConditionsSchema.optional()
|
|
31973
32012
|
});
|
|
31974
32013
|
/** One camera slot, as the operator sees it: firmware truth + our binding. */
|
|
31975
32014
|
var OsdSlotViewSchema = object({
|
|
@@ -47646,12 +47685,14 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
|
|
|
47646
47685
|
{
|
|
47647
47686
|
id: "addons",
|
|
47648
47687
|
family: "system",
|
|
47649
|
-
label: "Addons",
|
|
47650
|
-
kinds: [
|
|
47651
|
-
|
|
47652
|
-
|
|
47653
|
-
|
|
47654
|
-
|
|
47688
|
+
label: "Addons stopped",
|
|
47689
|
+
kinds: ["addon-crash-loop"]
|
|
47690
|
+
},
|
|
47691
|
+
{
|
|
47692
|
+
id: "addon-updates",
|
|
47693
|
+
family: "system",
|
|
47694
|
+
label: "Addon updates",
|
|
47695
|
+
kinds: ["addon-update-available", "addon-updated"]
|
|
47655
47696
|
},
|
|
47656
47697
|
{
|
|
47657
47698
|
id: "updates",
|
|
@@ -47811,13 +47852,15 @@ var STATE_SUMMARY_SECTION_VARS = [
|
|
|
47811
47852
|
},
|
|
47812
47853
|
{
|
|
47813
47854
|
name: "summaryAddons",
|
|
47814
|
-
label: "Summary: addons",
|
|
47815
|
-
example: "
|
|
47816
|
-
kinds: [
|
|
47817
|
-
|
|
47818
|
-
|
|
47819
|
-
|
|
47820
|
-
|
|
47855
|
+
label: "Summary: addons stopped",
|
|
47856
|
+
example: "hub — recorder stopped after repeated crashes",
|
|
47857
|
+
kinds: ["addon-crash-loop"]
|
|
47858
|
+
},
|
|
47859
|
+
{
|
|
47860
|
+
name: "summaryAddonUpdates",
|
|
47861
|
+
label: "Summary: addon updates",
|
|
47862
|
+
example: "hub:\n• @camstack/addon-recorder 1.2.3 → 1.2.4",
|
|
47863
|
+
kinds: ["addon-update-available", "addon-updated"]
|
|
47821
47864
|
},
|
|
47822
47865
|
{
|
|
47823
47866
|
name: "summaryUpdates",
|
|
@@ -47901,6 +47944,7 @@ var STATE_SUMMARY_VARS = [
|
|
|
47901
47944
|
[...RULE_BODY_ONLY],
|
|
47902
47945
|
[...RULE_TEXT],
|
|
47903
47946
|
([...RULE_TEXT], [...DEVICE_EVENTS]),
|
|
47947
|
+
([...RULE_TEXT], [...COMBINED_ALARM]),
|
|
47904
47948
|
([...RULE_TEXT], [...DEVICE_EVENTS]),
|
|
47905
47949
|
([...RULE_TEXT], [...BATTERY, ...CONSUMABLE]),
|
|
47906
47950
|
([...RULE_TEXT], [...CONSUMABLE]),
|
|
@@ -47941,6 +47985,8 @@ var STATE_SUMMARY_VARS = [
|
|
|
47941
47985
|
[...RULE_TEXT],
|
|
47942
47986
|
[...RULE_TEXT],
|
|
47943
47987
|
[...RULE_TEXT],
|
|
47988
|
+
[...RULE_TEXT],
|
|
47989
|
+
[...RULE_TEXT],
|
|
47944
47990
|
...STATE_SUMMARY_VARS
|
|
47945
47991
|
];
|
|
47946
47992
|
new Set([
|
|
@@ -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-
|
|
5
|
+
const require_dist = require("../dist-B5khvoZj.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-
|
|
1
|
+
import { a as EventCategory, i as BaseAddon, n as networkAccessCapability } from "../dist-CnsQ7vyF.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.
|
|
3
|
+
"version": "1.2.118",
|
|
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",
|