@camstack/types 1.2.26 → 1.2.28

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/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_sleep = require("./sleep-BvSjpsfC.js");
2
+ const require_sleep = require("./sleep-6oDIDtYV.js");
3
3
  const require_event_category = require("./event-category-BE4PDZ_3.js");
4
4
  const require_enums = require("./enums.js");
5
5
  const require_err_msg = require("./err-msg-COpsHMw2.js");
@@ -4857,6 +4857,69 @@ var NcZoneConditionSchema = zod.z.object({
4857
4857
  * membership lists are OR within the list (spec §2.3).
4858
4858
  */
4859
4859
  /**
4860
+ * What a rule may actuate.
4861
+ *
4862
+ * **No hand-maintained allowlist** (operator decision, and the right one — a
4863
+ * written list of methods is a third parallel map to keep aligned, and this
4864
+ * repo has paid for those). The boundary instead comes from a property the
4865
+ * capabilities already carry: an action may target only a **device-scoped**
4866
+ * capability method.
4867
+ *
4868
+ * That is not decoration. A rule can be authored by a NON-ADMIN — personal
4869
+ * rules are a supported flow — and the executor runs with the addon's
4870
+ * privileges, so an unbounded action is an arbitrary RPC channel with a
4871
+ * privilege escalation attached. Restricting to device scope excludes the
4872
+ * system caps (`device-manager.removeDevice` and friends) by construction,
4873
+ * costs nothing to maintain, and cannot rot: a cap that stops being
4874
+ * device-scoped stops being actuatable in the same change.
4875
+ *
4876
+ * The executor enforces it; {@link NcRuleActionSchema} carries the intent.
4877
+ */
4878
+ /**
4879
+ * One step of a sequence.
4880
+ *
4881
+ * `wait` is a first-class step rather than a property of the next action: it is
4882
+ * what makes a sequence a SEQUENCE and not a list — "unlock, wait 5s, open"
4883
+ * cannot be expressed otherwise.
4884
+ */
4885
+ var NcRuleActionSchema = zod.z.discriminatedUnion("kind", [zod.z.object({
4886
+ kind: zod.z.literal("wait"),
4887
+ seconds: zod.z.number().min(0).max(300)
4888
+ }), zod.z.object({
4889
+ kind: zod.z.literal("cap"),
4890
+ deviceId: zod.z.number().int(),
4891
+ /** Capability name, e.g. `alarm-panel`. */
4892
+ cap: zod.z.string().min(1),
4893
+ /** Method on it. The executor refuses a non-device-scoped cap. */
4894
+ method: zod.z.string().min(1),
4895
+ /** Method arguments, minus `deviceId` (the executor injects it). */
4896
+ args: zod.z.record(zod.z.string(), zod.z.unknown()).optional()
4897
+ })]);
4898
+ /**
4899
+ * A named, ordered run of steps with its own throttle.
4900
+ *
4901
+ * `minDelaySec` exists because a noisy rule otherwise hammers a physical
4902
+ * actuator — the rule's own cooldown governs NOTIFICATIONS, which is a
4903
+ * different budget from "how often may this gate actually open".
4904
+ */
4905
+ var NcRuleActionSequenceSchema = zod.z.object({
4906
+ name: zod.z.string().min(1).max(120),
4907
+ enabled: zod.z.boolean(),
4908
+ minDelaySec: zod.z.number().int().min(0).max(86400).optional(),
4909
+ actions: zod.z.array(NcRuleActionSchema).min(1)
4910
+ });
4911
+ /**
4912
+ * Sequences a rule runs, by hook point.
4913
+ *
4914
+ * ONLY `onTrigger` is here, deliberately. The reference also has activation /
4915
+ * deactivation / reset / post-generation hooks, and they are wanted — but this
4916
+ * repo's expensive failure mode is declaring a surface nothing produces, so a
4917
+ * hook appears here in the same change that produces its edge, never before.
4918
+ */
4919
+ var NcRuleActionsSchema = zod.z.object({
4920
+ /** Runs when the rule MATCHES. */
4921
+ onTrigger: zod.z.array(NcRuleActionSequenceSchema).optional() });
4922
+ /**
4860
4923
  * "This rule applies only while `deviceId` is in one of `states`."
4861
4924
  *
4862
4925
  * The states are the DEVICE's own vocabulary — `AlarmState` for a panel,
@@ -5167,7 +5230,16 @@ var NcRuleInputSchema = zod.z.object({
5167
5230
  * read as `false` by {@link canSetGlobal} in the engine. Admins are not bound
5168
5231
  * by this flag — see the scope rules on that function.
5169
5232
  */
5170
- snoozeAllowGlobal: zod.z.boolean().optional()
5233
+ snoozeAllowGlobal: zod.z.boolean().optional(),
5234
+ /**
5235
+ * Devices this rule ACTUATES — arm the alarm, open a gate, turn on a light.
5236
+ *
5237
+ * This is what makes the rule set the alarm's trigger set without the alarm
5238
+ * being a special case: arming is
5239
+ * `{ cap: 'alarm-panel', method: 'arm', args: { mode: 'away' } }`, the same
5240
+ * shape as every other actuation.
5241
+ */
5242
+ actions: NcRuleActionsSchema.optional()
5171
5243
  });
5172
5244
  /**
5173
5245
  * Partial patch for `updateRule` — any subset of the input fields, plus the
@@ -14900,6 +14972,16 @@ function createSystemProxy(api) {
14900
14972
  getState: (input) => dispatch("broker", "getState", "query", input),
14901
14973
  getStatus: (input) => dispatch("broker", "getStatus", "query", input)
14902
14974
  },
14975
+ coreBlocks: {
14976
+ list: (input) => dispatch("coreBlocks", "list", "query", input),
14977
+ get: (input) => dispatch("coreBlocks", "get", "query", input),
14978
+ create: (input) => dispatch("coreBlocks", "create", "mutation", input),
14979
+ update: (input) => dispatch("coreBlocks", "update", "mutation", input),
14980
+ delete: (input) => dispatch("coreBlocks", "delete", "mutation", input),
14981
+ setEnabled: (input) => dispatch("coreBlocks", "setEnabled", "mutation", input),
14982
+ compile: (input) => dispatch("coreBlocks", "compile", "mutation", input),
14983
+ getTypeDefs: (input) => dispatch("coreBlocks", "getTypeDefs", "query", input)
14984
+ },
14903
14985
  decoder: {
14904
14986
  supportsCodec: (input) => dispatch("decoder", "supportsCodec", "query", input),
14905
14987
  getInfo: (input) => dispatch("decoder", "getInfo", "query", input),
@@ -20720,6 +20802,137 @@ var notificationOutputCapability = {
20720
20802
  }
20721
20803
  };
20722
20804
  //#endregion
20805
+ //#region src/capabilities/core-blocks.cap.ts
20806
+ /**
20807
+ * core-blocks — user-authored TypeScript, stored in the kernel and executed in
20808
+ * its own process.
20809
+ *
20810
+ * Spec: `docs/superpowers/specs/2026-08-04-core-blocks-and-synthetic-devices-design.md`.
20811
+ *
20812
+ * The first use is **owning devices without being a device provider**: a block
20813
+ * declares devices under a system or custom integration and drives their state,
20814
+ * with the same `ctx` an addon gets. Automations come later; nothing here
20815
+ * models a trigger.
20816
+ *
20817
+ * **Stated plainly, because it does not change by being true:** a block has an
20818
+ * addon's powers — devices, storage, the event bus, `ctx.api`. It is a plugin
20819
+ * with no review step. What makes that survivable is not a sandbox, it is
20820
+ * PROCESS ISOLATION: one process per block, supervised by `CrashSupervisor`,
20821
+ * so a block that throws or never returns is marked `failed` and visible
20822
+ * instead of taking the hub with it (D6). Every method here is admin-only, and
20823
+ * must stay so.
20824
+ */
20825
+ /** Where a block runs. The operator chooses — a block driving a device on an
20826
+ * agent is the reason placement is not fixed to the hub. */
20827
+ var CoreBlockPlacementSchema = zod.z.union([zod.z.literal("hub"), zod.z.string().min(1)]);
20828
+ /** What a block's process is doing. Mirrors the addon runner's own lifecycle so
20829
+ * a failing block reads the same way a failing addon does. */
20830
+ var CoreBlockStatusSchema = zod.z.enum([
20831
+ "stopped",
20832
+ "starting",
20833
+ "running",
20834
+ "failed"
20835
+ ]);
20836
+ /** Client-authored fields. */
20837
+ var CoreBlockInputSchema = zod.z.object({
20838
+ name: zod.z.string().min(1).max(120),
20839
+ /** TypeScript source. Compiled server-side before it is ever stored — a
20840
+ * block that does not compile is a fork failure the operator would meet
20841
+ * minutes later, in a log, instead of in the editor. */
20842
+ code: zod.z.string().max(2e5),
20843
+ enabled: zod.z.boolean(),
20844
+ placement: CoreBlockPlacementSchema,
20845
+ /**
20846
+ * Integration the block's devices hang from. Absent = the system integration
20847
+ * blocks share. A block may declare its own instead.
20848
+ */
20849
+ integrationId: zod.z.string().optional()
20850
+ });
20851
+ /** A stored block. */
20852
+ var CoreBlockSchema = CoreBlockInputSchema.extend({
20853
+ id: zod.z.string(),
20854
+ createdAt: zod.z.number(),
20855
+ updatedAt: zod.z.number(),
20856
+ /** Server-stamped author. */
20857
+ createdBy: zod.z.string(),
20858
+ status: CoreBlockStatusSchema,
20859
+ /**
20860
+ * Why the block is not running, when it is not. The operator's ONLY window
20861
+ * into a block that failed at load — a block that is silently absent is the
20862
+ * failure mode this whole feature has to avoid.
20863
+ */
20864
+ lastError: zod.z.string().optional(),
20865
+ /** Ms epoch of the last state change. */
20866
+ lastChangedAt: zod.z.number()
20867
+ });
20868
+ /** What a compile attempt produced. */
20869
+ var CoreBlockCompileResultSchema = zod.z.object({
20870
+ ok: zod.z.boolean(),
20871
+ /** Present when `ok` is false — the first error, in the author's words. */
20872
+ error: zod.z.string().optional(),
20873
+ line: zod.z.number().optional(),
20874
+ column: zod.z.number().optional()
20875
+ });
20876
+ var coreBlocksCapability = {
20877
+ name: "core-blocks",
20878
+ scope: "system",
20879
+ mode: "singleton",
20880
+ methods: {
20881
+ list: require_sleep.method(zod.z.object({}), zod.z.object({ blocks: zod.z.array(CoreBlockSchema) }), { auth: "admin" }),
20882
+ get: require_sleep.method(zod.z.object({ blockId: zod.z.string() }), zod.z.object({ block: CoreBlockSchema.nullable() }), { auth: "admin" }),
20883
+ /**
20884
+ * Create a block. The code is COMPILED first: storing source that does not
20885
+ * compile turns an editor error into a fork failure the operator meets
20886
+ * minutes later in a log.
20887
+ */
20888
+ create: require_sleep.method(zod.z.object({ block: CoreBlockInputSchema }), zod.z.object({ block: CoreBlockSchema }), {
20889
+ kind: "mutation",
20890
+ auth: "admin",
20891
+ caller: "required"
20892
+ }),
20893
+ update: require_sleep.method(zod.z.object({
20894
+ blockId: zod.z.string(),
20895
+ block: CoreBlockInputSchema.partial()
20896
+ }), zod.z.object({ block: CoreBlockSchema }), {
20897
+ kind: "mutation",
20898
+ auth: "admin",
20899
+ caller: "required"
20900
+ }),
20901
+ delete: require_sleep.method(zod.z.object({ blockId: zod.z.string() }), zod.z.object({ success: zod.z.literal(true) }), {
20902
+ kind: "mutation",
20903
+ auth: "admin"
20904
+ }),
20905
+ setEnabled: require_sleep.method(zod.z.object({
20906
+ blockId: zod.z.string(),
20907
+ enabled: zod.z.boolean()
20908
+ }), zod.z.object({ block: CoreBlockSchema }), {
20909
+ kind: "mutation",
20910
+ auth: "admin"
20911
+ }),
20912
+ /**
20913
+ * Type-check without saving — what the editor calls as the author types, so
20914
+ * the compiler's verdict is the same one the server will reach.
20915
+ */
20916
+ compile: require_sleep.method(zod.z.object({ code: zod.z.string() }), CoreBlockCompileResultSchema, {
20917
+ kind: "mutation",
20918
+ auth: "admin"
20919
+ }),
20920
+ /**
20921
+ * The declaration files the editor type-checks against.
20922
+ *
20923
+ * Served rather than bundled: the graph is 3.4 MB across 344 files, and
20924
+ * bundling it would roughly double the admin remote. Served rather than
20925
+ * hand-stubbed: a block runs with the same `ctx` an addon gets, so a stub
20926
+ * would drift and the editor would confidently autocomplete methods that
20927
+ * do not exist.
20928
+ */
20929
+ getTypeDefs: require_sleep.method(zod.z.object({}), zod.z.object({ libs: zod.z.array(zod.z.object({
20930
+ filePath: zod.z.string(),
20931
+ content: zod.z.string()
20932
+ })) }), { auth: "admin" })
20933
+ }
20934
+ };
20935
+ //#endregion
20723
20936
  //#region src/schemas/auth-records.ts
20724
20937
  /**
20725
20938
  * Zod schemas for persisted record types.
@@ -27388,6 +27601,7 @@ var CAPABILITY_NAMES = {
27388
27601
  consumables: "consumables",
27389
27602
  contact: "contact",
27390
27603
  control: "control",
27604
+ coreBlocks: "core-blocks",
27391
27605
  cover: "cover",
27392
27606
  customModelRegistry: "custom-model-registry",
27393
27607
  dataStoreProvider: "data-store-provider",
@@ -27640,6 +27854,10 @@ var CAPABILITY_ROUTER_KEYS = [
27640
27854
  key: "control",
27641
27855
  name: "control"
27642
27856
  },
27857
+ {
27858
+ key: "coreBlocks",
27859
+ name: "core-blocks"
27860
+ },
27643
27861
  {
27644
27862
  key: "cover",
27645
27863
  name: "cover"
@@ -28122,6 +28340,7 @@ var ALL_CAPABILITY_DEFINITIONS = [
28122
28340
  consumablesCapability,
28123
28341
  contactCapability,
28124
28342
  controlCapability,
28343
+ coreBlocksCapability,
28125
28344
  coverCapability,
28126
28345
  customModelRegistryCapability,
28127
28346
  dataStoreProviderCapability,
@@ -29098,6 +29317,54 @@ var METHOD_ACCESS_MAP = Object.freeze({
29098
29317
  addonId: null,
29099
29318
  access: "create"
29100
29319
  },
29320
+ "coreBlocks.compile": {
29321
+ capName: "core-blocks",
29322
+ capScope: "system",
29323
+ addonId: null,
29324
+ access: "create"
29325
+ },
29326
+ "coreBlocks.create": {
29327
+ capName: "core-blocks",
29328
+ capScope: "system",
29329
+ addonId: null,
29330
+ access: "create"
29331
+ },
29332
+ "coreBlocks.delete": {
29333
+ capName: "core-blocks",
29334
+ capScope: "system",
29335
+ addonId: null,
29336
+ access: "delete"
29337
+ },
29338
+ "coreBlocks.get": {
29339
+ capName: "core-blocks",
29340
+ capScope: "system",
29341
+ addonId: null,
29342
+ access: "view"
29343
+ },
29344
+ "coreBlocks.getTypeDefs": {
29345
+ capName: "core-blocks",
29346
+ capScope: "system",
29347
+ addonId: null,
29348
+ access: "view"
29349
+ },
29350
+ "coreBlocks.list": {
29351
+ capName: "core-blocks",
29352
+ capScope: "system",
29353
+ addonId: null,
29354
+ access: "view"
29355
+ },
29356
+ "coreBlocks.setEnabled": {
29357
+ capName: "core-blocks",
29358
+ capScope: "system",
29359
+ addonId: null,
29360
+ access: "create"
29361
+ },
29362
+ "coreBlocks.update": {
29363
+ capName: "core-blocks",
29364
+ capScope: "system",
29365
+ addonId: null,
29366
+ access: "create"
29367
+ },
29101
29368
  "cover.close": {
29102
29369
  capName: "cover",
29103
29370
  capScope: "device",
@@ -33407,6 +33674,7 @@ var KNOWN_CAP_NAMES = [
33407
33674
  "color",
33408
33675
  "consumables",
33409
33676
  "control",
33677
+ "core-blocks",
33410
33678
  "cover",
33411
33679
  "custom-model-registry",
33412
33680
  "data-store-provider",
@@ -33571,6 +33839,7 @@ var SYSTEM_CAP_NAMES = [
33571
33839
  "auth-provider",
33572
33840
  "backup",
33573
33841
  "broker",
33842
+ "core-blocks",
33574
33843
  "custom-model-registry",
33575
33844
  "data-store-provider",
33576
33845
  "decoder",
@@ -34368,6 +34637,11 @@ exports.ControlStatusSchema = ControlStatusSchema;
34368
34637
  exports.ConvertArtifactSchema = ConvertArtifactSchema;
34369
34638
  exports.ConvertResultSchema = ConvertResultSchema;
34370
34639
  exports.ConvertTargetSchema = ConvertTargetSchema;
34640
+ exports.CoreBlockCompileResultSchema = CoreBlockCompileResultSchema;
34641
+ exports.CoreBlockInputSchema = CoreBlockInputSchema;
34642
+ exports.CoreBlockPlacementSchema = CoreBlockPlacementSchema;
34643
+ exports.CoreBlockSchema = CoreBlockSchema;
34644
+ exports.CoreBlockStatusSchema = CoreBlockStatusSchema;
34371
34645
  exports.CoverStateSchema = CoverStateSchema;
34372
34646
  exports.CoverStatusSchema = CoverStatusSchema;
34373
34647
  exports.CreateApiKeyInputSchema = CreateApiKeyInputSchema;
@@ -34389,6 +34663,7 @@ exports.DEFAULT_SCRUB_THUMBNAIL_PRESET = DEFAULT_SCRUB_THUMBNAIL_PRESET;
34389
34663
  exports.DEVICE_BACKEND_TO_FORMAT = DEVICE_BACKEND_TO_FORMAT;
34390
34664
  exports.DEVICE_CAP_NAMES = DEVICE_CAP_NAMES;
34391
34665
  exports.DEVICE_PROFILES = DEVICE_PROFILES;
34666
+ exports.DEVICE_SCOPED_CAPS = require_sleep.DEVICE_SCOPED_CAPS;
34392
34667
  exports.DEVICE_SETTINGS_CONTRIBUTION_METHODS = require_sleep.DEVICE_SETTINGS_CONTRIBUTION_METHODS;
34393
34668
  exports.DEVICE_STATE_READERS = DEVICE_STATE_READERS;
34394
34669
  exports.DEVICE_STATUS_METHOD = require_sleep.DEVICE_STATUS_METHOD;
@@ -34612,6 +34887,9 @@ exports.NcMediaFrameSchema = NcMediaFrameSchema;
34612
34887
  exports.NcMediaPolicySchema = NcMediaPolicySchema;
34613
34888
  exports.NcOccupancyConditionSchema = NcOccupancyConditionSchema;
34614
34889
  exports.NcPlateMatcherSchema = NcPlateMatcherSchema;
34890
+ exports.NcRuleActionSchema = NcRuleActionSchema;
34891
+ exports.NcRuleActionSequenceSchema = NcRuleActionSequenceSchema;
34892
+ exports.NcRuleActionsSchema = NcRuleActionsSchema;
34615
34893
  exports.NcRuleInputSchema = NcRuleInputSchema;
34616
34894
  exports.NcRulePatchSchema = NcRulePatchSchema;
34617
34895
  exports.NcRuleSchema = NcRuleSchema;
@@ -34948,6 +35226,7 @@ exports.consumablesCapability = consumablesCapability;
34948
35226
  exports.contactCapability = contactCapability;
34949
35227
  exports.controlCapability = controlCapability;
34950
35228
  exports.convertUnit = convertUnit;
35229
+ exports.coreBlocksCapability = coreBlocksCapability;
34951
35230
  exports.cosineSimilarity = cosineSimilarity;
34952
35231
  exports.coverCapability = coverCapability;
34953
35232
  exports.createDeviceProxy = require_sleep.createDeviceProxy;
@@ -35028,6 +35307,7 @@ exports.isBaseConditionKey = isBaseConditionKey;
35028
35307
  exports.isCollectionArrayMethod = isCollectionArrayMethod;
35029
35308
  exports.isDeployableToAgent = isDeployableToAgent;
35030
35309
  exports.isDeviceConfigCap = require_sleep.isDeviceConfigCap;
35310
+ exports.isDeviceScopedCap = require_sleep.isDeviceScopedCap;
35031
35311
  exports.isEvent = require_sleep.isEvent;
35032
35312
  exports.isNode = isNode;
35033
35313
  exports.isObjectInput = isObjectInput;