@camstack/addon-waste-collections 0.1.10 → 0.1.12

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.
@@ -5550,7 +5550,7 @@ var ZodIssueCode = {
5550
5550
  var ZodFirstPartyTypeKind;
5551
5551
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5552
5552
  //#endregion
5553
- //#region ../types/dist/sleep-BxjU_fJM.mjs
5553
+ //#region ../types/dist/sleep-yKL5gfrH.mjs
5554
5554
  /**
5555
5555
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5556
5556
  * window to float samples (D455).
@@ -7942,6 +7942,12 @@ function normalizeAddonInitResult(result) {
7942
7942
  if (Array.isArray(result)) return { providers: result };
7943
7943
  return result;
7944
7944
  }
7945
+ /**
7946
+ * The share-view scope kinds a share-link token can carry. The hub mints
7947
+ * and validates them (`ShareViewGrantSchema` builds its
7948
+ * enum from this list); a data plane names the kinds it ACCEPTS in `share`.
7949
+ */
7950
+ var SHARE_VIEW_KINDS = ["grid-view", "events-view"];
7945
7951
  /** The wire shape of {@link PeerBytesTicket} — see the type for what it is. */
7946
7952
  var PeerBytesTicketSchema = object({
7947
7953
  /** `http://127.0.0.1:<port>/<token>`. One `GET` takes it. */
@@ -12814,6 +12820,280 @@ var ConvertResultSchema = object({
12814
12820
  files: array(string()).readonly()
12815
12821
  })).readonly()
12816
12822
  });
12823
+ /**
12824
+ * Zod schemas for persisted record types.
12825
+ *
12826
+ * These schemas serve as the single source of truth for types that are
12827
+ * stored in the settings-store backend and retrieved via tRPC. They
12828
+ * replace the manual TypeScript interfaces with schema-derived types,
12829
+ * enabling runtime validation when reading from the backend.
12830
+ *
12831
+ * Convention: each schema is named `<Type>Schema`, the inferred TS type
12832
+ * keeps the original name for backward compatibility.
12833
+ */
12834
+ /**
12835
+ * Auth model (v2 — 2026-05-12 caps-only):
12836
+ *
12837
+ * Two principals:
12838
+ * - `isAdmin: true` — full bypass. Admin scope set is ignored.
12839
+ * - `isAdmin: false` — every call gated by `scopes` (see TokenScope).
12840
+ *
12841
+ * No role enum. There used to be `viewer / agent / scoped` and earlier
12842
+ * `super_admin` — collapsed onto the single boolean because every
12843
+ * non-admin caller is governed by the same scope-check rules; the
12844
+ * distinction was only ever used to route role-specific procedures
12845
+ * which we no longer have. CLI / webhook integrations are tokens (`auth.mintToken`)
12846
+ * with `isAdmin: false` + an explicit scope list.
12847
+ */
12848
+ /** Per-method access flavour. Materialised on every cap method via codegen. */
12849
+ var MethodAccessSchema = _enum([
12850
+ "view",
12851
+ "create",
12852
+ "delete"
12853
+ ]);
12854
+ /**
12855
+ * A single scope grant. Three forms — checked in matcher with OR
12856
+ * semantics; the first match decides whether the call passes:
12857
+ *
12858
+ * - `category` — broadest. `target: 'device' | 'system'` selects every
12859
+ * cap with the matching `scope` declaration. New caps inherit grants
12860
+ * automatically — adding a device cap to the codebase makes it
12861
+ * reachable to every user with `category:device [...]` without a
12862
+ * re-grant. Use this for "family viewer" / "operator" tiers.
12863
+ *
12864
+ * - `addon` — every cap that ships inside a given addon id. Niche;
12865
+ * useful when an integration needs to interact with one specific
12866
+ * addon's surface regardless of how many caps it exports.
12867
+ *
12868
+ * - `capability` — the most precise form. Single cap name. Use for
12869
+ * integration tokens where you want to grant `addons.installPackage`
12870
+ * and nothing else.
12871
+ *
12872
+ * `access` is REQUIRED with min 1 element. `admin` bypass is the
12873
+ * "give me everything" escape; there is no wildcard scope.
12874
+ */
12875
+ var AllowedProviderSchema = union([literal("*"), array(string())]);
12876
+ var AllowedDevicesSchema = record(string(), union([literal("*"), array(string())]));
12877
+ var CapScopeSchema = _enum(["device", "system"]);
12878
+ /**
12879
+ * DeviceSelector (scope model v3 — 2026-08-12).
12880
+ *
12881
+ * A `device` grant no longer carries a frozen list of deviceIds. It carries
12882
+ * a SELECTOR the matcher resolves against the live fleet, so the grant can be
12883
+ * DYNAMIC: a `types:['camera']` selector automatically covers a camera added
12884
+ * AFTER the grant was minted — no re-grant, no re-login.
12885
+ *
12886
+ * - `all` — every device in the deployment. The broad viewer/operator
12887
+ * lever without a `category` grant (a `category` grant also covers device
12888
+ * caps that carry no deviceId; `all` is specifically the device set).
12889
+ * - `ids` — an explicit deviceId list. This is what a v2 `device:[…]`
12890
+ * grant migrates to (see {@link TokenScopeSchema}); STATIC — a new camera
12891
+ * is NOT covered until the grant is edited.
12892
+ * - `types` — every device of a `DeviceType` (e.g. every `camera`).
12893
+ * DYNAMIC. A device that changes type, or a new device of the type,
12894
+ * re-resolves on the next request.
12895
+ * - `locations` — every device whose operator-assigned `location` label is
12896
+ * in the set (e.g. "Garden", "Front door"). DYNAMIC. A device with a
12897
+ * null/unset location matches NO `locations` selector.
12898
+ */
12899
+ var DeviceSelectorSchema = discriminatedUnion("kind", [
12900
+ object({ kind: literal("all") }),
12901
+ object({
12902
+ kind: literal("ids"),
12903
+ ids: array(number().int()).min(1)
12904
+ }),
12905
+ object({
12906
+ kind: literal("types"),
12907
+ types: array(_enum(DeviceType)).min(1)
12908
+ }),
12909
+ object({
12910
+ kind: literal("locations"),
12911
+ locations: array(string().min(1)).min(1)
12912
+ })
12913
+ ]);
12914
+ var DeviceTokenScopeSchema = object({
12915
+ type: literal("device"),
12916
+ /** The device SET this grant covers — resolved against the live fleet. */
12917
+ selector: DeviceSelectorSchema,
12918
+ access: array(MethodAccessSchema).min(1),
12919
+ /**
12920
+ * Whether a grant on a PARENT device transparently covers its accessory
12921
+ * CHILDREN (siren / floodlight / PIR) via the persisted-parentage walk.
12922
+ * Direction is parent → children ONLY.
12923
+ *
12924
+ * Absent → the matcher DERIVES it from the access flavour: `view`
12925
+ * inherits (a camera viewer sees the camera's accessories), `create` /
12926
+ * `delete` do NOT (actuating/removing a child is an explicit act the
12927
+ * operator must grant on the child, not inherit from the parent). Set it
12928
+ * explicitly to override that default per grant.
12929
+ */
12930
+ includeLinked: boolean().optional()
12931
+ });
12932
+ /**
12933
+ * v2 → v3 lazy migration. A pre-v3 `device` grant carried
12934
+ * `targets: string[]` (stringified deviceIds); it rewrites to the equivalent
12935
+ * `selector: {kind:'ids', ids}`. Applied as a `preprocess` so it runs on
12936
+ * EVERY parse path — stored records AND the JWT-carried scope arrays
12937
+ * normalised at the request boundary ({@link normalizeTokenScopes} in
12938
+ * `device-selector.ts`). Chosen over a one-time DB migration because a
12939
+ * migration cannot reach a JWT already in a client's hands; parse-time
12940
+ * migration covers both without a flag day. No cast — the raw object is read
12941
+ * through `Reflect.get` (its static type is `unknown`).
12942
+ */
12943
+ function migrateLegacyTokenScope(raw) {
12944
+ if (raw === null || typeof raw !== "object" || Array.isArray(raw)) return raw;
12945
+ if (Reflect.get(raw, "type") !== "device") return raw;
12946
+ if (Reflect.get(raw, "selector") !== void 0) return raw;
12947
+ const targets = Reflect.get(raw, "targets");
12948
+ if (!Array.isArray(targets)) return raw;
12949
+ return {
12950
+ type: "device",
12951
+ selector: {
12952
+ kind: "ids",
12953
+ ids: targets.map((t) => typeof t === "string" ? Number(t) : t).filter((n) => typeof n === "number" && Number.isInteger(n))
12954
+ },
12955
+ access: Reflect.get(raw, "access")
12956
+ };
12957
+ }
12958
+ var TokenScopeSchema = preprocess(migrateLegacyTokenScope, discriminatedUnion("type", [
12959
+ object({
12960
+ type: literal("category"),
12961
+ target: CapScopeSchema,
12962
+ access: array(MethodAccessSchema).min(1)
12963
+ }),
12964
+ object({
12965
+ type: literal("capability"),
12966
+ target: string(),
12967
+ access: array(MethodAccessSchema).min(1)
12968
+ }),
12969
+ object({
12970
+ type: literal("addon"),
12971
+ target: string(),
12972
+ access: array(MethodAccessSchema).min(1)
12973
+ }),
12974
+ DeviceTokenScopeSchema
12975
+ ]));
12976
+ object({
12977
+ id: string(),
12978
+ username: string(),
12979
+ passwordHash: string(),
12980
+ /**
12981
+ * Admin bypass. When true, the middleware skips the scope-access
12982
+ * check entirely. There is no other axis of privilege; the legacy
12983
+ * role enum collapsed onto this boolean in v2.
12984
+ */
12985
+ isAdmin: boolean().default(false),
12986
+ allowedProviders: AllowedProviderSchema,
12987
+ allowedDevices: AllowedDevicesSchema,
12988
+ /**
12989
+ * Scopes granted to this user. Admins bypass; their `scopes` is
12990
+ * ignored. Non-admins without scopes are locked out of every
12991
+ * protected call.
12992
+ */
12993
+ scopes: array(TokenScopeSchema).default([]),
12994
+ createdAt: number(),
12995
+ updatedAt: number()
12996
+ });
12997
+ object({
12998
+ id: string(),
12999
+ label: string(),
13000
+ isAdmin: boolean().default(false),
13001
+ allowedProviders: AllowedProviderSchema,
13002
+ allowedDevices: AllowedDevicesSchema,
13003
+ tokenHash: string(),
13004
+ tokenPrefix: string(),
13005
+ createdAt: number(),
13006
+ lastUsedAt: number().optional()
13007
+ });
13008
+ object({
13009
+ id: string(),
13010
+ userId: string(),
13011
+ name: string(),
13012
+ tokenHash: string(),
13013
+ tokenPrefix: string(),
13014
+ scopes: array(TokenScopeSchema),
13015
+ expiresAt: number().nullish(),
13016
+ lastUsedAt: number().nullish(),
13017
+ createdAt: number()
13018
+ });
13019
+ /** What a share-view grant lets its holder see. */
13020
+ var ShareViewGrantSchema = object({
13021
+ kind: _enum(SHARE_VIEW_KINDS),
13022
+ deviceIds: array(number().int().nonnegative()).min(1).max(64),
13023
+ /** Talk-back, opt-in at mint time; absent means off. */
13024
+ talk: boolean().optional()
13025
+ });
13026
+ var ShareViewScopeSchema = object({
13027
+ type: literal("share-view"),
13028
+ grant: ShareViewGrantSchema
13029
+ });
13030
+ var AddonRoutesScopeSchema = object({
13031
+ type: literal("addon-routes"),
13032
+ access: array(MethodAccessSchema).min(1)
13033
+ });
13034
+ var PreferencesSelfScopeSchema = object({ type: literal("preferences-self") });
13035
+ var CredentialScopeSchema = union([
13036
+ literal("*"),
13037
+ ShareViewScopeSchema,
13038
+ AddonRoutesScopeSchema,
13039
+ PreferencesSelfScopeSchema,
13040
+ TokenScopeSchema
13041
+ ]);
13042
+ object({
13043
+ kind: literal("credential"),
13044
+ sub: string().min(1),
13045
+ jti: string().min(16),
13046
+ scopes: array(CredentialScopeSchema).min(1)
13047
+ });
13048
+ var PreferenceNamespaceSchema = string().regex(/^[a-z][a-z0-9.-]{0,63}$/);
13049
+ /** A namespace's value: a JSON object, opaque to the hub. */
13050
+ var PreferenceValueSchema = record(string(), unknown());
13051
+ var PreferenceDeviceIdSchema = string().min(1).max(64);
13052
+ /** A stored row, as the owner reads it. */
13053
+ var PreferenceRowSchema = object({
13054
+ namespace: PreferenceNamespaceSchema,
13055
+ value: PreferenceValueSchema,
13056
+ /** Starts at 1, +1 on every write of this namespace. A delete ends the row and its count. */
13057
+ revision: number().int().positive(),
13058
+ updatedAt: number().int(),
13059
+ /** The client id the last writer sent; `null` when it sent none. */
13060
+ updatedByDevice: PreferenceDeviceIdSchema.nullable()
13061
+ });
13062
+ object({
13063
+ /** Absent: every namespace the caller holds. */
13064
+ namespaces: array(PreferenceNamespaceSchema).max(32).optional() });
13065
+ object({ rows: array(PreferenceRowSchema) });
13066
+ object({
13067
+ namespace: PreferenceNamespaceSchema,
13068
+ value: PreferenceValueSchema,
13069
+ /**
13070
+ * The revision the edit was based on. Absent: last write wins. `0`: the
13071
+ * namespace must not exist yet. Any other value that is not the current
13072
+ * revision answers `conflict` and writes nothing.
13073
+ */
13074
+ baseRevision: number().int().nonnegative().optional(),
13075
+ deviceId: PreferenceDeviceIdSchema.optional()
13076
+ });
13077
+ discriminatedUnion("status", [object({
13078
+ status: literal("saved"),
13079
+ row: PreferenceRowSchema
13080
+ }), object({
13081
+ status: literal("conflict"),
13082
+ current: PreferenceRowSchema.nullable()
13083
+ })]);
13084
+ object({ namespace: PreferenceNamespaceSchema });
13085
+ object({
13086
+ /** `false` when the namespace did not exist. */
13087
+ deleted: boolean() });
13088
+ object({
13089
+ /** The revision the client holds per namespace; a namespace it does not list is new to it. */
13090
+ revisionByNamespace: record(PreferenceNamespaceSchema, number().int().nonnegative()).refine((map) => Object.keys(map).length <= 32, { message: `at most 32 namespaces` }) });
13091
+ object({
13092
+ /** Every row whose revision differs from the client's, and every row it did not list. */
13093
+ rows: array(PreferenceRowSchema),
13094
+ /** Namespaces the client listed that no longer exist. */
13095
+ deleted: array(PreferenceNamespaceSchema)
13096
+ });
12817
13097
  _enum(["new-session", "step-up"]);
12818
13098
  /** The languages the hub's app landing pages are written in (D858). */
12819
13099
  var AppPageLangSchema = _enum(["en", "it"]);
@@ -39692,38 +39972,37 @@ method(LlmRuntimeCompleteInputSchema, LlmGenerateResultSchema, {
39692
39972
  auth: "admin",
39693
39973
  timeoutMs: AI_CAP_TRANSPORT_TIMEOUT_MS
39694
39974
  });
39975
+ var LlmProfileKindSchema = string().regex(/^[a-z0-9][a-z0-9-]{0,63}$/, "a kind id is lower-case letters, digits and dashes");
39976
+ /** What a model (or, by default, every model of a kind) can do. */
39977
+ var LlmModelFeaturesSchema = object({
39978
+ vision: boolean(),
39979
+ tools: boolean(),
39980
+ streaming: boolean()
39981
+ });
39982
+ /** One model a provider offers. `features` overrides the kind's defaults, per field. */
39983
+ var LlmModelInfoSchema = object({
39984
+ id: string(),
39985
+ label: string().optional(),
39986
+ contextLength: number().int().positive().optional(),
39987
+ features: LlmModelFeaturesSchema.partial().optional()
39988
+ });
39695
39989
  /**
39696
- * `llm` — consumer-facing LLM surface (spec §1-§3). Collection-mode: array
39697
- * methods concat-fan across providers; single-row methods route to ONE
39698
- * provider by the `addonId` in the call input (the notification-output
39699
- * posture, notification-output.cap.ts:215-250). Provided by `addon-ai`
39700
- * (hub-placed); the cap stays open for future providers.
39701
- *
39702
- * Profiles are ROWS (data), not addons: one row = one usable model endpoint.
39703
- * `apiKey` is a password field — providers REDACT it on read and merge on
39704
- * write; a stored key NEVER round-trips to a client.
39990
+ * The provider-specific part of a profile, validated by the provider that owns
39991
+ * the kind (`upsertProfile` refuses what it does not accept). A field its
39992
+ * `connectionSchema` declares `type: 'password'` is a secret: it is held in the
39993
+ * keychain, never in the row, and reads back as the redaction marker.
39705
39994
  */
39706
- var LlmProfileKindSchema = _enum([
39707
- "openai-compatible",
39708
- "openai",
39709
- "anthropic",
39710
- "google",
39711
- "managed-local",
39712
- "apple-foundation"
39713
- ]);
39995
+ var LlmProviderConfigSchema = record(string(), unknown());
39714
39996
  var LlmProfileSchema = object({
39715
39997
  id: string(),
39716
39998
  name: string(),
39999
+ /** The provider-declared kind (`LlmProfileKindDescriptor.kind`). */
39717
40000
  kind: LlmProfileKindSchema,
39718
40001
  /** Stamped by the provider — keeps the fanned catalog routable. */
39719
40002
  addonId: string(),
39720
40003
  enabled: boolean(),
39721
40004
  /** Vendor model id, or the managed runtime's loaded model. */
39722
40005
  model: string(),
39723
- /** Required for openai-compatible; override for cloud kinds. */
39724
- baseUrl: string().optional(),
39725
- /** ConfigUISchema type:'password' — never round-trips (spec §5). */
39726
- apiKey: string().optional(),
39727
40006
  /** Vision on/off. A vision call against a `false` profile is REFUSED, never
39728
40007
  * degraded to text — that shipped once and produced a confident answer to a
39729
40008
  * question about a picture nobody sent. */
@@ -39731,15 +40010,11 @@ var LlmProfileSchema = object({
39731
40010
  temperature: number().min(0).max(2).optional(),
39732
40011
  /** Nucleus sampling. Every wire we speak has it. */
39733
40012
  topP: number().min(0).max(1).optional(),
39734
- /** Top-k sampling. Carried only by the wires that have it — NEITHER OpenAI
39735
- * wire does, and the client drops it there (measured: the request body gets
39736
- * `top_p` and no `top_k`). The profile editor hides the field wherever it
39737
- * would change nothing; `KINDS_WITH_TOP_K` is the single owner of that list. */
40013
+ /** Top-k sampling. Carried only by the wires that have it — a kind offers the
40014
+ * field in its editor only when its descriptor lists it in `profileFields`. */
39738
40015
  topK: number().int().positive().optional(),
39739
40016
  maxTokens: number().int().positive().optional(),
39740
- /** Prompt context window. Advisory for cloud kinds (they enforce their own);
39741
- * for `managed-local` it is the llama.cpp `--ctx-size` the runtime starts
39742
- * the model with, so it is the one field that changes a PROCESS. */
40017
+ /** Prompt context window. Advisory for cloud kinds (they enforce their own). */
39743
40018
  contextLength: number().int().positive().optional(),
39744
40019
  /** Default system prompt. A caller's `system` REPLACES it (never appends —
39745
40020
  * two system prompts fighting is worse than either alone). */
@@ -39765,16 +40040,37 @@ var LlmProfileSchema = object({
39765
40040
  * library; the REGISTRY of callable tools is ours and is empty in v1, so a
39766
40041
  * `true` here buys the wiring, not behaviour, until tools are registered. */
39767
40042
  toolsEnabled: boolean().default(false),
39768
- extraHeaders: record(string(), string()).optional(),
39769
- /** kind === 'managed-local' only (spec §4). */
39770
- runtime: ManagedRuntimeConfigSchema.optional(),
39771
- /**
39772
- * kind === 'apple-foundation' only: WHERE it runs — the only thing there is
39773
- * to configure (no key, no URL, no download; `model` is `apple-system`).
39774
- * `supportsVision` on such a row is stamped by the provider from the node's
39775
- * reported `imageInput`, never taken from the operator (D62).
39776
- */
39777
- appleFoundation: object({ nodeId: string() }).optional()
40043
+ /** Everything the kind's provider owns (endpoint, key, node, runtime…). */
40044
+ providerConfig: LlmProviderConfigSchema.default({})
40045
+ });
40046
+ /**
40047
+ * The common profile fields a kind's editor offers. The editor owns how each
40048
+ * one is drawn; the provider says which of them mean something on its wire.
40049
+ */
40050
+ var LlmProfileFieldSchema = _enum([
40051
+ "temperature",
40052
+ "topP",
40053
+ "topK",
40054
+ "maxTokens",
40055
+ "contextLength",
40056
+ "systemPrompt",
40057
+ "timeoutMs",
40058
+ "connectTimeoutMs",
40059
+ "firstTokenTimeoutMs",
40060
+ "idleTimeoutMs",
40061
+ "retry",
40062
+ "toolsEnabled"
40063
+ ]);
40064
+ /**
40065
+ * A provider-drawn part of the editor, by a generic widget id the admin UI
40066
+ * registers (`ai/apple-node`). `placement: 'model'` replaces the generic model
40067
+ * picker: that widget owns the model choice.
40068
+ */
40069
+ var LlmProviderWidgetSchema = object({
40070
+ id: string(),
40071
+ placement: _enum(["connection", "model"]),
40072
+ /** `providerConfig` keys this widget must fill before the profile can be saved. */
40073
+ requires: array(string()).optional()
39778
40074
  });
39779
40075
  /** ConfigUISchema tree passed through untyped on the wire (the
39780
40076
  * notification-output `ConfigSchemaPassthrough` precedent at
@@ -39783,11 +40079,56 @@ var ConfigSchemaPassthrough$3 = unknown();
39783
40079
  var LlmProfileKindDescriptorSchema = object({
39784
40080
  kind: LlmProfileKindSchema,
39785
40081
  label: string(),
40082
+ /** A generic icon name (`cloud`, `plug`, `cpu`) — never a glyph or a logo. */
39786
40083
  icon: string(),
39787
40084
  /** Stamped by each provider so the concat-fanned catalog stays routable. */
39788
40085
  addonId: string(),
39789
- configSchema: ConfigSchemaPassthrough$3
40086
+ /** The provider's own fields (`providerConfig`); `password` fields are keychain-held. */
40087
+ connectionSchema: ConfigSchemaPassthrough$3,
40088
+ /** Provider fields that belong under "Advanced" (extra headers, runtime tuning). */
40089
+ advancedSchema: ConfigSchemaPassthrough$3.optional(),
40090
+ /** The kind's defaults; a model from `listModels` may override any of them. */
40091
+ features: LlmModelFeaturesSchema,
40092
+ /** `false` = the provider stamps `supportsVision` itself (from what a node reports). */
40093
+ visionEditable: boolean(),
40094
+ /** Where the model list comes from: `listModels`, `staticModels`, or nowhere. */
40095
+ modelCatalog: _enum([
40096
+ "fetch",
40097
+ "static",
40098
+ "none"
40099
+ ]),
40100
+ staticModels: array(LlmModelInfoSchema).optional(),
40101
+ /** The common fields that mean something on this kind's wire. */
40102
+ profileFields: array(LlmProfileFieldSchema),
40103
+ providerWidgets: array(LlmProviderWidgetSchema).optional()
40104
+ });
40105
+ /**
40106
+ * `listModels` input. `connection` is an UNSAVED draft of `providerConfig`
40107
+ * (the editor's form); with `profileId` too, a secret the draft leaves
40108
+ * untouched (absent or the redaction marker) is resolved server-side from the
40109
+ * stored profile — the browser never receives it.
40110
+ */
40111
+ var LlmListModelsInputSchema = object({
40112
+ addonId: string(),
40113
+ kind: LlmProfileKindSchema,
40114
+ profileId: string().optional(),
40115
+ connection: LlmProviderConfigSchema.optional()
39790
40116
  });
40117
+ var LlmListModelsErrorCodeSchema = _enum([
40118
+ "auth",
40119
+ "network",
40120
+ "unsupported",
40121
+ "invalid"
40122
+ ]);
40123
+ /** A RESULT, never a throw: "wrong key" is an answer the editor renders inline. */
40124
+ var LlmListModelsResultSchema = discriminatedUnion("ok", [object({
40125
+ ok: literal(true),
40126
+ models: array(LlmModelInfoSchema)
40127
+ }), object({
40128
+ ok: literal(false),
40129
+ code: LlmListModelsErrorCodeSchema,
40130
+ message: string()
40131
+ })]);
39791
40132
  var LlmDefaultSelectorSchema = union([object({ consumer: string() }), object({ purpose: _enum(["text", "vision"]) })]);
39792
40133
  var LlmDefaultSchema = object({
39793
40134
  selector: LlmDefaultSelectorSchema,
@@ -39887,7 +40228,10 @@ method(LlmGenerateBaseInputSchema, LlmGenerateResultSchema, {
39887
40228
  kind: "mutation",
39888
40229
  auth: "admin",
39889
40230
  timeoutMs: AI_CAP_TRANSPORT_TIMEOUT_MS
39890
- }), method(ProfileRefInputSchema, array(string())), method(object({}), array(LlmDefaultSchema)), method(object({
40231
+ }), method(LlmListModelsInputSchema, LlmListModelsResultSchema, {
40232
+ kind: "mutation",
40233
+ auth: "admin"
40234
+ }), method(object({}), array(LlmDefaultSchema)), method(object({
39891
40235
  selector: LlmDefaultSelectorSchema,
39892
40236
  profileId: string().nullable()
39893
40237
  }), _void(), {
@@ -43951,202 +44295,6 @@ method(object({}), object({ rules: array(NcRuleSchema) }), { auth: "admin" }), m
43951
44295
  auth: "admin"
43952
44296
  }), method(NcAlarmSensorsInputSchema, NcAlarmSensorsSchema, { auth: "admin" });
43953
44297
  /**
43954
- * Zod schemas for persisted record types.
43955
- *
43956
- * These schemas serve as the single source of truth for types that are
43957
- * stored in the settings-store backend and retrieved via tRPC. They
43958
- * replace the manual TypeScript interfaces with schema-derived types,
43959
- * enabling runtime validation when reading from the backend.
43960
- *
43961
- * Convention: each schema is named `<Type>Schema`, the inferred TS type
43962
- * keeps the original name for backward compatibility.
43963
- */
43964
- /**
43965
- * Auth model (v2 — 2026-05-12 caps-only):
43966
- *
43967
- * Two principals:
43968
- * - `isAdmin: true` — full bypass. Admin scope set is ignored.
43969
- * - `isAdmin: false` — every call gated by `scopes` (see TokenScope).
43970
- *
43971
- * No role enum. There used to be `viewer / agent / scoped` and earlier
43972
- * `super_admin` — collapsed onto the single boolean because every
43973
- * non-admin caller is governed by the same scope-check rules; the
43974
- * distinction was only ever used to route role-specific procedures
43975
- * which we no longer have. CLI / webhook integrations are `cst_*` tokens
43976
- * with `isAdmin: false` + an explicit scope list.
43977
- */
43978
- /** Per-method access flavour. Materialised on every cap method via codegen. */
43979
- var MethodAccessSchema = _enum([
43980
- "view",
43981
- "create",
43982
- "delete"
43983
- ]);
43984
- /**
43985
- * A single scope grant. Three forms — checked in matcher with OR
43986
- * semantics; the first match decides whether the call passes:
43987
- *
43988
- * - `category` — broadest. `target: 'device' | 'system'` selects every
43989
- * cap with the matching `scope` declaration. New caps inherit grants
43990
- * automatically — adding a device cap to the codebase makes it
43991
- * reachable to every user with `category:device [...]` without a
43992
- * re-grant. Use this for "family viewer" / "operator" tiers.
43993
- *
43994
- * - `addon` — every cap that ships inside a given addon id. Niche;
43995
- * useful when an integration needs to interact with one specific
43996
- * addon's surface regardless of how many caps it exports.
43997
- *
43998
- * - `capability` — the most precise form. Single cap name. Use for
43999
- * integration tokens where you want to grant `addons.installPackage`
44000
- * and nothing else.
44001
- *
44002
- * `access` is REQUIRED with min 1 element. `admin` bypass is the
44003
- * "give me everything" escape; there is no wildcard scope.
44004
- */
44005
- var AllowedProviderSchema = union([literal("*"), array(string())]);
44006
- var AllowedDevicesSchema = record(string(), union([literal("*"), array(string())]));
44007
- var CapScopeSchema = _enum(["device", "system"]);
44008
- /**
44009
- * DeviceSelector (scope model v3 — 2026-08-12).
44010
- *
44011
- * A `device` grant no longer carries a frozen list of deviceIds. It carries
44012
- * a SELECTOR the matcher resolves against the live fleet, so the grant can be
44013
- * DYNAMIC: a `types:['camera']` selector automatically covers a camera added
44014
- * AFTER the grant was minted — no re-grant, no re-login.
44015
- *
44016
- * - `all` — every device in the deployment. The broad viewer/operator
44017
- * lever without a `category` grant (a `category` grant also covers device
44018
- * caps that carry no deviceId; `all` is specifically the device set).
44019
- * - `ids` — an explicit deviceId list. This is what a v2 `device:[…]`
44020
- * grant migrates to (see {@link TokenScopeSchema}); STATIC — a new camera
44021
- * is NOT covered until the grant is edited.
44022
- * - `types` — every device of a `DeviceType` (e.g. every `camera`).
44023
- * DYNAMIC. A device that changes type, or a new device of the type,
44024
- * re-resolves on the next request.
44025
- * - `locations` — every device whose operator-assigned `location` label is
44026
- * in the set (e.g. "Garden", "Front door"). DYNAMIC. A device with a
44027
- * null/unset location matches NO `locations` selector.
44028
- */
44029
- var DeviceSelectorSchema = discriminatedUnion("kind", [
44030
- object({ kind: literal("all") }),
44031
- object({
44032
- kind: literal("ids"),
44033
- ids: array(number().int()).min(1)
44034
- }),
44035
- object({
44036
- kind: literal("types"),
44037
- types: array(_enum(DeviceType)).min(1)
44038
- }),
44039
- object({
44040
- kind: literal("locations"),
44041
- locations: array(string().min(1)).min(1)
44042
- })
44043
- ]);
44044
- var DeviceTokenScopeSchema = object({
44045
- type: literal("device"),
44046
- /** The device SET this grant covers — resolved against the live fleet. */
44047
- selector: DeviceSelectorSchema,
44048
- access: array(MethodAccessSchema).min(1),
44049
- /**
44050
- * Whether a grant on a PARENT device transparently covers its accessory
44051
- * CHILDREN (siren / floodlight / PIR) via the persisted-parentage walk.
44052
- * Direction is parent → children ONLY.
44053
- *
44054
- * Absent → the matcher DERIVES it from the access flavour: `view`
44055
- * inherits (a camera viewer sees the camera's accessories), `create` /
44056
- * `delete` do NOT (actuating/removing a child is an explicit act the
44057
- * operator must grant on the child, not inherit from the parent). Set it
44058
- * explicitly to override that default per grant.
44059
- */
44060
- includeLinked: boolean().optional()
44061
- });
44062
- /**
44063
- * v2 → v3 lazy migration. A pre-v3 `device` grant carried
44064
- * `targets: string[]` (stringified deviceIds); it rewrites to the equivalent
44065
- * `selector: {kind:'ids', ids}`. Applied as a `preprocess` so it runs on
44066
- * EVERY parse path — stored records AND the JWT-carried scope arrays
44067
- * normalised at the request boundary ({@link normalizeTokenScopes} in
44068
- * `device-selector.ts`). Chosen over a one-time DB migration because a
44069
- * migration cannot reach a JWT already in a client's hands; parse-time
44070
- * migration covers both without a flag day. No cast — the raw object is read
44071
- * through `Reflect.get` (its static type is `unknown`).
44072
- */
44073
- function migrateLegacyTokenScope(raw) {
44074
- if (raw === null || typeof raw !== "object" || Array.isArray(raw)) return raw;
44075
- if (Reflect.get(raw, "type") !== "device") return raw;
44076
- if (Reflect.get(raw, "selector") !== void 0) return raw;
44077
- const targets = Reflect.get(raw, "targets");
44078
- if (!Array.isArray(targets)) return raw;
44079
- return {
44080
- type: "device",
44081
- selector: {
44082
- kind: "ids",
44083
- ids: targets.map((t) => typeof t === "string" ? Number(t) : t).filter((n) => typeof n === "number" && Number.isInteger(n))
44084
- },
44085
- access: Reflect.get(raw, "access")
44086
- };
44087
- }
44088
- var TokenScopeSchema = preprocess(migrateLegacyTokenScope, discriminatedUnion("type", [
44089
- object({
44090
- type: literal("category"),
44091
- target: CapScopeSchema,
44092
- access: array(MethodAccessSchema).min(1)
44093
- }),
44094
- object({
44095
- type: literal("capability"),
44096
- target: string(),
44097
- access: array(MethodAccessSchema).min(1)
44098
- }),
44099
- object({
44100
- type: literal("addon"),
44101
- target: string(),
44102
- access: array(MethodAccessSchema).min(1)
44103
- }),
44104
- DeviceTokenScopeSchema
44105
- ]));
44106
- object({
44107
- id: string(),
44108
- username: string(),
44109
- passwordHash: string(),
44110
- /**
44111
- * Admin bypass. When true, the middleware skips the scope-access
44112
- * check entirely. There is no other axis of privilege; the legacy
44113
- * role enum collapsed onto this boolean in v2.
44114
- */
44115
- isAdmin: boolean().default(false),
44116
- allowedProviders: AllowedProviderSchema,
44117
- allowedDevices: AllowedDevicesSchema,
44118
- /**
44119
- * Scopes granted to this user. Admins bypass; their `scopes` is
44120
- * ignored. Non-admins without scopes are locked out of every
44121
- * protected call.
44122
- */
44123
- scopes: array(TokenScopeSchema).default([]),
44124
- createdAt: number(),
44125
- updatedAt: number()
44126
- });
44127
- object({
44128
- id: string(),
44129
- label: string(),
44130
- isAdmin: boolean().default(false),
44131
- allowedProviders: AllowedProviderSchema,
44132
- allowedDevices: AllowedDevicesSchema,
44133
- tokenHash: string(),
44134
- tokenPrefix: string(),
44135
- createdAt: number(),
44136
- lastUsedAt: number().optional()
44137
- });
44138
- object({
44139
- id: string(),
44140
- userId: string(),
44141
- name: string(),
44142
- tokenHash: string(),
44143
- tokenPrefix: string(),
44144
- scopes: array(TokenScopeSchema),
44145
- expiresAt: number().nullish(),
44146
- lastUsedAt: number().nullish(),
44147
- createdAt: number()
44148
- });
44149
- /**
44150
44298
  * `oauth-integration` — a collection cap by which an addon declares
44151
44299
  * itself a linkable OAuth client of the hub's core `/oauth2/*` server.
44152
44300
  * Each provider returns a static descriptor; the core enumerates them
@@ -61088,26 +61236,6 @@ var ApiKeySummarySchema = object({
61088
61236
  createdAt: number(),
61089
61237
  lastUsedAt: number().optional()
61090
61238
  });
61091
- var ScopedTokenSummarySchema = object({
61092
- id: string(),
61093
- userId: string(),
61094
- name: string(),
61095
- tokenPrefix: string(),
61096
- scopes: array(TokenScopeSchema),
61097
- expiresAt: number().nullish(),
61098
- lastUsedAt: number().nullish(),
61099
- createdAt: number()
61100
- });
61101
- var CreateScopedTokenInputSchema = object({
61102
- userId: string(),
61103
- name: string(),
61104
- scopes: array(TokenScopeSchema),
61105
- expiresAt: number().optional()
61106
- });
61107
- var CreateScopedTokenResultSchema = object({
61108
- token: string(),
61109
- record: ScopedTokenSummarySchema
61110
- });
61111
61239
  var OauthSessionSummarySchema = object({
61112
61240
  id: string(),
61113
61241
  userId: string(),
@@ -61129,11 +61257,11 @@ var TotpStatusSchema = object({
61129
61257
  confirmedAt: number().nullable()
61130
61258
  });
61131
61259
  /**
61132
- * user-management — singleton capability for user accounts, API keys,
61133
- * and scoped tokens.
61260
+ * user-management — singleton capability for user accounts and the
61261
+ * legacy API-key rows.
61134
61262
  *
61135
61263
  * v2 model: every method gated by `auth: 'admin'`. Admin-only delegation
61136
- * — the subset check on `setUserScopes` / `createScopedToken` is moot
61264
+ * — the subset check on `setUserScopes` is moot
61137
61265
  * because non-admins never reach these. If/when we open non-admin
61138
61266
  * delegation, structural caller-scope subset check goes inside the
61139
61267
  * provider.
@@ -61190,15 +61318,7 @@ method(_void(), array(UserSummarySchema), { auth: "admin" }), method(CreateUserI
61190
61318
  kind: "mutation",
61191
61319
  auth: "admin",
61192
61320
  access: "delete"
61193
- }), method(CreateScopedTokenInputSchema, CreateScopedTokenResultSchema, {
61194
- kind: "mutation",
61195
- auth: "admin",
61196
- access: "create"
61197
- }), method(object({ id: string() }), object({ success: literal(true) }), {
61198
- kind: "mutation",
61199
- auth: "admin",
61200
- access: "delete"
61201
- }), method(object({ token: string() }), ScopedTokenSummarySchema.nullable(), { access: "view" }), method(object({ userId: string() }), array(ScopedTokenSummarySchema), { auth: "admin" }), method(object({ userId: string() }), TotpSetupResultSchema, {
61321
+ }), method(object({ userId: string() }), TotpSetupResultSchema, {
61202
61322
  kind: "mutation",
61203
61323
  auth: "admin",
61204
61324
  access: "create"
@@ -65354,7 +65474,7 @@ Object.freeze({
65354
65474
  capName: "llm",
65355
65475
  capScope: "system",
65356
65476
  addonId: null,
65357
- access: "view"
65477
+ access: "create"
65358
65478
  },
65359
65479
  "llm.listNodeModels": {
65360
65480
  capName: "llm",
@@ -70018,12 +70138,6 @@ Object.freeze({
70018
70138
  addonId: null,
70019
70139
  access: "create"
70020
70140
  },
70021
- "userManagement.createScopedToken": {
70022
- capName: "user-management",
70023
- capScope: "system",
70024
- addonId: null,
70025
- access: "create"
70026
- },
70027
70141
  "userManagement.createUser": {
70028
70142
  capName: "user-management",
70029
70143
  capScope: "system",
@@ -70072,12 +70186,6 @@ Object.freeze({
70072
70186
  addonId: null,
70073
70187
  access: "view"
70074
70188
  },
70075
- "userManagement.listScopedTokens": {
70076
- capName: "user-management",
70077
- capScope: "system",
70078
- addonId: null,
70079
- access: "view"
70080
- },
70081
70189
  "userManagement.listUsers": {
70082
70190
  capName: "user-management",
70083
70191
  capScope: "system",
@@ -70132,12 +70240,6 @@ Object.freeze({
70132
70240
  addonId: null,
70133
70241
  access: "delete"
70134
70242
  },
70135
- "userManagement.revokeScopedToken": {
70136
- capName: "user-management",
70137
- capScope: "system",
70138
- addonId: null,
70139
- access: "delete"
70140
- },
70141
70243
  "userManagement.setupTotp": {
70142
70244
  capName: "user-management",
70143
70245
  capScope: "system",
@@ -70168,12 +70270,6 @@ Object.freeze({
70168
70270
  addonId: null,
70169
70271
  access: "view"
70170
70272
  },
70171
- "userManagement.validateScopedToken": {
70172
- capName: "user-management",
70173
- capScope: "system",
70174
- addonId: null,
70175
- access: "view"
70176
- },
70177
70273
  "userManagement.verifyTotp": {
70178
70274
  capName: "user-management",
70179
70275
  capScope: "system",