@camstack/addon-decoder-nodeav 1.2.125 → 1.2.127

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.
Files changed (3) hide show
  1. package/dist/index.js +390 -294
  2. package/dist/index.mjs +390 -294
  3. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -5418,7 +5418,7 @@ var ZodIssueCode = {
5418
5418
  var ZodFirstPartyTypeKind;
5419
5419
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5420
5420
  //#endregion
5421
- //#region ../types/dist/sleep-BxjU_fJM.mjs
5421
+ //#region ../types/dist/sleep-yKL5gfrH.mjs
5422
5422
  /**
5423
5423
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5424
5424
  * window to float samples (D455).
@@ -7800,6 +7800,12 @@ function normalizeAddonInitResult(result) {
7800
7800
  if (Array.isArray(result)) return { providers: result };
7801
7801
  return result;
7802
7802
  }
7803
+ /**
7804
+ * The share-view scope kinds a share-link token can carry. The hub mints
7805
+ * and validates them (`ShareViewGrantSchema` builds its
7806
+ * enum from this list); a data plane names the kinds it ACCEPTS in `share`.
7807
+ */
7808
+ var SHARE_VIEW_KINDS = ["grid-view", "events-view"];
7803
7809
  /** The wire shape of {@link PeerBytesTicket} — see the type for what it is. */
7804
7810
  var PeerBytesTicketSchema = object({
7805
7811
  /** `http://127.0.0.1:<port>/<token>`. One `GET` takes it. */
@@ -12394,6 +12400,280 @@ var ConvertResultSchema = object({
12394
12400
  files: array(string()).readonly()
12395
12401
  })).readonly()
12396
12402
  });
12403
+ /**
12404
+ * Zod schemas for persisted record types.
12405
+ *
12406
+ * These schemas serve as the single source of truth for types that are
12407
+ * stored in the settings-store backend and retrieved via tRPC. They
12408
+ * replace the manual TypeScript interfaces with schema-derived types,
12409
+ * enabling runtime validation when reading from the backend.
12410
+ *
12411
+ * Convention: each schema is named `<Type>Schema`, the inferred TS type
12412
+ * keeps the original name for backward compatibility.
12413
+ */
12414
+ /**
12415
+ * Auth model (v2 — 2026-05-12 caps-only):
12416
+ *
12417
+ * Two principals:
12418
+ * - `isAdmin: true` — full bypass. Admin scope set is ignored.
12419
+ * - `isAdmin: false` — every call gated by `scopes` (see TokenScope).
12420
+ *
12421
+ * No role enum. There used to be `viewer / agent / scoped` and earlier
12422
+ * `super_admin` — collapsed onto the single boolean because every
12423
+ * non-admin caller is governed by the same scope-check rules; the
12424
+ * distinction was only ever used to route role-specific procedures
12425
+ * which we no longer have. CLI / webhook integrations are tokens (`auth.mintToken`)
12426
+ * with `isAdmin: false` + an explicit scope list.
12427
+ */
12428
+ /** Per-method access flavour. Materialised on every cap method via codegen. */
12429
+ var MethodAccessSchema = _enum([
12430
+ "view",
12431
+ "create",
12432
+ "delete"
12433
+ ]);
12434
+ /**
12435
+ * A single scope grant. Three forms — checked in matcher with OR
12436
+ * semantics; the first match decides whether the call passes:
12437
+ *
12438
+ * - `category` — broadest. `target: 'device' | 'system'` selects every
12439
+ * cap with the matching `scope` declaration. New caps inherit grants
12440
+ * automatically — adding a device cap to the codebase makes it
12441
+ * reachable to every user with `category:device [...]` without a
12442
+ * re-grant. Use this for "family viewer" / "operator" tiers.
12443
+ *
12444
+ * - `addon` — every cap that ships inside a given addon id. Niche;
12445
+ * useful when an integration needs to interact with one specific
12446
+ * addon's surface regardless of how many caps it exports.
12447
+ *
12448
+ * - `capability` — the most precise form. Single cap name. Use for
12449
+ * integration tokens where you want to grant `addons.installPackage`
12450
+ * and nothing else.
12451
+ *
12452
+ * `access` is REQUIRED with min 1 element. `admin` bypass is the
12453
+ * "give me everything" escape; there is no wildcard scope.
12454
+ */
12455
+ var AllowedProviderSchema = union([literal("*"), array(string())]);
12456
+ var AllowedDevicesSchema = record(string(), union([literal("*"), array(string())]));
12457
+ var CapScopeSchema = _enum(["device", "system"]);
12458
+ /**
12459
+ * DeviceSelector (scope model v3 — 2026-08-12).
12460
+ *
12461
+ * A `device` grant no longer carries a frozen list of deviceIds. It carries
12462
+ * a SELECTOR the matcher resolves against the live fleet, so the grant can be
12463
+ * DYNAMIC: a `types:['camera']` selector automatically covers a camera added
12464
+ * AFTER the grant was minted — no re-grant, no re-login.
12465
+ *
12466
+ * - `all` — every device in the deployment. The broad viewer/operator
12467
+ * lever without a `category` grant (a `category` grant also covers device
12468
+ * caps that carry no deviceId; `all` is specifically the device set).
12469
+ * - `ids` — an explicit deviceId list. This is what a v2 `device:[…]`
12470
+ * grant migrates to (see {@link TokenScopeSchema}); STATIC — a new camera
12471
+ * is NOT covered until the grant is edited.
12472
+ * - `types` — every device of a `DeviceType` (e.g. every `camera`).
12473
+ * DYNAMIC. A device that changes type, or a new device of the type,
12474
+ * re-resolves on the next request.
12475
+ * - `locations` — every device whose operator-assigned `location` label is
12476
+ * in the set (e.g. "Garden", "Front door"). DYNAMIC. A device with a
12477
+ * null/unset location matches NO `locations` selector.
12478
+ */
12479
+ var DeviceSelectorSchema = discriminatedUnion("kind", [
12480
+ object({ kind: literal("all") }),
12481
+ object({
12482
+ kind: literal("ids"),
12483
+ ids: array(number().int()).min(1)
12484
+ }),
12485
+ object({
12486
+ kind: literal("types"),
12487
+ types: array(_enum(DeviceType)).min(1)
12488
+ }),
12489
+ object({
12490
+ kind: literal("locations"),
12491
+ locations: array(string().min(1)).min(1)
12492
+ })
12493
+ ]);
12494
+ var DeviceTokenScopeSchema = object({
12495
+ type: literal("device"),
12496
+ /** The device SET this grant covers — resolved against the live fleet. */
12497
+ selector: DeviceSelectorSchema,
12498
+ access: array(MethodAccessSchema).min(1),
12499
+ /**
12500
+ * Whether a grant on a PARENT device transparently covers its accessory
12501
+ * CHILDREN (siren / floodlight / PIR) via the persisted-parentage walk.
12502
+ * Direction is parent → children ONLY.
12503
+ *
12504
+ * Absent → the matcher DERIVES it from the access flavour: `view`
12505
+ * inherits (a camera viewer sees the camera's accessories), `create` /
12506
+ * `delete` do NOT (actuating/removing a child is an explicit act the
12507
+ * operator must grant on the child, not inherit from the parent). Set it
12508
+ * explicitly to override that default per grant.
12509
+ */
12510
+ includeLinked: boolean().optional()
12511
+ });
12512
+ /**
12513
+ * v2 → v3 lazy migration. A pre-v3 `device` grant carried
12514
+ * `targets: string[]` (stringified deviceIds); it rewrites to the equivalent
12515
+ * `selector: {kind:'ids', ids}`. Applied as a `preprocess` so it runs on
12516
+ * EVERY parse path — stored records AND the JWT-carried scope arrays
12517
+ * normalised at the request boundary ({@link normalizeTokenScopes} in
12518
+ * `device-selector.ts`). Chosen over a one-time DB migration because a
12519
+ * migration cannot reach a JWT already in a client's hands; parse-time
12520
+ * migration covers both without a flag day. No cast — the raw object is read
12521
+ * through `Reflect.get` (its static type is `unknown`).
12522
+ */
12523
+ function migrateLegacyTokenScope(raw) {
12524
+ if (raw === null || typeof raw !== "object" || Array.isArray(raw)) return raw;
12525
+ if (Reflect.get(raw, "type") !== "device") return raw;
12526
+ if (Reflect.get(raw, "selector") !== void 0) return raw;
12527
+ const targets = Reflect.get(raw, "targets");
12528
+ if (!Array.isArray(targets)) return raw;
12529
+ return {
12530
+ type: "device",
12531
+ selector: {
12532
+ kind: "ids",
12533
+ ids: targets.map((t) => typeof t === "string" ? Number(t) : t).filter((n) => typeof n === "number" && Number.isInteger(n))
12534
+ },
12535
+ access: Reflect.get(raw, "access")
12536
+ };
12537
+ }
12538
+ var TokenScopeSchema = preprocess(migrateLegacyTokenScope, discriminatedUnion("type", [
12539
+ object({
12540
+ type: literal("category"),
12541
+ target: CapScopeSchema,
12542
+ access: array(MethodAccessSchema).min(1)
12543
+ }),
12544
+ object({
12545
+ type: literal("capability"),
12546
+ target: string(),
12547
+ access: array(MethodAccessSchema).min(1)
12548
+ }),
12549
+ object({
12550
+ type: literal("addon"),
12551
+ target: string(),
12552
+ access: array(MethodAccessSchema).min(1)
12553
+ }),
12554
+ DeviceTokenScopeSchema
12555
+ ]));
12556
+ object({
12557
+ id: string(),
12558
+ username: string(),
12559
+ passwordHash: string(),
12560
+ /**
12561
+ * Admin bypass. When true, the middleware skips the scope-access
12562
+ * check entirely. There is no other axis of privilege; the legacy
12563
+ * role enum collapsed onto this boolean in v2.
12564
+ */
12565
+ isAdmin: boolean().default(false),
12566
+ allowedProviders: AllowedProviderSchema,
12567
+ allowedDevices: AllowedDevicesSchema,
12568
+ /**
12569
+ * Scopes granted to this user. Admins bypass; their `scopes` is
12570
+ * ignored. Non-admins without scopes are locked out of every
12571
+ * protected call.
12572
+ */
12573
+ scopes: array(TokenScopeSchema).default([]),
12574
+ createdAt: number(),
12575
+ updatedAt: number()
12576
+ });
12577
+ object({
12578
+ id: string(),
12579
+ label: string(),
12580
+ isAdmin: boolean().default(false),
12581
+ allowedProviders: AllowedProviderSchema,
12582
+ allowedDevices: AllowedDevicesSchema,
12583
+ tokenHash: string(),
12584
+ tokenPrefix: string(),
12585
+ createdAt: number(),
12586
+ lastUsedAt: number().optional()
12587
+ });
12588
+ object({
12589
+ id: string(),
12590
+ userId: string(),
12591
+ name: string(),
12592
+ tokenHash: string(),
12593
+ tokenPrefix: string(),
12594
+ scopes: array(TokenScopeSchema),
12595
+ expiresAt: number().nullish(),
12596
+ lastUsedAt: number().nullish(),
12597
+ createdAt: number()
12598
+ });
12599
+ /** What a share-view grant lets its holder see. */
12600
+ var ShareViewGrantSchema = object({
12601
+ kind: _enum(SHARE_VIEW_KINDS),
12602
+ deviceIds: array(number().int().nonnegative()).min(1).max(64),
12603
+ /** Talk-back, opt-in at mint time; absent means off. */
12604
+ talk: boolean().optional()
12605
+ });
12606
+ var ShareViewScopeSchema = object({
12607
+ type: literal("share-view"),
12608
+ grant: ShareViewGrantSchema
12609
+ });
12610
+ var AddonRoutesScopeSchema = object({
12611
+ type: literal("addon-routes"),
12612
+ access: array(MethodAccessSchema).min(1)
12613
+ });
12614
+ var PreferencesSelfScopeSchema = object({ type: literal("preferences-self") });
12615
+ var CredentialScopeSchema = union([
12616
+ literal("*"),
12617
+ ShareViewScopeSchema,
12618
+ AddonRoutesScopeSchema,
12619
+ PreferencesSelfScopeSchema,
12620
+ TokenScopeSchema
12621
+ ]);
12622
+ object({
12623
+ kind: literal("credential"),
12624
+ sub: string().min(1),
12625
+ jti: string().min(16),
12626
+ scopes: array(CredentialScopeSchema).min(1)
12627
+ });
12628
+ var PreferenceNamespaceSchema = string().regex(/^[a-z][a-z0-9.-]{0,63}$/);
12629
+ /** A namespace's value: a JSON object, opaque to the hub. */
12630
+ var PreferenceValueSchema = record(string(), unknown());
12631
+ var PreferenceDeviceIdSchema = string().min(1).max(64);
12632
+ /** A stored row, as the owner reads it. */
12633
+ var PreferenceRowSchema = object({
12634
+ namespace: PreferenceNamespaceSchema,
12635
+ value: PreferenceValueSchema,
12636
+ /** Starts at 1, +1 on every write of this namespace. A delete ends the row and its count. */
12637
+ revision: number().int().positive(),
12638
+ updatedAt: number().int(),
12639
+ /** The client id the last writer sent; `null` when it sent none. */
12640
+ updatedByDevice: PreferenceDeviceIdSchema.nullable()
12641
+ });
12642
+ object({
12643
+ /** Absent: every namespace the caller holds. */
12644
+ namespaces: array(PreferenceNamespaceSchema).max(32).optional() });
12645
+ object({ rows: array(PreferenceRowSchema) });
12646
+ object({
12647
+ namespace: PreferenceNamespaceSchema,
12648
+ value: PreferenceValueSchema,
12649
+ /**
12650
+ * The revision the edit was based on. Absent: last write wins. `0`: the
12651
+ * namespace must not exist yet. Any other value that is not the current
12652
+ * revision answers `conflict` and writes nothing.
12653
+ */
12654
+ baseRevision: number().int().nonnegative().optional(),
12655
+ deviceId: PreferenceDeviceIdSchema.optional()
12656
+ });
12657
+ discriminatedUnion("status", [object({
12658
+ status: literal("saved"),
12659
+ row: PreferenceRowSchema
12660
+ }), object({
12661
+ status: literal("conflict"),
12662
+ current: PreferenceRowSchema.nullable()
12663
+ })]);
12664
+ object({ namespace: PreferenceNamespaceSchema });
12665
+ object({
12666
+ /** `false` when the namespace did not exist. */
12667
+ deleted: boolean() });
12668
+ object({
12669
+ /** The revision the client holds per namespace; a namespace it does not list is new to it. */
12670
+ revisionByNamespace: record(PreferenceNamespaceSchema, number().int().nonnegative()).refine((map) => Object.keys(map).length <= 32, { message: `at most 32 namespaces` }) });
12671
+ object({
12672
+ /** Every row whose revision differs from the client's, and every row it did not list. */
12673
+ rows: array(PreferenceRowSchema),
12674
+ /** Namespaces the client listed that no longer exist. */
12675
+ deleted: array(PreferenceNamespaceSchema)
12676
+ });
12397
12677
  _enum(["new-session", "step-up"]);
12398
12678
  /** The languages the hub's app landing pages are written in (D858). */
12399
12679
  var AppPageLangSchema = _enum(["en", "it"]);
@@ -39390,38 +39670,37 @@ method(LlmRuntimeCompleteInputSchema, LlmGenerateResultSchema, {
39390
39670
  auth: "admin",
39391
39671
  timeoutMs: AI_CAP_TRANSPORT_TIMEOUT_MS
39392
39672
  });
39673
+ var LlmProfileKindSchema = string().regex(/^[a-z0-9][a-z0-9-]{0,63}$/, "a kind id is lower-case letters, digits and dashes");
39674
+ /** What a model (or, by default, every model of a kind) can do. */
39675
+ var LlmModelFeaturesSchema = object({
39676
+ vision: boolean(),
39677
+ tools: boolean(),
39678
+ streaming: boolean()
39679
+ });
39680
+ /** One model a provider offers. `features` overrides the kind's defaults, per field. */
39681
+ var LlmModelInfoSchema = object({
39682
+ id: string(),
39683
+ label: string().optional(),
39684
+ contextLength: number().int().positive().optional(),
39685
+ features: LlmModelFeaturesSchema.partial().optional()
39686
+ });
39393
39687
  /**
39394
- * `llm` — consumer-facing LLM surface (spec §1-§3). Collection-mode: array
39395
- * methods concat-fan across providers; single-row methods route to ONE
39396
- * provider by the `addonId` in the call input (the notification-output
39397
- * posture, notification-output.cap.ts:215-250). Provided by `addon-ai`
39398
- * (hub-placed); the cap stays open for future providers.
39399
- *
39400
- * Profiles are ROWS (data), not addons: one row = one usable model endpoint.
39401
- * `apiKey` is a password field — providers REDACT it on read and merge on
39402
- * write; a stored key NEVER round-trips to a client.
39688
+ * The provider-specific part of a profile, validated by the provider that owns
39689
+ * the kind (`upsertProfile` refuses what it does not accept). A field its
39690
+ * `connectionSchema` declares `type: 'password'` is a secret: it is held in the
39691
+ * keychain, never in the row, and reads back as the redaction marker.
39403
39692
  */
39404
- var LlmProfileKindSchema = _enum([
39405
- "openai-compatible",
39406
- "openai",
39407
- "anthropic",
39408
- "google",
39409
- "managed-local",
39410
- "apple-foundation"
39411
- ]);
39693
+ var LlmProviderConfigSchema = record(string(), unknown());
39412
39694
  var LlmProfileSchema = object({
39413
39695
  id: string(),
39414
39696
  name: string(),
39697
+ /** The provider-declared kind (`LlmProfileKindDescriptor.kind`). */
39415
39698
  kind: LlmProfileKindSchema,
39416
39699
  /** Stamped by the provider — keeps the fanned catalog routable. */
39417
39700
  addonId: string(),
39418
39701
  enabled: boolean(),
39419
39702
  /** Vendor model id, or the managed runtime's loaded model. */
39420
39703
  model: string(),
39421
- /** Required for openai-compatible; override for cloud kinds. */
39422
- baseUrl: string().optional(),
39423
- /** ConfigUISchema type:'password' — never round-trips (spec §5). */
39424
- apiKey: string().optional(),
39425
39704
  /** Vision on/off. A vision call against a `false` profile is REFUSED, never
39426
39705
  * degraded to text — that shipped once and produced a confident answer to a
39427
39706
  * question about a picture nobody sent. */
@@ -39429,15 +39708,11 @@ var LlmProfileSchema = object({
39429
39708
  temperature: number().min(0).max(2).optional(),
39430
39709
  /** Nucleus sampling. Every wire we speak has it. */
39431
39710
  topP: number().min(0).max(1).optional(),
39432
- /** Top-k sampling. Carried only by the wires that have it — NEITHER OpenAI
39433
- * wire does, and the client drops it there (measured: the request body gets
39434
- * `top_p` and no `top_k`). The profile editor hides the field wherever it
39435
- * would change nothing; `KINDS_WITH_TOP_K` is the single owner of that list. */
39711
+ /** Top-k sampling. Carried only by the wires that have it — a kind offers the
39712
+ * field in its editor only when its descriptor lists it in `profileFields`. */
39436
39713
  topK: number().int().positive().optional(),
39437
39714
  maxTokens: number().int().positive().optional(),
39438
- /** Prompt context window. Advisory for cloud kinds (they enforce their own);
39439
- * for `managed-local` it is the llama.cpp `--ctx-size` the runtime starts
39440
- * the model with, so it is the one field that changes a PROCESS. */
39715
+ /** Prompt context window. Advisory for cloud kinds (they enforce their own). */
39441
39716
  contextLength: number().int().positive().optional(),
39442
39717
  /** Default system prompt. A caller's `system` REPLACES it (never appends —
39443
39718
  * two system prompts fighting is worse than either alone). */
@@ -39463,16 +39738,37 @@ var LlmProfileSchema = object({
39463
39738
  * library; the REGISTRY of callable tools is ours and is empty in v1, so a
39464
39739
  * `true` here buys the wiring, not behaviour, until tools are registered. */
39465
39740
  toolsEnabled: boolean().default(false),
39466
- extraHeaders: record(string(), string()).optional(),
39467
- /** kind === 'managed-local' only (spec §4). */
39468
- runtime: ManagedRuntimeConfigSchema.optional(),
39469
- /**
39470
- * kind === 'apple-foundation' only: WHERE it runs — the only thing there is
39471
- * to configure (no key, no URL, no download; `model` is `apple-system`).
39472
- * `supportsVision` on such a row is stamped by the provider from the node's
39473
- * reported `imageInput`, never taken from the operator (D62).
39474
- */
39475
- appleFoundation: object({ nodeId: string() }).optional()
39741
+ /** Everything the kind's provider owns (endpoint, key, node, runtime…). */
39742
+ providerConfig: LlmProviderConfigSchema.default({})
39743
+ });
39744
+ /**
39745
+ * The common profile fields a kind's editor offers. The editor owns how each
39746
+ * one is drawn; the provider says which of them mean something on its wire.
39747
+ */
39748
+ var LlmProfileFieldSchema = _enum([
39749
+ "temperature",
39750
+ "topP",
39751
+ "topK",
39752
+ "maxTokens",
39753
+ "contextLength",
39754
+ "systemPrompt",
39755
+ "timeoutMs",
39756
+ "connectTimeoutMs",
39757
+ "firstTokenTimeoutMs",
39758
+ "idleTimeoutMs",
39759
+ "retry",
39760
+ "toolsEnabled"
39761
+ ]);
39762
+ /**
39763
+ * A provider-drawn part of the editor, by a generic widget id the admin UI
39764
+ * registers (`ai/apple-node`). `placement: 'model'` replaces the generic model
39765
+ * picker: that widget owns the model choice.
39766
+ */
39767
+ var LlmProviderWidgetSchema = object({
39768
+ id: string(),
39769
+ placement: _enum(["connection", "model"]),
39770
+ /** `providerConfig` keys this widget must fill before the profile can be saved. */
39771
+ requires: array(string()).optional()
39476
39772
  });
39477
39773
  /** ConfigUISchema tree passed through untyped on the wire (the
39478
39774
  * notification-output `ConfigSchemaPassthrough` precedent at
@@ -39481,11 +39777,56 @@ var ConfigSchemaPassthrough$3 = unknown();
39481
39777
  var LlmProfileKindDescriptorSchema = object({
39482
39778
  kind: LlmProfileKindSchema,
39483
39779
  label: string(),
39780
+ /** A generic icon name (`cloud`, `plug`, `cpu`) — never a glyph or a logo. */
39484
39781
  icon: string(),
39485
39782
  /** Stamped by each provider so the concat-fanned catalog stays routable. */
39486
39783
  addonId: string(),
39487
- configSchema: ConfigSchemaPassthrough$3
39784
+ /** The provider's own fields (`providerConfig`); `password` fields are keychain-held. */
39785
+ connectionSchema: ConfigSchemaPassthrough$3,
39786
+ /** Provider fields that belong under "Advanced" (extra headers, runtime tuning). */
39787
+ advancedSchema: ConfigSchemaPassthrough$3.optional(),
39788
+ /** The kind's defaults; a model from `listModels` may override any of them. */
39789
+ features: LlmModelFeaturesSchema,
39790
+ /** `false` = the provider stamps `supportsVision` itself (from what a node reports). */
39791
+ visionEditable: boolean(),
39792
+ /** Where the model list comes from: `listModels`, `staticModels`, or nowhere. */
39793
+ modelCatalog: _enum([
39794
+ "fetch",
39795
+ "static",
39796
+ "none"
39797
+ ]),
39798
+ staticModels: array(LlmModelInfoSchema).optional(),
39799
+ /** The common fields that mean something on this kind's wire. */
39800
+ profileFields: array(LlmProfileFieldSchema),
39801
+ providerWidgets: array(LlmProviderWidgetSchema).optional()
39802
+ });
39803
+ /**
39804
+ * `listModels` input. `connection` is an UNSAVED draft of `providerConfig`
39805
+ * (the editor's form); with `profileId` too, a secret the draft leaves
39806
+ * untouched (absent or the redaction marker) is resolved server-side from the
39807
+ * stored profile — the browser never receives it.
39808
+ */
39809
+ var LlmListModelsInputSchema = object({
39810
+ addonId: string(),
39811
+ kind: LlmProfileKindSchema,
39812
+ profileId: string().optional(),
39813
+ connection: LlmProviderConfigSchema.optional()
39488
39814
  });
39815
+ var LlmListModelsErrorCodeSchema = _enum([
39816
+ "auth",
39817
+ "network",
39818
+ "unsupported",
39819
+ "invalid"
39820
+ ]);
39821
+ /** A RESULT, never a throw: "wrong key" is an answer the editor renders inline. */
39822
+ var LlmListModelsResultSchema = discriminatedUnion("ok", [object({
39823
+ ok: literal(true),
39824
+ models: array(LlmModelInfoSchema)
39825
+ }), object({
39826
+ ok: literal(false),
39827
+ code: LlmListModelsErrorCodeSchema,
39828
+ message: string()
39829
+ })]);
39489
39830
  var LlmDefaultSelectorSchema = union([object({ consumer: string() }), object({ purpose: _enum(["text", "vision"]) })]);
39490
39831
  var LlmDefaultSchema = object({
39491
39832
  selector: LlmDefaultSelectorSchema,
@@ -39585,7 +39926,10 @@ method(LlmGenerateBaseInputSchema, LlmGenerateResultSchema, {
39585
39926
  kind: "mutation",
39586
39927
  auth: "admin",
39587
39928
  timeoutMs: AI_CAP_TRANSPORT_TIMEOUT_MS
39588
- }), method(ProfileRefInputSchema, array(string())), method(object({}), array(LlmDefaultSchema)), method(object({
39929
+ }), method(LlmListModelsInputSchema, LlmListModelsResultSchema, {
39930
+ kind: "mutation",
39931
+ auth: "admin"
39932
+ }), method(object({}), array(LlmDefaultSchema)), method(object({
39589
39933
  selector: LlmDefaultSelectorSchema,
39590
39934
  profileId: string().nullable()
39591
39935
  }), _void(), {
@@ -43649,202 +43993,6 @@ method(object({}), object({ rules: array(NcRuleSchema) }), { auth: "admin" }), m
43649
43993
  auth: "admin"
43650
43994
  }), method(NcAlarmSensorsInputSchema, NcAlarmSensorsSchema, { auth: "admin" });
43651
43995
  /**
43652
- * Zod schemas for persisted record types.
43653
- *
43654
- * These schemas serve as the single source of truth for types that are
43655
- * stored in the settings-store backend and retrieved via tRPC. They
43656
- * replace the manual TypeScript interfaces with schema-derived types,
43657
- * enabling runtime validation when reading from the backend.
43658
- *
43659
- * Convention: each schema is named `<Type>Schema`, the inferred TS type
43660
- * keeps the original name for backward compatibility.
43661
- */
43662
- /**
43663
- * Auth model (v2 — 2026-05-12 caps-only):
43664
- *
43665
- * Two principals:
43666
- * - `isAdmin: true` — full bypass. Admin scope set is ignored.
43667
- * - `isAdmin: false` — every call gated by `scopes` (see TokenScope).
43668
- *
43669
- * No role enum. There used to be `viewer / agent / scoped` and earlier
43670
- * `super_admin` — collapsed onto the single boolean because every
43671
- * non-admin caller is governed by the same scope-check rules; the
43672
- * distinction was only ever used to route role-specific procedures
43673
- * which we no longer have. CLI / webhook integrations are `cst_*` tokens
43674
- * with `isAdmin: false` + an explicit scope list.
43675
- */
43676
- /** Per-method access flavour. Materialised on every cap method via codegen. */
43677
- var MethodAccessSchema = _enum([
43678
- "view",
43679
- "create",
43680
- "delete"
43681
- ]);
43682
- /**
43683
- * A single scope grant. Three forms — checked in matcher with OR
43684
- * semantics; the first match decides whether the call passes:
43685
- *
43686
- * - `category` — broadest. `target: 'device' | 'system'` selects every
43687
- * cap with the matching `scope` declaration. New caps inherit grants
43688
- * automatically — adding a device cap to the codebase makes it
43689
- * reachable to every user with `category:device [...]` without a
43690
- * re-grant. Use this for "family viewer" / "operator" tiers.
43691
- *
43692
- * - `addon` — every cap that ships inside a given addon id. Niche;
43693
- * useful when an integration needs to interact with one specific
43694
- * addon's surface regardless of how many caps it exports.
43695
- *
43696
- * - `capability` — the most precise form. Single cap name. Use for
43697
- * integration tokens where you want to grant `addons.installPackage`
43698
- * and nothing else.
43699
- *
43700
- * `access` is REQUIRED with min 1 element. `admin` bypass is the
43701
- * "give me everything" escape; there is no wildcard scope.
43702
- */
43703
- var AllowedProviderSchema = union([literal("*"), array(string())]);
43704
- var AllowedDevicesSchema = record(string(), union([literal("*"), array(string())]));
43705
- var CapScopeSchema = _enum(["device", "system"]);
43706
- /**
43707
- * DeviceSelector (scope model v3 — 2026-08-12).
43708
- *
43709
- * A `device` grant no longer carries a frozen list of deviceIds. It carries
43710
- * a SELECTOR the matcher resolves against the live fleet, so the grant can be
43711
- * DYNAMIC: a `types:['camera']` selector automatically covers a camera added
43712
- * AFTER the grant was minted — no re-grant, no re-login.
43713
- *
43714
- * - `all` — every device in the deployment. The broad viewer/operator
43715
- * lever without a `category` grant (a `category` grant also covers device
43716
- * caps that carry no deviceId; `all` is specifically the device set).
43717
- * - `ids` — an explicit deviceId list. This is what a v2 `device:[…]`
43718
- * grant migrates to (see {@link TokenScopeSchema}); STATIC — a new camera
43719
- * is NOT covered until the grant is edited.
43720
- * - `types` — every device of a `DeviceType` (e.g. every `camera`).
43721
- * DYNAMIC. A device that changes type, or a new device of the type,
43722
- * re-resolves on the next request.
43723
- * - `locations` — every device whose operator-assigned `location` label is
43724
- * in the set (e.g. "Garden", "Front door"). DYNAMIC. A device with a
43725
- * null/unset location matches NO `locations` selector.
43726
- */
43727
- var DeviceSelectorSchema = discriminatedUnion("kind", [
43728
- object({ kind: literal("all") }),
43729
- object({
43730
- kind: literal("ids"),
43731
- ids: array(number().int()).min(1)
43732
- }),
43733
- object({
43734
- kind: literal("types"),
43735
- types: array(_enum(DeviceType)).min(1)
43736
- }),
43737
- object({
43738
- kind: literal("locations"),
43739
- locations: array(string().min(1)).min(1)
43740
- })
43741
- ]);
43742
- var DeviceTokenScopeSchema = object({
43743
- type: literal("device"),
43744
- /** The device SET this grant covers — resolved against the live fleet. */
43745
- selector: DeviceSelectorSchema,
43746
- access: array(MethodAccessSchema).min(1),
43747
- /**
43748
- * Whether a grant on a PARENT device transparently covers its accessory
43749
- * CHILDREN (siren / floodlight / PIR) via the persisted-parentage walk.
43750
- * Direction is parent → children ONLY.
43751
- *
43752
- * Absent → the matcher DERIVES it from the access flavour: `view`
43753
- * inherits (a camera viewer sees the camera's accessories), `create` /
43754
- * `delete` do NOT (actuating/removing a child is an explicit act the
43755
- * operator must grant on the child, not inherit from the parent). Set it
43756
- * explicitly to override that default per grant.
43757
- */
43758
- includeLinked: boolean().optional()
43759
- });
43760
- /**
43761
- * v2 → v3 lazy migration. A pre-v3 `device` grant carried
43762
- * `targets: string[]` (stringified deviceIds); it rewrites to the equivalent
43763
- * `selector: {kind:'ids', ids}`. Applied as a `preprocess` so it runs on
43764
- * EVERY parse path — stored records AND the JWT-carried scope arrays
43765
- * normalised at the request boundary ({@link normalizeTokenScopes} in
43766
- * `device-selector.ts`). Chosen over a one-time DB migration because a
43767
- * migration cannot reach a JWT already in a client's hands; parse-time
43768
- * migration covers both without a flag day. No cast — the raw object is read
43769
- * through `Reflect.get` (its static type is `unknown`).
43770
- */
43771
- function migrateLegacyTokenScope(raw) {
43772
- if (raw === null || typeof raw !== "object" || Array.isArray(raw)) return raw;
43773
- if (Reflect.get(raw, "type") !== "device") return raw;
43774
- if (Reflect.get(raw, "selector") !== void 0) return raw;
43775
- const targets = Reflect.get(raw, "targets");
43776
- if (!Array.isArray(targets)) return raw;
43777
- return {
43778
- type: "device",
43779
- selector: {
43780
- kind: "ids",
43781
- ids: targets.map((t) => typeof t === "string" ? Number(t) : t).filter((n) => typeof n === "number" && Number.isInteger(n))
43782
- },
43783
- access: Reflect.get(raw, "access")
43784
- };
43785
- }
43786
- var TokenScopeSchema = preprocess(migrateLegacyTokenScope, discriminatedUnion("type", [
43787
- object({
43788
- type: literal("category"),
43789
- target: CapScopeSchema,
43790
- access: array(MethodAccessSchema).min(1)
43791
- }),
43792
- object({
43793
- type: literal("capability"),
43794
- target: string(),
43795
- access: array(MethodAccessSchema).min(1)
43796
- }),
43797
- object({
43798
- type: literal("addon"),
43799
- target: string(),
43800
- access: array(MethodAccessSchema).min(1)
43801
- }),
43802
- DeviceTokenScopeSchema
43803
- ]));
43804
- object({
43805
- id: string(),
43806
- username: string(),
43807
- passwordHash: string(),
43808
- /**
43809
- * Admin bypass. When true, the middleware skips the scope-access
43810
- * check entirely. There is no other axis of privilege; the legacy
43811
- * role enum collapsed onto this boolean in v2.
43812
- */
43813
- isAdmin: boolean().default(false),
43814
- allowedProviders: AllowedProviderSchema,
43815
- allowedDevices: AllowedDevicesSchema,
43816
- /**
43817
- * Scopes granted to this user. Admins bypass; their `scopes` is
43818
- * ignored. Non-admins without scopes are locked out of every
43819
- * protected call.
43820
- */
43821
- scopes: array(TokenScopeSchema).default([]),
43822
- createdAt: number(),
43823
- updatedAt: number()
43824
- });
43825
- object({
43826
- id: string(),
43827
- label: string(),
43828
- isAdmin: boolean().default(false),
43829
- allowedProviders: AllowedProviderSchema,
43830
- allowedDevices: AllowedDevicesSchema,
43831
- tokenHash: string(),
43832
- tokenPrefix: string(),
43833
- createdAt: number(),
43834
- lastUsedAt: number().optional()
43835
- });
43836
- object({
43837
- id: string(),
43838
- userId: string(),
43839
- name: string(),
43840
- tokenHash: string(),
43841
- tokenPrefix: string(),
43842
- scopes: array(TokenScopeSchema),
43843
- expiresAt: number().nullish(),
43844
- lastUsedAt: number().nullish(),
43845
- createdAt: number()
43846
- });
43847
- /**
43848
43996
  * `oauth-integration` — a collection cap by which an addon declares
43849
43997
  * itself a linkable OAuth client of the hub's core `/oauth2/*` server.
43850
43998
  * Each provider returns a static descriptor; the core enumerates them
@@ -60776,26 +60924,6 @@ var ApiKeySummarySchema = object({
60776
60924
  createdAt: number(),
60777
60925
  lastUsedAt: number().optional()
60778
60926
  });
60779
- var ScopedTokenSummarySchema = object({
60780
- id: string(),
60781
- userId: string(),
60782
- name: string(),
60783
- tokenPrefix: string(),
60784
- scopes: array(TokenScopeSchema),
60785
- expiresAt: number().nullish(),
60786
- lastUsedAt: number().nullish(),
60787
- createdAt: number()
60788
- });
60789
- var CreateScopedTokenInputSchema = object({
60790
- userId: string(),
60791
- name: string(),
60792
- scopes: array(TokenScopeSchema),
60793
- expiresAt: number().optional()
60794
- });
60795
- var CreateScopedTokenResultSchema = object({
60796
- token: string(),
60797
- record: ScopedTokenSummarySchema
60798
- });
60799
60927
  var OauthSessionSummarySchema = object({
60800
60928
  id: string(),
60801
60929
  userId: string(),
@@ -60817,11 +60945,11 @@ var TotpStatusSchema = object({
60817
60945
  confirmedAt: number().nullable()
60818
60946
  });
60819
60947
  /**
60820
- * user-management — singleton capability for user accounts, API keys,
60821
- * and scoped tokens.
60948
+ * user-management — singleton capability for user accounts and the
60949
+ * legacy API-key rows.
60822
60950
  *
60823
60951
  * v2 model: every method gated by `auth: 'admin'`. Admin-only delegation
60824
- * — the subset check on `setUserScopes` / `createScopedToken` is moot
60952
+ * — the subset check on `setUserScopes` is moot
60825
60953
  * because non-admins never reach these. If/when we open non-admin
60826
60954
  * delegation, structural caller-scope subset check goes inside the
60827
60955
  * provider.
@@ -60878,15 +61006,7 @@ method(_void(), array(UserSummarySchema), { auth: "admin" }), method(CreateUserI
60878
61006
  kind: "mutation",
60879
61007
  auth: "admin",
60880
61008
  access: "delete"
60881
- }), method(CreateScopedTokenInputSchema, CreateScopedTokenResultSchema, {
60882
- kind: "mutation",
60883
- auth: "admin",
60884
- access: "create"
60885
- }), method(object({ id: string() }), object({ success: literal(true) }), {
60886
- kind: "mutation",
60887
- auth: "admin",
60888
- access: "delete"
60889
- }), method(object({ token: string() }), ScopedTokenSummarySchema.nullable(), { access: "view" }), method(object({ userId: string() }), array(ScopedTokenSummarySchema), { auth: "admin" }), method(object({ userId: string() }), TotpSetupResultSchema, {
61009
+ }), method(object({ userId: string() }), TotpSetupResultSchema, {
60890
61010
  kind: "mutation",
60891
61011
  auth: "admin",
60892
61012
  access: "create"
@@ -65042,7 +65162,7 @@ Object.freeze({
65042
65162
  capName: "llm",
65043
65163
  capScope: "system",
65044
65164
  addonId: null,
65045
- access: "view"
65165
+ access: "create"
65046
65166
  },
65047
65167
  "llm.listNodeModels": {
65048
65168
  capName: "llm",
@@ -69706,12 +69826,6 @@ Object.freeze({
69706
69826
  addonId: null,
69707
69827
  access: "create"
69708
69828
  },
69709
- "userManagement.createScopedToken": {
69710
- capName: "user-management",
69711
- capScope: "system",
69712
- addonId: null,
69713
- access: "create"
69714
- },
69715
69829
  "userManagement.createUser": {
69716
69830
  capName: "user-management",
69717
69831
  capScope: "system",
@@ -69760,12 +69874,6 @@ Object.freeze({
69760
69874
  addonId: null,
69761
69875
  access: "view"
69762
69876
  },
69763
- "userManagement.listScopedTokens": {
69764
- capName: "user-management",
69765
- capScope: "system",
69766
- addonId: null,
69767
- access: "view"
69768
- },
69769
69877
  "userManagement.listUsers": {
69770
69878
  capName: "user-management",
69771
69879
  capScope: "system",
@@ -69820,12 +69928,6 @@ Object.freeze({
69820
69928
  addonId: null,
69821
69929
  access: "delete"
69822
69930
  },
69823
- "userManagement.revokeScopedToken": {
69824
- capName: "user-management",
69825
- capScope: "system",
69826
- addonId: null,
69827
- access: "delete"
69828
- },
69829
69931
  "userManagement.setupTotp": {
69830
69932
  capName: "user-management",
69831
69933
  capScope: "system",
@@ -69856,12 +69958,6 @@ Object.freeze({
69856
69958
  addonId: null,
69857
69959
  access: "view"
69858
69960
  },
69859
- "userManagement.validateScopedToken": {
69860
- capName: "user-management",
69861
- capScope: "system",
69862
- addonId: null,
69863
- access: "view"
69864
- },
69865
69961
  "userManagement.verifyTotp": {
69866
69962
  capName: "user-management",
69867
69963
  capScope: "system",