@camstack/addon-provider-rtsp 0.1.25 → 0.1.27

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.
package/dist/addon.js CHANGED
@@ -8695,10 +8695,30 @@ const StatusSchema = object({
8695
8695
  }
8696
8696
  });
8697
8697
  const LinkStateSchema = _enum(["unlinked", "linked", "error"]);
8698
+ const ExportSetupFieldSchema = object({
8699
+ label: string(),
8700
+ value: string(),
8701
+ /** Mask the value by default + render a reveal toggle (client id, secrets). */
8702
+ secret: boolean().optional()
8703
+ });
8704
+ const ExportSetupSchema = object({
8705
+ /** A string to render as a scannable QR — HAP `X-HM://…` URI, a pairing URL, etc. Omitted when there's nothing to scan. */
8706
+ qr: string().optional(),
8707
+ /** Label/value rows shown with a copy button (HAP setup code, OAuth URLs, client id, linked-account count, …). */
8708
+ fields: array(ExportSetupFieldSchema).readonly().optional(),
8709
+ /** Free-form operator instructions rendered above the fields. */
8710
+ note: string().optional()
8711
+ });
8698
8712
  const DeviceExportStatusSchema = object({
8699
8713
  linkState: LinkStateSchema,
8700
8714
  exposedDeviceCount: number(),
8701
- error: string().optional()
8715
+ error: string().optional(),
8716
+ /**
8717
+ * Optional pairing/account info the panel renders in a generic
8718
+ * "Setup" section. Addon-agnostic — the addon id identifies the
8719
+ * export target, never an `ecosystem` key here.
8720
+ */
8721
+ setup: ExportSetupSchema.optional()
8702
8722
  });
8703
8723
  const DeviceKindSchema = string();
8704
8724
  const ExposedDeviceSchema = object({
@@ -10368,51 +10388,6 @@ const AuthResultSchema = object({
10368
10388
  validateToken: method(object({ token: string() }), AuthResultSchema.nullable())
10369
10389
  }
10370
10390
  });
10371
- const AuthProviderInfoSchema = object({
10372
- /** Stable id matching the addon id (used for `getLoginUrl({addonId,…})`). */
10373
- addonId: string(),
10374
- /**
10375
- * Per-instance id when one addon registers multiple "logical"
10376
- * providers (e.g. OIDC with Google + Microsoft + custom). The login
10377
- * URL becomes `/addon/${addonId}/${instanceId}/start` — handler reads
10378
- * `:instanceId` from the route. Empty/unset means the addon is a
10379
- * single-instance provider; the URL is `/addon/${addonId}/start`.
10380
- */
10381
- instanceId: string().optional(),
10382
- /** Display label shown on the login button + admin row. */
10383
- displayName: string(),
10384
- /** Optional iconography hint (lucide-react icon name OR emoji). */
10385
- icon: string().optional(),
10386
- /** When true, the provider exposes a redirect-based login flow
10387
- * (`getLoginUrl` returns a URL the browser navigates to). */
10388
- hasRedirectFlow: boolean(),
10389
- /** When true, the provider exposes a credential-form login flow
10390
- * (`validateCredentials` accepts username + password). */
10391
- hasCredentialFlow: boolean(),
10392
- /** Provider kind, drives admin-UI hint dispatch (oidc / saml / totp / …). */
10393
- kind: string().optional(),
10394
- /** Operator-facing status string (e.g. "Connected to https://login.acme.com"). */
10395
- status: string().optional(),
10396
- /** When false, the provider is registered but disabled by config; the
10397
- * UI surfaces it as inactive without enumerating it for login. */
10398
- enabled: boolean()
10399
- });
10400
- ({
10401
- methods: {
10402
- /** All registered auth providers, both enabled and disabled. */
10403
- listProviders: method(_void(), array(AuthProviderInfoSchema).readonly()),
10404
- /**
10405
- * Toggle a provider's enabled flag. Disabled providers stay
10406
- * registered but aren't surfaced on the login page. The orchestrator
10407
- * persists the state in `addon-settings` so it survives restarts.
10408
- */
10409
- setProviderEnabled: method(
10410
- object({ addonId: string(), enabled: boolean() }),
10411
- object({ success: literal(true) }),
10412
- { kind: "mutation", auth: "admin" }
10413
- )
10414
- }
10415
- });
10416
10391
  const NetworkEndpointSchema = object({
10417
10392
  url: string(),
10418
10393
  hostname: string(),
@@ -10444,55 +10419,13 @@ const NetworkEndpointEntrySchema = NetworkEndpointSchema.extend({
10444
10419
  getEndpoint: method(_void(), NetworkEndpointSchema.nullable()),
10445
10420
  getStatus: method(_void(), NetworkAccessStatusSchema),
10446
10421
  /**
10447
- * Enumerate every active ingress entry. Default implementation (when
10448
- * the provider omits this method) is derived from `getEndpoint()` —
10449
- * see the remote-access orchestrator for the fallback path.
10422
+ * Enumerate every active ingress entry. Providers that expose only a
10423
+ * single endpoint may omit this method; callers fall back to
10424
+ * `getEndpoint()` in that case.
10450
10425
  */
10451
10426
  listEndpoints: method(_void(), array(NetworkEndpointEntrySchema).readonly())
10452
10427
  }
10453
10428
  });
10454
- const RemoteAccessEndpointSchema = object({
10455
- url: string(),
10456
- hostname: string(),
10457
- port: number(),
10458
- protocol: _enum(["http", "https"])
10459
- });
10460
- const RemoteAccessProviderInfoSchema = object({
10461
- /** Stable id matching the addon id. */
10462
- addonId: string(),
10463
- /** Display label shown on the admin row — sourced from the addon manifest. */
10464
- displayName: string(),
10465
- /** When false, the provider is registered but disabled. */
10466
- enabled: boolean(),
10467
- /** True when the underlying tunnel/connection is up. */
10468
- connected: boolean(),
10469
- /** Public-facing endpoint, when connected. Null otherwise. */
10470
- endpoint: RemoteAccessEndpointSchema.nullable(),
10471
- /** Last error message (when connected=false), if available. */
10472
- error: string().optional()
10473
- });
10474
- ({
10475
- methods: {
10476
- /** All registered remote-access providers + their live status. */
10477
- listProviders: method(_void(), array(RemoteAccessProviderInfoSchema).readonly()),
10478
- /**
10479
- * Start a specific provider's tunnel. Per-provider config still
10480
- * lives on the addon's settings panel; this is just the on/off
10481
- * trigger so the admin UI can manage the lifecycle from one place.
10482
- */
10483
- startProvider: method(
10484
- object({ addonId: string() }),
10485
- RemoteAccessEndpointSchema,
10486
- { kind: "mutation", auth: "admin" }
10487
- ),
10488
- /** Stop a specific provider's tunnel (idempotent on already-stopped). */
10489
- stopProvider: method(
10490
- object({ addonId: string() }),
10491
- object({ success: literal(true) }),
10492
- { kind: "mutation", auth: "admin" }
10493
- )
10494
- }
10495
- });
10496
10429
  const TurnServerSchema = object({
10497
10430
  /** Single URL or list of URLs (e.g. "turn:turn.example.com:3478?transport=udp"). */
10498
10431
  urls: union([string(), array(string())]),
@@ -10512,45 +10445,6 @@ const TurnServerSchema = object({
10512
10445
  )
10513
10446
  }
10514
10447
  });
10515
- const TurnProviderInfoSchema = object({
10516
- /** Stable id matching the addon id. */
10517
- addonId: string(),
10518
- /** Display label shown on the admin row — sourced from the addon manifest. */
10519
- displayName: string(),
10520
- /** When false, the provider is registered but disabled. */
10521
- enabled: boolean(),
10522
- /** Number of servers this provider is currently exposing. */
10523
- serverCount: number(),
10524
- /**
10525
- * Flat list of every TURN/STUN URL this provider currently exposes.
10526
- * One row per URL (multi-URL ICE server entries are flattened). The
10527
- * admin UI shows this in a compact per-provider list so operators
10528
- * can verify what's actually being negotiated without having to dig
10529
- * into the combined `getAllServers` output.
10530
- */
10531
- urls: array(string()).readonly(),
10532
- /** Last fetch error (when serverCount=0 due to API failure), if any. */
10533
- error: string().optional()
10534
- });
10535
- ({
10536
- methods: {
10537
- /** All registered TURN providers + per-provider stats. */
10538
- listProviders: method(_void(), array(TurnProviderInfoSchema).readonly()),
10539
- /**
10540
- * Combined list of TURN/STUN servers from all ENABLED providers.
10541
- * Consumed by the WebRTC layer at session-creation time —
10542
- * implementations may fetch fresh short-lived credentials each
10543
- * call (e.g. Cloudflare API), so consumers SHOULD call per-session.
10544
- */
10545
- getAllServers: method(_void(), array(TurnServerSchema).readonly()),
10546
- /** Toggle a provider's enabled flag. */
10547
- setProviderEnabled: method(
10548
- object({ addonId: string(), enabled: boolean() }),
10549
- object({ success: literal(true) }),
10550
- { kind: "mutation", auth: "admin" }
10551
- )
10552
- }
10553
- });
10554
10448
  const SnapshotImageSchema = object({
10555
10449
  base64: string(),
10556
10450
  contentType: string()
@@ -12030,7 +11924,7 @@ const AllowedAddressesSchema = object({
12030
11924
  )
12031
11925
  }
12032
11926
  });
12033
- const MeshEndpointSchema$1 = object({
11927
+ const MeshEndpointSchema = object({
12034
11928
  /** Stable identifier within the provider (e.g. `mesh-ipv4`, `magicdns`, `funnel`). */
12035
11929
  id: string(),
12036
11930
  /** Operator-facing label (e.g. "Mesh IPv4", "MagicDNS"). */
@@ -12103,7 +11997,7 @@ const MeshStatusSchema = object({
12103
11997
  /** Number of peers visible to this host (excluding self). */
12104
11998
  peerCount: number(),
12105
11999
  /** Every endpoint this provider exposes for the current host. */
12106
- endpoints: array(MeshEndpointSchema$1).readonly(),
12000
+ endpoints: array(MeshEndpointSchema).readonly(),
12107
12001
  /** Last error from the daemon, when not joined. */
12108
12002
  error: string().optional(),
12109
12003
  // ── Account / tenant identity (generic across providers) ────────
@@ -12136,7 +12030,25 @@ const MeshStatusSchema = object({
12136
12030
  * doesn't rotate keys for the bound host. Operator-facing surface
12137
12031
  * for "your access expires on …" banners.
12138
12032
  */
12139
- keyExpiry: number().nullable()
12033
+ keyExpiry: number().nullable(),
12034
+ // ── Onboard-daemon handoff (Tailscale, generic slot) ────────────
12035
+ /**
12036
+ * When the provider runs its OWN mesh daemon (e.g. the Tailscale
12037
+ * client addon in `onboard` mode spawns a private `tailscaled`),
12038
+ * this carries the local control-socket path. Companion addons that
12039
+ * must drive the SAME daemon — chiefly `tailscale-ingress` for
12040
+ * Serve/Funnel — read it to point their CLI at the right socket
12041
+ * instead of the system default. Empty when the provider uses the
12042
+ * host's system daemon (or doesn't have the concept).
12043
+ */
12044
+ daemonSocket: string().optional(),
12045
+ /**
12046
+ * Path to the mesh CLI binary the provider downloaded for onboard
12047
+ * mode. Companion addons reuse it so they don't need a system
12048
+ * install when the operator chose a fully self-contained mesh.
12049
+ * Empty in host mode.
12050
+ */
12051
+ daemonCliPath: string().optional()
12140
12052
  });
12141
12053
  ({
12142
12054
  methods: {
@@ -12248,105 +12160,6 @@ const MeshStatusSchema = object({
12248
12160
  // tabs driven by this cap.
12249
12161
  }
12250
12162
  });
12251
- const MeshEndpointSchema = object({
12252
- id: string(),
12253
- label: string(),
12254
- scope: _enum(["mesh", "public"]),
12255
- url: string(),
12256
- hostname: string(),
12257
- port: number(),
12258
- protocol: _enum(["http", "https"])
12259
- });
12260
- const MeshProviderInfoSchema = object({
12261
- /** Stable id matching the addon id. */
12262
- addonId: string(),
12263
- /** Display label shown on the admin row — sourced from the addon manifest. */
12264
- displayName: string(),
12265
- /** True when the host is joined to this provider's mesh. */
12266
- joined: boolean(),
12267
- /** Local mesh IP (empty when not joined). */
12268
- meshIp: string(),
12269
- /** MagicDNS / mesh hostname (empty when not configured). */
12270
- magicDnsHostname: string(),
12271
- /** Peer count (excluding self). */
12272
- peerCount: number(),
12273
- /** Active endpoints (mesh IP + MagicDNS + optional public Funnel). */
12274
- endpoints: array(MeshEndpointSchema).readonly(),
12275
- /** Last error reported by the provider. */
12276
- error: string().optional(),
12277
- // ── Generic identity fields mirrored from MeshStatus ─────────────
12278
- /** Tenant / tailnet / network display name. Empty pre-join. */
12279
- tenantName: string(),
12280
- /** Mesh DNS suffix (e.g. tailXXXX.ts.net). Empty when not configured. */
12281
- magicDnsSuffix: string(),
12282
- /** Authenticated user / account login. Null for token-only providers. */
12283
- userLogin: string().nullable(),
12284
- /** Provider control-plane URL. */
12285
- controlPlaneUrl: string(),
12286
- /** Machine-key expiry (epoch ms). Null when keys don't rotate. */
12287
- keyExpiry: number().nullable()
12288
- });
12289
- ({
12290
- methods: {
12291
- /** All registered mesh-network providers + live status. */
12292
- listProviders: method(_void(), array(MeshProviderInfoSchema).readonly()),
12293
- /**
12294
- * Join the mesh of a specific provider. Per-provider config still
12295
- * lives on its settings panel; the orchestrator forwards.
12296
- */
12297
- joinProvider: method(
12298
- object({
12299
- addonId: string(),
12300
- authKey: string().min(8),
12301
- hostname: string().optional()
12302
- }),
12303
- object({ joined: literal(true) }),
12304
- { kind: "mutation" }
12305
- ),
12306
- leaveProvider: method(
12307
- object({ addonId: string() }),
12308
- object({ success: literal(true) }),
12309
- { kind: "mutation" }
12310
- ),
12311
- /**
12312
- * Browser-redirect login flow. Forwards to the named provider's
12313
- * `mesh-network.startLogin` and returns the URL the daemon
12314
- * prints. UI opens it in a new tab, then polls `listProviders`
12315
- * for `joined: true`.
12316
- */
12317
- startLoginProvider: method(
12318
- object({
12319
- addonId: string(),
12320
- hostname: string().optional()
12321
- }),
12322
- object({ loginUrl: string() }),
12323
- { kind: "mutation" }
12324
- ),
12325
- /**
12326
- * Sign out of the provider's account entirely (`mesh-network.logout`).
12327
- * Distinct from `leaveProvider` which only takes the host off-mesh;
12328
- * `logoutProvider` wipes credentials so the next start requires a
12329
- * fresh login.
12330
- */
12331
- logoutProvider: method(
12332
- object({ addonId: string() }),
12333
- object({ loggedOut: literal(true) }),
12334
- { kind: "mutation" }
12335
- ),
12336
- /**
12337
- * Per-provider peer list. Forwards to `mesh-network.listPeers` on
12338
- * the addressed provider. Separate from `listProviders` because
12339
- * peer payloads can be large on a heavily-populated tailnet —
12340
- * fetch only when the operator opens the Peers tab.
12341
- */
12342
- listProviderPeers: method(
12343
- object({ addonId: string() }),
12344
- object({
12345
- peers: array(MeshPeerSchema).readonly()
12346
- })
12347
- )
12348
- }
12349
- });
12350
12163
  const MethodAccessSchema = _enum(["view", "create", "delete"]);
12351
12164
  const AllowedProviderSchema = union([literal("*"), array(string())]);
12352
12165
  const AllowedDevicesSchema = record(string(), union([literal("*"), array(string())]));
@@ -13022,6 +12835,21 @@ const AddonAutoUpdateSchema = ChannelWithInheritSchema;
13022
12835
  const RestartAddonResultSchema = unknown();
13023
12836
  const InstallPackageResultSchema = unknown();
13024
12837
  const ReloadPackagesResultSchema = unknown();
12838
+ const UpdateFrameworkPackageResultSchema = object({
12839
+ packageName: string(),
12840
+ fromVersion: string(),
12841
+ toVersion: string(),
12842
+ /** Ms-epoch the server scheduled its self-restart. */
12843
+ restartingAt: number()
12844
+ });
12845
+ const FrameworkPackageStatusSchema = object({
12846
+ packageName: string(),
12847
+ currentVersion: string(),
12848
+ latestVersion: string().nullable(),
12849
+ hasUpdate: boolean(),
12850
+ /** Optional manifest description for the row tooltip. */
12851
+ description: string().optional()
12852
+ });
13025
12853
  const LogStreamEntrySchema = object({
13026
12854
  timestamp: string(),
13027
12855
  level: string(),
@@ -13081,13 +12909,29 @@ const CustomActionInputSchema = object({
13081
12909
  object({ query: string().optional() }),
13082
12910
  array(SearchResultSchema)
13083
12911
  ),
12912
+ /**
12913
+ * Available package updates for a node. `nodeId` omitted (or
12914
+ * `'hub'`) checks the hub's own installed packages; an agent
12915
+ * `nodeId` checks that agent's installed roster against npm
12916
+ * (the hub does the npm lookups + diff — agents stay npm-free).
12917
+ */
13084
12918
  listUpdates: method(
13085
- _void(),
12919
+ object({ nodeId: string().optional() }),
13086
12920
  array(PackageUpdateSchema).readonly(),
13087
12921
  { auth: "admin" }
13088
12922
  ),
12923
+ /**
12924
+ * Update one package on a node. `nodeId` omitted (or `'hub'`)
12925
+ * installs on the hub via npm; an agent `nodeId` makes the hub
12926
+ * pack the resolved version and push the tarball to that agent
12927
+ * (`$agent.deploy` + `$agent.reload`) — agents need no npm runtime.
12928
+ */
13089
12929
  updatePackage: method(
13090
- object({ name: string().min(1), version: string().optional() }),
12930
+ object({
12931
+ name: string().min(1),
12932
+ version: string().optional(),
12933
+ nodeId: string().optional()
12934
+ }),
13091
12935
  unknown(),
13092
12936
  { kind: "mutation", auth: "admin" }
13093
12937
  ),
@@ -13108,12 +12952,128 @@ const CustomActionInputSchema = object({
13108
12952
  object({ rolledBackTo: string().nullable() }),
13109
12953
  { kind: "mutation", auth: "admin" }
13110
12954
  ),
13111
- forceRefresh: method(_void(), unknown(), { kind: "mutation", auth: "admin" }),
12955
+ /** Re-check updates for a node, bypassing any cache. `nodeId`
12956
+ * omitted (or `'hub'`) refreshes the hub; an agent `nodeId`
12957
+ * re-checks that agent's roster. */
12958
+ forceRefresh: method(
12959
+ object({ nodeId: string().optional() }),
12960
+ unknown(),
12961
+ { kind: "mutation", auth: "admin" }
12962
+ ),
13112
12963
  restartServer: method(
13113
12964
  object({ confirm: literal(true) }),
13114
12965
  unknown(),
13115
12966
  { kind: "mutation", auth: "admin" }
13116
12967
  ),
12968
+ /**
12969
+ * Most-recent restart marker (kind / packageName / from→to versions
12970
+ * / requestedBy / requestedAt). Returns `null` when this process
12971
+ * didn't boot from a tracked restart, or when the
12972
+ * post-boot retention window (5 min) has elapsed.
12973
+ *
12974
+ * Drives the admin-UI reconnect overlay's success toast — the
12975
+ * `system.restart-completed` event itself is fired before the
12976
+ * client has time to re-subscribe, so the client queries this on
12977
+ * first reconnect instead.
12978
+ */
12979
+ getLastRestart: method(
12980
+ _void(),
12981
+ object({
12982
+ kind: _enum(["framework-update", "manual", "system"]),
12983
+ packageName: string().optional(),
12984
+ fromVersion: string().optional(),
12985
+ toVersion: string().optional(),
12986
+ requestedBy: string().optional(),
12987
+ requestedAt: number()
12988
+ }).nullable(),
12989
+ { auth: "admin" }
12990
+ ),
12991
+ /**
12992
+ * Snapshot of the framework packages installed under the hub's
12993
+ * `<appRoot>/node_modules/`. Each row carries the currently
12994
+ * installed version and (best-effort) the latest version
12995
+ * available on npm. Drives the admin-UI "System packages" panel.
12996
+ *
12997
+ * Spec: docs/superpowers/specs/2026-05-14-framework-live-update-design.md
12998
+ */
12999
+ listFrameworkPackages: method(
13000
+ _void(),
13001
+ array(FrameworkPackageStatusSchema).readonly(),
13002
+ { auth: "admin" }
13003
+ ),
13004
+ /**
13005
+ * Cluster-wide capability-provider discovery. Returns the list of
13006
+ * `{ addonId, mode, isActive }` tuples for whatever addon(s)
13007
+ * currently provide the requested capability across the cluster.
13008
+ *
13009
+ * Why this lives on `addons` (and not on a `capabilities` cap of
13010
+ * its own): the hub's main-process `CapabilityRegistry` already
13011
+ * aggregates registrations from every forked group-runner and
13012
+ * remote agent via Moleculer event propagation — there's no
13013
+ * cross-process registry mirror to build, just an introspection
13014
+ * shim.
13015
+ *
13016
+ * Use this from addon code when you need to know whether another
13017
+ * addon has registered a specific cap (e.g. `tailscale-ingress`
13018
+ * checking `tailscale-client` is up before calling `tailscale
13019
+ * serve`). Don't reach for `ctx.capabilities.getCollectionEntries`
13020
+ * — that reads the LOCAL registry of the calling addon's group
13021
+ * runner and never sees providers in other processes. See
13022
+ * `CLAUDE.md` → Critical rules → ctx.api vs ctx.capabilities.
13023
+ */
13024
+ listCapabilityProviders: method(
13025
+ object({ capName: string().min(1) }),
13026
+ array(object({
13027
+ addonId: string(),
13028
+ mode: _enum(["singleton", "collection"]),
13029
+ isActive: boolean()
13030
+ })).readonly()
13031
+ ),
13032
+ /**
13033
+ * Toggle a single collection-cap provider on/off. Generic write-side
13034
+ * counterpart of `listCapabilityProviders` — drives the per-provider
13035
+ * Enable/Disable affordance in admin pages (TURN servers, etc.)
13036
+ * without needing a bespoke orchestrator cap.
13037
+ *
13038
+ * Reaches the hub's `CapabilityRegistry` directly:
13039
+ * `enableCollectionProvider` / `disableCollectionProvider` flip the
13040
+ * registry-level `disabledProviders` set. `getCollectionEntries`
13041
+ * already filters disabled providers out, so a disabled provider
13042
+ * drops out of every collection aggregate immediately. Only valid
13043
+ * for `mode: 'collection'` caps — the registry no-ops + warns for
13044
+ * singletons.
13045
+ */
13046
+ setCapabilityProviderEnabled: method(
13047
+ object({
13048
+ capName: string().min(1),
13049
+ addonId: string().min(1),
13050
+ enabled: boolean()
13051
+ }),
13052
+ object({ success: literal(true) }),
13053
+ { kind: "mutation", auth: "admin" }
13054
+ ),
13055
+ /**
13056
+ * Live-update one of the framework packages marked
13057
+ * `camstack.system: true` (`@camstack/types|kernel|core|sdk|ui-library`).
13058
+ * Runs `npm install --prefix <appRoot> <name>@<version> --no-save`,
13059
+ * writes a `.restart-pending` marker, emits `system.restarting`
13060
+ * and schedules a graceful process exit. The supervisor (Docker /
13061
+ * Electron / systemd) brings the hub back up; on first boot after
13062
+ * the restart the marker fires `system.restart-completed`.
13063
+ *
13064
+ * `version` defaults to `'latest'`. The allow-list of valid
13065
+ * `packageName` values is enforced server-side.
13066
+ *
13067
+ * Spec: docs/superpowers/specs/2026-05-14-framework-live-update-design.md
13068
+ */
13069
+ updateFrameworkPackage: method(
13070
+ object({
13071
+ packageName: string().min(1),
13072
+ version: string().optional()
13073
+ }),
13074
+ UpdateFrameworkPackageResultSchema,
13075
+ { kind: "mutation", auth: "admin" }
13076
+ ),
13117
13077
  getVersions: method(
13118
13078
  object({ name: string() }),
13119
13079
  array(PackageVersionInfoSchema).readonly()
@@ -13184,6 +13144,7 @@ var EventCategory = /* @__PURE__ */ ((EventCategory2) => {
13184
13144
  EventCategory2["SystemBoot"] = "system.boot";
13185
13145
  EventCategory2["SystemAddonsReady"] = "system.addons-ready";
13186
13146
  EventCategory2["SystemRestarting"] = "system.restarting";
13147
+ EventCategory2["SystemRestartCompleted"] = "system.restart-completed";
13187
13148
  EventCategory2["SystemReadyState"] = "system.ready-state";
13188
13149
  EventCategory2["AddonStarted"] = "addon.started";
13189
13150
  EventCategory2["AddonStopped"] = "addon.stopped";