@camstack/addon-google-services 0.2.13 → 0.2.15

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.
@@ -5547,7 +5547,7 @@ var ZodIssueCode = {
5547
5547
  var ZodFirstPartyTypeKind;
5548
5548
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5549
5549
  //#endregion
5550
- //#region ../types/dist/sleep-BxjU_fJM.mjs
5550
+ //#region ../types/dist/sleep-BSuCCFjf.mjs
5551
5551
  /**
5552
5552
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5553
5553
  * window to float samples (D455).
@@ -7930,9 +7930,9 @@ function normalizeAddonInitResult(result) {
7930
7930
  return result;
7931
7931
  }
7932
7932
  /**
7933
- * The share-view scope kinds a `csv_*` share token can carry. The hub mints
7934
- * and validates them (`share-token.service.ts` builds its enum from this
7935
- * list); a data plane names the kinds it ACCEPTS in `share`.
7933
+ * The share-view scope kinds a share-link token can carry. The hub mints
7934
+ * and validates them (`ShareViewGrantSchema` builds its
7935
+ * enum from this list); a data plane names the kinds it ACCEPTS in `share`.
7936
7936
  */
7937
7937
  var SHARE_VIEW_KINDS = ["grid-view", "events-view"];
7938
7938
  /** The wire shape of {@link PeerBytesTicket} — see the type for what it is. */
@@ -12939,7 +12939,7 @@ var ConvertResultSchema = object({
12939
12939
  * `super_admin` — collapsed onto the single boolean because every
12940
12940
  * non-admin caller is governed by the same scope-check rules; the
12941
12941
  * distinction was only ever used to route role-specific procedures
12942
- * which we no longer have. CLI / webhook integrations are `cst_*` tokens
12942
+ * which we no longer have. CLI / webhook integrations are tokens (`auth.mintToken`)
12943
12943
  * with `isAdmin: false` + an explicit scope list.
12944
12944
  */
12945
12945
  /** Per-method access flavour. Materialised on every cap method via codegen. */
@@ -13128,10 +13128,12 @@ var AddonRoutesScopeSchema = object({
13128
13128
  type: literal("addon-routes"),
13129
13129
  access: array(MethodAccessSchema).min(1)
13130
13130
  });
13131
+ var PreferencesSelfScopeSchema = object({ type: literal("preferences-self") });
13131
13132
  var CredentialScopeSchema = union([
13132
13133
  literal("*"),
13133
13134
  ShareViewScopeSchema,
13134
13135
  AddonRoutesScopeSchema,
13136
+ PreferencesSelfScopeSchema,
13135
13137
  TokenScopeSchema
13136
13138
  ]);
13137
13139
  object({
@@ -13140,6 +13142,55 @@ object({
13140
13142
  jti: string().min(16),
13141
13143
  scopes: array(CredentialScopeSchema).min(1)
13142
13144
  });
13145
+ var PreferenceNamespaceSchema = string().regex(/^[a-z][a-z0-9.-]{0,63}$/);
13146
+ /** A namespace's value: a JSON object, opaque to the hub. */
13147
+ var PreferenceValueSchema = record(string(), unknown());
13148
+ var PreferenceDeviceIdSchema = string().min(1).max(64);
13149
+ /** A stored row, as the owner reads it. */
13150
+ var PreferenceRowSchema = object({
13151
+ namespace: PreferenceNamespaceSchema,
13152
+ value: PreferenceValueSchema,
13153
+ /** Starts at 1, +1 on every write of this namespace. A delete ends the row and its count. */
13154
+ revision: number().int().positive(),
13155
+ updatedAt: number().int(),
13156
+ /** The client id the last writer sent; `null` when it sent none. */
13157
+ updatedByDevice: PreferenceDeviceIdSchema.nullable()
13158
+ });
13159
+ object({
13160
+ /** Absent: every namespace the caller holds. */
13161
+ namespaces: array(PreferenceNamespaceSchema).max(32).optional() });
13162
+ object({ rows: array(PreferenceRowSchema) });
13163
+ object({
13164
+ namespace: PreferenceNamespaceSchema,
13165
+ value: PreferenceValueSchema,
13166
+ /**
13167
+ * The revision the edit was based on. Absent: last write wins. `0`: the
13168
+ * namespace must not exist yet. Any other value that is not the current
13169
+ * revision answers `conflict` and writes nothing.
13170
+ */
13171
+ baseRevision: number().int().nonnegative().optional(),
13172
+ deviceId: PreferenceDeviceIdSchema.optional()
13173
+ });
13174
+ discriminatedUnion("status", [object({
13175
+ status: literal("saved"),
13176
+ row: PreferenceRowSchema
13177
+ }), object({
13178
+ status: literal("conflict"),
13179
+ current: PreferenceRowSchema.nullable()
13180
+ })]);
13181
+ object({ namespace: PreferenceNamespaceSchema });
13182
+ object({
13183
+ /** `false` when the namespace did not exist. */
13184
+ deleted: boolean() });
13185
+ object({
13186
+ /** The revision the client holds per namespace; a namespace it does not list is new to it. */
13187
+ revisionByNamespace: record(PreferenceNamespaceSchema, number().int().nonnegative()).refine((map) => Object.keys(map).length <= 32, { message: `at most 32 namespaces` }) });
13188
+ object({
13189
+ /** Every row whose revision differs from the client's, and every row it did not list. */
13190
+ rows: array(PreferenceRowSchema),
13191
+ /** Namespaces the client listed that no longer exist. */
13192
+ deleted: array(PreferenceNamespaceSchema)
13193
+ });
13143
13194
  _enum(["new-session", "step-up"]);
13144
13195
  /** The languages the hub's app landing pages are written in (D858). */
13145
13196
  var AppPageLangSchema = _enum(["en", "it"]);
@@ -17355,7 +17406,19 @@ var DeviceHistorySubjectSchema = discriminatedUnion("kind", [object({
17355
17406
  kind: literal("node"),
17356
17407
  nodeId: string().min(1)
17357
17408
  })]);
17409
+ /**
17410
+ * `enum` stores a STATE as the ordinal of its value in the series' value list
17411
+ * (`DeviceHistorySeriesInfo.values`, append-only, so an ordinal never changes
17412
+ * meaning); a rollup keeps the time spent in each state (`states`).
17413
+ */
17358
17414
  var DeviceHistoryKindSchema = _enum([
17415
+ "gauge",
17416
+ "counter",
17417
+ "boolean",
17418
+ "enum"
17419
+ ]);
17420
+ /** What a PRODUCER may declare. `enum` is cap-only: its value list is the cap field's. */
17421
+ var DeviceHistoryProducerKindSchema = _enum([
17359
17422
  "gauge",
17360
17423
  "counter",
17361
17424
  "boolean"
@@ -17392,7 +17455,13 @@ var SeriesInfoSchema = object({
17392
17455
  /** `null` is unknown (a `unitFrom` series whose device does not state a unit right now), never a guess. */
17393
17456
  unit: string().nullable(),
17394
17457
  displayName: string(),
17395
- source: _enum(["cap", "addon"]),
17458
+ source: _enum([
17459
+ "cap",
17460
+ "addon",
17461
+ "derived"
17462
+ ]),
17463
+ /** `enum`: the value of each ordinal (index = ordinal); `null` for every other kind. */
17464
+ values: array(string()).readonly().nullable(),
17396
17465
  firstTs: number(),
17397
17466
  lastTs: number()
17398
17467
  });
@@ -17406,17 +17475,31 @@ var QueryPointSchema = object({
17406
17475
  twMean: number().nullable(),
17407
17476
  min: number(),
17408
17477
  max: number(),
17409
- /** `null` is unknown, never zero (D393). */
17410
- last: number().nullable()
17478
+ /** `null` is unknown, never zero (D393). For an `enum` series: the ordinal of {@link state}. */
17479
+ last: number().nullable(),
17480
+ /**
17481
+ * The increase over the point: a `counter`'s growth since the previous point
17482
+ * or bucket (a drop is a reset, counted from zero), and for
17483
+ * {@link DEVICE_HISTORY_ENERGY_KEY} the kWh used in the bucket. `null` for
17484
+ * every other kind, and when it cannot be known.
17485
+ */
17486
+ delta: number().nullable(),
17487
+ /** `enum`: the state in force at the end of the point (the name of `last`); `null` otherwise. */
17488
+ state: string().nullable(),
17489
+ /** `enum` rollup: milliseconds spent in each state inside the bucket; `null` for raw points and other kinds. */
17490
+ states: record(string(), number()).nullable()
17411
17491
  });
17412
17492
  var QuerySeriesSchema = object({
17413
17493
  scope: string(),
17414
17494
  /** The last point STRICTLY BEFORE `from` in the chosen tier, so a step chart can start at the held value. */
17415
17495
  before: object({
17416
17496
  t: number(),
17417
- value: number().nullable()
17497
+ value: number().nullable(),
17498
+ state: string().nullable()
17418
17499
  }).nullable(),
17419
- points: array(QueryPointSchema).readonly()
17500
+ points: array(QueryPointSchema).readonly(),
17501
+ /** A derived key: the stored key its points were computed from; `null` for a stored series. */
17502
+ derivedFrom: string().nullable()
17420
17503
  });
17421
17504
  /** The window part of a query, shared by the device and node forms. */
17422
17505
  var QueryWindowShape = {
@@ -17432,6 +17515,23 @@ var QueryResultSchema = object({
17432
17515
  series: array(QuerySeriesSchema).readonly(),
17433
17516
  truncated: boolean()
17434
17517
  });
17518
+ /** One read of a batch: a device's key or a node's key (exactly one subject). */
17519
+ var QueryManyItemSchema = union([object({
17520
+ deviceId: number().int(),
17521
+ key: string(),
17522
+ scope: string().optional()
17523
+ }), object({
17524
+ forNodeId: string().min(1),
17525
+ key: string(),
17526
+ scope: string().optional()
17527
+ })]);
17528
+ var QueryManyEntrySchema = discriminatedUnion("ok", [object({
17529
+ ok: literal(true),
17530
+ result: QueryResultSchema
17531
+ }), object({
17532
+ ok: literal(false),
17533
+ error: string()
17534
+ })]);
17435
17535
  var TierStatusSchema = object({
17436
17536
  tier: DeviceHistoryResolutionSchema,
17437
17537
  /** `null` until the first background count answered. */
@@ -17487,16 +17587,22 @@ var DeviceHistoryStatusSchema = object({
17487
17587
  lastRefreshAt: number().nullable()
17488
17588
  })
17489
17589
  });
17490
- method(object({ deviceId: number().int() }), array(SeriesInfoSchema).readonly()), method(object({ nodeId: string().min(1) }), array(SeriesInfoSchema).readonly(), { auth: "admin" }), method(object({
17590
+ method(object({ deviceId: number().int() }), array(SeriesInfoSchema).readonly()), method(object({ forNodeId: string().min(1) }), array(SeriesInfoSchema).readonly(), { auth: "admin" }), method(object({
17491
17591
  deviceId: number().int(),
17492
17592
  ...QueryWindowShape
17493
17593
  }), QueryResultSchema), method(object({
17494
- nodeId: string().min(1),
17594
+ forNodeId: string().min(1),
17495
17595
  ...QueryWindowShape
17496
17596
  }), QueryResultSchema, { auth: "admin" }), method(object({
17597
+ items: array(QueryManyItemSchema).min(1).max(24),
17598
+ from: QueryWindowShape.from,
17599
+ to: QueryWindowShape.to,
17600
+ resolution: QueryWindowShape.resolution,
17601
+ maxPoints: QueryWindowShape.maxPoints
17602
+ }), object({ results: array(QueryManyEntrySchema).readonly() }), { auth: "admin" }), method(object({
17497
17603
  name: string().regex(/^[a-z0-9-]+$/),
17498
17604
  subjectKind: _enum(["device", "node"]),
17499
- kind: DeviceHistoryKindSchema,
17605
+ kind: DeviceHistoryProducerKindSchema,
17500
17606
  unit: string().optional(),
17501
17607
  displayName: string().min(1),
17502
17608
  ingest: _enum(["points", "buckets"])
@@ -40086,38 +40192,37 @@ method(LlmRuntimeCompleteInputSchema, LlmGenerateResultSchema, {
40086
40192
  auth: "admin",
40087
40193
  timeoutMs: AI_CAP_TRANSPORT_TIMEOUT_MS
40088
40194
  });
40195
+ var LlmProfileKindSchema = string().regex(/^[a-z0-9][a-z0-9-]{0,63}$/, "a kind id is lower-case letters, digits and dashes");
40196
+ /** What a model (or, by default, every model of a kind) can do. */
40197
+ var LlmModelFeaturesSchema = object({
40198
+ vision: boolean(),
40199
+ tools: boolean(),
40200
+ streaming: boolean()
40201
+ });
40202
+ /** One model a provider offers. `features` overrides the kind's defaults, per field. */
40203
+ var LlmModelInfoSchema = object({
40204
+ id: string(),
40205
+ label: string().optional(),
40206
+ contextLength: number().int().positive().optional(),
40207
+ features: LlmModelFeaturesSchema.partial().optional()
40208
+ });
40089
40209
  /**
40090
- * `llm` — consumer-facing LLM surface (spec §1-§3). Collection-mode: array
40091
- * methods concat-fan across providers; single-row methods route to ONE
40092
- * provider by the `addonId` in the call input (the notification-output
40093
- * posture, notification-output.cap.ts:215-250). Provided by `addon-ai`
40094
- * (hub-placed); the cap stays open for future providers.
40095
- *
40096
- * Profiles are ROWS (data), not addons: one row = one usable model endpoint.
40097
- * `apiKey` is a password field — providers REDACT it on read and merge on
40098
- * write; a stored key NEVER round-trips to a client.
40210
+ * The provider-specific part of a profile, validated by the provider that owns
40211
+ * the kind (`upsertProfile` refuses what it does not accept). A field its
40212
+ * `connectionSchema` declares `type: 'password'` is a secret: it is held in the
40213
+ * keychain, never in the row, and reads back as the redaction marker.
40099
40214
  */
40100
- var LlmProfileKindSchema = _enum([
40101
- "openai-compatible",
40102
- "openai",
40103
- "anthropic",
40104
- "google",
40105
- "managed-local",
40106
- "apple-foundation"
40107
- ]);
40215
+ var LlmProviderConfigSchema = record(string(), unknown());
40108
40216
  var LlmProfileSchema = object({
40109
40217
  id: string(),
40110
40218
  name: string(),
40219
+ /** The provider-declared kind (`LlmProfileKindDescriptor.kind`). */
40111
40220
  kind: LlmProfileKindSchema,
40112
40221
  /** Stamped by the provider — keeps the fanned catalog routable. */
40113
40222
  addonId: string(),
40114
40223
  enabled: boolean(),
40115
40224
  /** Vendor model id, or the managed runtime's loaded model. */
40116
40225
  model: string(),
40117
- /** Required for openai-compatible; override for cloud kinds. */
40118
- baseUrl: string().optional(),
40119
- /** ConfigUISchema type:'password' — never round-trips (spec §5). */
40120
- apiKey: string().optional(),
40121
40226
  /** Vision on/off. A vision call against a `false` profile is REFUSED, never
40122
40227
  * degraded to text — that shipped once and produced a confident answer to a
40123
40228
  * question about a picture nobody sent. */
@@ -40125,15 +40230,11 @@ var LlmProfileSchema = object({
40125
40230
  temperature: number().min(0).max(2).optional(),
40126
40231
  /** Nucleus sampling. Every wire we speak has it. */
40127
40232
  topP: number().min(0).max(1).optional(),
40128
- /** Top-k sampling. Carried only by the wires that have it — NEITHER OpenAI
40129
- * wire does, and the client drops it there (measured: the request body gets
40130
- * `top_p` and no `top_k`). The profile editor hides the field wherever it
40131
- * would change nothing; `KINDS_WITH_TOP_K` is the single owner of that list. */
40233
+ /** Top-k sampling. Carried only by the wires that have it — a kind offers the
40234
+ * field in its editor only when its descriptor lists it in `profileFields`. */
40132
40235
  topK: number().int().positive().optional(),
40133
40236
  maxTokens: number().int().positive().optional(),
40134
- /** Prompt context window. Advisory for cloud kinds (they enforce their own);
40135
- * for `managed-local` it is the llama.cpp `--ctx-size` the runtime starts
40136
- * the model with, so it is the one field that changes a PROCESS. */
40237
+ /** Prompt context window. Advisory for cloud kinds (they enforce their own). */
40137
40238
  contextLength: number().int().positive().optional(),
40138
40239
  /** Default system prompt. A caller's `system` REPLACES it (never appends —
40139
40240
  * two system prompts fighting is worse than either alone). */
@@ -40159,16 +40260,37 @@ var LlmProfileSchema = object({
40159
40260
  * library; the REGISTRY of callable tools is ours and is empty in v1, so a
40160
40261
  * `true` here buys the wiring, not behaviour, until tools are registered. */
40161
40262
  toolsEnabled: boolean().default(false),
40162
- extraHeaders: record(string(), string()).optional(),
40163
- /** kind === 'managed-local' only (spec §4). */
40164
- runtime: ManagedRuntimeConfigSchema.optional(),
40165
- /**
40166
- * kind === 'apple-foundation' only: WHERE it runs — the only thing there is
40167
- * to configure (no key, no URL, no download; `model` is `apple-system`).
40168
- * `supportsVision` on such a row is stamped by the provider from the node's
40169
- * reported `imageInput`, never taken from the operator (D62).
40170
- */
40171
- appleFoundation: object({ nodeId: string() }).optional()
40263
+ /** Everything the kind's provider owns (endpoint, key, node, runtime…). */
40264
+ providerConfig: LlmProviderConfigSchema.default({})
40265
+ });
40266
+ /**
40267
+ * The common profile fields a kind's editor offers. The editor owns how each
40268
+ * one is drawn; the provider says which of them mean something on its wire.
40269
+ */
40270
+ var LlmProfileFieldSchema = _enum([
40271
+ "temperature",
40272
+ "topP",
40273
+ "topK",
40274
+ "maxTokens",
40275
+ "contextLength",
40276
+ "systemPrompt",
40277
+ "timeoutMs",
40278
+ "connectTimeoutMs",
40279
+ "firstTokenTimeoutMs",
40280
+ "idleTimeoutMs",
40281
+ "retry",
40282
+ "toolsEnabled"
40283
+ ]);
40284
+ /**
40285
+ * A provider-drawn part of the editor, by a generic widget id the admin UI
40286
+ * registers (`ai/apple-node`). `placement: 'model'` replaces the generic model
40287
+ * picker: that widget owns the model choice.
40288
+ */
40289
+ var LlmProviderWidgetSchema = object({
40290
+ id: string(),
40291
+ placement: _enum(["connection", "model"]),
40292
+ /** `providerConfig` keys this widget must fill before the profile can be saved. */
40293
+ requires: array(string()).optional()
40172
40294
  });
40173
40295
  /** ConfigUISchema tree passed through untyped on the wire (the
40174
40296
  * notification-output `ConfigSchemaPassthrough` precedent at
@@ -40177,11 +40299,56 @@ var ConfigSchemaPassthrough$3 = unknown();
40177
40299
  var LlmProfileKindDescriptorSchema = object({
40178
40300
  kind: LlmProfileKindSchema,
40179
40301
  label: string(),
40302
+ /** A generic icon name (`cloud`, `plug`, `cpu`) — never a glyph or a logo. */
40180
40303
  icon: string(),
40181
40304
  /** Stamped by each provider so the concat-fanned catalog stays routable. */
40182
40305
  addonId: string(),
40183
- configSchema: ConfigSchemaPassthrough$3
40306
+ /** The provider's own fields (`providerConfig`); `password` fields are keychain-held. */
40307
+ connectionSchema: ConfigSchemaPassthrough$3,
40308
+ /** Provider fields that belong under "Advanced" (extra headers, runtime tuning). */
40309
+ advancedSchema: ConfigSchemaPassthrough$3.optional(),
40310
+ /** The kind's defaults; a model from `listModels` may override any of them. */
40311
+ features: LlmModelFeaturesSchema,
40312
+ /** `false` = the provider stamps `supportsVision` itself (from what a node reports). */
40313
+ visionEditable: boolean(),
40314
+ /** Where the model list comes from: `listModels`, `staticModels`, or nowhere. */
40315
+ modelCatalog: _enum([
40316
+ "fetch",
40317
+ "static",
40318
+ "none"
40319
+ ]),
40320
+ staticModels: array(LlmModelInfoSchema).optional(),
40321
+ /** The common fields that mean something on this kind's wire. */
40322
+ profileFields: array(LlmProfileFieldSchema),
40323
+ providerWidgets: array(LlmProviderWidgetSchema).optional()
40324
+ });
40325
+ /**
40326
+ * `listModels` input. `connection` is an UNSAVED draft of `providerConfig`
40327
+ * (the editor's form); with `profileId` too, a secret the draft leaves
40328
+ * untouched (absent or the redaction marker) is resolved server-side from the
40329
+ * stored profile — the browser never receives it.
40330
+ */
40331
+ var LlmListModelsInputSchema = object({
40332
+ addonId: string(),
40333
+ kind: LlmProfileKindSchema,
40334
+ profileId: string().optional(),
40335
+ connection: LlmProviderConfigSchema.optional()
40184
40336
  });
40337
+ var LlmListModelsErrorCodeSchema = _enum([
40338
+ "auth",
40339
+ "network",
40340
+ "unsupported",
40341
+ "invalid"
40342
+ ]);
40343
+ /** A RESULT, never a throw: "wrong key" is an answer the editor renders inline. */
40344
+ var LlmListModelsResultSchema = discriminatedUnion("ok", [object({
40345
+ ok: literal(true),
40346
+ models: array(LlmModelInfoSchema)
40347
+ }), object({
40348
+ ok: literal(false),
40349
+ code: LlmListModelsErrorCodeSchema,
40350
+ message: string()
40351
+ })]);
40185
40352
  var LlmDefaultSelectorSchema = union([object({ consumer: string() }), object({ purpose: _enum(["text", "vision"]) })]);
40186
40353
  var LlmDefaultSchema = object({
40187
40354
  selector: LlmDefaultSelectorSchema,
@@ -40281,7 +40448,10 @@ method(LlmGenerateBaseInputSchema, LlmGenerateResultSchema, {
40281
40448
  kind: "mutation",
40282
40449
  auth: "admin",
40283
40450
  timeoutMs: AI_CAP_TRANSPORT_TIMEOUT_MS
40284
- }), method(ProfileRefInputSchema, array(string())), method(object({}), array(LlmDefaultSchema)), method(object({
40451
+ }), method(LlmListModelsInputSchema, LlmListModelsResultSchema, {
40452
+ kind: "mutation",
40453
+ auth: "admin"
40454
+ }), method(object({}), array(LlmDefaultSchema)), method(object({
40285
40455
  selector: LlmDefaultSelectorSchema,
40286
40456
  profileId: string().nullable()
40287
40457
  }), _void(), {
@@ -40449,14 +40619,106 @@ var LogEntrySchema = object({
40449
40619
  meta: record(string(), unknown()).optional(),
40450
40620
  tags: record(string(), string()).optional()
40451
40621
  });
40452
- method(LogEntrySchema, _void(), { kind: "mutation" }), method(object({
40453
- scope: array(string()).optional(),
40622
+ /**
40623
+ * A history READ against one destination (D898).
40624
+ *
40625
+ * Every filter is applied by the PROVIDER, before the limit — a filter the
40626
+ * browser applied after the limit is what made a rare device's lines
40627
+ * unreachable behind a busy one's. `before` / `after` are cursors the provider
40628
+ * minted (opaque to everyone else): a file position for the rotated files, a
40629
+ * nanosecond timestamp for Loki.
40630
+ *
40631
+ * A read is BOUNDED by `budgetMs`: a filter that matches nothing on a 30-day
40632
+ * store answers `done: false` with the cursor it reached and the bytes it
40633
+ * scanned, and the caller decides whether to go on. That is what makes a long
40634
+ * scan show progress and stop when asked — `cancelRead` ends the slice in
40635
+ * flight, and not asking for the next slice ends the scan.
40636
+ */
40637
+ var LogReadQuerySchema = object({
40638
+ /** Correlates `cancelRead`. Caller-chosen, unique per in-flight read. */
40639
+ requestId: string().min(1).max(64).optional(),
40640
+ /** The device the line is about (`tags.deviceId`, numeric). */
40641
+ deviceId: number().int().optional(),
40642
+ /**
40643
+ * The emitting addon — bare manifest id; `@<version>` / `::<sub>` suffixes
40644
+ * match. Not `addonId`: a cap router reads that name as "which provider".
40645
+ */
40646
+ fromAddonId: string().min(1).max(200).optional(),
40647
+ /**
40648
+ * The emitting node: matches the agent that emitted the line, the node
40649
+ * itself, or a worker under it (`<agent>/<runner>`) — the `agentId`
40650
+ * semantics of `matchesLogTags`. Not `nodeId`: a cap router reads that
40651
+ * name as "which node's provider".
40652
+ */
40653
+ fromNodeId: string().min(1).max(200).optional(),
40654
+ /** Any other tag, exact match (AND). */
40655
+ tags: record(string(), union([string(), number()])).optional(),
40656
+ /** Severity FLOOR: this level and above. */
40454
40657
  level: LogLevelSchema.optional(),
40455
- since: date().optional(),
40456
- until: date().optional(),
40457
- limit: number().optional(),
40458
- tags: record(string(), string()).optional()
40459
- }), array(LogEntrySchema).readonly());
40658
+ /** Case-insensitive substring over message, scope, tag values and meta values. */
40659
+ text: string().min(1).max(200).optional(),
40660
+ /** Epoch ms, inclusive. */
40661
+ since: number().optional(),
40662
+ /** Epoch ms, inclusive. */
40663
+ until: number().optional(),
40664
+ /** Older than this cursor (exclusive). Absent with `after` absent ⇒ from the newest. */
40665
+ before: string().min(1).max(1024).optional(),
40666
+ /** Newer than this cursor (exclusive). */
40667
+ after: string().min(1).max(1024).optional(),
40668
+ limit: number().int().min(1).max(1e3).optional(),
40669
+ /** Wall-clock bound of this slice. The provider caps it. */
40670
+ budgetMs: number().int().min(50).max(1e4).optional()
40671
+ });
40672
+ var LogReadResultSchema = object({
40673
+ /** Newest first. */
40674
+ entries: array(object({
40675
+ /** `<bootId>.<seq>` minted by the emitting LogManager — the dedupe key. */
40676
+ id: string().optional(),
40677
+ /** Epoch ms. */
40678
+ timestamp: number(),
40679
+ level: LogLevelSchema,
40680
+ scope: string().optional(),
40681
+ message: string(),
40682
+ tags: record(string(), union([string(), number()])).optional(),
40683
+ meta: record(string(), unknown()).optional()
40684
+ })),
40685
+ /** Pass as `before` for the next older page; null when nothing older exists. */
40686
+ nextBefore: string().nullable(),
40687
+ /** Pass as `after` to read what arrived since; null when unknown. */
40688
+ nextAfter: string().nullable(),
40689
+ /** Bytes this slice read (files) or received (remote). Progress, not a promise. */
40690
+ scannedBytes: number().int().nonnegative(),
40691
+ /**
40692
+ * True when the scan in this direction reached the end of the store.
40693
+ * False with fewer than `limit` entries means the budget ran out first —
40694
+ * call again with `nextBefore` to go on.
40695
+ */
40696
+ done: boolean(),
40697
+ /** True when `cancelRead` ended this slice early. */
40698
+ cancelled: boolean().optional()
40699
+ });
40700
+ var LogReadCapabilitiesSchema = object({
40701
+ /** False ⇒ this destination only ships lines (console, forwarder, an unconfigured Loki). */
40702
+ readable: boolean(),
40703
+ /** Why not, when `readable` is false — rendered next to the source. */
40704
+ reason: string().nullable(),
40705
+ /** Filters the provider applies itself. A false one is applied by nobody. */
40706
+ filters: object({
40707
+ deviceId: boolean(),
40708
+ addonId: boolean(),
40709
+ nodeId: boolean(),
40710
+ tags: boolean(),
40711
+ level: boolean(),
40712
+ text: boolean(),
40713
+ timeRange: boolean()
40714
+ }),
40715
+ /** How far back the store reaches, when the provider knows (days). */
40716
+ retentionDays: number().nullable()
40717
+ });
40718
+ method(LogEntrySchema, _void(), { kind: "mutation" }), optionalMethod(_void(), LogReadCapabilitiesSchema, { auth: "admin" }), optionalMethod(LogReadQuerySchema, LogReadResultSchema, { auth: "admin" }), optionalMethod(object({ requestId: string().min(1).max(64) }), object({ cancelled: boolean() }), {
40719
+ kind: "mutation",
40720
+ auth: "admin"
40721
+ });
40460
40722
  /**
40461
40723
  * `login-method` — collection cap through which auth addons contribute
40462
40724
  * their pre-auth login surfaces to the login page. This is the SINGLE,
@@ -43012,6 +43274,33 @@ var NcRuleTargetSchema = object({
43012
43274
  params: record(string(), unknown()).optional()
43013
43275
  });
43014
43276
  /**
43277
+ * WHAT THE NOTIFICATION'S PICTURE IS (D897) — the ONE media choice of a rule.
43278
+ *
43279
+ * Every mode starts from the same CLEAN source frame of the trigger moment
43280
+ * (keyFrame → sceneFrame → lastSceneFrame, narrowed to the trigger instant and
43281
+ * to the zone that fired the rule) and renders it once at send time:
43282
+ * - `scene-boxes` — the whole scene, the subject outlined thick in the accent
43283
+ * colour and every OTHER track visible at that instant outlined thin, each
43284
+ * labelled with class and confidence ("dog 87%").
43285
+ * - `crop` — the subject cut out of that frame around its box at that instant.
43286
+ * - `clean` — the whole scene with nothing drawn on it.
43287
+ * - `none` — no picture.
43288
+ *
43289
+ * A mode that cannot be honoured (no box at that instant, a photograph with no
43290
+ * tracked subject) ships `clean` and names the reason in the log, per camera.
43291
+ * It replaces the `attach` × `frame` × `zoneCrop` triple, which let one rule
43292
+ * ship a crop on one event and a boxed scene on the next depending on which
43293
+ * stored kind had landed.
43294
+ */
43295
+ var NcMediaImageSchema = _enum([
43296
+ "scene-boxes",
43297
+ "crop",
43298
+ "clean",
43299
+ "none"
43300
+ ]);
43301
+ /**
43302
+ * @deprecated Read only by `normalizeNcMediaPolicy` (D897) — see {@link NcMediaImageSchema}.
43303
+ *
43015
43304
  * Media attachment policy (P1 still-image subset).
43016
43305
  * - `best` — the best AVAILABLE subject image at dispatch time (D-3).
43017
43306
  * - `best-matching` — the media that explains WHY the rule fired: a rule
@@ -43025,6 +43314,8 @@ var NcRuleTargetSchema = object({
43025
43314
  * - `none` — no attachment.
43026
43315
  */
43027
43316
  /**
43317
+ * @deprecated Read only by `normalizeNcMediaPolicy` (D897) — see {@link NcMediaImageSchema}.
43318
+ *
43028
43319
  * WHAT THE PICTURE SHOWS — chosen explicitly, because the implicit ladders
43029
43320
  * conflate it with the selection strategy and betray the request: asking for
43030
43321
  * the clean scene frame on an object-event owner used to start at
@@ -43053,16 +43344,29 @@ var NcMediaFrameSchema = _enum([
43053
43344
  */
43054
43345
  var NcLinkedCameraModeSchema = _enum(["mosaic", "each"]);
43055
43346
  var NcMediaPolicySchema = object({
43347
+ /**
43348
+ * The picture — see {@link NcMediaImageSchema}. Absent on a rule nobody has
43349
+ * saved since D897: `normalizeNcMediaPolicy` derives it from the legacy
43350
+ * triple below, at load and at every write, and the store keeps only this.
43351
+ */
43352
+ image: NcMediaImageSchema.optional(),
43353
+ /**
43354
+ * Draw the zone that FIRED the rule on the picture (`scene-boxes` / `clean`;
43355
+ * a `crop` never shows it). Valid only on a rule whose trigger is a zone —
43356
+ * `conditions.zones` or an occupancy zone — and refused on save otherwise.
43357
+ * Replaces `zoneCrop`.
43358
+ */
43359
+ showTriggerZone: boolean().optional(),
43360
+ /** @deprecated D897 — accepted from an editor that predates `image`, folded into it on save. */
43056
43361
  attach: _enum([
43057
43362
  "best",
43058
43363
  "best-matching",
43059
43364
  "keyFrame",
43060
43365
  "none"
43061
- ]).default("best"),
43062
- /** What the still shows. Absent = `cropped` (the historical `best` shape). */
43366
+ ]).optional(),
43367
+ /** @deprecated D897 — accepted from an editor that predates `image`, folded into it on save. */
43063
43368
  frame: NcMediaFrameSchema.optional(),
43064
- /** Crop the attached still to the rule's condition-zone bbox (padded) —
43065
- * "show me the ZONE", not the whole scene or the subject crop. */
43369
+ /** @deprecated D897 — folded into `image: 'clean'` + `showTriggerZone` on save. */
43066
43370
  zoneCrop: boolean().optional(),
43067
43371
  /**
43068
43372
  * Also attach a short GIF cut from the stream broker's clip ring around the
@@ -43234,7 +43538,9 @@ var NcRuleInputSchema = object({
43234
43538
  * targets.
43235
43539
  */
43236
43540
  targetUsers: array(string()).optional(),
43237
- media: NcMediaPolicySchema.default({ attach: "best" }),
43541
+ /** Absent = the kind's default picture (`resolveNcMediaImage`): the subject crop for a
43542
+ * detection, the clean scene for a sensor or a sound. Set explicitly on save (D897). */
43543
+ media: NcMediaPolicySchema.default({}),
43238
43544
  throttle: NcThrottleSchema.default({
43239
43545
  cooldownSec: 60,
43240
43546
  scope: "rule-device"
@@ -44171,13 +44477,37 @@ var NcAlarmModeOpeningsSchema = object({
44171
44477
  /** Covered devices whose state could not be read (D49): neither open nor closed. */
44172
44478
  unknown: array(number().int())
44173
44479
  });
44480
+ /**
44481
+ * One alarm INPUT — a (rule, device) pair — the operator bypassed until the
44482
+ * next disarm ("Bypass this input until disarm" on a trigger notification, or
44483
+ * `nc.bypassAlarmInput`). Reported so an armed alarm with a silenced input
44484
+ * never looks fully armed (D62: off must never look like broken).
44485
+ */
44486
+ var NcAlarmInputBypassViewSchema = object({
44487
+ ruleId: string(),
44488
+ /** The rule's current name (its frozen name when the rule is gone). */
44489
+ ruleName: string(),
44490
+ /** The input: the sensor of the match, else its camera. */
44491
+ deviceId: number().int(),
44492
+ /** The input's current name. */
44493
+ name: string(),
44494
+ /** When it was bypassed (ms epoch). */
44495
+ since: number(),
44496
+ /** Triggers from this input dropped since. */
44497
+ dropped: number().int().min(0)
44498
+ });
44174
44499
  var NcAlarmLiveSchema = object({
44175
44500
  state: AlarmStateSchema,
44176
44501
  /** The mode being armed into (exit delay) or held; null when disarmed. */
44177
44502
  targetMode: AlarmArmModeSchema.nullable(),
44178
44503
  availableModes: array(AlarmArmModeSchema),
44179
44504
  openings: array(NcAlarmModeOpeningsSchema),
44180
- exclusions: array(NcAlarmExclusionViewSchema)
44505
+ exclusions: array(NcAlarmExclusionViewSchema),
44506
+ /**
44507
+ * Inputs bypassed for the rest of this arm session; cleared on disarm.
44508
+ * Defaulted so an older hub answer still parses (as "none known").
44509
+ */
44510
+ bypassedInputs: array(NcAlarmInputBypassViewSchema).default([])
44181
44511
  });
44182
44512
  var NcAlarmConfigSchema = object({
44183
44513
  /**
@@ -61299,26 +61629,6 @@ var ApiKeySummarySchema = object({
61299
61629
  createdAt: number(),
61300
61630
  lastUsedAt: number().optional()
61301
61631
  });
61302
- var ScopedTokenSummarySchema = object({
61303
- id: string(),
61304
- userId: string(),
61305
- name: string(),
61306
- tokenPrefix: string(),
61307
- scopes: array(TokenScopeSchema),
61308
- expiresAt: number().nullish(),
61309
- lastUsedAt: number().nullish(),
61310
- createdAt: number()
61311
- });
61312
- var CreateScopedTokenInputSchema = object({
61313
- userId: string(),
61314
- name: string(),
61315
- scopes: array(TokenScopeSchema),
61316
- expiresAt: number().optional()
61317
- });
61318
- var CreateScopedTokenResultSchema = object({
61319
- token: string(),
61320
- record: ScopedTokenSummarySchema
61321
- });
61322
61632
  var OauthSessionSummarySchema = object({
61323
61633
  id: string(),
61324
61634
  userId: string(),
@@ -61340,11 +61650,11 @@ var TotpStatusSchema = object({
61340
61650
  confirmedAt: number().nullable()
61341
61651
  });
61342
61652
  /**
61343
- * user-management — singleton capability for user accounts, API keys,
61344
- * and scoped tokens.
61653
+ * user-management — singleton capability for user accounts and the
61654
+ * legacy API-key rows.
61345
61655
  *
61346
61656
  * v2 model: every method gated by `auth: 'admin'`. Admin-only delegation
61347
- * — the subset check on `setUserScopes` / `createScopedToken` is moot
61657
+ * — the subset check on `setUserScopes` is moot
61348
61658
  * because non-admins never reach these. If/when we open non-admin
61349
61659
  * delegation, structural caller-scope subset check goes inside the
61350
61660
  * provider.
@@ -61401,15 +61711,7 @@ method(_void(), array(UserSummarySchema), { auth: "admin" }), method(CreateUserI
61401
61711
  kind: "mutation",
61402
61712
  auth: "admin",
61403
61713
  access: "delete"
61404
- }), method(CreateScopedTokenInputSchema, CreateScopedTokenResultSchema, {
61405
- kind: "mutation",
61406
- auth: "admin",
61407
- access: "create"
61408
- }), method(object({ id: string() }), object({ success: literal(true) }), {
61409
- kind: "mutation",
61410
- auth: "admin",
61411
- access: "delete"
61412
- }), method(object({ token: string() }), ScopedTokenSummarySchema.nullable(), { access: "view" }), method(object({ userId: string() }), array(ScopedTokenSummarySchema), { auth: "admin" }), method(object({ userId: string() }), TotpSetupResultSchema, {
61714
+ }), method(object({ userId: string() }), TotpSetupResultSchema, {
61413
61715
  kind: "mutation",
61414
61716
  auth: "admin",
61415
61717
  access: "create"
@@ -65565,7 +65867,7 @@ Object.freeze({
65565
65867
  capName: "llm",
65566
65868
  capScope: "system",
65567
65869
  addonId: null,
65568
- access: "view"
65870
+ access: "create"
65569
65871
  },
65570
65872
  "llm.listNodeModels": {
65571
65873
  capName: "llm",
@@ -65867,7 +66169,19 @@ Object.freeze({
65867
66169
  addonId: null,
65868
66170
  access: "view"
65869
66171
  },
65870
- "logDestination.query": {
66172
+ "logDestination.cancelRead": {
66173
+ capName: "log-destination",
66174
+ capScope: "system",
66175
+ addonId: null,
66176
+ access: "create"
66177
+ },
66178
+ "logDestination.describeRead": {
66179
+ capName: "log-destination",
66180
+ capScope: "system",
66181
+ addonId: null,
66182
+ access: "view"
66183
+ },
66184
+ "logDestination.read": {
65871
66185
  capName: "log-destination",
65872
66186
  capScope: "system",
65873
66187
  addonId: null,
@@ -70229,12 +70543,6 @@ Object.freeze({
70229
70543
  addonId: null,
70230
70544
  access: "create"
70231
70545
  },
70232
- "userManagement.createScopedToken": {
70233
- capName: "user-management",
70234
- capScope: "system",
70235
- addonId: null,
70236
- access: "create"
70237
- },
70238
70546
  "userManagement.createUser": {
70239
70547
  capName: "user-management",
70240
70548
  capScope: "system",
@@ -70283,12 +70591,6 @@ Object.freeze({
70283
70591
  addonId: null,
70284
70592
  access: "view"
70285
70593
  },
70286
- "userManagement.listScopedTokens": {
70287
- capName: "user-management",
70288
- capScope: "system",
70289
- addonId: null,
70290
- access: "view"
70291
- },
70292
70594
  "userManagement.listUsers": {
70293
70595
  capName: "user-management",
70294
70596
  capScope: "system",
@@ -70343,12 +70645,6 @@ Object.freeze({
70343
70645
  addonId: null,
70344
70646
  access: "delete"
70345
70647
  },
70346
- "userManagement.revokeScopedToken": {
70347
- capName: "user-management",
70348
- capScope: "system",
70349
- addonId: null,
70350
- access: "delete"
70351
- },
70352
70648
  "userManagement.setupTotp": {
70353
70649
  capName: "user-management",
70354
70650
  capScope: "system",
@@ -70379,12 +70675,6 @@ Object.freeze({
70379
70675
  addonId: null,
70380
70676
  access: "view"
70381
70677
  },
70382
- "userManagement.validateScopedToken": {
70383
- capName: "user-management",
70384
- capScope: "system",
70385
- addonId: null,
70386
- access: "view"
70387
- },
70388
70678
  "userManagement.verifyTotp": {
70389
70679
  capName: "user-management",
70390
70680
  capScope: "system",
@@ -71898,6 +72188,11 @@ Object.freeze({
71898
72188
  form: "single",
71899
72189
  optional: false
71900
72190
  }],
72191
+ "logDestination.read": [{
72192
+ name: "deviceId",
72193
+ form: "single",
72194
+ optional: true
72195
+ }],
71901
72196
  "mediaPlayer.getStatus": [{
71902
72197
  name: "deviceId",
71903
72198
  form: "single",