@camstack/addon-post-analysis 1.2.33 → 1.2.34

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.
@@ -9493,6 +9493,276 @@ var MaskGridDimsSchema = object({
9493
9493
  height: number()
9494
9494
  });
9495
9495
  /**
9496
+ * notification-output — canonical, capability-gated notification delivery.
9497
+ *
9498
+ * Apprise-derived model (see
9499
+ * `docs/superpowers/specs/2026-07-03-notification-output-notifier-matrix.md`):
9500
+ * callers emit ONE canonical `Notification`; each provider declares a
9501
+ * per-kind capability descriptor (`TargetKind`), and the pure degrade
9502
+ * engine (`@camstack/types` `prepareNotification`) transcodes / degrades the
9503
+ * message to what the kind supports — callers never special-case a service.
9504
+ *
9505
+ * DESIGN DECISIONS (locked):
9506
+ * - Target CRUD lives on THIS cap (`upsertTarget` / `deleteTarget` /
9507
+ * `setTargetEnabled`), each provider persisting via the `settings-store`
9508
+ * cap. Rationale: the admin UI needs one uniform surface across the
9509
+ * notifiers addon AND the HA addon; the addon-`globalSettingsSchema`-array
9510
+ * alternative would fork the UI per addon and cannot host the
9511
+ * discovery→adopt flow.
9512
+ * - `listTargetKinds` / `listTargets` / `discoverTargets` return arrays →
9513
+ * the generated cap-mount auto-`concatCollection`-fans them across every
9514
+ * registered provider (notifiers addon + HA addon) so one catalog is
9515
+ * routable. `send` / `testTarget` / CRUD route to ONE provider by the
9516
+ * `addonId` the generated collection router extracts from the call input.
9517
+ * - `Attachment.bytes` is `Uint8Array`. Transport-safe: superjson (the tRPC
9518
+ * transformer) + UDS MsgPack both round-trip typed arrays — already used by
9519
+ * `storage` / `storage-provider` / `recording` caps over the same path. No
9520
+ * base64 fallback needed.
9521
+ *
9522
+ * TODO (deferred, closed-set change — separate decision): add
9523
+ * `providerKind: 'notify'` so notification providers surface on the unified
9524
+ * admin "Integrations" page.
9525
+ */
9526
+ /**
9527
+ * Zentik-derived typed-media enum — the superset across every kind. Each
9528
+ * adapter picks what it supports and the degrade engine filters the rest.
9529
+ */
9530
+ var AttachmentMediaTypeSchema = _enum([
9531
+ "image",
9532
+ "video",
9533
+ "gif",
9534
+ "audio",
9535
+ "icon"
9536
+ ]);
9537
+ /**
9538
+ * A single attachment. Exactly one of `url` (remote source, most adapters
9539
+ * prefer this) or `bytes` (inline source; required for Pushover-style
9540
+ * bytes-only kinds) MUST be present — the degrade engine expresses a
9541
+ * url→bytes fetch as a `needsFetch` directive the adapter executes.
9542
+ */
9543
+ var AttachmentSchema = object({
9544
+ mediaType: AttachmentMediaTypeSchema,
9545
+ url: string().optional(),
9546
+ bytes: _instanceof(Uint8Array).optional(),
9547
+ mime: string().optional(),
9548
+ name: string().optional()
9549
+ }).refine((a) => a.url !== void 0 || a.bytes !== void 0, { message: "Attachment requires either `url` or `bytes`" });
9550
+ var NotificationFormatSchema = _enum([
9551
+ "text",
9552
+ "markdown",
9553
+ "html"
9554
+ ]);
9555
+ /**
9556
+ * The CLOSED icon vocabulary an action button may use.
9557
+ *
9558
+ * A closed set, not a free string, and that is the whole point: an arbitrary
9559
+ * icon name is one that ntfy renders, zentik silently drops, and nobody
9560
+ * notices — the same class of gap as a zone vocabulary nothing produced
9561
+ * ([D35](../../../docs/decisions/adr-0035.md)). Every adapter maps this set or
9562
+ * declares `actionIcons: false` and the degrade engine strips the field.
9563
+ *
9564
+ * Named by INTENT, never by glyph. "check" would tie the vocabulary to one
9565
+ * renderer's icon set; "acknowledge" survives an adapter that draws it
9566
+ * differently.
9567
+ */
9568
+ var NotificationActionIconSchema = _enum([
9569
+ "acknowledge",
9570
+ "dismiss",
9571
+ "silence",
9572
+ "view",
9573
+ "play",
9574
+ "open",
9575
+ "close",
9576
+ "lock",
9577
+ "unlock",
9578
+ "arm",
9579
+ "disarm",
9580
+ "light",
9581
+ "alert"
9582
+ ]);
9583
+ /** A single tap-through action button. */
9584
+ var NotificationActionSchema = object({
9585
+ id: string(),
9586
+ label: string(),
9587
+ url: string().optional(),
9588
+ /** Dropped by the degrade engine for a kind with `caps.actionIcons: false`. */
9589
+ icon: NotificationActionIconSchema.optional(),
9590
+ /**
9591
+ * Renders in a warning style where the notifier supports it.
9592
+ *
9593
+ * A HINT, never a gate. The callback's authority is its token and nothing
9594
+ * else — see `notification-center/action-token.ts` for what that does and
9595
+ * does not buy.
9596
+ */
9597
+ destructive: boolean().optional()
9598
+ });
9599
+ /**
9600
+ * The canonical notification. `body` is the only hard field (Apprise model).
9601
+ * `priority` is a 5-level ORDINAL (1=lowest … 3=normal(default) … 5=urgent),
9602
+ * NOT a fixed severity enum — each kind declares its own `caps.levels` and
9603
+ * the adapter maps this ordinal onto its native level. `level?` is an
9604
+ * optional kind-native level id (`emergency`, `silent`, …) that overrides
9605
+ * `priority` for that one target.
9606
+ */
9607
+ var NotificationSchema = object({
9608
+ body: string(),
9609
+ title: string().optional(),
9610
+ format: NotificationFormatSchema.default("text"),
9611
+ priority: number().int().min(1).max(5).default(3),
9612
+ level: string().optional(),
9613
+ attachments: array(AttachmentSchema).optional(),
9614
+ clickUrl: string().optional(),
9615
+ actions: array(NotificationActionSchema).optional(),
9616
+ sound: string().optional(),
9617
+ ttl: number().optional(),
9618
+ tag: string().optional(),
9619
+ deviceId: number().optional(),
9620
+ eventId: string().optional(),
9621
+ metadata: record(string(), unknown()).optional()
9622
+ });
9623
+ /** One declared native severity/priority level for a kind. */
9624
+ var TargetKindLevelSchema = object({
9625
+ id: string(),
9626
+ label: string(),
9627
+ /** Which canonical priority (1..5) this level maps to. `null` = qualitative-only. */
9628
+ ordinal: number().int().min(1).max(5).nullable(),
9629
+ flags: object({
9630
+ critical: boolean().optional(),
9631
+ silent: boolean().optional(),
9632
+ noPush: boolean().optional()
9633
+ }).optional(),
9634
+ /** e.g. Pushover `emergency` requires `retry` / `expire`. */
9635
+ requires: array(string()).optional(),
9636
+ description: string().optional()
9637
+ });
9638
+ /** The full capability block consulted before dispatch. */
9639
+ var TargetKindCapsSchema = object({
9640
+ attachments: object({
9641
+ mediaTypes: array(AttachmentMediaTypeSchema),
9642
+ mode: _enum([
9643
+ "url",
9644
+ "bytes",
9645
+ "both"
9646
+ ]),
9647
+ max: number().int().nonnegative(),
9648
+ maxBytes: number().int().positive().optional()
9649
+ }),
9650
+ /** Max action buttons (0 = none). */
9651
+ actions: number().int().nonnegative(),
9652
+ /**
9653
+ * Whether this kind renders a per-action ICON.
9654
+ *
9655
+ * `.optional()`, deliberately NOT `.default(false)`: a Zod default does not
9656
+ * run on the addon cap path — three production failures in one day taught
9657
+ * this repo that once. Absent is read as false by the degrade engine, which
9658
+ * is the safe direction: an icon that is not rendered costs nothing, an icon
9659
+ * assumed and dropped costs the operator's trust in the field.
9660
+ */
9661
+ actionIcons: boolean().optional(),
9662
+ levels: array(TargetKindLevelSchema),
9663
+ format: array(NotificationFormatSchema),
9664
+ clickUrl: boolean(),
9665
+ sound: boolean(),
9666
+ ttl: boolean(),
9667
+ bodyMaxLen: number().int().positive()
9668
+ });
9669
+ /**
9670
+ * `configSchema` is a `ConfigUISchema` tree passed through to the admin
9671
+ * FormBuilder. Stored as `z.unknown()` at the cap seam (mirrors
9672
+ * `device-provider.getChildCreationSchema` `CreationSchemaOutputSchema`) —
9673
+ * the union is large and not meant for runtime validation here; the exported
9674
+ * `TargetKind` type re-tightens `configSchema` to `ConfigUISchema`.
9675
+ */
9676
+ var ConfigSchemaPassthrough$1 = unknown();
9677
+ var TargetKindSchema = object({
9678
+ kind: string(),
9679
+ label: string(),
9680
+ icon: string(),
9681
+ /** Stamped by each provider so the concat-fanned catalog stays routable. */
9682
+ addonId: string(),
9683
+ /**
9684
+ * URL of the kind's bundled BRAND icon, served by the providing addon over
9685
+ * its own `addon-routes` surface (`/addon/<addonId>/icons/<kind>`). Absent
9686
+ * when the addon bundles no icon for that kind — the client then falls back
9687
+ * to a neutral glyph rather than rendering the raw `icon` NAME as text.
9688
+ *
9689
+ * Root-relative on purpose: it resolves against whatever origin serves a web
9690
+ * client, and a native client joins it onto its own hub base.
9691
+ *
9692
+ * DECLARED here deliberately. It used to travel as an undeclared passthrough
9693
+ * field that survived only because the runtime cap-router forwards provider
9694
+ * output verbatim — so every consumer had to re-declare it by hand to stop
9695
+ * its own Zod parse from stripping it, and the whole arrangement would have
9696
+ * broken silently the moment output validation was tightened anywhere.
9697
+ */
9698
+ iconUrl: string().optional(),
9699
+ /**
9700
+ * Media type of {@link iconUrl} (`image/svg+xml`, `image/png`, …).
9701
+ *
9702
+ * The server knows this and therefore says it, because the client cannot
9703
+ * safely guess: a React-Native client renders SVG and raster through two
9704
+ * DIFFERENT components (`react-native-svg` vs `expo-image` — expo-image does
9705
+ * not decode SVG on iOS/Android), so without this it silently fell back to a
9706
+ * placeholder glyph for every vector icon while the web build looked fine.
9707
+ *
9708
+ * Absent when {@link iconUrl} is absent, or for a legacy provider that has
9709
+ * not been updated — a client that cannot determine the type should prefer
9710
+ * its raster path, which is the safe default for an unknown image.
9711
+ */
9712
+ iconMediaType: string().optional(),
9713
+ configSchema: ConfigSchemaPassthrough$1,
9714
+ supportsDiscovery: boolean(),
9715
+ caps: TargetKindCapsSchema
9716
+ });
9717
+ /**
9718
+ * A persisted target. `config` holds secrets; providers REDACT secret fields
9719
+ * (return a presence marker only) when serving `listTargets` — never
9720
+ * round-trip a stored secret to the UI.
9721
+ */
9722
+ var TargetSchema = object({
9723
+ id: string(),
9724
+ name: string(),
9725
+ kind: string(),
9726
+ addonId: string(),
9727
+ enabled: boolean(),
9728
+ config: record(string(), unknown())
9729
+ });
9730
+ /** A discovery-surfaced candidate (config is partial + non-secret). */
9731
+ var DiscoveredTargetSchema = object({
9732
+ kind: string(),
9733
+ suggestedName: string(),
9734
+ config: record(string(), unknown())
9735
+ });
9736
+ /** The degrade engine's report — what was resolved / dropped / degraded. */
9737
+ var RenderedAsSchema = object({
9738
+ level: string(),
9739
+ format: NotificationFormatSchema,
9740
+ attachmentsSent: number().int().nonnegative(),
9741
+ actionsSent: number().int().nonnegative(),
9742
+ truncated: boolean(),
9743
+ dropped: array(string())
9744
+ });
9745
+ var SendResultSchema = object({
9746
+ success: boolean(),
9747
+ error: string().optional(),
9748
+ renderedAs: RenderedAsSchema.optional()
9749
+ });
9750
+ /** Same shape as SendResult — kept as a distinct name for the test panel. */
9751
+ var TestResultSchema = SendResultSchema;
9752
+ method(object({}), array(TargetKindSchema)), method(object({}), array(TargetSchema)), method(object({
9753
+ kind: string(),
9754
+ config: record(string(), unknown()).optional()
9755
+ }), array(DiscoveredTargetSchema)), method(object({
9756
+ targetId: string(),
9757
+ notification: NotificationSchema
9758
+ }), SendResultSchema, { kind: "mutation" }), method(object({
9759
+ targetId: string(),
9760
+ sample: NotificationSchema.optional()
9761
+ }), TestResultSchema, { kind: "mutation" }), method(object({ target: TargetSchema }), TargetSchema, { kind: "mutation" }), method(object({ targetId: string() }), _void(), { kind: "mutation" }), method(object({
9762
+ targetId: string(),
9763
+ enabled: boolean()
9764
+ }), _void(), { kind: "mutation" });
9765
+ /**
9496
9766
  * notification-rules — the Notification Center rule surface (P1 core).
9497
9767
  *
9498
9768
  * Spec: `docs/superpowers/specs/2026-07-22-notification-center-requirements.md`
@@ -9662,6 +9932,41 @@ var NcRuleActionSchema = discriminatedUnion("kind", [object({
9662
9932
  args: record(string(), unknown()).optional()
9663
9933
  })]);
9664
9934
  /**
9935
+ * A named, ordered run of steps with its own throttle.
9936
+ *
9937
+ * `minDelaySec` exists because a noisy rule otherwise hammers a physical
9938
+ * actuator — the rule's own cooldown governs NOTIFICATIONS, which is a
9939
+ * different budget from "how often may this gate actually open".
9940
+ */
9941
+ var NcRuleActionSequenceSchema = object({
9942
+ name: string().min(1).max(120),
9943
+ enabled: boolean(),
9944
+ minDelaySec: number().int().min(0).max(86400).optional(),
9945
+ actions: array(NcRuleActionSchema).min(1)
9946
+ });
9947
+ /**
9948
+ * One button carried by the notification, running a named sequence on tap.
9949
+ *
9950
+ * **Read this before adding a button that does something physical.** The tap
9951
+ * arrives over a link that travelled through third-party infrastructure — ntfy,
9952
+ * a push relay, whatever forwarded the message — and the callback's ONLY
9953
+ * authority is the token in that link: single-use, short-lived, bound to this
9954
+ * one action of this one notification. It does not identify who tapped.
9955
+ * Whoever holds the notification can run the button, once, inside the window.
9956
+ * That is the operator's explicit choice (2026-08-05), and `destructive` is a
9957
+ * rendering hint, not a second gate. [D47](decisions/adr-0047.md).
9958
+ */
9959
+ var NcRuleNotificationButtonSchema = object({
9960
+ /** Stable id — travels in the callback and identifies the button in logs. */
9961
+ id: string().min(1).max(64),
9962
+ label: string().min(1).max(40),
9963
+ /** Name of a sequence in `onTrigger`. The dispatcher drops a button whose
9964
+ * sequence does not exist rather than minting a token for nothing. */
9965
+ sequence: string().min(1).max(120),
9966
+ icon: NotificationActionIconSchema.optional(),
9967
+ destructive: boolean().optional()
9968
+ });
9969
+ /**
9665
9970
  * Sequences a rule runs, by hook point.
9666
9971
  *
9667
9972
  * ONLY `onTrigger` is here, deliberately. The reference also has activation /
@@ -9669,14 +9974,26 @@ var NcRuleActionSchema = discriminatedUnion("kind", [object({
9669
9974
  * repo's expensive failure mode is declaring a surface nothing produces, so a
9670
9975
  * hook appears here in the same change that produces its edge, never before.
9671
9976
  */
9672
- var NcRuleActionsSchema = object({
9673
- /** Runs when the rule MATCHES. */
9674
- onTrigger: array(object({
9675
- name: string().min(1).max(120),
9676
- enabled: boolean(),
9677
- minDelaySec: number().int().min(0).max(86400).optional(),
9678
- actions: array(NcRuleActionSchema).min(1)
9679
- })).optional() });
9977
+ var NcRuleActionsSchema = object({
9978
+ /** Runs when the rule MATCHES. */
9979
+ onTrigger: array(NcRuleActionSequenceSchema).optional(),
9980
+ /**
9981
+ * Buttons the NOTIFICATION carries, each running one of this rule's
9982
+ * sequences when tapped.
9983
+ *
9984
+ * Deliberately a REFERENCE to a sequence rather than a second place to
9985
+ * author steps. A button that could define its own actions would be a
9986
+ * parallel actuation vocabulary — the executor's device-scope check, the
9987
+ * stop-at-first-failure rule and the per-sequence throttle all live on
9988
+ * sequences, and a second authoring surface would drift from every one of
9989
+ * them.
9990
+ *
9991
+ * A sequence reachable ONLY by a button simply appears in `onTrigger` with
9992
+ * `enabled: false`: it is then authored, throttled and validated like the
9993
+ * rest, and nothing runs it automatically.
9994
+ */
9995
+ buttons: array(NcRuleNotificationButtonSchema).max(8).optional()
9996
+ });
9680
9997
  var NcConditionsSchema = object({
9681
9998
  /** Gate on ANOTHER device's current state (the alarm armed, a switch on). */
9682
9999
  deviceState: object({
@@ -20001,14 +20318,14 @@ var LlmProfileSchema = object({
20001
20318
  /** ConfigUISchema tree passed through untyped on the wire (the
20002
20319
  * notification-output `ConfigSchemaPassthrough` precedent at
20003
20320
  * notification-output.cap.ts:151); the exported TS type re-tightens it. */
20004
- var ConfigSchemaPassthrough$1 = unknown();
20321
+ var ConfigSchemaPassthrough = unknown();
20005
20322
  var LlmProfileKindDescriptorSchema = object({
20006
20323
  kind: LlmProfileKindSchema,
20007
20324
  label: string(),
20008
20325
  icon: string(),
20009
20326
  /** Stamped by each provider so the concat-fanned catalog stays routable. */
20010
20327
  addonId: string(),
20011
- configSchema: ConfigSchemaPassthrough$1
20328
+ configSchema: ConfigSchemaPassthrough
20012
20329
  });
20013
20330
  var LlmDefaultSelectorSchema = union([object({ consumer: string() }), object({ purpose: _enum(["text", "vision"]) })]);
20014
20331
  var LlmDefaultSchema = object({
@@ -20539,228 +20856,6 @@ var NetworkEndpointEntrySchema = NetworkEndpointSchema.extend({
20539
20856
  });
20540
20857
  method(_void(), NetworkEndpointSchema, { kind: "mutation" }), method(_void(), _void(), { kind: "mutation" }), method(_void(), NetworkEndpointSchema.nullable()), method(_void(), NetworkAccessStatusSchema), method(_void(), array(NetworkEndpointEntrySchema).readonly());
20541
20858
  /**
20542
- * notification-output — canonical, capability-gated notification delivery.
20543
- *
20544
- * Apprise-derived model (see
20545
- * `docs/superpowers/specs/2026-07-03-notification-output-notifier-matrix.md`):
20546
- * callers emit ONE canonical `Notification`; each provider declares a
20547
- * per-kind capability descriptor (`TargetKind`), and the pure degrade
20548
- * engine (`@camstack/types` `prepareNotification`) transcodes / degrades the
20549
- * message to what the kind supports — callers never special-case a service.
20550
- *
20551
- * DESIGN DECISIONS (locked):
20552
- * - Target CRUD lives on THIS cap (`upsertTarget` / `deleteTarget` /
20553
- * `setTargetEnabled`), each provider persisting via the `settings-store`
20554
- * cap. Rationale: the admin UI needs one uniform surface across the
20555
- * notifiers addon AND the HA addon; the addon-`globalSettingsSchema`-array
20556
- * alternative would fork the UI per addon and cannot host the
20557
- * discovery→adopt flow.
20558
- * - `listTargetKinds` / `listTargets` / `discoverTargets` return arrays →
20559
- * the generated cap-mount auto-`concatCollection`-fans them across every
20560
- * registered provider (notifiers addon + HA addon) so one catalog is
20561
- * routable. `send` / `testTarget` / CRUD route to ONE provider by the
20562
- * `addonId` the generated collection router extracts from the call input.
20563
- * - `Attachment.bytes` is `Uint8Array`. Transport-safe: superjson (the tRPC
20564
- * transformer) + UDS MsgPack both round-trip typed arrays — already used by
20565
- * `storage` / `storage-provider` / `recording` caps over the same path. No
20566
- * base64 fallback needed.
20567
- *
20568
- * TODO (deferred, closed-set change — separate decision): add
20569
- * `providerKind: 'notify'` so notification providers surface on the unified
20570
- * admin "Integrations" page.
20571
- */
20572
- /**
20573
- * Zentik-derived typed-media enum — the superset across every kind. Each
20574
- * adapter picks what it supports and the degrade engine filters the rest.
20575
- */
20576
- var AttachmentMediaTypeSchema = _enum([
20577
- "image",
20578
- "video",
20579
- "gif",
20580
- "audio",
20581
- "icon"
20582
- ]);
20583
- /**
20584
- * A single attachment. Exactly one of `url` (remote source, most adapters
20585
- * prefer this) or `bytes` (inline source; required for Pushover-style
20586
- * bytes-only kinds) MUST be present — the degrade engine expresses a
20587
- * url→bytes fetch as a `needsFetch` directive the adapter executes.
20588
- */
20589
- var AttachmentSchema = object({
20590
- mediaType: AttachmentMediaTypeSchema,
20591
- url: string().optional(),
20592
- bytes: _instanceof(Uint8Array).optional(),
20593
- mime: string().optional(),
20594
- name: string().optional()
20595
- }).refine((a) => a.url !== void 0 || a.bytes !== void 0, { message: "Attachment requires either `url` or `bytes`" });
20596
- var NotificationFormatSchema = _enum([
20597
- "text",
20598
- "markdown",
20599
- "html"
20600
- ]);
20601
- /** A single tap-through action button. */
20602
- var NotificationActionSchema = object({
20603
- id: string(),
20604
- label: string(),
20605
- url: string().optional()
20606
- });
20607
- /**
20608
- * The canonical notification. `body` is the only hard field (Apprise model).
20609
- * `priority` is a 5-level ORDINAL (1=lowest … 3=normal(default) … 5=urgent),
20610
- * NOT a fixed severity enum — each kind declares its own `caps.levels` and
20611
- * the adapter maps this ordinal onto its native level. `level?` is an
20612
- * optional kind-native level id (`emergency`, `silent`, …) that overrides
20613
- * `priority` for that one target.
20614
- */
20615
- var NotificationSchema = object({
20616
- body: string(),
20617
- title: string().optional(),
20618
- format: NotificationFormatSchema.default("text"),
20619
- priority: number().int().min(1).max(5).default(3),
20620
- level: string().optional(),
20621
- attachments: array(AttachmentSchema).optional(),
20622
- clickUrl: string().optional(),
20623
- actions: array(NotificationActionSchema).optional(),
20624
- sound: string().optional(),
20625
- ttl: number().optional(),
20626
- tag: string().optional(),
20627
- deviceId: number().optional(),
20628
- eventId: string().optional(),
20629
- metadata: record(string(), unknown()).optional()
20630
- });
20631
- /** One declared native severity/priority level for a kind. */
20632
- var TargetKindLevelSchema = object({
20633
- id: string(),
20634
- label: string(),
20635
- /** Which canonical priority (1..5) this level maps to. `null` = qualitative-only. */
20636
- ordinal: number().int().min(1).max(5).nullable(),
20637
- flags: object({
20638
- critical: boolean().optional(),
20639
- silent: boolean().optional(),
20640
- noPush: boolean().optional()
20641
- }).optional(),
20642
- /** e.g. Pushover `emergency` requires `retry` / `expire`. */
20643
- requires: array(string()).optional(),
20644
- description: string().optional()
20645
- });
20646
- /** The full capability block consulted before dispatch. */
20647
- var TargetKindCapsSchema = object({
20648
- attachments: object({
20649
- mediaTypes: array(AttachmentMediaTypeSchema),
20650
- mode: _enum([
20651
- "url",
20652
- "bytes",
20653
- "both"
20654
- ]),
20655
- max: number().int().nonnegative(),
20656
- maxBytes: number().int().positive().optional()
20657
- }),
20658
- /** Max action buttons (0 = none). */
20659
- actions: number().int().nonnegative(),
20660
- levels: array(TargetKindLevelSchema),
20661
- format: array(NotificationFormatSchema),
20662
- clickUrl: boolean(),
20663
- sound: boolean(),
20664
- ttl: boolean(),
20665
- bodyMaxLen: number().int().positive()
20666
- });
20667
- /**
20668
- * `configSchema` is a `ConfigUISchema` tree passed through to the admin
20669
- * FormBuilder. Stored as `z.unknown()` at the cap seam (mirrors
20670
- * `device-provider.getChildCreationSchema` `CreationSchemaOutputSchema`) —
20671
- * the union is large and not meant for runtime validation here; the exported
20672
- * `TargetKind` type re-tightens `configSchema` to `ConfigUISchema`.
20673
- */
20674
- var ConfigSchemaPassthrough = unknown();
20675
- var TargetKindSchema = object({
20676
- kind: string(),
20677
- label: string(),
20678
- icon: string(),
20679
- /** Stamped by each provider so the concat-fanned catalog stays routable. */
20680
- addonId: string(),
20681
- /**
20682
- * URL of the kind's bundled BRAND icon, served by the providing addon over
20683
- * its own `addon-routes` surface (`/addon/<addonId>/icons/<kind>`). Absent
20684
- * when the addon bundles no icon for that kind — the client then falls back
20685
- * to a neutral glyph rather than rendering the raw `icon` NAME as text.
20686
- *
20687
- * Root-relative on purpose: it resolves against whatever origin serves a web
20688
- * client, and a native client joins it onto its own hub base.
20689
- *
20690
- * DECLARED here deliberately. It used to travel as an undeclared passthrough
20691
- * field that survived only because the runtime cap-router forwards provider
20692
- * output verbatim — so every consumer had to re-declare it by hand to stop
20693
- * its own Zod parse from stripping it, and the whole arrangement would have
20694
- * broken silently the moment output validation was tightened anywhere.
20695
- */
20696
- iconUrl: string().optional(),
20697
- /**
20698
- * Media type of {@link iconUrl} (`image/svg+xml`, `image/png`, …).
20699
- *
20700
- * The server knows this and therefore says it, because the client cannot
20701
- * safely guess: a React-Native client renders SVG and raster through two
20702
- * DIFFERENT components (`react-native-svg` vs `expo-image` — expo-image does
20703
- * not decode SVG on iOS/Android), so without this it silently fell back to a
20704
- * placeholder glyph for every vector icon while the web build looked fine.
20705
- *
20706
- * Absent when {@link iconUrl} is absent, or for a legacy provider that has
20707
- * not been updated — a client that cannot determine the type should prefer
20708
- * its raster path, which is the safe default for an unknown image.
20709
- */
20710
- iconMediaType: string().optional(),
20711
- configSchema: ConfigSchemaPassthrough,
20712
- supportsDiscovery: boolean(),
20713
- caps: TargetKindCapsSchema
20714
- });
20715
- /**
20716
- * A persisted target. `config` holds secrets; providers REDACT secret fields
20717
- * (return a presence marker only) when serving `listTargets` — never
20718
- * round-trip a stored secret to the UI.
20719
- */
20720
- var TargetSchema = object({
20721
- id: string(),
20722
- name: string(),
20723
- kind: string(),
20724
- addonId: string(),
20725
- enabled: boolean(),
20726
- config: record(string(), unknown())
20727
- });
20728
- /** A discovery-surfaced candidate (config is partial + non-secret). */
20729
- var DiscoveredTargetSchema = object({
20730
- kind: string(),
20731
- suggestedName: string(),
20732
- config: record(string(), unknown())
20733
- });
20734
- /** The degrade engine's report — what was resolved / dropped / degraded. */
20735
- var RenderedAsSchema = object({
20736
- level: string(),
20737
- format: NotificationFormatSchema,
20738
- attachmentsSent: number().int().nonnegative(),
20739
- actionsSent: number().int().nonnegative(),
20740
- truncated: boolean(),
20741
- dropped: array(string())
20742
- });
20743
- var SendResultSchema = object({
20744
- success: boolean(),
20745
- error: string().optional(),
20746
- renderedAs: RenderedAsSchema.optional()
20747
- });
20748
- /** Same shape as SendResult — kept as a distinct name for the test panel. */
20749
- var TestResultSchema = SendResultSchema;
20750
- method(object({}), array(TargetKindSchema)), method(object({}), array(TargetSchema)), method(object({
20751
- kind: string(),
20752
- config: record(string(), unknown()).optional()
20753
- }), array(DiscoveredTargetSchema)), method(object({
20754
- targetId: string(),
20755
- notification: NotificationSchema
20756
- }), SendResultSchema, { kind: "mutation" }), method(object({
20757
- targetId: string(),
20758
- sample: NotificationSchema.optional()
20759
- }), TestResultSchema, { kind: "mutation" }), method(object({ target: TargetSchema }), TargetSchema, { kind: "mutation" }), method(object({ targetId: string() }), _void(), { kind: "mutation" }), method(object({
20760
- targetId: string(),
20761
- enabled: boolean()
20762
- }), _void(), { kind: "mutation" });
20763
- /**
20764
20859
  * core-blocks — user-authored TypeScript, stored in the kernel and executed in
20765
20860
  * its own process.
20766
20861
  *
@@ -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-DPAMoN4x.js");
5
+ const require_dist = require("../dist-7ujnICn7.js");
6
6
  let node_fs = require("node:fs");
7
7
  let node_fs$1 = require_dist.__toESM(node_fs, 1);
8
8
  node_fs = require_dist.__toESM(node_fs);
@@ -1,4 +1,4 @@
1
- import { E as embeddingEncoderCapability, O as hfModelUrl, R as BaseAddon } from "../dist-D3Ht9Ae5.mjs";
1
+ import { E as embeddingEncoderCapability, O as hfModelUrl, R as BaseAddon } from "../dist-Bjhp9nkX.mjs";
2
2
  import { createRequire } from "node:module";
3
3
  import * as fs from "node:fs";
4
4
  import "node:fs";
@@ -1,4 +1,4 @@
1
- const require_dist = require("./dist-DPAMoN4x.js");
1
+ const require_dist = require("./dist-7ujnICn7.js");
2
2
  let node_fs = require("node:fs");
3
3
  node_fs = require_dist.__toESM(node_fs, 1);
4
4
  let node_path = require("node:path");
@@ -18,7 +18,7 @@ var e = {
18
18
  },
19
19
  "@camstack/types": {
20
20
  name: "@camstack/types",
21
- version: "1.2.31",
21
+ version: "1.2.32",
22
22
  scope: ["default"],
23
23
  loaded: !1,
24
24
  from: "addon_pipeline_analytics_widgets",
@@ -36,7 +36,7 @@ async function r() {
36
36
  }
37
37
  },
38
38
  "@camstack/types": {
39
- version: "1.2.31",
39
+ version: "1.2.32",
40
40
  scope: "default",
41
41
  shareConfig: {
42
42
  singleton: !0,