@camstack/addon-provider-hikvision 1.2.141 → 1.2.142

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/addon.js CHANGED
@@ -14532,7 +14532,7 @@ DeviceType.Camera;
14532
14532
  * This matters here more than anywhere else in the repo, because every provider
14533
14533
  * that knows a device's host knows its PASSWORD too: `{ host, port, username,
14534
14534
  * password }` sit in one object on Hikvision, Amcrest, Reolink and ONVIF alike,
14535
- * and `http://admin:hunter2@192.168.x.x/` is a URL a browser accepts. The
14535
+ * and `http://admin:hunter2@192.168.60.139/` is a URL a browser accepts. The
14536
14536
  * camera's own page will ask for its own login. That is correct, and pre-
14537
14537
  * filling it is the operator's business, not ours.
14538
14538
  *
@@ -20340,8 +20340,9 @@ var NcRuleSchema = NcRuleInputSchema.extend({
20340
20340
  disabledTargetIds: array(string()).default([])
20341
20341
  });
20342
20342
  /**
20343
- * The state-summary SECTIONS (D647 / D698): the D637 kind groups that report a
20344
- * still-true state. `backups-exports` and `alarm` are not sections — a completed
20343
+ * The state-summary SECTIONS (D647 / D698 / D708): the D637 kind groups that
20344
+ * report a still-true state. `addons` is the crash-looped addons only and
20345
+ * `addon-updates` the addons that are behind (D708 split them). `backups-exports` and `alarm` are not sections — a completed
20345
20346
  * job is not an open state, and the alarm stays instant.
20346
20347
  */
20347
20348
  var NcStateSummarySectionIdSchema = _enum([
@@ -20353,6 +20354,7 @@ var NcStateSummarySectionIdSchema = _enum([
20353
20354
  "detection-blind",
20354
20355
  "nodes",
20355
20356
  "addons",
20357
+ "addon-updates",
20356
20358
  "updates"
20357
20359
  ]);
20358
20360
  /** One section of a previewed state summary. `unavailable` = its state could not be read. */
@@ -20833,7 +20835,19 @@ var NcAlarmModeDelaysListSchema = array(object({
20833
20835
  * When this mode may be armed. Absent / null = always allowed (same as a
20834
20836
  * rule with no `schedule`). Evaluated with {@link isScheduleActive}.
20835
20837
  */
20836
- schedule: NcScheduleSchema.optional()
20838
+ schedule: NcScheduleSchema.optional(),
20839
+ /**
20840
+ * D706: while this mode's ENTRY DELAY runs, do the alarm rules' own pushes go out (as an
20841
+ * intrusion naming the locations)? Absent = false — the entry-delay notification is the
20842
+ * only one, and the matches ride the triggered notification's mosaic (D705).
20843
+ */
20844
+ notifyDuringEntryDelay: boolean().optional(),
20845
+ /**
20846
+ * D706: notify "watched again" when a sensor this arm bypassed closes and opens again.
20847
+ * Absent = false (logged, not sent). Even when true it is not sent when that same sensor
20848
+ * is the one that starts the entry delay — the entry-delay notification already names it.
20849
+ */
20850
+ notifySensorRewatched: boolean().optional()
20837
20851
  })).max(8).refine(uniqueModes, { message: "modeDelays: at most one entry per arm mode" });
20838
20852
  var NcAlarmModeDelaysEditListSchema = array(object({
20839
20853
  mode: AlarmArmModeSchema,
@@ -20842,7 +20856,11 @@ var NcAlarmModeDelaysEditListSchema = array(object({
20842
20856
  triggeredDurationSec: NcAlarmTriggeredSecSchema.nullable().optional(),
20843
20857
  postTriggeredAction: NcAlarmPostTriggeredActionSchema.nullable().optional(),
20844
20858
  /** Set a schedule, or `null` to clear (mode always allowed again). */
20845
- schedule: NcScheduleSchema.nullable().optional()
20859
+ schedule: NcScheduleSchema.nullable().optional(),
20860
+ /** D706: set the switch, or `null` to clear it (back to the default, false). */
20861
+ notifyDuringEntryDelay: boolean().nullable().optional(),
20862
+ /** D706: set the switch, or `null` to clear it (back to the default, false). */
20863
+ notifySensorRewatched: boolean().nullable().optional()
20846
20864
  })).max(8).refine(uniqueModes, { message: "modeDelays: at most one edit per arm mode" });
20847
20865
  /** One switch of the alarm table: put ONE device on, or take it off, ONE mode's list. */
20848
20866
  var NcAlarmNonBlockingEditSchema = object({
@@ -24703,6 +24721,22 @@ var MotionSourceEnum = _enum([
24703
24721
  "device-activity"
24704
24722
  ]);
24705
24723
  /**
24724
+ * What opened an on-motion detection SESSION: the motion source that passed the
24725
+ * camera's `motionSources` gate, and what raised it (the camera itself, or a
24726
+ * sensor the operator attached — D672). `sensorName` is the attached sensor's
24727
+ * device name as the orchestrator's camera-sensors resolution last read it;
24728
+ * absent when unknown or when the camera itself triggered.
24729
+ *
24730
+ * Carried on the session attach ONLY so the runner's `DetectionPhaseTransition`
24731
+ * can say what started the session (D672 rule 11, amended 2026-10-06). The
24732
+ * runner never decides anything on it.
24733
+ */
24734
+ var SessionTriggerSchema = object({
24735
+ source: MotionSourceEnum,
24736
+ triggeredBy: MotionTriggeredBySchema,
24737
+ sensorName: string().optional()
24738
+ });
24739
+ /**
24706
24740
  * List of motion sources active on a camera. Empty array is valid:
24707
24741
  * "no source" — happens for battery cams without firmware motion when
24708
24742
  * the operator hasn't opted into the SW analyzer (would hold the
@@ -24954,6 +24988,14 @@ var RunnerCameraConfigSchema = object({
24954
24988
  */
24955
24989
  motionSources: MotionSourcesSchema.default(["analyzer"]),
24956
24990
  /**
24991
+ * What opened this attach, on a SESSION attach only (see
24992
+ * {@link SessionTriggerSchema}). OPTIONAL with no default: absent on a
24993
+ * standing attach, an occupancy burst, a re-dispatch with no motion event
24994
+ * behind it, and every attach from an orchestrator older than the field — the
24995
+ * runner then names no source on the phase event.
24996
+ */
24997
+ sessionTrigger: SessionTriggerSchema.optional(),
24998
+ /**
24957
24999
  * WHICH root detector runs for this camera. The detection counterpart of
24958
25000
  * {@link motionSources}, same shape and same discipline: a per-camera list
24959
25001
  * of sources the system understands, vendor-agnostic, owned here.
@@ -32864,7 +32906,7 @@ var LocalInterfaceSchema = object({
32864
32906
  name: string(),
32865
32907
  family: _enum(["IPv4", "IPv6"]),
32866
32908
  address: string(),
32867
- /** CIDR shorthand (e.g. `192.168.x.x/24`). Empty when OS doesn't expose. */
32909
+ /** CIDR shorthand (e.g. `192.168.10.10/24`). Empty when OS doesn't expose. */
32868
32910
  cidr: string(),
32869
32911
  /** OS netmask. Stable across calls so the SDK can hash on it. */
32870
32912
  netmask: string(),
@@ -32918,7 +32960,8 @@ var ConnectionEndpointSchema = object({
32918
32960
  "lan-ipv4",
32919
32961
  "lan-ipv6",
32920
32962
  "public",
32921
- "loopback"
32963
+ "loopback",
32964
+ "app-link"
32922
32965
  ]),
32923
32966
  /**
32924
32967
  * Originating-interface kind — `lan`/`wifi`/`docker`/`vpn`/`other`/
@@ -32987,15 +33030,27 @@ var GetConnectionEndpointsResultSchema = object({
32987
33030
  localPort: AdvertisedLocalPortSchema
32988
33031
  });
32989
33032
  /**
32990
- * The chosen outbound endpoint for notification artifacts. `baseUrl: null` =
32991
- * AUTO (resolved from the candidate ranking at send time); `resolved` reports
32992
- * what AUTO currently picks, so the UI can show the effective value either way.
33033
+ * The address flagged for notification links. `baseUrl: null` = AUTO, which
33034
+ * since D709 is the CamStack app link; `resolved` reports the effective value,
33035
+ * so the UI can show it either way.
32993
33036
  */
32994
33037
  var NotificationEndpointSchema = object({
32995
33038
  /** The operator's explicit choice, or null for AUTO. */
32996
33039
  baseUrl: string().nullable(),
32997
- /** What the ranking currently resolves to (null when nothing is reachable). */
32998
- resolved: string().nullable()
33040
+ /**
33041
+ * The effective flagged address: the explicit choice, else (AUTO) the
33042
+ * CamStack app link `https://camstack.zentik.app` (D709). A pre-D709 hub
33043
+ * answered the public tunnel / mesh here, or null.
33044
+ */
33045
+ resolved: string().nullable(),
33046
+ /**
33047
+ * The hub origin an app link carries as `hub=` (D709): the hub's best
33048
+ * public HTTPS address — the tunnel, then the mesh (Tailscale MagicDNS) —
33049
+ * picked from this cap's own palette by `pickAppLinkHub`. `null` when the
33050
+ * hub advertises neither; the app link is then minted without `hub=`.
33051
+ * Absent on a pre-D709 hub.
33052
+ */
33053
+ appLinkHub: string().nullable()
32999
33054
  });
33000
33055
  /**
33001
33056
  * The URLs the SDK / viewer should race for API access. `baseUrls` empty =
@@ -33049,7 +33104,11 @@ method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(obje
33049
33104
  * Pass `'https'` when the caller is itself loaded over HTTPS
33050
33105
  * to avoid mixed-content blocks in the browser. The public
33051
33106
  * tunnel always emits `https://` regardless. */
33052
- scheme: _enum(["http", "https"]).optional()
33107
+ scheme: _enum(["http", "https"]).optional(),
33108
+ /** Append the CamStack app link entry (`kind: 'app-link'`, D709) —
33109
+ * an address notification links can be flagged with, not a hub
33110
+ * route. Default `false`: racers and rankers never see it. */
33111
+ includeAppLink: boolean().optional()
33053
33112
  }), 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, {
33054
33113
  kind: "mutation",
33055
33114
  auth: "admin"
@@ -33378,7 +33437,7 @@ var MeshPeerSchema = object({
33378
33437
  tags: array(string()).readonly(),
33379
33438
  /** True when the peer advertises itself as an exit-node candidate. */
33380
33439
  exitNodeOption: boolean(),
33381
- /** Subnet routes the peer advertises (e.g. `["192.168.x.x/24"]`). */
33440
+ /** Subnet routes the peer advertises (e.g. `["192.168.10.0/24"]`). */
33382
33441
  advertisedRoutes: array(string()).readonly(),
33383
33442
  /** Owner account login (e.g. `foo@example.com`). Null for tagged peers. */
33384
33443
  userLogin: string().nullable(),
@@ -53855,12 +53914,14 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
53855
53914
  {
53856
53915
  id: "addons",
53857
53916
  family: "system",
53858
- label: "Addons",
53859
- kinds: [
53860
- "addon-crash-loop",
53861
- "addon-update-available",
53862
- "addon-updated"
53863
- ]
53917
+ label: "Addons stopped",
53918
+ kinds: ["addon-crash-loop"]
53919
+ },
53920
+ {
53921
+ id: "addon-updates",
53922
+ family: "system",
53923
+ label: "Addon updates",
53924
+ kinds: ["addon-update-available", "addon-updated"]
53864
53925
  },
53865
53926
  {
53866
53927
  id: "updates",
@@ -54020,13 +54081,15 @@ var STATE_SUMMARY_SECTION_VARS = [
54020
54081
  },
54021
54082
  {
54022
54083
  name: "summaryAddons",
54023
- label: "Summary: addons",
54024
- example: "@camstack/addon-recorder 1.2.3 → 1.2.4",
54025
- kinds: [
54026
- "addon-crash-loop",
54027
- "addon-update-available",
54028
- "addon-updated"
54029
- ]
54084
+ label: "Summary: addons stopped",
54085
+ example: "hub — recorder stopped after repeated crashes",
54086
+ kinds: ["addon-crash-loop"]
54087
+ },
54088
+ {
54089
+ name: "summaryAddonUpdates",
54090
+ label: "Summary: addon updates",
54091
+ example: "hub:\n• @camstack/addon-recorder 1.2.3 → 1.2.4",
54092
+ kinds: ["addon-update-available", "addon-updated"]
54030
54093
  },
54031
54094
  {
54032
54095
  name: "summaryUpdates",
@@ -54110,6 +54173,7 @@ var STATE_SUMMARY_VARS = [
54110
54173
  [...RULE_BODY_ONLY],
54111
54174
  [...RULE_TEXT],
54112
54175
  ([...RULE_TEXT], [...DEVICE_EVENTS]),
54176
+ ([...RULE_TEXT], [...COMBINED_ALARM]),
54113
54177
  ([...RULE_TEXT], [...DEVICE_EVENTS]),
54114
54178
  ([...RULE_TEXT], [...BATTERY, ...CONSUMABLE]),
54115
54179
  ([...RULE_TEXT], [...CONSUMABLE]),
@@ -66857,7 +66921,7 @@ var HikvisionCamera = class HikvisionCamera extends BaseDevice {
66857
66921
  key: "host",
66858
66922
  label: "Camera IP",
66859
66923
  required: true,
66860
- placeholder: "192.168.x.x"
66924
+ placeholder: "192.168.10.100"
66861
66925
  },
66862
66926
  {
66863
66927
  type: "number",
@@ -76906,13 +76970,13 @@ function enumerateHosts(cidr) {
76906
76970
  for (let d = 1; d <= 254; d += 1) out.push(`${a}.${b}.${c}.${d}`);
76907
76971
  return out;
76908
76972
  }
76909
- /** Best-effort local /24 from the first non-internal IPv4 interface (e.g. `192.168.x.x/24`). */
76973
+ /** Best-effort local /24 from the first non-internal IPv4 interface (e.g. `192.168.10.0/24`). */
76910
76974
  function detectLocalCidr() {
76911
76975
  for (const addrs of Object.values((0, node_os.networkInterfaces)())) for (const addr of addrs ?? []) if (addr.family === "IPv4" && !addr.internal) {
76912
76976
  const [a, b, c] = addr.address.split(".");
76913
76977
  return `${a}.${b}.${c}.0/24`;
76914
76978
  }
76915
- return "192.168.x.x/24";
76979
+ return "192.168.10.0/24";
76916
76980
  }
76917
76981
  /** Flatten a host into a flat row-key slug — must match `generateStableId`'s host fallback so a
76918
76982
  * re-scan of a host-added camera is detected as already onboarded. */
@@ -76982,7 +77046,7 @@ function buildCreationFormSchema() {
76982
77046
  key: "host",
76983
77047
  label: "Camera IP",
76984
77048
  required: true,
76985
- placeholder: "192.168.x.x",
77049
+ placeholder: "192.168.10.100",
76986
77050
  inputType: "text"
76987
77051
  },
76988
77052
  {
@@ -77032,14 +77096,14 @@ function buildDiscoveryParamsFormSchema() {
77032
77096
  }, {
77033
77097
  id: "scan",
77034
77098
  title: "Scan options",
77035
- description: "The credentialed ISAPI subnet scan is the reliable path (multicast WS-Discovery is not received on a macvlan/br0 hub). IMPORTANT: leaving the network blank scans only the HUB’s own subnet — if your cameras are on a DIFFERENT subnet than the hub, you MUST enter their CIDR here (e.g. 192.168.x.x/24), otherwise the scan returns nothing.",
77099
+ description: "The credentialed ISAPI subnet scan is the reliable path (multicast WS-Discovery is not received on a macvlan/br0 hub). IMPORTANT: leaving the network blank scans only the HUB’s own subnet — if your cameras are on a DIFFERENT subnet than the hub, you MUST enter their CIDR here (e.g. 192.168.60.0/24), otherwise the scan returns nothing.",
77036
77100
  columns: 1,
77037
77101
  fields: [{
77038
77102
  type: "text",
77039
77103
  key: "networkCidr",
77040
77104
  label: "Network (CIDR) — required if cameras are on a different subnet than the hub",
77041
77105
  required: false,
77042
- placeholder: "192.168.x.x/24"
77106
+ placeholder: "192.168.60.0/24"
77043
77107
  }, {
77044
77108
  type: "number",
77045
77109
  key: "timeoutMs",
package/dist/addon.mjs CHANGED
@@ -14511,7 +14511,7 @@ DeviceType.Camera;
14511
14511
  * This matters here more than anywhere else in the repo, because every provider
14512
14512
  * that knows a device's host knows its PASSWORD too: `{ host, port, username,
14513
14513
  * password }` sit in one object on Hikvision, Amcrest, Reolink and ONVIF alike,
14514
- * and `http://admin:hunter2@192.168.x.x/` is a URL a browser accepts. The
14514
+ * and `http://admin:hunter2@192.168.60.139/` is a URL a browser accepts. The
14515
14515
  * camera's own page will ask for its own login. That is correct, and pre-
14516
14516
  * filling it is the operator's business, not ours.
14517
14517
  *
@@ -20319,8 +20319,9 @@ var NcRuleSchema = NcRuleInputSchema.extend({
20319
20319
  disabledTargetIds: array(string()).default([])
20320
20320
  });
20321
20321
  /**
20322
- * The state-summary SECTIONS (D647 / D698): the D637 kind groups that report a
20323
- * still-true state. `backups-exports` and `alarm` are not sections — a completed
20322
+ * The state-summary SECTIONS (D647 / D698 / D708): the D637 kind groups that
20323
+ * report a still-true state. `addons` is the crash-looped addons only and
20324
+ * `addon-updates` the addons that are behind (D708 split them). `backups-exports` and `alarm` are not sections — a completed
20324
20325
  * job is not an open state, and the alarm stays instant.
20325
20326
  */
20326
20327
  var NcStateSummarySectionIdSchema = _enum([
@@ -20332,6 +20333,7 @@ var NcStateSummarySectionIdSchema = _enum([
20332
20333
  "detection-blind",
20333
20334
  "nodes",
20334
20335
  "addons",
20336
+ "addon-updates",
20335
20337
  "updates"
20336
20338
  ]);
20337
20339
  /** One section of a previewed state summary. `unavailable` = its state could not be read. */
@@ -20812,7 +20814,19 @@ var NcAlarmModeDelaysListSchema = array(object({
20812
20814
  * When this mode may be armed. Absent / null = always allowed (same as a
20813
20815
  * rule with no `schedule`). Evaluated with {@link isScheduleActive}.
20814
20816
  */
20815
- schedule: NcScheduleSchema.optional()
20817
+ schedule: NcScheduleSchema.optional(),
20818
+ /**
20819
+ * D706: while this mode's ENTRY DELAY runs, do the alarm rules' own pushes go out (as an
20820
+ * intrusion naming the locations)? Absent = false — the entry-delay notification is the
20821
+ * only one, and the matches ride the triggered notification's mosaic (D705).
20822
+ */
20823
+ notifyDuringEntryDelay: boolean().optional(),
20824
+ /**
20825
+ * D706: notify "watched again" when a sensor this arm bypassed closes and opens again.
20826
+ * Absent = false (logged, not sent). Even when true it is not sent when that same sensor
20827
+ * is the one that starts the entry delay — the entry-delay notification already names it.
20828
+ */
20829
+ notifySensorRewatched: boolean().optional()
20816
20830
  })).max(8).refine(uniqueModes, { message: "modeDelays: at most one entry per arm mode" });
20817
20831
  var NcAlarmModeDelaysEditListSchema = array(object({
20818
20832
  mode: AlarmArmModeSchema,
@@ -20821,7 +20835,11 @@ var NcAlarmModeDelaysEditListSchema = array(object({
20821
20835
  triggeredDurationSec: NcAlarmTriggeredSecSchema.nullable().optional(),
20822
20836
  postTriggeredAction: NcAlarmPostTriggeredActionSchema.nullable().optional(),
20823
20837
  /** Set a schedule, or `null` to clear (mode always allowed again). */
20824
- schedule: NcScheduleSchema.nullable().optional()
20838
+ schedule: NcScheduleSchema.nullable().optional(),
20839
+ /** D706: set the switch, or `null` to clear it (back to the default, false). */
20840
+ notifyDuringEntryDelay: boolean().nullable().optional(),
20841
+ /** D706: set the switch, or `null` to clear it (back to the default, false). */
20842
+ notifySensorRewatched: boolean().nullable().optional()
20825
20843
  })).max(8).refine(uniqueModes, { message: "modeDelays: at most one edit per arm mode" });
20826
20844
  /** One switch of the alarm table: put ONE device on, or take it off, ONE mode's list. */
20827
20845
  var NcAlarmNonBlockingEditSchema = object({
@@ -24682,6 +24700,22 @@ var MotionSourceEnum = _enum([
24682
24700
  "device-activity"
24683
24701
  ]);
24684
24702
  /**
24703
+ * What opened an on-motion detection SESSION: the motion source that passed the
24704
+ * camera's `motionSources` gate, and what raised it (the camera itself, or a
24705
+ * sensor the operator attached — D672). `sensorName` is the attached sensor's
24706
+ * device name as the orchestrator's camera-sensors resolution last read it;
24707
+ * absent when unknown or when the camera itself triggered.
24708
+ *
24709
+ * Carried on the session attach ONLY so the runner's `DetectionPhaseTransition`
24710
+ * can say what started the session (D672 rule 11, amended 2026-10-06). The
24711
+ * runner never decides anything on it.
24712
+ */
24713
+ var SessionTriggerSchema = object({
24714
+ source: MotionSourceEnum,
24715
+ triggeredBy: MotionTriggeredBySchema,
24716
+ sensorName: string().optional()
24717
+ });
24718
+ /**
24685
24719
  * List of motion sources active on a camera. Empty array is valid:
24686
24720
  * "no source" — happens for battery cams without firmware motion when
24687
24721
  * the operator hasn't opted into the SW analyzer (would hold the
@@ -24933,6 +24967,14 @@ var RunnerCameraConfigSchema = object({
24933
24967
  */
24934
24968
  motionSources: MotionSourcesSchema.default(["analyzer"]),
24935
24969
  /**
24970
+ * What opened this attach, on a SESSION attach only (see
24971
+ * {@link SessionTriggerSchema}). OPTIONAL with no default: absent on a
24972
+ * standing attach, an occupancy burst, a re-dispatch with no motion event
24973
+ * behind it, and every attach from an orchestrator older than the field — the
24974
+ * runner then names no source on the phase event.
24975
+ */
24976
+ sessionTrigger: SessionTriggerSchema.optional(),
24977
+ /**
24936
24978
  * WHICH root detector runs for this camera. The detection counterpart of
24937
24979
  * {@link motionSources}, same shape and same discipline: a per-camera list
24938
24980
  * of sources the system understands, vendor-agnostic, owned here.
@@ -32843,7 +32885,7 @@ var LocalInterfaceSchema = object({
32843
32885
  name: string(),
32844
32886
  family: _enum(["IPv4", "IPv6"]),
32845
32887
  address: string(),
32846
- /** CIDR shorthand (e.g. `192.168.x.x/24`). Empty when OS doesn't expose. */
32888
+ /** CIDR shorthand (e.g. `192.168.10.10/24`). Empty when OS doesn't expose. */
32847
32889
  cidr: string(),
32848
32890
  /** OS netmask. Stable across calls so the SDK can hash on it. */
32849
32891
  netmask: string(),
@@ -32897,7 +32939,8 @@ var ConnectionEndpointSchema = object({
32897
32939
  "lan-ipv4",
32898
32940
  "lan-ipv6",
32899
32941
  "public",
32900
- "loopback"
32942
+ "loopback",
32943
+ "app-link"
32901
32944
  ]),
32902
32945
  /**
32903
32946
  * Originating-interface kind — `lan`/`wifi`/`docker`/`vpn`/`other`/
@@ -32966,15 +33009,27 @@ var GetConnectionEndpointsResultSchema = object({
32966
33009
  localPort: AdvertisedLocalPortSchema
32967
33010
  });
32968
33011
  /**
32969
- * The chosen outbound endpoint for notification artifacts. `baseUrl: null` =
32970
- * AUTO (resolved from the candidate ranking at send time); `resolved` reports
32971
- * what AUTO currently picks, so the UI can show the effective value either way.
33012
+ * The address flagged for notification links. `baseUrl: null` = AUTO, which
33013
+ * since D709 is the CamStack app link; `resolved` reports the effective value,
33014
+ * so the UI can show it either way.
32972
33015
  */
32973
33016
  var NotificationEndpointSchema = object({
32974
33017
  /** The operator's explicit choice, or null for AUTO. */
32975
33018
  baseUrl: string().nullable(),
32976
- /** What the ranking currently resolves to (null when nothing is reachable). */
32977
- resolved: string().nullable()
33019
+ /**
33020
+ * The effective flagged address: the explicit choice, else (AUTO) the
33021
+ * CamStack app link `https://camstack.zentik.app` (D709). A pre-D709 hub
33022
+ * answered the public tunnel / mesh here, or null.
33023
+ */
33024
+ resolved: string().nullable(),
33025
+ /**
33026
+ * The hub origin an app link carries as `hub=` (D709): the hub's best
33027
+ * public HTTPS address — the tunnel, then the mesh (Tailscale MagicDNS) —
33028
+ * picked from this cap's own palette by `pickAppLinkHub`. `null` when the
33029
+ * hub advertises neither; the app link is then minted without `hub=`.
33030
+ * Absent on a pre-D709 hub.
33031
+ */
33032
+ appLinkHub: string().nullable()
32978
33033
  });
32979
33034
  /**
32980
33035
  * The URLs the SDK / viewer should race for API access. `baseUrls` empty =
@@ -33028,7 +33083,11 @@ method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(obje
33028
33083
  * Pass `'https'` when the caller is itself loaded over HTTPS
33029
33084
  * to avoid mixed-content blocks in the browser. The public
33030
33085
  * tunnel always emits `https://` regardless. */
33031
- scheme: _enum(["http", "https"]).optional()
33086
+ scheme: _enum(["http", "https"]).optional(),
33087
+ /** Append the CamStack app link entry (`kind: 'app-link'`, D709) —
33088
+ * an address notification links can be flagged with, not a hub
33089
+ * route. Default `false`: racers and rankers never see it. */
33090
+ includeAppLink: boolean().optional()
33032
33091
  }), 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, {
33033
33092
  kind: "mutation",
33034
33093
  auth: "admin"
@@ -33357,7 +33416,7 @@ var MeshPeerSchema = object({
33357
33416
  tags: array(string()).readonly(),
33358
33417
  /** True when the peer advertises itself as an exit-node candidate. */
33359
33418
  exitNodeOption: boolean(),
33360
- /** Subnet routes the peer advertises (e.g. `["192.168.x.x/24"]`). */
33419
+ /** Subnet routes the peer advertises (e.g. `["192.168.10.0/24"]`). */
33361
33420
  advertisedRoutes: array(string()).readonly(),
33362
33421
  /** Owner account login (e.g. `foo@example.com`). Null for tagged peers. */
33363
33422
  userLogin: string().nullable(),
@@ -53834,12 +53893,14 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
53834
53893
  {
53835
53894
  id: "addons",
53836
53895
  family: "system",
53837
- label: "Addons",
53838
- kinds: [
53839
- "addon-crash-loop",
53840
- "addon-update-available",
53841
- "addon-updated"
53842
- ]
53896
+ label: "Addons stopped",
53897
+ kinds: ["addon-crash-loop"]
53898
+ },
53899
+ {
53900
+ id: "addon-updates",
53901
+ family: "system",
53902
+ label: "Addon updates",
53903
+ kinds: ["addon-update-available", "addon-updated"]
53843
53904
  },
53844
53905
  {
53845
53906
  id: "updates",
@@ -53999,13 +54060,15 @@ var STATE_SUMMARY_SECTION_VARS = [
53999
54060
  },
54000
54061
  {
54001
54062
  name: "summaryAddons",
54002
- label: "Summary: addons",
54003
- example: "@camstack/addon-recorder 1.2.3 → 1.2.4",
54004
- kinds: [
54005
- "addon-crash-loop",
54006
- "addon-update-available",
54007
- "addon-updated"
54008
- ]
54063
+ label: "Summary: addons stopped",
54064
+ example: "hub — recorder stopped after repeated crashes",
54065
+ kinds: ["addon-crash-loop"]
54066
+ },
54067
+ {
54068
+ name: "summaryAddonUpdates",
54069
+ label: "Summary: addon updates",
54070
+ example: "hub:\n• @camstack/addon-recorder 1.2.3 → 1.2.4",
54071
+ kinds: ["addon-update-available", "addon-updated"]
54009
54072
  },
54010
54073
  {
54011
54074
  name: "summaryUpdates",
@@ -54089,6 +54152,7 @@ var STATE_SUMMARY_VARS = [
54089
54152
  [...RULE_BODY_ONLY],
54090
54153
  [...RULE_TEXT],
54091
54154
  ([...RULE_TEXT], [...DEVICE_EVENTS]),
54155
+ ([...RULE_TEXT], [...COMBINED_ALARM]),
54092
54156
  ([...RULE_TEXT], [...DEVICE_EVENTS]),
54093
54157
  ([...RULE_TEXT], [...BATTERY, ...CONSUMABLE]),
54094
54158
  ([...RULE_TEXT], [...CONSUMABLE]),
@@ -66836,7 +66900,7 @@ var HikvisionCamera = class HikvisionCamera extends BaseDevice {
66836
66900
  key: "host",
66837
66901
  label: "Camera IP",
66838
66902
  required: true,
66839
- placeholder: "192.168.x.x"
66903
+ placeholder: "192.168.10.100"
66840
66904
  },
66841
66905
  {
66842
66906
  type: "number",
@@ -76885,13 +76949,13 @@ function enumerateHosts(cidr) {
76885
76949
  for (let d = 1; d <= 254; d += 1) out.push(`${a}.${b}.${c}.${d}`);
76886
76950
  return out;
76887
76951
  }
76888
- /** Best-effort local /24 from the first non-internal IPv4 interface (e.g. `192.168.x.x/24`). */
76952
+ /** Best-effort local /24 from the first non-internal IPv4 interface (e.g. `192.168.10.0/24`). */
76889
76953
  function detectLocalCidr() {
76890
76954
  for (const addrs of Object.values(networkInterfaces())) for (const addr of addrs ?? []) if (addr.family === "IPv4" && !addr.internal) {
76891
76955
  const [a, b, c] = addr.address.split(".");
76892
76956
  return `${a}.${b}.${c}.0/24`;
76893
76957
  }
76894
- return "192.168.x.x/24";
76958
+ return "192.168.10.0/24";
76895
76959
  }
76896
76960
  /** Flatten a host into a flat row-key slug — must match `generateStableId`'s host fallback so a
76897
76961
  * re-scan of a host-added camera is detected as already onboarded. */
@@ -76961,7 +77025,7 @@ function buildCreationFormSchema() {
76961
77025
  key: "host",
76962
77026
  label: "Camera IP",
76963
77027
  required: true,
76964
- placeholder: "192.168.x.x",
77028
+ placeholder: "192.168.10.100",
76965
77029
  inputType: "text"
76966
77030
  },
76967
77031
  {
@@ -77011,14 +77075,14 @@ function buildDiscoveryParamsFormSchema() {
77011
77075
  }, {
77012
77076
  id: "scan",
77013
77077
  title: "Scan options",
77014
- description: "The credentialed ISAPI subnet scan is the reliable path (multicast WS-Discovery is not received on a macvlan/br0 hub). IMPORTANT: leaving the network blank scans only the HUB’s own subnet — if your cameras are on a DIFFERENT subnet than the hub, you MUST enter their CIDR here (e.g. 192.168.x.x/24), otherwise the scan returns nothing.",
77078
+ description: "The credentialed ISAPI subnet scan is the reliable path (multicast WS-Discovery is not received on a macvlan/br0 hub). IMPORTANT: leaving the network blank scans only the HUB’s own subnet — if your cameras are on a DIFFERENT subnet than the hub, you MUST enter their CIDR here (e.g. 192.168.60.0/24), otherwise the scan returns nothing.",
77015
77079
  columns: 1,
77016
77080
  fields: [{
77017
77081
  type: "text",
77018
77082
  key: "networkCidr",
77019
77083
  label: "Network (CIDR) — required if cameras are on a different subnet than the hub",
77020
77084
  required: false,
77021
- placeholder: "192.168.x.x/24"
77085
+ placeholder: "192.168.60.0/24"
77022
77086
  }, {
77023
77087
  type: "number",
77024
77088
  key: "timeoutMs",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-hikvision",
3
- "version": "1.2.141",
3
+ "version": "1.2.142",
4
4
  "description": "Hikvision camera device provider addon for CamStack — ISAPI over HTTP(S) with digest auth (snapshot, alarm stream, RTSP discovery)",
5
5
  "keywords": [
6
6
  "camstack",