@camstack/addon-agent-ui 1.2.154 → 1.2.156
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 +274 -206
- package/package.json +1 -1
package/dist/addon.js
CHANGED
|
@@ -5371,7 +5371,7 @@ var ZodIssueCode = {
|
|
|
5371
5371
|
var ZodFirstPartyTypeKind;
|
|
5372
5372
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5373
5373
|
//#endregion
|
|
5374
|
-
//#region ../types/dist/sleep-
|
|
5374
|
+
//#region ../types/dist/sleep-C-v96WpE.mjs
|
|
5375
5375
|
/**
|
|
5376
5376
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5377
5377
|
* window to float samples (D455).
|
|
@@ -6927,6 +6927,10 @@ var ProfileRtspEntrySchema = object({
|
|
|
6927
6927
|
codec: string().optional(),
|
|
6928
6928
|
resolution: CamStreamResolutionSchema.optional()
|
|
6929
6929
|
});
|
|
6930
|
+
object({
|
|
6931
|
+
field: string().min(1),
|
|
6932
|
+
on: literal("advance")
|
|
6933
|
+
});
|
|
6930
6934
|
/**
|
|
6931
6935
|
* Output schema shared by the contribution + live methods.
|
|
6932
6936
|
*
|
|
@@ -7414,7 +7418,43 @@ var DeviceRole = /* @__PURE__ */ function(DeviceRole) {
|
|
|
7414
7418
|
return DeviceRole;
|
|
7415
7419
|
}({});
|
|
7416
7420
|
//#endregion
|
|
7417
|
-
//#region ../types/dist/composition-
|
|
7421
|
+
//#region ../types/dist/composition-BK-GTFYb.mjs
|
|
7422
|
+
/**
|
|
7423
|
+
* LA tabella "quale booleano di questo tipo di device conta come ALTO", e il
|
|
7424
|
+
* valutatore puro del suo FRONTE.
|
|
7425
|
+
*
|
|
7426
|
+
* Viveva dentro il builtin virtual-doorbell
|
|
7427
|
+
* (`@camstack/system` — `builtins/doorbell/trigger-engine.ts`) e i suoi
|
|
7428
|
+
* predicati erano privati al modulo. Il recorder ne ha bisogno per il trigger
|
|
7429
|
+
* `RecordingTriggers.sensorDeviceIds`: copiarla avrebbe creato la SECONDA
|
|
7430
|
+
* tabella, che diverge alla prima cap aggiunta e il cui sintomo — "il sensore
|
|
7431
|
+
* fa suonare il campanello ma non registra" — è esattamente D62. Quindi si
|
|
7432
|
+
* SPOSTA qui e il doorbell la ri-esporta.
|
|
7433
|
+
*
|
|
7434
|
+
* ⚠ NON è `DEVICE_STATE_READERS` (`catalogs/device-state-vocabulary.ts`), e le
|
|
7435
|
+
* due non vanno unificate: quella risponde a "qual è la PAROLA di stato per una
|
|
7436
|
+
* regola" (e include `presence`, `cover`, `alarm-panel`), questa a "qual è il
|
|
7437
|
+
* booleano il cui FRONTE conta". Vocabolari deliberatamente diversi.
|
|
7438
|
+
*/
|
|
7439
|
+
/**
|
|
7440
|
+
* Known binary / switch source caps → the boolean slice field whose
|
|
7441
|
+
* false→true rise counts as ACTIVE. Every entry is "fire on active".
|
|
7442
|
+
* Sensors whose "active" reading is not a plain boolean (presence's string
|
|
7443
|
+
* state, connectivity's connected flag) are deliberately excluded — a
|
|
7444
|
+
* reconnect is not a doorbell press, and it is not a recording either.
|
|
7445
|
+
*/
|
|
7446
|
+
var SOURCE_CAP_ACTIVE_FIELD = {
|
|
7447
|
+
contact: "entryOpen",
|
|
7448
|
+
binary: "on",
|
|
7449
|
+
switch: "on",
|
|
7450
|
+
motion: "detected",
|
|
7451
|
+
flood: "flooded",
|
|
7452
|
+
gas: "detected",
|
|
7453
|
+
smoke: "detected",
|
|
7454
|
+
"carbon-monoxide": "detected",
|
|
7455
|
+
vibration: "detected",
|
|
7456
|
+
tamper: "tampered"
|
|
7457
|
+
};
|
|
7418
7458
|
/**
|
|
7419
7459
|
* Error types for the safe expression engine. Two distinct classes so callers
|
|
7420
7460
|
* can tell a compile-time (grammar) failure from a runtime (evaluation)
|
|
@@ -7612,6 +7652,20 @@ var table = {
|
|
|
7612
7652
|
const present = args.flatMap((a, i) => a === null ? [] : [asFiniteNumber(a, "latest", i)]);
|
|
7613
7653
|
return present.length === 0 ? null : finiteResult(Math.max(...present), "latest");
|
|
7614
7654
|
}
|
|
7655
|
+
},
|
|
7656
|
+
rose: {
|
|
7657
|
+
minArgs: 2,
|
|
7658
|
+
maxArgs: 3,
|
|
7659
|
+
apply: () => {
|
|
7660
|
+
throw new ExpressionEvalError("rose: stateful evaluation context is required");
|
|
7661
|
+
}
|
|
7662
|
+
},
|
|
7663
|
+
count: {
|
|
7664
|
+
minArgs: 1,
|
|
7665
|
+
maxArgs: 1,
|
|
7666
|
+
apply: () => {
|
|
7667
|
+
throw new ExpressionEvalError("count: stateful evaluation context is required");
|
|
7668
|
+
}
|
|
7615
7669
|
}
|
|
7616
7670
|
};
|
|
7617
7671
|
Object.freeze(Object.assign(Object.create(null), table));
|
|
@@ -8126,6 +8180,7 @@ var CompositionItemEntrySchema = object({
|
|
|
8126
8180
|
var CompositionFeatureSchema = discriminatedUnion("kind", [object({
|
|
8127
8181
|
kind: literal("fields"),
|
|
8128
8182
|
cap: string().min(1),
|
|
8183
|
+
enabled: boolean().optional(),
|
|
8129
8184
|
fields: record(string().min(1), CompositionFieldSourceSchema).refine((fields) => Object.keys(fields).length <= 32, { message: `at most 32 fields per capability` }),
|
|
8130
8185
|
/**
|
|
8131
8186
|
* Items of the cap's item array, keyed by item key (D663). Naming `items`
|
|
@@ -8137,6 +8192,7 @@ var CompositionFeatureSchema = discriminatedUnion("kind", [object({
|
|
|
8137
8192
|
}), object({
|
|
8138
8193
|
kind: literal("passthrough"),
|
|
8139
8194
|
cap: string().min(1),
|
|
8195
|
+
enabled: boolean().optional(),
|
|
8140
8196
|
source: CompositionSourceRefSchema
|
|
8141
8197
|
})]);
|
|
8142
8198
|
var CompositionSchema = object({
|
|
@@ -8166,7 +8222,6 @@ var CompositionSchema = object({
|
|
|
8166
8222
|
});
|
|
8167
8223
|
new Set([
|
|
8168
8224
|
"track",
|
|
8169
|
-
"summary",
|
|
8170
8225
|
"face",
|
|
8171
8226
|
"identity",
|
|
8172
8227
|
"plate",
|
|
@@ -12770,6 +12825,15 @@ DeviceType.Camera, method(object({ deviceId: number().int().nonnegative() }), ar
|
|
|
12770
12825
|
}),
|
|
12771
12826
|
lastChangedAt: number()
|
|
12772
12827
|
});
|
|
12828
|
+
EventCategory.DoorbellOnPressed;
|
|
12829
|
+
var CompositionEventPlanSchema = object({
|
|
12830
|
+
featureIndex: number().int().nonnegative(),
|
|
12831
|
+
cap: string(),
|
|
12832
|
+
eventName: string(),
|
|
12833
|
+
category: _enum(EventCategory),
|
|
12834
|
+
stateField: string(),
|
|
12835
|
+
fieldKey: string()
|
|
12836
|
+
});
|
|
12773
12837
|
/** One refusal, named (D391). `path` points into the composition, e.g. `features[0].fields.celsius`. */
|
|
12774
12838
|
var CompositionProblemSchema = object({
|
|
12775
12839
|
code: _enum([
|
|
@@ -12819,12 +12883,14 @@ var CompositionUnavailableModeSchema = _enum([
|
|
|
12819
12883
|
]);
|
|
12820
12884
|
/**
|
|
12821
12885
|
* `derived` reads a source · `clock` reads only `now`, recomputed when a sibling
|
|
12822
|
-
* field of its cap changes value · `constant` reads nothing, computed once
|
|
12886
|
+
* field of its cap changes value · `constant` reads nothing, computed once ·
|
|
12887
|
+
* `accumulator` advances from the target's seed/current output.
|
|
12823
12888
|
*/
|
|
12824
12889
|
var CompositionFieldRoleSchema = _enum([
|
|
12825
12890
|
"derived",
|
|
12826
12891
|
"clock",
|
|
12827
|
-
"constant"
|
|
12892
|
+
"constant",
|
|
12893
|
+
"accumulator"
|
|
12828
12894
|
]);
|
|
12829
12895
|
/** The item a planned field belongs to; its `path` is then the dotted path INSIDE the item. */
|
|
12830
12896
|
var CompositionFieldItemSchema = object({
|
|
@@ -12860,6 +12926,7 @@ var CompositionFeatureModeSchema = _enum([
|
|
|
12860
12926
|
"replace"
|
|
12861
12927
|
]);
|
|
12862
12928
|
var CompositionFeaturePlanSchema = object({
|
|
12929
|
+
/** Index in the stored feature array; disabled features are omitted rather than re-indexed. */
|
|
12863
12930
|
featureIndex: number().int().nonnegative(),
|
|
12864
12931
|
cap: string(),
|
|
12865
12932
|
mode: CompositionFeatureModeSchema
|
|
@@ -12868,7 +12935,8 @@ var CompositionValidationSchema = object({
|
|
|
12868
12935
|
ok: boolean(),
|
|
12869
12936
|
problems: array(CompositionProblemSchema),
|
|
12870
12937
|
fields: array(CompositionFieldPlanSchema),
|
|
12871
|
-
features: array(CompositionFeaturePlanSchema)
|
|
12938
|
+
features: array(CompositionFeaturePlanSchema),
|
|
12939
|
+
events: array(CompositionEventPlanSchema)
|
|
12872
12940
|
});
|
|
12873
12941
|
/**
|
|
12874
12942
|
* Mirrors `CoreBlockStatus`, pinned by `core-blocks-source.spec.ts`. `degraded`:
|
|
@@ -14463,6 +14531,34 @@ var DeviceBindingsForDeviceSchema = object({
|
|
|
14463
14531
|
nativeAddonId: string()
|
|
14464
14532
|
}))
|
|
14465
14533
|
});
|
|
14534
|
+
/**
|
|
14535
|
+
* The STORED wrapper activation for one `(device, capability)` pair — the row
|
|
14536
|
+
* `setWrapperActive` writes, read back three-way (D675):
|
|
14537
|
+
*
|
|
14538
|
+
* - `value` — the store answered and holds an activation: the bound wrapper's
|
|
14539
|
+
* addon id, or `null`, the operator's explicit "off" marker (D62);
|
|
14540
|
+
* - `missing` — the store answered, its activation map exists, and it holds
|
|
14541
|
+
* nothing for this pair: the operator never activated or deactivated a
|
|
14542
|
+
* wrapper here;
|
|
14543
|
+
* - `failed` — the store could not be read, holds no activation map at all
|
|
14544
|
+
* (an empty or unready snapshot, D44), or holds something that is not an
|
|
14545
|
+
* activation. It carries NO information: a consumer must never read it as
|
|
14546
|
+
* `missing` (D315, D393).
|
|
14547
|
+
*
|
|
14548
|
+
* This is the persisted INPUT, not the derived `getBindings` view — no registry
|
|
14549
|
+
* resolution, no `defaultActive` auto-binding, no cluster native-cap folding.
|
|
14550
|
+
*/
|
|
14551
|
+
var WrapperActivationReadSchema = discriminatedUnion("kind", [
|
|
14552
|
+
object({
|
|
14553
|
+
kind: literal("value"),
|
|
14554
|
+
wrapperAddonId: string().nullable()
|
|
14555
|
+
}),
|
|
14556
|
+
object({ kind: literal("missing") }),
|
|
14557
|
+
object({
|
|
14558
|
+
kind: literal("failed"),
|
|
14559
|
+
error: string()
|
|
14560
|
+
})
|
|
14561
|
+
]);
|
|
14466
14562
|
var SavedDeviceRowSchema = object({
|
|
14467
14563
|
/** Numeric id reserved at allocateDeviceId time. */
|
|
14468
14564
|
id: number(),
|
|
@@ -14813,7 +14909,10 @@ method(object({
|
|
|
14813
14909
|
}), _void(), {
|
|
14814
14910
|
kind: "mutation",
|
|
14815
14911
|
auth: "admin"
|
|
14816
|
-
}), method(object({
|
|
14912
|
+
}), method(object({
|
|
14913
|
+
deviceId: number(),
|
|
14914
|
+
capName: string().min(1)
|
|
14915
|
+
}), WrapperActivationReadSchema), method(object({ capName: string() }), array(string())), method(object({ deviceType: string() }), array(object({
|
|
14817
14916
|
capName: string(),
|
|
14818
14917
|
wrappers: array(string())
|
|
14819
14918
|
}))), method(object({ deviceId: number() }), SettingsSchemaWithValuesSchema.nullable()), method(object({ deviceId: number() }), SettingsSchemaWithValuesSchema.nullable()), method(object({ deviceId: number() }), object({
|
|
@@ -19924,6 +20023,102 @@ var OauthIntegrationDescriptorSchema = object({
|
|
|
19924
20023
|
});
|
|
19925
20024
|
method(_void(), OauthIntegrationDescriptorSchema, { auth: "admin" });
|
|
19926
20025
|
/**
|
|
20026
|
+
* What started a camera's onboard motion (D672). `camera` is the camera's own
|
|
20027
|
+
* firmware; `sensor` is a device the operator ATTACHED to it. Absent on the
|
|
20028
|
+
* wire means the camera: only the camera-sensors bridge ever says `sensor`.
|
|
20029
|
+
*/
|
|
20030
|
+
var MotionTriggeredBySchema = discriminatedUnion("kind", [object({ kind: literal("camera") }), object({
|
|
20031
|
+
kind: literal("sensor"),
|
|
20032
|
+
deviceId: number().int().positive()
|
|
20033
|
+
})]);
|
|
20034
|
+
Object.freeze({ kind: "camera" });
|
|
20035
|
+
var CameraSensorRefSchema = object({
|
|
20036
|
+
addonId: string().min(1),
|
|
20037
|
+
stableId: string().min(1)
|
|
20038
|
+
});
|
|
20039
|
+
function cameraSensorRefKey(ref) {
|
|
20040
|
+
return `${ref.addonId}/${ref.stableId}`;
|
|
20041
|
+
}
|
|
20042
|
+
/** CS-1 accepts exactly one mode; CS-2 (D673) widens it to confirm / replace. */
|
|
20043
|
+
var CameraSensorsModeSchema = _enum(["in-addition"]);
|
|
20044
|
+
object({
|
|
20045
|
+
mode: CameraSensorsModeSchema,
|
|
20046
|
+
sensors: array(CameraSensorRefSchema).min(1).max(8)
|
|
20047
|
+
}).superRefine((value, ctx) => {
|
|
20048
|
+
const seen = /* @__PURE__ */ new Set();
|
|
20049
|
+
value.sensors.forEach((ref, index) => {
|
|
20050
|
+
const key = cameraSensorRefKey(ref);
|
|
20051
|
+
if (seen.has(key)) ctx.addIssue({
|
|
20052
|
+
code: "custom",
|
|
20053
|
+
path: ["sensors", index],
|
|
20054
|
+
message: `duplicate camera sensor ${key}`
|
|
20055
|
+
});
|
|
20056
|
+
seen.add(key);
|
|
20057
|
+
});
|
|
20058
|
+
});
|
|
20059
|
+
var RefFields = {
|
|
20060
|
+
addonId: string(),
|
|
20061
|
+
stableId: string()
|
|
20062
|
+
};
|
|
20063
|
+
var CameraSensorAttachmentSchema = discriminatedUnion("state", [
|
|
20064
|
+
object({
|
|
20065
|
+
...RefFields,
|
|
20066
|
+
state: literal("ready"),
|
|
20067
|
+
deviceId: number(),
|
|
20068
|
+
name: string(),
|
|
20069
|
+
caps: array(string()).readonly()
|
|
20070
|
+
}),
|
|
20071
|
+
object({
|
|
20072
|
+
...RefFields,
|
|
20073
|
+
state: literal("offline"),
|
|
20074
|
+
deviceId: number(),
|
|
20075
|
+
name: string(),
|
|
20076
|
+
reason: _enum(["offline", "disabled"])
|
|
20077
|
+
}),
|
|
20078
|
+
object({
|
|
20079
|
+
...RefFields,
|
|
20080
|
+
state: literal("missing"),
|
|
20081
|
+
reason: string()
|
|
20082
|
+
}),
|
|
20083
|
+
object({
|
|
20084
|
+
...RefFields,
|
|
20085
|
+
state: literal("unsupported"),
|
|
20086
|
+
deviceId: number(),
|
|
20087
|
+
name: string(),
|
|
20088
|
+
reason: string()
|
|
20089
|
+
}),
|
|
20090
|
+
object({
|
|
20091
|
+
...RefFields,
|
|
20092
|
+
state: literal("unreadable"),
|
|
20093
|
+
reason: string()
|
|
20094
|
+
})
|
|
20095
|
+
]);
|
|
20096
|
+
/**
|
|
20097
|
+
* Why a configured camera forwards NOTHING from its sensors, however ready they
|
|
20098
|
+
* are (D672): it does not list `onboard` in `motionSources` (attaching a sensor
|
|
20099
|
+
* does not add it), or it has no active detection config at all (the bridge
|
|
20100
|
+
* reads the active config). Absent = forwarded, or an older node that does not
|
|
20101
|
+
* say.
|
|
20102
|
+
*/
|
|
20103
|
+
var CameraSensorsNotForwardedSchema = _enum(["onboard-not-listed", "no-active-detection"]);
|
|
20104
|
+
var CameraSensorsStatusSchema = discriminatedUnion("state", [
|
|
20105
|
+
object({ state: literal("not-configured") }),
|
|
20106
|
+
object({
|
|
20107
|
+
state: literal("unreadable"),
|
|
20108
|
+
reason: string()
|
|
20109
|
+
}),
|
|
20110
|
+
object({
|
|
20111
|
+
state: literal("configured"),
|
|
20112
|
+
mode: CameraSensorsModeSchema,
|
|
20113
|
+
sensors: array(CameraSensorAttachmentSchema).readonly(),
|
|
20114
|
+
notForwarded: CameraSensorsNotForwardedSchema.optional()
|
|
20115
|
+
})
|
|
20116
|
+
]);
|
|
20117
|
+
Object.freeze({
|
|
20118
|
+
state: "unreadable",
|
|
20119
|
+
reason: "camera sensor mappings not loaded"
|
|
20120
|
+
});
|
|
20121
|
+
/**
|
|
19927
20122
|
* A model choice has a SCOPE, and a scope change has a workflow.
|
|
19928
20123
|
*
|
|
19929
20124
|
* ## The two scopes
|
|
@@ -20672,6 +20867,12 @@ var MotionEventSchema = object({
|
|
|
20672
20867
|
/** Populated by B5 (recording playback URL for this event). */
|
|
20673
20868
|
mediaUrl: string().optional(),
|
|
20674
20869
|
/**
|
|
20870
|
+
* The FIRST trigger of an `onboard` episode, written once at open (D672).
|
|
20871
|
+
* Absent = not recorded (a row written before D672, or an analyzer /
|
|
20872
|
+
* device-activity episode) — never read as "the camera" (D393).
|
|
20873
|
+
*/
|
|
20874
|
+
triggeredBy: MotionTriggeredBySchema.optional(),
|
|
20875
|
+
/**
|
|
20675
20876
|
* One row per motion EPISODE, not one per push (D475). `null` while the
|
|
20676
20877
|
* episode is still open — a further rising edge extends it in place rather
|
|
20677
20878
|
* than inserting a new row. Set once, at close, to `lastOnAt - startedAt`
|
|
@@ -21165,131 +21366,6 @@ var RecentTracksQueryInput = object({
|
|
|
21165
21366
|
/** See {@link ExcludeSourcesDoc}. */
|
|
21166
21367
|
excludeSources: array(TrackSourceSchema).optional()
|
|
21167
21368
|
});
|
|
21168
|
-
/**
|
|
21169
|
-
* A Summary (D359): the per-camera session envelope that references tracks.
|
|
21170
|
-
* `groupShotMediaId` is the media ROW id of its group shot (`ownerKind:
|
|
21171
|
-
* 'summary'`, served by the event-media plane at `/m/<id>`), null until the
|
|
21172
|
-
* first frame with a member visible has been materialised (D482 — it was the
|
|
21173
|
-
* row's composite key, which embedded the owner and could name another table's
|
|
21174
|
-
* row once event ids became per-table rowids).
|
|
21175
|
-
*/
|
|
21176
|
-
var SummarySchema = object({
|
|
21177
|
-
id: string(),
|
|
21178
|
-
deviceId: number(),
|
|
21179
|
-
openedAt: number(),
|
|
21180
|
-
lastActiveAt: number(),
|
|
21181
|
-
sealedAt: number().nullable(),
|
|
21182
|
-
memberCount: number().int().nonnegative(),
|
|
21183
|
-
groupShotMediaId: number().int().nullable()
|
|
21184
|
-
});
|
|
21185
|
-
var SummariesQueryInput = object({
|
|
21186
|
-
deviceIds: array(number()).min(1),
|
|
21187
|
-
since: number().optional(),
|
|
21188
|
-
until: number().optional(),
|
|
21189
|
-
limit: number().int().min(1).max(200).default(50),
|
|
21190
|
-
/** The same member-wise filter {@link listRecentSummaries} takes — one
|
|
21191
|
-
* meaning of "dog" on every summary surface. */
|
|
21192
|
-
classes: array(string().min(1).max(60)).max(40).optional()
|
|
21193
|
-
});
|
|
21194
|
-
var SummaryDetailSchema = object({
|
|
21195
|
-
summary: SummarySchema,
|
|
21196
|
-
/** Members in absorption order, oldest join first. */
|
|
21197
|
-
members: array(object({
|
|
21198
|
-
trackId: string(),
|
|
21199
|
-
/**
|
|
21200
|
-
* The track's class at the time it JOINED, or `null` when it was unresolved
|
|
21201
|
-
* and the track no longer exists to fill it.
|
|
21202
|
-
*
|
|
21203
|
-
* The join, not the latest opinion: class voting can re-decide a track's
|
|
21204
|
-
* class afterwards, and a group's composition is the history of who came
|
|
21205
|
-
* together. A consumer counts these to badge a thumbnail — "two people and a
|
|
21206
|
-
* dog" — rather than being handed a second, denormalised tally that would
|
|
21207
|
-
* drift from the members it claims to describe.
|
|
21208
|
-
*/
|
|
21209
|
-
className: string().nullable(),
|
|
21210
|
-
/** `primary` is the one member that carries the group's identity. */
|
|
21211
|
-
role: _enum([
|
|
21212
|
-
"primary",
|
|
21213
|
-
"sibling",
|
|
21214
|
-
"child"
|
|
21215
|
-
]).nullable(),
|
|
21216
|
-
joinedAt: number(),
|
|
21217
|
-
/** Tier 1 — the sub-class (`dog`, `van`), resolved from the member's track
|
|
21218
|
-
* at read time. Absent when nothing resolved, never an empty string. */
|
|
21219
|
-
label: string().optional(),
|
|
21220
|
-
/** Tier 2 — the instance: a person's name, a plate. Absent when the pipeline
|
|
21221
|
-
* recognised nobody, and absent for a member whose track has been pruned —
|
|
21222
|
-
* a thumbnail that names the wrong person is worse than one naming nobody. */
|
|
21223
|
-
subLabel: string().optional()
|
|
21224
|
-
})).readonly()
|
|
21225
|
-
});
|
|
21226
|
-
/**
|
|
21227
|
-
* What a LIST of groups carries: the envelope plus what it is MADE OF.
|
|
21228
|
-
*
|
|
21229
|
-
* Coarse on purpose — the operator's rule is "only the rough data on the list,
|
|
21230
|
-
* we extend when we notice we need more". Enough to draw the card ("two people
|
|
21231
|
-
* and a dog") and no more. The MEMBERS, their names and the per-member links
|
|
21232
|
-
* are on {@link getSummary}: shipping every member of every group so a client
|
|
21233
|
-
* can count them turns a page of two hundred groups into a thousand records to
|
|
21234
|
-
* draw two hundred badges.
|
|
21235
|
-
*/
|
|
21236
|
-
var SummaryListItemSchema = object({
|
|
21237
|
-
summary: SummarySchema,
|
|
21238
|
-
/** Class counts, most numerous first; `className: null` is a member whose
|
|
21239
|
-
* class never resolved, counted so the counts add up to `memberCount`. */
|
|
21240
|
-
classes: array(object({
|
|
21241
|
-
className: string().nullable(),
|
|
21242
|
-
count: number().int().positive()
|
|
21243
|
-
})).readonly()
|
|
21244
|
-
});
|
|
21245
|
-
var SummariesPageSchema = object({ summaries: array(SummaryListItemSchema).readonly() });
|
|
21246
|
-
/**
|
|
21247
|
-
* The paged feed, deliberately the SAME shape as {@link RecentTracksQueryInput}.
|
|
21248
|
-
*
|
|
21249
|
-
* The reel on the cameras page and the Events gallery both ride a cursor, so a
|
|
21250
|
-
* summaries feed that could only answer "the last N for these cameras"
|
|
21251
|
-
* (`listSummaries`) would make groups available in the timeline and nowhere
|
|
21252
|
-
* else. Two feeds with different ordering contracts would be two ideas of what
|
|
21253
|
-
* "newest" means, on one screen.
|
|
21254
|
-
*/
|
|
21255
|
-
var RecentSummariesQueryInput = object({
|
|
21256
|
-
/** Devices to merge. An empty array yields an empty page. */
|
|
21257
|
-
deviceIds: array(number()),
|
|
21258
|
-
/** Window lower bound on `lastActiveAt` (inclusive). */
|
|
21259
|
-
since: number().optional(),
|
|
21260
|
-
/** Window upper bound on `lastActiveAt` (inclusive). */
|
|
21261
|
-
until: number().optional(),
|
|
21262
|
-
limit: number().int().min(1).max(500).default(100),
|
|
21263
|
-
/** Opaque continuation cursor from a previous page's `nextCursor`. */
|
|
21264
|
-
cursor: string().optional(),
|
|
21265
|
-
/**
|
|
21266
|
-
* Restrict to these classes — THE SAME FIELD `listRecentTracks` takes, and
|
|
21267
|
-
* deliberately the same name: the events filter tree emits one list of ticked
|
|
21268
|
-
* taxonomy nodes, and a summaries feed that called it something else would
|
|
21269
|
-
* make the operator's one filter component produce two shapes.
|
|
21270
|
-
*
|
|
21271
|
-
* A question about the MEMBERS: a group matches when ANY of them does. "Show
|
|
21272
|
-
* me the arrivals with a dog" has to return the group of four people who had
|
|
21273
|
-
* one with them; a filter on the group's own fields could only ever answer
|
|
21274
|
-
* about its primary.
|
|
21275
|
-
*
|
|
21276
|
-
* Matched against all THREE tiers of a member — the class (`animal`), the
|
|
21277
|
-
* sub-class (`dog`) and the instance (a name, a plate) — because which tier a
|
|
21278
|
-
* ticked node lives on is the taxonomy's business, not the caller's. `dog` is
|
|
21279
|
-
* an event kind in the tree and a tier-1 label on an `animal` track; a filter
|
|
21280
|
-
* that read only the class would answer "animal" and never "dog".
|
|
21281
|
-
*
|
|
21282
|
-
* ABSENT or EMPTY means no filter — absent is not a selection of none.
|
|
21283
|
-
*/
|
|
21284
|
-
classes: array(string().min(1).max(60)).max(40).optional()
|
|
21285
|
-
});
|
|
21286
|
-
var RecentSummariesPageSchema = object({
|
|
21287
|
-
/** Ordered by (`lastActiveAt` DESC, id DESC). Same light item as
|
|
21288
|
-
* {@link listSummaries} — one list shape, so a card renders the same
|
|
21289
|
-
* whichever feed drew it. */
|
|
21290
|
-
summaries: array(SummaryListItemSchema).readonly(),
|
|
21291
|
-
nextCursor: string().nullable()
|
|
21292
|
-
});
|
|
21293
21369
|
var RecentTracksPageSchema = object({
|
|
21294
21370
|
/** Merged page, ordered by (`lastSeen` DESC, `trackId` DESC). */
|
|
21295
21371
|
tracks: array(TrackSchema).readonly(),
|
|
@@ -21801,7 +21877,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
21801
21877
|
classes: array(string()).optional(),
|
|
21802
21878
|
/** See {@link ExcludeSourcesDoc}. */
|
|
21803
21879
|
excludeSources: array(TrackSourceSchema).optional()
|
|
21804
|
-
}), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(
|
|
21880
|
+
}), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(object({ deviceId: number() }), _void(), {
|
|
21805
21881
|
kind: "mutation",
|
|
21806
21882
|
auth: "admin"
|
|
21807
21883
|
}), method(DeviceEventQueryInput, array(MotionEventSchema).readonly()), method(ObjectEventQueryInput, array(ObjectEventSchema).readonly()), method(DeviceEventQueryInput, array(AudioEventSchema).readonly()), method(object({ deviceId: number() }), array(EventKindDescriptorSchema).readonly()), method(object({ deviceIds: array(number()).min(1).max(200) }), array(EventKindsForDeviceSchema).readonly()), method(object({
|
|
@@ -22981,6 +23057,23 @@ var MotionSourceEnum = _enum([
|
|
|
22981
23057
|
*/
|
|
22982
23058
|
var MotionSourcesSchema = array(MotionSourceEnum);
|
|
22983
23059
|
/**
|
|
23060
|
+
* The operator-facing name of each MOTION source (D672: `onboard` = the
|
|
23061
|
+
* camera's sensors — its own motion plus any sensor attached to it). The wire
|
|
23062
|
+
* value stays `onboard`; only the label changed. `detectionSources: 'onboard'`
|
|
23063
|
+
* ("Camera onboard AI") and the notification source filter keep their labels.
|
|
23064
|
+
*/
|
|
23065
|
+
var MOTION_SOURCE_LABELS = {
|
|
23066
|
+
analyzer: "Frame-diff Analyzer (motion addon)",
|
|
23067
|
+
onboard: "Camera sensors",
|
|
23068
|
+
"device-activity": "Device activity (the device says it is working)"
|
|
23069
|
+
};
|
|
23070
|
+
/** The order the motion-source picker offers them in (not the enum's order). */
|
|
23071
|
+
var MOTION_SOURCE_PICKER_ORDER = [
|
|
23072
|
+
"analyzer",
|
|
23073
|
+
"onboard",
|
|
23074
|
+
"device-activity"
|
|
23075
|
+
];
|
|
23076
|
+
/**
|
|
22984
23077
|
* Which root detector a camera runs — EXACTLY ONE.
|
|
22985
23078
|
*
|
|
22986
23079
|
* Deliberately the SAME vocabulary post-analysis already tags every detection
|
|
@@ -23327,7 +23420,14 @@ var RunnerCameraConfigSchema = object({
|
|
|
23327
23420
|
*/
|
|
23328
23421
|
inferenceDevices: array(RunnerInferenceDeviceSchema).readonly().optional()
|
|
23329
23422
|
});
|
|
23330
|
-
|
|
23423
|
+
MOTION_SOURCE_PICKER_ORDER.map((value) => value === "onboard" ? {
|
|
23424
|
+
value,
|
|
23425
|
+
label: MOTION_SOURCE_LABELS[value],
|
|
23426
|
+
description: "The camera's own motion, plus any sensor attached to it"
|
|
23427
|
+
} : {
|
|
23428
|
+
value,
|
|
23429
|
+
label: MOTION_SOURCE_LABELS[value]
|
|
23430
|
+
}), motionFpsField.min, motionFpsField.max, motionFpsField.step, motionFpsField.default, detectionFpsField.min, detectionFpsField.max, detectionFpsField.step, detectionFpsField.default, motionCooldownMsField.min, motionCooldownMsField.max, motionCooldownMsField.step, motionCooldownMsField.default, maxSessionHoldMsField.min, maxSessionHoldMsField.max, maxSessionHoldMsField.step, maxSessionHoldMsField.default, audioMotionWindowMsField.min, audioMotionWindowMsField.max, audioMotionWindowMsField.step, audioMotionWindowMsField.default, preRollInferenceFramesField.min, preRollInferenceFramesField.max, preRollInferenceFramesField.step, preRollInferenceFramesField.default, occupancyRecheckSecField.min, occupancyRecheckSecField.max, occupancyRecheckSecField.step, occupancyRecheckSecField.default, occupancyRecheckFramesField.min, occupancyRecheckFramesField.max, occupancyRecheckFramesField.step, occupancyRecheckFramesField.default;
|
|
23331
23431
|
/**
|
|
23332
23432
|
* Runtime load summary returned by `getLocalLoad`. Used by the orchestrator's
|
|
23333
23433
|
* load-balancing levels (L2 capacity-based, L3 hardware-aware) to decide
|
|
@@ -23901,6 +24001,11 @@ var CameraStatusSchema = object({
|
|
|
23901
24001
|
*/
|
|
23902
24002
|
switchedOff: array(CameraSwitchIdSchema).readonly(),
|
|
23903
24003
|
/**
|
|
24004
|
+
* The camera's attached sensors (D672). Optional only for a status composed
|
|
24005
|
+
* by an orchestrator older than D672; this orchestrator always sets it.
|
|
24006
|
+
*/
|
|
24007
|
+
cameraSensors: CameraSensorsStatusSchema.optional(),
|
|
24008
|
+
/**
|
|
23904
24009
|
* Stages of the bounded fan-out that were CUT SHORT — a timeout or a
|
|
23905
24010
|
* rejection — and whose block is therefore `null` because we could not
|
|
23906
24011
|
* READ it, not because there is nothing there.
|
|
@@ -26323,42 +26428,6 @@ DeviceType.Camera, method(object({
|
|
|
26323
26428
|
kind: "query",
|
|
26324
26429
|
auth: "protected"
|
|
26325
26430
|
});
|
|
26326
|
-
/**
|
|
26327
|
-
* LA tabella "quale booleano di questo tipo di device conta come ALTO", e il
|
|
26328
|
-
* valutatore puro del suo FRONTE.
|
|
26329
|
-
*
|
|
26330
|
-
* Viveva dentro il builtin virtual-doorbell
|
|
26331
|
-
* (`@camstack/system` — `builtins/doorbell/trigger-engine.ts`) e i suoi
|
|
26332
|
-
* predicati erano privati al modulo. Il recorder ne ha bisogno per il trigger
|
|
26333
|
-
* `RecordingTriggers.sensorDeviceIds`: copiarla avrebbe creato la SECONDA
|
|
26334
|
-
* tabella, che diverge alla prima cap aggiunta e il cui sintomo — "il sensore
|
|
26335
|
-
* fa suonare il campanello ma non registra" — è esattamente D62. Quindi si
|
|
26336
|
-
* SPOSTA qui e il doorbell la ri-esporta.
|
|
26337
|
-
*
|
|
26338
|
-
* ⚠ NON è `DEVICE_STATE_READERS` (`catalogs/device-state-vocabulary.ts`), e le
|
|
26339
|
-
* due non vanno unificate: quella risponde a "qual è la PAROLA di stato per una
|
|
26340
|
-
* regola" (e include `presence`, `cover`, `alarm-panel`), questa a "qual è il
|
|
26341
|
-
* booleano il cui FRONTE conta". Vocabolari deliberatamente diversi.
|
|
26342
|
-
*/
|
|
26343
|
-
/**
|
|
26344
|
-
* Known binary / switch source caps → the boolean slice field whose
|
|
26345
|
-
* false→true rise counts as ACTIVE. Every entry is "fire on active".
|
|
26346
|
-
* Sensors whose "active" reading is not a plain boolean (presence's string
|
|
26347
|
-
* state, connectivity's connected flag) are deliberately excluded — a
|
|
26348
|
-
* reconnect is not a doorbell press, and it is not a recording either.
|
|
26349
|
-
*/
|
|
26350
|
-
var SOURCE_CAP_ACTIVE_FIELD = {
|
|
26351
|
-
contact: "entryOpen",
|
|
26352
|
-
binary: "on",
|
|
26353
|
-
switch: "on",
|
|
26354
|
-
motion: "detected",
|
|
26355
|
-
flood: "flooded",
|
|
26356
|
-
gas: "detected",
|
|
26357
|
-
smoke: "detected",
|
|
26358
|
-
"carbon-monoxide": "detected",
|
|
26359
|
-
vibration: "detected",
|
|
26360
|
-
tamper: "tampered"
|
|
26361
|
-
};
|
|
26362
26431
|
object({
|
|
26363
26432
|
/** Ms epoch of the last press. null = never observed since this provider started. */
|
|
26364
26433
|
lastPressedAt: number().nullable(),
|
|
@@ -30008,7 +30077,9 @@ object({
|
|
|
30008
30077
|
detected: boolean(),
|
|
30009
30078
|
timestamp: number(),
|
|
30010
30079
|
source: MotionSourceEnum,
|
|
30011
|
-
regions: array(MotionRegionSchema).readonly().optional()
|
|
30080
|
+
regions: array(MotionRegionSchema).readonly().optional(),
|
|
30081
|
+
/** Who started it (D672). Absent = the camera itself. Only `onboard` carries `sensor`. */
|
|
30082
|
+
triggeredBy: MotionTriggeredBySchema.optional()
|
|
30012
30083
|
});
|
|
30013
30084
|
DeviceType.Camera, DeviceType.Sensor, method(object({ deviceId: number() }), boolean());
|
|
30014
30085
|
object({
|
|
@@ -32330,12 +32401,21 @@ var RecordingStorageUsageSchema = object({
|
|
|
32330
32401
|
*/
|
|
32331
32402
|
devicesRead: _enum(["archive", "unavailable"]).optional(),
|
|
32332
32403
|
/**
|
|
32404
|
+
* Is the `archive` answer WHOLE (D674): the hour ledger loaded without
|
|
32405
|
+
* hitting its row cap, and at least one location resolved? Only then may a
|
|
32406
|
+
* camera ABSENT from `devices[]` be read as "no footage" — and only then is a
|
|
32407
|
+
* row's `oldestMs` the archive's oldest rather than the oldest of a fraction.
|
|
32408
|
+
* OPTIONAL: a recorder predating D674 omits it, and a consumer must read the
|
|
32409
|
+
* absence as `false`. A retention floor is a delete; it never guesses.
|
|
32410
|
+
*/
|
|
32411
|
+
complete: boolean().optional(),
|
|
32412
|
+
/**
|
|
32333
32413
|
* Per-physical-volume capacity. OPTIONAL, and consumers must render the rest
|
|
32334
|
-
* of the payload without it:
|
|
32335
|
-
*
|
|
32336
|
-
*
|
|
32337
|
-
*
|
|
32338
|
-
*
|
|
32414
|
+
* of the payload without it: a recorder that could not build it omits it. A
|
|
32415
|
+
* UI that dereferences it unconditionally crashes the whole Storage page over
|
|
32416
|
+
* a missing disk bar. (The hub's cap routers pass output through unvalidated
|
|
32417
|
+
* since 2026-07-11 — `cap-router-builder.ts` — so a newer recorder's fields
|
|
32418
|
+
* are not stripped by an older hub.)
|
|
32339
32419
|
*/
|
|
32340
32420
|
locations: array(RecordingLocationUsageSchema).optional()
|
|
32341
32421
|
});
|
|
@@ -35106,7 +35186,12 @@ Object.freeze({
|
|
|
35106
35186
|
number: {
|
|
35107
35187
|
kind: "fixed",
|
|
35108
35188
|
result: ["number", "null"]
|
|
35109
|
-
}
|
|
35189
|
+
},
|
|
35190
|
+
rose: {
|
|
35191
|
+
kind: "fixed",
|
|
35192
|
+
result: ["number", "null"]
|
|
35193
|
+
},
|
|
35194
|
+
count: NUMBER
|
|
35110
35195
|
});
|
|
35111
35196
|
`${COMPOSED_DEVICE_STABLE_ID_PREFIX}`;
|
|
35112
35197
|
/**
|
|
@@ -38221,6 +38306,12 @@ Object.freeze({
|
|
|
38221
38306
|
addonId: null,
|
|
38222
38307
|
access: "view"
|
|
38223
38308
|
},
|
|
38309
|
+
"deviceManager.getWrapperActivation": {
|
|
38310
|
+
capName: "device-manager",
|
|
38311
|
+
capScope: "system",
|
|
38312
|
+
addonId: null,
|
|
38313
|
+
access: "view"
|
|
38314
|
+
},
|
|
38224
38315
|
"deviceManager.listAll": {
|
|
38225
38316
|
capName: "device-manager",
|
|
38226
38317
|
capScope: "system",
|
|
@@ -40495,12 +40586,6 @@ Object.freeze({
|
|
|
40495
40586
|
addonId: null,
|
|
40496
40587
|
access: "view"
|
|
40497
40588
|
},
|
|
40498
|
-
"pipelineAnalytics.getSummary": {
|
|
40499
|
-
capName: "pipeline-analytics",
|
|
40500
|
-
capScope: "device",
|
|
40501
|
-
addonId: null,
|
|
40502
|
-
access: "view"
|
|
40503
|
-
},
|
|
40504
40589
|
"pipelineAnalytics.getTrack": {
|
|
40505
40590
|
capName: "pipeline-analytics",
|
|
40506
40591
|
capScope: "device",
|
|
@@ -40561,12 +40646,6 @@ Object.freeze({
|
|
|
40561
40646
|
addonId: null,
|
|
40562
40647
|
access: "view"
|
|
40563
40648
|
},
|
|
40564
|
-
"pipelineAnalytics.listRecentSummaries": {
|
|
40565
|
-
capName: "pipeline-analytics",
|
|
40566
|
-
capScope: "device",
|
|
40567
|
-
addonId: null,
|
|
40568
|
-
access: "view"
|
|
40569
|
-
},
|
|
40570
40649
|
"pipelineAnalytics.listRecentTracks": {
|
|
40571
40650
|
capName: "pipeline-analytics",
|
|
40572
40651
|
capScope: "device",
|
|
@@ -40597,12 +40676,6 @@ Object.freeze({
|
|
|
40597
40676
|
addonId: null,
|
|
40598
40677
|
access: "view"
|
|
40599
40678
|
},
|
|
40600
|
-
"pipelineAnalytics.listSummaries": {
|
|
40601
|
-
capName: "pipeline-analytics",
|
|
40602
|
-
capScope: "device",
|
|
40603
|
-
addonId: null,
|
|
40604
|
-
access: "view"
|
|
40605
|
-
},
|
|
40606
40679
|
"pipelineAnalytics.listTrackMedia": {
|
|
40607
40680
|
capName: "pipeline-analytics",
|
|
40608
40681
|
capScope: "device",
|
|
@@ -44030,6 +44103,11 @@ Object.freeze({
|
|
|
44030
44103
|
form: "single",
|
|
44031
44104
|
optional: false
|
|
44032
44105
|
}],
|
|
44106
|
+
"deviceManager.getWrapperActivation": [{
|
|
44107
|
+
name: "deviceId",
|
|
44108
|
+
form: "single",
|
|
44109
|
+
optional: false
|
|
44110
|
+
}],
|
|
44033
44111
|
"deviceManager.listAll": [{
|
|
44034
44112
|
name: "deviceIds",
|
|
44035
44113
|
form: "array",
|
|
@@ -44767,11 +44845,6 @@ Object.freeze({
|
|
|
44767
44845
|
form: "single",
|
|
44768
44846
|
optional: true
|
|
44769
44847
|
}],
|
|
44770
|
-
"pipelineAnalytics.listRecentSummaries": [{
|
|
44771
|
-
name: "deviceIds",
|
|
44772
|
-
form: "array",
|
|
44773
|
-
optional: false
|
|
44774
|
-
}],
|
|
44775
44848
|
"pipelineAnalytics.listRecentTracks": [{
|
|
44776
44849
|
name: "deviceIds",
|
|
44777
44850
|
form: "array",
|
|
@@ -44782,11 +44855,6 @@ Object.freeze({
|
|
|
44782
44855
|
form: "array",
|
|
44783
44856
|
optional: true
|
|
44784
44857
|
}],
|
|
44785
|
-
"pipelineAnalytics.listSummaries": [{
|
|
44786
|
-
name: "deviceIds",
|
|
44787
|
-
form: "array",
|
|
44788
|
-
optional: false
|
|
44789
|
-
}],
|
|
44790
44858
|
"pipelineAnalytics.listTrackMedia": [{
|
|
44791
44859
|
name: "deviceId",
|
|
44792
44860
|
form: "single",
|
|
@@ -46598,7 +46666,7 @@ var AgentUIAddon = class extends BaseAddon {
|
|
|
46598
46666
|
capability: adminUiCapability,
|
|
46599
46667
|
provider: {
|
|
46600
46668
|
getStaticDir: async () => ({ staticDir: path.resolve(__dirname) }),
|
|
46601
|
-
getVersion: async () => ({ version: "1.2.
|
|
46669
|
+
getVersion: async () => ({ version: "1.2.156" })
|
|
46602
46670
|
}
|
|
46603
46671
|
}];
|
|
46604
46672
|
}
|