@camstack/core 0.1.33 → 0.1.35

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 (42) hide show
  1. package/dist/auth/api-key-manager.d.ts +2 -2
  2. package/dist/auth/api-key-manager.d.ts.map +1 -1
  3. package/dist/auth/auth-manager.d.ts +70 -3
  4. package/dist/auth/auth-manager.d.ts.map +1 -1
  5. package/dist/auth/totp-manager.d.ts +53 -0
  6. package/dist/auth/totp-manager.d.ts.map +1 -0
  7. package/dist/auth/user-manager.d.ts +3 -3
  8. package/dist/auth/user-manager.d.ts.map +1 -1
  9. package/dist/builtins/auth-orchestrator/auth-orchestrator.addon.d.ts.map +1 -1
  10. package/dist/builtins/auth-orchestrator/auth-orchestrator.addon.js +29 -9
  11. package/dist/builtins/auth-orchestrator/auth-orchestrator.addon.js.map +1 -1
  12. package/dist/builtins/auth-orchestrator/auth-orchestrator.addon.mjs +29 -9
  13. package/dist/builtins/auth-orchestrator/auth-orchestrator.addon.mjs.map +1 -1
  14. package/dist/builtins/local-auth/auth-schema.d.ts +14 -0
  15. package/dist/builtins/local-auth/auth-schema.d.ts.map +1 -1
  16. package/dist/builtins/local-auth/local-auth.addon.d.ts +1 -0
  17. package/dist/builtins/local-auth/local-auth.addon.d.ts.map +1 -1
  18. package/dist/builtins/local-auth/local-auth.addon.js +1014 -22
  19. package/dist/builtins/local-auth/local-auth.addon.js.map +1 -1
  20. package/dist/builtins/local-auth/local-auth.addon.mjs +1025 -33
  21. package/dist/builtins/local-auth/local-auth.addon.mjs.map +1 -1
  22. package/dist/builtins/platform-probe/hardware-encoder-probe.d.ts +14 -0
  23. package/dist/builtins/platform-probe/hardware-encoder-probe.d.ts.map +1 -0
  24. package/dist/builtins/platform-probe/index.d.ts +2 -0
  25. package/dist/builtins/platform-probe/index.d.ts.map +1 -1
  26. package/dist/builtins/platform-probe/index.js +198 -5
  27. package/dist/builtins/platform-probe/index.js.map +1 -1
  28. package/dist/builtins/platform-probe/index.mjs +198 -6
  29. package/dist/builtins/platform-probe/index.mjs.map +1 -1
  30. package/dist/builtins/sqlite-storage/sqlite-settings-backend.d.ts +8 -0
  31. package/dist/builtins/sqlite-storage/sqlite-settings-backend.d.ts.map +1 -1
  32. package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +27 -21
  33. package/dist/builtins/sqlite-storage/sqlite-settings.addon.js.map +1 -1
  34. package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +27 -21
  35. package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs.map +1 -1
  36. package/dist/index.d.ts +1 -1
  37. package/dist/index.d.ts.map +1 -1
  38. package/dist/index.js +558 -94
  39. package/dist/index.js.map +1 -1
  40. package/dist/index.mjs +558 -94
  41. package/dist/index.mjs.map +1 -1
  42. package/package.json +2 -1
package/dist/index.js CHANGED
@@ -37,7 +37,7 @@ let node_vm = require("node:vm");
37
37
  node_vm = require_chunk.__toESM(node_vm);
38
38
  let node_os = require("node:os");
39
39
  node_os = require_chunk.__toESM(node_os);
40
- //#region ../types/dist/index-DVKPWMwv.mjs
40
+ //#region ../types/dist/index-BBVUwOlZ.mjs
41
41
  var MODEL_FORMATS = [
42
42
  "onnx",
43
43
  "coreml",
@@ -898,7 +898,7 @@ var DecodedFrameSchema = zod.z.object({
898
898
  ]),
899
899
  timestamp: zod.z.number()
900
900
  });
901
- var BrokerStatusSchema = zod.z.enum([
901
+ var BrokerStatusSchema$1 = zod.z.enum([
902
902
  "idle",
903
903
  "connecting",
904
904
  "streaming",
@@ -906,7 +906,7 @@ var BrokerStatusSchema = zod.z.enum([
906
906
  "stopped"
907
907
  ]);
908
908
  var BrokerStatsSchema = zod.z.object({
909
- status: BrokerStatusSchema,
909
+ status: BrokerStatusSchema$1,
910
910
  inputFps: zod.z.number(),
911
911
  decodeFps: zod.z.number(),
912
912
  encodedSubscribers: zod.z.number(),
@@ -1006,6 +1006,37 @@ zod.z.enum([
1006
1006
  "disabled",
1007
1007
  "waking"
1008
1008
  ]);
1009
+ var VideoCodecTargetSchema = zod.z.enum([
1010
+ "H264",
1011
+ "H265",
1012
+ "auto"
1013
+ ]);
1014
+ var AudioCodecTargetSchema = zod.z.enum([
1015
+ "AAC",
1016
+ "Opus",
1017
+ "PCMU",
1018
+ "none"
1019
+ ]);
1020
+ var MaxResolutionSchema = zod.z.object({
1021
+ width: zod.z.number().int().positive(),
1022
+ height: zod.z.number().int().positive()
1023
+ });
1024
+ var GetStreamWithCodecInputSchema = zod.z.object({
1025
+ deviceId: zod.z.number().int().nonnegative(),
1026
+ videoCodec: VideoCodecTargetSchema,
1027
+ audioCodec: AudioCodecTargetSchema.optional(),
1028
+ maxResolution: MaxResolutionSchema.optional(),
1029
+ tag: zod.z.string().optional()
1030
+ });
1031
+ var RtpSourceSchema = zod.z.object({
1032
+ url: zod.z.string(),
1033
+ videoCodec: zod.z.enum(["H264", "H265"]),
1034
+ audioCodec: zod.z.string(),
1035
+ resolution: MaxResolutionSchema,
1036
+ transcoded: zod.z.boolean(),
1037
+ encoder: zod.z.string(),
1038
+ pipelineKey: zod.z.string()
1039
+ });
1009
1040
  method(zod.z.object({
1010
1041
  deviceId: zod.z.number().int().nonnegative(),
1011
1042
  camStreamId: zod.z.string().min(1),
@@ -1015,28 +1046,8 @@ method(zod.z.object({
1015
1046
  resolution: CamStreamResolutionSchema.optional(),
1016
1047
  fps: zod.z.number().positive().optional(),
1017
1048
  label: zod.z.string().optional(),
1018
- /**
1019
- * Device-level features that the broker / manager / snapshot
1020
- * orchestrator consult to derive per-stream policy (e.g.
1021
- * `BatteryOperated` → relax stall watchdog, default pre-buffer
1022
- * to off, raise snapshot rate-limit). Single source of truth —
1023
- * publishers no longer set per-stream flags like `allowStall`.
1024
- */
1025
1049
  deviceFeatures: zod.z.array(zod.z.string()).optional(),
1026
- /**
1027
- * Whether this stream participates in the broker's automatic
1028
- * profile assignment. Defaults `true`. Publishers set `false` for
1029
- * streams that should be SELECTABLE but not auto-picked — e.g.
1030
- * Reolink publishes native Baichuan as eligible and RTSP/RTMP
1031
- * mirrors as ineligible (still assignable manually via
1032
- * `assignProfile`).
1033
- */
1034
1050
  autoEligible: zod.z.boolean().optional(),
1035
- /**
1036
- * Transport-specific opaque metadata stashed alongside the stream
1037
- * record. `pull-rfc4571` publishers put the SDP here so the broker
1038
- * reader can route packets without an in-band DESCRIBE phase.
1039
- */
1040
1051
  metadata: zod.z.record(zod.z.string(), zod.z.unknown()).optional()
1041
1052
  }), zod.z.object({ success: zod.z.literal(true) }), {
1042
1053
  kind: "mutation",
@@ -1080,7 +1091,16 @@ method(zod.z.object({
1080
1091
  }), method(zod.z.object({
1081
1092
  streamId: zod.z.string(),
1082
1093
  format: StreamFormatSchema
1083
- }), zod.z.object({ url: zod.z.string() })), method(zod.z.object({ brokerId: zod.z.string() }), zod.z.custom()), method(zod.z.object({
1094
+ }), zod.z.object({ url: zod.z.string() })), method(GetStreamWithCodecInputSchema, RtpSourceSchema, {
1095
+ kind: "mutation",
1096
+ auth: "admin"
1097
+ }), method(zod.z.object({ pipelineKey: zod.z.string() }), zod.z.object({
1098
+ released: zod.z.boolean(),
1099
+ refcount: zod.z.number().int().nonnegative()
1100
+ }), {
1101
+ kind: "mutation",
1102
+ auth: "admin"
1103
+ }), method(zod.z.object({ brokerId: zod.z.string() }), zod.z.custom()), method(zod.z.object({
1084
1104
  brokerId: zod.z.string(),
1085
1105
  seconds: zod.z.number().min(0).max(30)
1086
1106
  }), zod.z.void(), {
@@ -2378,7 +2398,8 @@ var CollectionColumnSchema = zod.z.object({
2378
2398
  "TEXT",
2379
2399
  "INTEGER",
2380
2400
  "REAL",
2381
- "JSON"
2401
+ "JSON",
2402
+ "BOOLEAN"
2382
2403
  ]),
2383
2404
  primaryKey: zod.z.boolean().optional(),
2384
2405
  notNull: zod.z.boolean().optional(),
@@ -2450,7 +2471,206 @@ method(LogEntrySchema, zod.z.void(), { kind: "mutation" }), method(zod.z.object(
2450
2471
  limit: zod.z.number().optional(),
2451
2472
  tags: zod.z.record(zod.z.string(), zod.z.string()).optional()
2452
2473
  }), zod.z.array(LogEntrySchema).readonly());
2453
- method(zod.z.void(), zod.z.string()), method(zod.z.void(), zod.z.string());
2474
+ var StaticDirOutputSchema = zod.z.object({ staticDir: zod.z.string() });
2475
+ var VersionOutputSchema = zod.z.object({ version: zod.z.string() });
2476
+ method(zod.z.void(), StaticDirOutputSchema), method(zod.z.void(), VersionOutputSchema);
2477
+ var SsoBridgeClaimsSchema = zod.z.object({
2478
+ userId: zod.z.string(),
2479
+ username: zod.z.string(),
2480
+ isAdmin: zod.z.boolean(),
2481
+ provider: zod.z.string(),
2482
+ email: zod.z.string().optional(),
2483
+ displayName: zod.z.string().optional(),
2484
+ /**
2485
+ * Public HTTPS URL of the hub that issued this token. Used by
2486
+ * cloud-mode OAuth proxies (Alexa Smart Home Lambda, future Google
2487
+ * Home Lambda) to route a request back to the originating hub
2488
+ * without holding routing state of their own. The Lambda decodes the
2489
+ * JWT WITHOUT verifying the signature — the hub re-verifies on every
2490
+ * inbound call so trust still rests with the signing hub.
2491
+ */
2492
+ hubUrl: zod.z.string().optional()
2493
+ });
2494
+ method(zod.z.object({
2495
+ claims: SsoBridgeClaimsSchema,
2496
+ ttlSec: zod.z.number().int().positive().optional()
2497
+ }), zod.z.object({ token: zod.z.string() })), method(zod.z.object({ token: zod.z.string() }), SsoBridgeClaimsSchema.nullable());
2498
+ var PasskeySummarySchema = zod.z.object({
2499
+ credentialId: zod.z.string(),
2500
+ label: zod.z.string(),
2501
+ createdAt: zod.z.number(),
2502
+ lastUsedAt: zod.z.number().nullable(),
2503
+ transports: zod.z.array(zod.z.string()).default([])
2504
+ });
2505
+ method(zod.z.object({
2506
+ userId: zod.z.string(),
2507
+ username: zod.z.string()
2508
+ }), zod.z.object({ optionsJSON: zod.z.record(zod.z.string(), zod.z.unknown()) }), {
2509
+ kind: "mutation",
2510
+ auth: "admin",
2511
+ access: "create"
2512
+ }), method(zod.z.object({
2513
+ userId: zod.z.string(),
2514
+ /** RegistrationResponseJSON from the browser. */
2515
+ response: zod.z.record(zod.z.string(), zod.z.unknown()),
2516
+ /** Operator-visible label (e.g. "MacBook Touch ID"). */
2517
+ label: zod.z.string()
2518
+ }), zod.z.object({
2519
+ success: zod.z.literal(true),
2520
+ credentialId: zod.z.string()
2521
+ }), {
2522
+ kind: "mutation",
2523
+ auth: "admin",
2524
+ access: "create"
2525
+ }), method(zod.z.object({ userId: zod.z.string().optional() }), zod.z.object({ optionsJSON: zod.z.record(zod.z.string(), zod.z.unknown()) }), {
2526
+ kind: "mutation",
2527
+ access: "view"
2528
+ }), method(zod.z.object({
2529
+ /** Required — the user the assertion belongs to (verified). */
2530
+ userId: zod.z.string(),
2531
+ /** AuthenticationResponseJSON from the browser. */
2532
+ response: zod.z.record(zod.z.string(), zod.z.unknown())
2533
+ }), zod.z.object({ verified: zod.z.boolean() }), {
2534
+ kind: "mutation",
2535
+ access: "view"
2536
+ }), method(zod.z.object({ userId: zod.z.string() }), zod.z.array(PasskeySummarySchema), { auth: "admin" }), method(zod.z.object({
2537
+ userId: zod.z.string(),
2538
+ credentialId: zod.z.string()
2539
+ }), zod.z.object({ success: zod.z.literal(true) }), {
2540
+ kind: "mutation",
2541
+ auth: "admin",
2542
+ access: "delete"
2543
+ });
2544
+ var EmailAddressSchema = zod.z.email();
2545
+ var SendEmailInputSchema = zod.z.object({
2546
+ to: zod.z.union([EmailAddressSchema, zod.z.array(EmailAddressSchema).min(1)]),
2547
+ cc: zod.z.array(EmailAddressSchema).optional(),
2548
+ bcc: zod.z.array(EmailAddressSchema).optional(),
2549
+ /** RFC 5322 `From` field. Most relays will reject if the domain
2550
+ * isn't authorised — the addon is responsible for substituting a
2551
+ * sane default when omitted. */
2552
+ from: zod.z.string().optional(),
2553
+ /** Optional `Reply-To` override. */
2554
+ replyTo: zod.z.string().optional(),
2555
+ subject: zod.z.string(),
2556
+ /** Plain-text body. Required even when `html` is present (fallback
2557
+ * for clients that strip HTML — including most spam filters). */
2558
+ text: zod.z.string(),
2559
+ /** Optional HTML body. Renders alongside `text` as multi-part. */
2560
+ html: zod.z.string().optional()
2561
+ });
2562
+ var SendEmailResultSchema = zod.z.object({
2563
+ messageId: zod.z.string(),
2564
+ accepted: zod.z.array(EmailAddressSchema).default([]),
2565
+ rejected: zod.z.array(EmailAddressSchema).default([])
2566
+ });
2567
+ var SmtpStatusSchema = zod.z.object({
2568
+ /** True iff the addon has successfully verified the relay. */
2569
+ ready: zod.z.boolean(),
2570
+ /** Operator-visible host string (no credentials). */
2571
+ host: zod.z.string(),
2572
+ /** Last error message reported by the relay, when not ready. */
2573
+ error: zod.z.string().optional(),
2574
+ /** Last successful verify timestamp (unix ms). */
2575
+ lastVerifiedAt: zod.z.number().optional()
2576
+ });
2577
+ method(SendEmailInputSchema, SendEmailResultSchema, {
2578
+ kind: "mutation",
2579
+ auth: "admin",
2580
+ access: "create"
2581
+ }), method(zod.z.void(), SmtpStatusSchema, {
2582
+ kind: "mutation",
2583
+ auth: "admin",
2584
+ access: "view"
2585
+ }), method(zod.z.void(), SmtpStatusSchema, { auth: "admin" });
2586
+ var BrokerKindSchema = zod.z.enum(["external", "embedded"]);
2587
+ var BrokerStatusSchema = zod.z.enum([
2588
+ "connected",
2589
+ "disconnected",
2590
+ "auth-failed",
2591
+ "unreachable",
2592
+ "tls-error"
2593
+ ]);
2594
+ var BrokerInfoSchema = zod.z.object({
2595
+ id: zod.z.string(),
2596
+ name: zod.z.string(),
2597
+ url: zod.z.string(),
2598
+ kind: BrokerKindSchema,
2599
+ status: BrokerStatusSchema,
2600
+ latencyMs: zod.z.number().nullable(),
2601
+ error: zod.z.string().optional(),
2602
+ /** Embedded brokers only: number of MQTT clients currently connected. */
2603
+ connectedClients: zod.z.number().int().nonnegative().optional(),
2604
+ /** Epoch ms of the last live probe (external) or aedes snapshot (embedded). */
2605
+ lastCheckedAt: zod.z.number().optional()
2606
+ });
2607
+ var BrokerConnectionDetailsSchema = zod.z.object({
2608
+ url: zod.z.string(),
2609
+ username: zod.z.string().optional(),
2610
+ password: zod.z.string().optional(),
2611
+ /**
2612
+ * Suggested prefix for `clientId`. Each consumer should suffix this
2613
+ * with its own discriminator (addon id, instance id) so reconnects
2614
+ * don't kick each other off (MQTT spec: clientId must be unique per
2615
+ * broker).
2616
+ */
2617
+ clientIdPrefix: zod.z.string().optional()
2618
+ });
2619
+ var AddBrokerInputSchema = zod.z.object({
2620
+ name: zod.z.string().min(1),
2621
+ url: zod.z.string().regex(/^(mqtt|mqtts|ws|wss):\/\//, "URL must start with mqtt(s):// or ws(s)://"),
2622
+ username: zod.z.string().optional(),
2623
+ password: zod.z.string().optional(),
2624
+ clientIdPrefix: zod.z.string().optional()
2625
+ });
2626
+ var AddBrokerResultSchema = zod.z.object({ id: zod.z.string() });
2627
+ var IdInputSchema = zod.z.object({ id: zod.z.string() });
2628
+ var TestResultSchema = zod.z.discriminatedUnion("ok", [zod.z.object({
2629
+ ok: zod.z.literal(true),
2630
+ latencyMs: zod.z.number()
2631
+ }), zod.z.object({
2632
+ ok: zod.z.literal(false),
2633
+ error: zod.z.string()
2634
+ })]);
2635
+ var StartEmbeddedInputSchema = zod.z.object({
2636
+ port: zod.z.number().int().min(1).max(65535).default(1883),
2637
+ /** Allow anonymous connect (no username/password). Default: false. */
2638
+ allowAnonymous: zod.z.boolean().default(false),
2639
+ /** Optional shared username/password for clients. */
2640
+ username: zod.z.string().optional(),
2641
+ password: zod.z.string().optional()
2642
+ });
2643
+ var StartEmbeddedResultSchema = zod.z.object({
2644
+ id: zod.z.string(),
2645
+ url: zod.z.string()
2646
+ });
2647
+ var StatusSchema = zod.z.object({
2648
+ brokerCount: zod.z.number(),
2649
+ embeddedRunning: zod.z.boolean()
2650
+ });
2651
+ method(zod.z.void(), zod.z.array(BrokerInfoSchema)), method(IdInputSchema, BrokerConnectionDetailsSchema), method(AddBrokerInputSchema, AddBrokerResultSchema, { kind: "mutation" }), method(IdInputSchema, zod.z.void(), { kind: "mutation" }), method(IdInputSchema, TestResultSchema, { kind: "mutation" }), method(StartEmbeddedInputSchema, StartEmbeddedResultSchema, { kind: "mutation" }), method(IdInputSchema, zod.z.void(), { kind: "mutation" }), method(zod.z.void(), StatusSchema);
2652
+ var LinkStateSchema = zod.z.enum([
2653
+ "unlinked",
2654
+ "linked",
2655
+ "error"
2656
+ ]);
2657
+ var DeviceExportStatusSchema = zod.z.object({
2658
+ linkState: LinkStateSchema,
2659
+ exposedDeviceCount: zod.z.number(),
2660
+ error: zod.z.string().optional()
2661
+ });
2662
+ var DeviceKindSchema = zod.z.string();
2663
+ var ExposedDeviceSchema = zod.z.object({
2664
+ deviceId: zod.z.string(),
2665
+ exposedAs: zod.z.string().optional(),
2666
+ capabilities: zod.z.array(zod.z.string()).optional()
2667
+ });
2668
+ var ExposeInputSchema = zod.z.object({
2669
+ deviceId: zod.z.string(),
2670
+ capabilities: zod.z.array(zod.z.string()).optional()
2671
+ });
2672
+ var UnexposeInputSchema = zod.z.object({ deviceId: zod.z.string() });
2673
+ method(zod.z.void(), DeviceExportStatusSchema), method(zod.z.void(), zod.z.array(DeviceKindSchema)), method(zod.z.void(), zod.z.array(ExposedDeviceSchema)), method(ExposeInputSchema, zod.z.void(), { kind: "mutation" }), method(UnexposeInputSchema, zod.z.void(), { kind: "mutation" });
2454
2674
  var AddonPageDeclarationSchema$1 = zod.z.object({
2455
2675
  id: zod.z.string(),
2456
2676
  label: zod.z.string(),
@@ -2554,9 +2774,41 @@ var AddonHttpRouteSchema = zod.z.object({
2554
2774
  "DELETE",
2555
2775
  "PATCH"
2556
2776
  ]),
2557
- path: zod.z.string()
2777
+ path: zod.z.string(),
2778
+ access: zod.z.enum([
2779
+ "public",
2780
+ "authenticated",
2781
+ "admin"
2782
+ ]).optional(),
2783
+ description: zod.z.string().optional()
2558
2784
  });
2559
- method(zod.z.void(), zod.z.array(AddonHttpRouteSchema));
2785
+ var InvokeRequestSchema = zod.z.object({
2786
+ method: zod.z.string(),
2787
+ path: zod.z.string(),
2788
+ params: zod.z.record(zod.z.string(), zod.z.string()),
2789
+ query: zod.z.record(zod.z.string(), zod.z.string()),
2790
+ body: zod.z.unknown(),
2791
+ headers: zod.z.record(zod.z.string(), zod.z.string()),
2792
+ user: zod.z.object({
2793
+ id: zod.z.string(),
2794
+ username: zod.z.string(),
2795
+ isAdmin: zod.z.boolean()
2796
+ }).optional(),
2797
+ scopedToken: zod.z.unknown().optional()
2798
+ });
2799
+ var InvokeReplyEnvelopeSchema = zod.z.object({
2800
+ status: zod.z.number().int(),
2801
+ headers: zod.z.record(zod.z.string(), zod.z.string()),
2802
+ /** When set, the hub MUST `reply.redirect(redirectUrl)` instead of
2803
+ * sending `body`. Status defaults to 302 when this is set unless
2804
+ * the handler called `reply.code(...)` explicitly. */
2805
+ redirectUrl: zod.z.string().nullable(),
2806
+ /** JSON-serializable body. `undefined` is treated as "no body". */
2807
+ body: zod.z.unknown().optional(),
2808
+ /** Set when the handler called `reply.type(mime)`. */
2809
+ contentType: zod.z.string().optional()
2810
+ });
2811
+ method(zod.z.void(), zod.z.array(AddonHttpRouteSchema)), method(InvokeRequestSchema, InvokeReplyEnvelopeSchema, { kind: "mutation" });
2560
2812
  method(zod.z.object({ codec: zod.z.string() }), zod.z.boolean()), method(zod.z.void(), zod.z.object({
2561
2813
  id: zod.z.string(),
2562
2814
  name: zod.z.string(),
@@ -2674,6 +2926,14 @@ DeviceType.Camera, method(zod.z.object({ deviceId: zod.z.number().int().nonnegat
2674
2926
  }), zod.z.object({
2675
2927
  sessionId: zod.z.string(),
2676
2928
  sdpOffer: zod.z.string()
2929
+ }), { kind: "mutation" }), method(zod.z.object({
2930
+ deviceId: zod.z.number().int().nonnegative(),
2931
+ target: WebrtcStreamTargetSchema.optional(),
2932
+ sdpOffer: zod.z.string(),
2933
+ sessionId: zod.z.string().optional()
2934
+ }), zod.z.object({
2935
+ sessionId: zod.z.string(),
2936
+ sdpAnswer: zod.z.string()
2677
2937
  }), { kind: "mutation" }), method(zod.z.object({
2678
2938
  deviceId: zod.z.number().int().nonnegative(),
2679
2939
  sessionId: zod.z.string(),
@@ -3012,12 +3272,12 @@ method(zod.z.void(), zod.z.array(AudioCodecInfoSchema).readonly()), method(zod.z
3012
3272
  }), zod.z.array(AudioEncodedChunkSchema), { kind: "mutation" }), method(zod.z.void(), zod.z.array(SessionInventoryEntrySchema).readonly());
3013
3273
  var EmbeddingResultSchema = zod.z.object({
3014
3274
  embedding: zod.z.array(zod.z.number()),
3015
- dimensions: zod.z.number()
3275
+ inferenceMs: zod.z.number()
3016
3276
  });
3017
3277
  var EmbeddingInfoSchema = zod.z.object({
3018
3278
  modelId: zod.z.string(),
3019
- dimensions: zod.z.number(),
3020
- inputSize: zod.z.number()
3279
+ embeddingDim: zod.z.number(),
3280
+ ready: zod.z.boolean()
3021
3281
  });
3022
3282
  method(zod.z.object({
3023
3283
  crop: zod.z.instanceof(Uint8Array),
@@ -3298,7 +3558,14 @@ var AuthResultSchema = zod.z.object({
3298
3558
  username: zod.z.string(),
3299
3559
  email: zod.z.string().optional(),
3300
3560
  displayName: zod.z.string().optional(),
3301
- roles: zod.z.array(zod.z.string()).optional()
3561
+ /**
3562
+ * Whether the authenticating user is an admin. The auth-provider
3563
+ * surface returns this so the server's login flow can mint a JWT
3564
+ * with the correct bypass flag. Non-admin users authenticated via
3565
+ * an external IdP still need their scopes assigned by an admin via
3566
+ * `setUserScopes` — the SSO flow doesn't carry permissions.
3567
+ */
3568
+ isAdmin: zod.z.boolean().default(false)
3302
3569
  });
3303
3570
  method(zod.z.object({
3304
3571
  username: zod.z.string(),
@@ -3307,6 +3574,14 @@ method(zod.z.object({
3307
3574
  var AuthProviderInfoSchema = zod.z.object({
3308
3575
  /** Stable id matching the addon id (used for `getLoginUrl({addonId,…})`). */
3309
3576
  addonId: zod.z.string(),
3577
+ /**
3578
+ * Per-instance id when one addon registers multiple "logical"
3579
+ * providers (e.g. OIDC with Google + Microsoft + custom). The login
3580
+ * URL becomes `/addon/${addonId}/${instanceId}/start` — handler reads
3581
+ * `:instanceId` from the route. Empty/unset means the addon is a
3582
+ * single-instance provider; the URL is `/addon/${addonId}/start`.
3583
+ */
3584
+ instanceId: zod.z.string().optional(),
3310
3585
  /** Display label shown on the login button + admin row. */
3311
3586
  displayName: zod.z.string(),
3312
3587
  /** Optional iconography hint (lucide-react icon name OR emoji). */
@@ -3317,6 +3592,8 @@ var AuthProviderInfoSchema = zod.z.object({
3317
3592
  /** When true, the provider exposes a credential-form login flow
3318
3593
  * (`validateCredentials` accepts username + password). */
3319
3594
  hasCredentialFlow: zod.z.boolean(),
3595
+ /** Provider kind, drives admin-UI hint dispatch (oidc / saml / totp / …). */
3596
+ kind: zod.z.string().optional(),
3320
3597
  /** Operator-facing status string (e.g. "Connected to https://login.acme.com"). */
3321
3598
  status: zod.z.string().optional(),
3322
3599
  /** When false, the provider is registered but disabled by config; the
@@ -3341,7 +3618,20 @@ var NetworkAccessStatusSchema = zod.z.object({
3341
3618
  endpoint: NetworkEndpointSchema.nullable(),
3342
3619
  error: zod.z.string().optional()
3343
3620
  });
3344
- method(zod.z.void(), NetworkEndpointSchema, { kind: "mutation" }), method(zod.z.void(), zod.z.void(), { kind: "mutation" }), method(zod.z.void(), NetworkEndpointSchema.nullable()), method(zod.z.void(), NetworkAccessStatusSchema);
3621
+ var NetworkEndpointEntrySchema = NetworkEndpointSchema.extend({
3622
+ /**
3623
+ * Stable id within the provider — typically `<mode>-<sourcePort>` so
3624
+ * the orchestrator can dedupe across `listEndpoints` polls.
3625
+ */
3626
+ id: zod.z.string(),
3627
+ /** Operator-facing label (mirrors `MeshEndpoint.label`). */
3628
+ label: zod.z.string(),
3629
+ /** Optional provider-specific mode tag, used for icon/colour in admin UI. */
3630
+ mode: zod.z.string().optional(),
3631
+ /** Originating local port the ingress fronts (informational). */
3632
+ sourcePort: zod.z.number().optional()
3633
+ });
3634
+ method(zod.z.void(), NetworkEndpointSchema, { kind: "mutation" }), method(zod.z.void(), zod.z.void(), { kind: "mutation" }), method(zod.z.void(), NetworkEndpointSchema.nullable()), method(zod.z.void(), NetworkAccessStatusSchema), method(zod.z.void(), zod.z.array(NetworkEndpointEntrySchema).readonly());
3345
3635
  var RemoteAccessEndpointSchema = zod.z.object({
3346
3636
  url: zod.z.string(),
3347
3637
  hostname: zod.z.string(),
@@ -3454,28 +3744,78 @@ method(zod.z.object({
3454
3744
  success: zod.z.boolean(),
3455
3745
  error: zod.z.string().optional()
3456
3746
  }), { kind: "mutation" });
3747
+ var NotificationRuleConditionsSchema = zod.z.object({
3748
+ deviceIds: zod.z.array(zod.z.number()).readonly().optional(),
3749
+ classNames: zod.z.array(zod.z.string()).readonly().optional(),
3750
+ zoneIds: zod.z.array(zod.z.string()).readonly().optional(),
3751
+ minConfidence: zod.z.number().optional(),
3752
+ source: zod.z.enum([
3753
+ "pipeline",
3754
+ "onboard",
3755
+ "any"
3756
+ ]).optional(),
3757
+ schedule: zod.z.object({
3758
+ days: zod.z.array(zod.z.number()).readonly(),
3759
+ startHour: zod.z.number(),
3760
+ endHour: zod.z.number()
3761
+ }).optional(),
3762
+ cooldownSeconds: zod.z.number().optional(),
3763
+ minDwellSeconds: zod.z.number().optional()
3764
+ });
3765
+ var NotificationRuleTemplateSchema = zod.z.object({
3766
+ title: zod.z.string(),
3767
+ body: zod.z.string(),
3768
+ imageMode: zod.z.enum([
3769
+ "crop",
3770
+ "annotated",
3771
+ "full",
3772
+ "none"
3773
+ ])
3774
+ });
3457
3775
  var NotificationRuleSchema = zod.z.object({
3458
3776
  id: zod.z.string(),
3459
3777
  name: zod.z.string(),
3460
3778
  enabled: zod.z.boolean(),
3461
- conditions: zod.z.record(zod.z.string(), zod.z.unknown()),
3462
- actions: zod.z.array(zod.z.record(zod.z.string(), zod.z.unknown()))
3779
+ eventTypes: zod.z.array(zod.z.string()).readonly(),
3780
+ conditions: NotificationRuleConditionsSchema,
3781
+ outputs: zod.z.array(zod.z.string()).readonly(),
3782
+ template: NotificationRuleTemplateSchema.optional(),
3783
+ priority: zod.z.enum([
3784
+ "low",
3785
+ "normal",
3786
+ "high",
3787
+ "critical"
3788
+ ])
3789
+ });
3790
+ var NotificationTestResultSchema = zod.z.object({
3791
+ ruleId: zod.z.string(),
3792
+ eventId: zod.z.string(),
3793
+ timestamp: zod.z.number(),
3794
+ wouldFire: zod.z.boolean(),
3795
+ reason: zod.z.string().optional()
3463
3796
  });
3464
3797
  var NotificationHistoryEntrySchema = zod.z.object({
3465
3798
  id: zod.z.string(),
3466
3799
  ruleId: zod.z.string(),
3800
+ ruleName: zod.z.string(),
3801
+ eventId: zod.z.string(),
3467
3802
  timestamp: zod.z.number(),
3468
- deviceId: zod.z.number().optional(),
3803
+ outputs: zod.z.array(zod.z.string()).readonly(),
3469
3804
  success: zod.z.boolean(),
3470
- error: zod.z.string().optional()
3805
+ error: zod.z.string().optional(),
3806
+ deviceId: zod.z.number().optional()
3471
3807
  });
3472
- method(zod.z.void(), zod.z.array(NotificationRuleSchema).readonly()), method(NotificationRuleSchema, zod.z.void(), { kind: "mutation" }), method(zod.z.object({ ruleId: zod.z.string() }), zod.z.void(), { kind: "mutation" }), method(zod.z.object({
3473
- ruleId: zod.z.string(),
3474
- lookbackMinutes: zod.z.number()
3475
- }), zod.z.array(zod.z.record(zod.z.string(), zod.z.unknown())), { kind: "mutation" }), method(zod.z.object({
3808
+ var NotificationHistoryFilterSchema = zod.z.object({
3476
3809
  ruleId: zod.z.string().optional(),
3810
+ deviceId: zod.z.number().optional(),
3811
+ from: zod.z.number().optional(),
3812
+ to: zod.z.number().optional(),
3477
3813
  limit: zod.z.number().optional()
3478
- }), zod.z.array(NotificationHistoryEntrySchema));
3814
+ });
3815
+ method(zod.z.void(), zod.z.object({ rules: zod.z.array(NotificationRuleSchema).readonly() })), method(zod.z.object({ rule: NotificationRuleSchema }), zod.z.object({ success: zod.z.literal(true) }), { kind: "mutation" }), method(zod.z.object({ ruleId: zod.z.string() }), zod.z.object({ success: zod.z.literal(true) }), { kind: "mutation" }), method(zod.z.object({
3816
+ ruleId: zod.z.string(),
3817
+ lookbackMinutes: zod.z.number()
3818
+ }), zod.z.object({ results: zod.z.array(NotificationTestResultSchema).readonly() }), { kind: "mutation" }), method(zod.z.object({ filter: NotificationHistoryFilterSchema.optional() }), zod.z.object({ entries: zod.z.array(NotificationHistoryEntrySchema).readonly() }));
3479
3819
  var RecordingModeSchema = zod.z.enum([
3480
3820
  "continuous",
3481
3821
  "motion",
@@ -4163,6 +4503,22 @@ DeviceType.Camera, method(zod.z.object({ deviceId: zod.z.number() }), zod.z.obje
4163
4503
  }), zod.z.void(), {
4164
4504
  kind: "mutation",
4165
4505
  auth: "admin"
4506
+ }), method(zod.z.object({ deviceId: zod.z.number() }), zod.z.object({ sessionId: zod.z.string() }), {
4507
+ kind: "mutation",
4508
+ auth: "admin"
4509
+ }), method(zod.z.object({
4510
+ deviceId: zod.z.number(),
4511
+ /** PCM frames as little-endian s16, mono. Base64-encoded so
4512
+ * the payload survives tRPC JSON serialization. */
4513
+ pcmBase64: zod.z.string(),
4514
+ /** Sequence number for ordering / dropping out-of-order frames. */
4515
+ sequenceNumber: zod.z.number().int()
4516
+ }), zod.z.object({ accepted: zod.z.boolean() }), {
4517
+ kind: "mutation",
4518
+ auth: "admin"
4519
+ }), method(zod.z.object({ deviceId: zod.z.number() }), zod.z.void(), {
4520
+ kind: "mutation",
4521
+ auth: "admin"
4166
4522
  }), zod.z.object({
4167
4523
  deviceId: zod.z.number(),
4168
4524
  status: IntercomStatusSchema
@@ -4214,6 +4570,40 @@ var HwAccelBackendInputSchema = zod.z.enum([
4214
4570
  "none"
4215
4571
  ]).nullable().optional();
4216
4572
  var HwAccelResolutionSchema = zod.z.object({ preferred: zod.z.array(zod.z.string()).readonly() });
4573
+ var HardwareEncoderIdSchema = zod.z.enum([
4574
+ "h264_videotoolbox",
4575
+ "hevc_videotoolbox",
4576
+ "h264_vaapi",
4577
+ "hevc_vaapi",
4578
+ "h264_nvenc",
4579
+ "hevc_nvenc",
4580
+ "h264_qsv",
4581
+ "hevc_qsv",
4582
+ "h264_amf",
4583
+ "hevc_amf",
4584
+ "libx264",
4585
+ "libx265"
4586
+ ]);
4587
+ var HardwareEncoderProbeSchema = zod.z.object({
4588
+ encoder: HardwareEncoderIdSchema,
4589
+ codec: zod.z.enum(["H264", "H265"]),
4590
+ family: zod.z.enum([
4591
+ "videotoolbox",
4592
+ "vaapi",
4593
+ "nvenc",
4594
+ "qsv",
4595
+ "amf",
4596
+ "software"
4597
+ ]),
4598
+ available: zod.z.boolean(),
4599
+ reason: zod.z.string().optional()
4600
+ });
4601
+ var HardwareEncodersSchema = zod.z.object({
4602
+ encoders: zod.z.array(HardwareEncoderProbeSchema).readonly(),
4603
+ defaultH264: HardwareEncoderIdSchema,
4604
+ defaultH265: HardwareEncoderIdSchema,
4605
+ probedAt: zod.z.number()
4606
+ });
4217
4607
  var HardwarePlatformSchema = zod.z.enum([
4218
4608
  "darwin",
4219
4609
  "linux",
@@ -4276,7 +4666,10 @@ var ResolvedInferenceConfigSchema = zod.z.object({
4276
4666
  method(zod.z.void(), PlatformCapabilitiesSchema), method(zod.z.void(), HardwareInfoSchema), method(zod.z.object({ requirements: zod.z.array(ModelRequirementSchema).readonly() }), ResolvedInferenceConfigSchema), method(zod.z.object({
4277
4667
  prefer: HwAccelBackendInputSchema,
4278
4668
  nodeId: zod.z.string().optional()
4279
- }), HwAccelResolutionSchema);
4669
+ }), HwAccelResolutionSchema), method(zod.z.void(), HardwareEncodersSchema), method(zod.z.void(), HardwareEncodersSchema, {
4670
+ kind: "mutation",
4671
+ auth: "admin"
4672
+ });
4280
4673
  var InterfaceKindEnum = zod.z.enum([
4281
4674
  "lan",
4282
4675
  "wifi",
@@ -4446,28 +4839,30 @@ var MeshStatusSchema = zod.z.object({
4446
4839
  /** Last error from the daemon, when not joined. */
4447
4840
  error: zod.z.string().optional()
4448
4841
  });
4449
- var PublicIngressConfigSchema = zod.z.object({
4450
- /** Whether the provider should expose CamStack via its public
4451
- * ingress (Tailscale Funnel, etc.). */
4452
- enabled: zod.z.boolean(),
4453
- /** Local port to forward. Auto-detected from the hub HTTP port
4454
- * when omitted. */
4455
- port: zod.z.number().int().min(1).max(65535).optional()
4456
- });
4457
- var MeshIngressConfigSchema = zod.z.object({
4458
- /** Whether the provider should expose CamStack inside the mesh
4459
- * via HTTPS (Tailscale Serve, etc.) instead of just raw IP. */
4460
- enabled: zod.z.boolean(),
4461
- /** Local port to forward. Auto-detected when omitted. */
4462
- port: zod.z.number().int().min(1).max(65535).optional()
4463
- });
4464
4842
  method(zod.z.void(), MeshStatusSchema), method(zod.z.object({
4465
4843
  /** Provider-specific auth key. For Tailscale this is the
4466
4844
  * `tskey-auth-*` token from admin.tailscale.com. */
4467
4845
  authKey: zod.z.string().min(8),
4468
4846
  /** Optional hostname override the host should advertise. */
4469
4847
  hostname: zod.z.string().optional()
4470
- }), zod.z.object({ joined: zod.z.literal(true) }), { kind: "mutation" }), method(zod.z.void(), zod.z.object({ left: zod.z.literal(true) }), { kind: "mutation" }), method(zod.z.void(), zod.z.object({ peers: zod.z.array(MeshPeerSchema).readonly() })), method(PublicIngressConfigSchema, zod.z.object({ success: zod.z.literal(true) }), { kind: "mutation" }), method(MeshIngressConfigSchema, zod.z.object({ success: zod.z.literal(true) }), { kind: "mutation" });
4848
+ }), zod.z.object({ joined: zod.z.literal(true) }), { kind: "mutation" }), method(zod.z.object({
4849
+ /** Optional hostname override the host should advertise once joined. */
4850
+ hostname: zod.z.string().optional() }), zod.z.object({
4851
+ /** Authentication URL the operator should open in a browser. */
4852
+ loginUrl: zod.z.string() }), { kind: "mutation" }), method(zod.z.void(), zod.z.object({ left: zod.z.literal(true) }), { kind: "mutation" }), method(zod.z.void(), zod.z.object({ peers: zod.z.array(MeshPeerSchema).readonly() })), method(zod.z.object({
4853
+ /** Optional auth key — when provided, probes the key validity
4854
+ * against the provider's API. Omit when already joined to
4855
+ * just ping the daemon. */
4856
+ authKey: zod.z.string().optional() }), zod.z.object({
4857
+ ok: zod.z.boolean(),
4858
+ /** Provider-side identifier resolved by the probe (tailnet
4859
+ * name for Tailscale, network id for ZeroTier, etc.). */
4860
+ tenant: zod.z.string().optional(),
4861
+ /** Daemon binary version, when reachable. */
4862
+ daemonVersion: zod.z.string().optional(),
4863
+ /** Human-readable error when `ok: false`. */
4864
+ error: zod.z.string().optional()
4865
+ }), { kind: "mutation" });
4471
4866
  var MeshEndpointSchema = zod.z.object({
4472
4867
  id: zod.z.string(),
4473
4868
  label: zod.z.string(),
@@ -4500,35 +4895,58 @@ method(zod.z.void(), zod.z.array(MeshProviderInfoSchema).readonly()), method(zod
4500
4895
  authKey: zod.z.string().min(8),
4501
4896
  hostname: zod.z.string().optional()
4502
4897
  }), zod.z.object({ joined: zod.z.literal(true) }), { kind: "mutation" }), method(zod.z.object({ addonId: zod.z.string() }), zod.z.object({ success: zod.z.literal(true) }), { kind: "mutation" });
4503
- var UserRoleSchema = zod.z.enum([
4504
- "admin",
4505
- "viewer",
4506
- "agent",
4507
- "scoped"
4508
- ]);
4509
- var AllowedProviderSchema = zod.z.union([zod.z.literal("*"), zod.z.array(zod.z.string())]);
4510
- var AllowedDevicesSchema = zod.z.record(zod.z.string(), zod.z.union([zod.z.literal("*"), zod.z.array(zod.z.string())]));
4511
4898
  var MethodAccessSchema = zod.z.enum([
4512
4899
  "view",
4513
4900
  "create",
4514
4901
  "delete"
4515
4902
  ]);
4516
- var TokenScopeSchema = zod.z.object({
4517
- type: zod.z.enum(["addon", "capability"]),
4518
- target: zod.z.string(),
4519
- access: zod.z.array(MethodAccessSchema).min(1)
4520
- });
4903
+ var AllowedProviderSchema = zod.z.union([zod.z.literal("*"), zod.z.array(zod.z.string())]);
4904
+ var AllowedDevicesSchema = zod.z.record(zod.z.string(), zod.z.union([zod.z.literal("*"), zod.z.array(zod.z.string())]));
4905
+ var CapScopeSchema = zod.z.enum(["device", "system"]);
4906
+ var TokenScopeSchema = zod.z.discriminatedUnion("type", [
4907
+ zod.z.object({
4908
+ type: zod.z.literal("category"),
4909
+ target: CapScopeSchema,
4910
+ access: zod.z.array(MethodAccessSchema).min(1)
4911
+ }),
4912
+ zod.z.object({
4913
+ type: zod.z.literal("capability"),
4914
+ target: zod.z.string(),
4915
+ access: zod.z.array(MethodAccessSchema).min(1)
4916
+ }),
4917
+ zod.z.object({
4918
+ type: zod.z.literal("addon"),
4919
+ target: zod.z.string(),
4920
+ access: zod.z.array(MethodAccessSchema).min(1)
4921
+ }),
4922
+ zod.z.object({
4923
+ type: zod.z.literal("device"),
4924
+ /**
4925
+ * One or more deviceIds (serialised as strings for wire-format
4926
+ * consistency with the rest of the union). Matcher accepts if
4927
+ * `input.deviceId` ∈ `targets`. Array shape avoids the row-explosion
4928
+ * of one scope-per-device when granting access to a set of cameras.
4929
+ */
4930
+ targets: zod.z.array(zod.z.string()).min(1),
4931
+ access: zod.z.array(MethodAccessSchema).min(1)
4932
+ })
4933
+ ]);
4521
4934
  zod.z.object({
4522
4935
  id: zod.z.string(),
4523
4936
  username: zod.z.string(),
4524
4937
  passwordHash: zod.z.string(),
4525
- role: UserRoleSchema,
4938
+ /**
4939
+ * Admin bypass. When true, the middleware skips the scope-access
4940
+ * check entirely. There is no other axis of privilege; the legacy
4941
+ * role enum collapsed onto this boolean in v2.
4942
+ */
4943
+ isAdmin: zod.z.boolean().default(false),
4526
4944
  allowedProviders: AllowedProviderSchema,
4527
4945
  allowedDevices: AllowedDevicesSchema,
4528
4946
  /**
4529
- * Scopes granted to this user. Admins bypass; their `scopes` is ignored.
4530
- * Non-admins (`viewer`, `agent`, `scoped`) without scopes are locked out
4531
- * of every protected call.
4947
+ * Scopes granted to this user. Admins bypass; their `scopes` is
4948
+ * ignored. Non-admins without scopes are locked out of every
4949
+ * protected call.
4532
4950
  */
4533
4951
  scopes: zod.z.array(TokenScopeSchema).default([]),
4534
4952
  createdAt: zod.z.number(),
@@ -4537,7 +4955,7 @@ zod.z.object({
4537
4955
  zod.z.object({
4538
4956
  id: zod.z.string(),
4539
4957
  label: zod.z.string(),
4540
- role: UserRoleSchema,
4958
+ isAdmin: zod.z.boolean().default(false),
4541
4959
  allowedProviders: AllowedProviderSchema,
4542
4960
  allowedDevices: AllowedDevicesSchema,
4543
4961
  tokenHash: zod.z.string(),
@@ -4559,7 +4977,7 @@ zod.z.object({
4559
4977
  var UserSummarySchema = zod.z.object({
4560
4978
  id: zod.z.string(),
4561
4979
  username: zod.z.string(),
4562
- role: UserRoleSchema,
4980
+ isAdmin: zod.z.boolean().default(false),
4563
4981
  allowedProviders: zod.z.union([zod.z.array(zod.z.string()), zod.z.literal("*")]),
4564
4982
  allowedDevices: zod.z.record(zod.z.string(), zod.z.union([zod.z.array(zod.z.string()), zod.z.literal("*")])),
4565
4983
  scopes: zod.z.array(TokenScopeSchema).default([]),
@@ -4569,14 +4987,14 @@ var UserSummarySchema = zod.z.object({
4569
4987
  var CreateUserInputSchema = zod.z.object({
4570
4988
  username: zod.z.string(),
4571
4989
  password: zod.z.string().min(6),
4572
- role: UserRoleSchema,
4990
+ isAdmin: zod.z.boolean().default(false),
4573
4991
  allowedProviders: zod.z.union([zod.z.array(zod.z.string()), zod.z.literal("*")]).optional(),
4574
4992
  allowedDevices: zod.z.record(zod.z.string(), zod.z.union([zod.z.array(zod.z.string()), zod.z.literal("*")])).optional(),
4575
4993
  scopes: zod.z.array(TokenScopeSchema).optional()
4576
4994
  });
4577
4995
  var UpdateUserInputSchema = zod.z.object({
4578
4996
  id: zod.z.string(),
4579
- role: UserRoleSchema.optional(),
4997
+ isAdmin: zod.z.boolean().optional(),
4580
4998
  allowedProviders: zod.z.union([zod.z.array(zod.z.string()), zod.z.literal("*")]).optional(),
4581
4999
  allowedDevices: zod.z.record(zod.z.string(), zod.z.union([zod.z.array(zod.z.string()), zod.z.literal("*")])).optional(),
4582
5000
  scopes: zod.z.array(TokenScopeSchema).optional()
@@ -4584,7 +5002,7 @@ var UpdateUserInputSchema = zod.z.object({
4584
5002
  var ApiKeySummarySchema = zod.z.object({
4585
5003
  id: zod.z.string(),
4586
5004
  label: zod.z.string(),
4587
- role: UserRoleSchema,
5005
+ isAdmin: zod.z.boolean().default(false),
4588
5006
  allowedProviders: zod.z.union([zod.z.array(zod.z.string()), zod.z.literal("*")]).optional(),
4589
5007
  allowedDevices: zod.z.record(zod.z.string(), zod.z.union([zod.z.array(zod.z.string()), zod.z.literal("*")])).optional(),
4590
5008
  tokenPrefix: zod.z.string(),
@@ -4593,7 +5011,7 @@ var ApiKeySummarySchema = zod.z.object({
4593
5011
  });
4594
5012
  var CreateApiKeyInputSchema = zod.z.object({
4595
5013
  label: zod.z.string(),
4596
- role: UserRoleSchema,
5014
+ isAdmin: zod.z.boolean().default(false),
4597
5015
  allowedProviders: zod.z.union([zod.z.array(zod.z.string()), zod.z.literal("*")]).optional(),
4598
5016
  allowedDevices: zod.z.record(zod.z.string(), zod.z.union([zod.z.array(zod.z.string()), zod.z.literal("*")])).optional()
4599
5017
  });
@@ -4621,43 +5039,89 @@ var CreateScopedTokenResultSchema = zod.z.object({
4621
5039
  token: zod.z.string(),
4622
5040
  record: ScopedTokenSummarySchema
4623
5041
  });
5042
+ var TotpSetupResultSchema = zod.z.object({
5043
+ secret: zod.z.string(),
5044
+ otpauthUrl: zod.z.string()
5045
+ });
5046
+ var TotpStatusSchema = zod.z.object({
5047
+ /** True iff `confirmedAt != null` — a pending half-enrollment is reported as `enabled: false`. */
5048
+ enabled: zod.z.boolean(),
5049
+ /** Null when no row exists OR the row is still pending confirmation. */
5050
+ confirmedAt: zod.z.number().nullable()
5051
+ });
4624
5052
  method(zod.z.void(), zod.z.array(UserSummarySchema), { auth: "admin" }), method(CreateUserInputSchema, UserSummarySchema, {
4625
5053
  kind: "mutation",
4626
- auth: "admin"
5054
+ auth: "admin",
5055
+ access: "create"
4627
5056
  }), method(UpdateUserInputSchema, zod.z.object({ success: zod.z.literal(true) }), {
4628
5057
  kind: "mutation",
4629
- auth: "admin"
5058
+ auth: "admin",
5059
+ access: "create"
4630
5060
  }), method(zod.z.object({ id: zod.z.string() }), zod.z.object({ success: zod.z.literal(true) }), {
4631
5061
  kind: "mutation",
4632
- auth: "admin"
5062
+ auth: "admin",
5063
+ access: "delete"
4633
5064
  }), method(zod.z.object({
4634
5065
  id: zod.z.string(),
4635
5066
  newPassword: zod.z.string().min(6)
4636
5067
  }), zod.z.object({ success: zod.z.literal(true) }), {
4637
5068
  kind: "mutation",
4638
- auth: "admin"
5069
+ auth: "admin",
5070
+ access: "create"
4639
5071
  }), method(zod.z.object({
4640
5072
  userId: zod.z.string(),
4641
5073
  scopes: zod.z.array(TokenScopeSchema)
4642
5074
  }), zod.z.object({ success: zod.z.literal(true) }), {
4643
5075
  kind: "mutation",
4644
- auth: "admin"
5076
+ auth: "admin",
5077
+ access: "create"
4645
5078
  }), method(zod.z.object({
4646
5079
  username: zod.z.string(),
4647
5080
  password: zod.z.string()
4648
- }), UserSummarySchema.extend({ passwordHash: zod.z.string() }).nullable(), { kind: "mutation" }), method(zod.z.void(), zod.z.array(ApiKeySummarySchema), { auth: "admin" }), method(CreateApiKeyInputSchema, CreateApiKeyResultSchema, {
5081
+ }), UserSummarySchema.extend({ passwordHash: zod.z.string() }).nullable(), {
4649
5082
  kind: "mutation",
4650
- auth: "admin"
5083
+ access: "view"
5084
+ }), method(zod.z.void(), zod.z.array(ApiKeySummarySchema), { auth: "admin" }), method(CreateApiKeyInputSchema, CreateApiKeyResultSchema, {
5085
+ kind: "mutation",
5086
+ auth: "admin",
5087
+ access: "create"
4651
5088
  }), method(zod.z.object({ id: zod.z.string() }), zod.z.object({ success: zod.z.literal(true) }), {
4652
5089
  kind: "mutation",
4653
- auth: "admin"
4654
- }), method(zod.z.object({ token: zod.z.string() }), ApiKeySummarySchema.nullable(), { kind: "mutation" }), method(CreateScopedTokenInputSchema, CreateScopedTokenResultSchema, {
5090
+ auth: "admin",
5091
+ access: "delete"
5092
+ }), method(zod.z.object({ token: zod.z.string() }), ApiKeySummarySchema.nullable(), {
4655
5093
  kind: "mutation",
4656
- auth: "admin"
5094
+ access: "view"
5095
+ }), method(CreateScopedTokenInputSchema, CreateScopedTokenResultSchema, {
5096
+ kind: "mutation",
5097
+ auth: "admin",
5098
+ access: "create"
4657
5099
  }), method(zod.z.object({ id: zod.z.string() }), zod.z.object({ success: zod.z.literal(true) }), {
4658
5100
  kind: "mutation",
4659
- auth: "admin"
4660
- }), method(zod.z.object({ token: zod.z.string() }), ScopedTokenSummarySchema.nullable()), method(zod.z.object({ userId: zod.z.string() }), zod.z.array(ScopedTokenSummarySchema), { auth: "admin" });
5101
+ auth: "admin",
5102
+ access: "delete"
5103
+ }), method(zod.z.object({ token: zod.z.string() }), ScopedTokenSummarySchema.nullable(), { access: "view" }), method(zod.z.object({ userId: zod.z.string() }), zod.z.array(ScopedTokenSummarySchema), { auth: "admin" }), method(zod.z.object({ userId: zod.z.string() }), TotpSetupResultSchema, {
5104
+ kind: "mutation",
5105
+ auth: "admin",
5106
+ access: "create"
5107
+ }), method(zod.z.object({
5108
+ userId: zod.z.string(),
5109
+ code: zod.z.string()
5110
+ }), zod.z.object({ success: zod.z.literal(true) }), {
5111
+ kind: "mutation",
5112
+ auth: "admin",
5113
+ access: "create"
5114
+ }), method(zod.z.object({ userId: zod.z.string() }), zod.z.object({ success: zod.z.literal(true) }), {
5115
+ kind: "mutation",
5116
+ auth: "admin",
5117
+ access: "delete"
5118
+ }), method(zod.z.object({ userId: zod.z.string() }), TotpStatusSchema, { auth: "admin" }), method(zod.z.object({
5119
+ userId: zod.z.string(),
5120
+ code: zod.z.string()
5121
+ }), zod.z.object({ valid: zod.z.boolean() }), {
5122
+ kind: "mutation",
5123
+ access: "view"
5124
+ });
4661
5125
  var FeatureManifestSchema = zod.z.object({
4662
5126
  streaming: zod.z.boolean(),
4663
5127
  notifications: zod.z.boolean(),