@camstack/addon-provider-rtsp 1.2.35 → 1.2.37

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/dist/addon.js +255 -25
  2. package/dist/addon.mjs +255 -25
  3. package/package.json +1 -1
package/dist/addon.js CHANGED
@@ -23,7 +23,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
23
23
  //#endregion
24
24
  let node_net = require("node:net");
25
25
  node_net = __toESM(node_net);
26
- //#region ../types/dist/event-category-CIa_iT6b.mjs
26
+ //#region ../types/dist/event-category-BZL-fdNj.mjs
27
27
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
28
28
  EventCategory["SystemBoot"] = "system.boot";
29
29
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -460,7 +460,7 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
460
460
  EventCategory["MetricsNodeResourcesSnapshot"] = "metrics.node-resources-snapshot";
461
461
  /**
462
462
  * Periodic per-node process-tree snapshot (camstack-related pids
463
- * with ghost / managed / root classification). Emitted ~0.2 Hz by
463
+ * with root / managed / system classification). Emitted ~0.2 Hz by
464
464
  * the metrics-provider addon. Drives the Cluster → Processes tab
465
465
  * without polling `metricsProvider.listNodeProcesses`.
466
466
  */
@@ -11284,6 +11284,19 @@ var SettingsRecordSchema = object({
11284
11284
  data: record(string(), unknown())
11285
11285
  });
11286
11286
  /**
11287
+ * One record of a BULK insert — {@link SettingsRecordSchema} with the id made
11288
+ * optional.
11289
+ *
11290
+ * A separate schema rather than loosening the shared one: every other method
11291
+ * on this cap addresses a row BY its id, and making that field optional
11292
+ * everywhere would turn a forgotten key into a silently generated one on
11293
+ * `update` and `delete` as well.
11294
+ */
11295
+ var BulkRecordSchema = object({
11296
+ id: string().optional(),
11297
+ data: record(string(), unknown())
11298
+ });
11299
+ /**
11287
11300
  * Column declaration for a structured (SQL-backed) collection.
11288
11301
  *
11289
11302
  * Logical types — the backend translates each to the matching SQLite
@@ -11340,6 +11353,10 @@ method(object({
11340
11353
  collection: string(),
11341
11354
  record: SettingsRecordSchema
11342
11355
  }), _void(), { kind: "mutation" }), method(object({
11356
+ namespace: string().optional(),
11357
+ collection: string(),
11358
+ records: array(BulkRecordSchema).readonly()
11359
+ }), object({ inserted: number().int() }), { kind: "mutation" }), method(object({
11343
11360
  namespace: string().optional(),
11344
11361
  collection: string(),
11345
11362
  id: string(),
@@ -11448,6 +11465,13 @@ method(_void(), EngineInfoSchema, { auth: "admin" }), method(object({
11448
11465
  }), _void(), {
11449
11466
  kind: "mutation",
11450
11467
  auth: "admin"
11468
+ }), method(object({
11469
+ namespace: string().optional(),
11470
+ collection: string(),
11471
+ records: array(BulkRecordSchema).readonly()
11472
+ }), object({ inserted: number().int() }), {
11473
+ kind: "mutation",
11474
+ auth: "admin"
11451
11475
  }), method(object({
11452
11476
  namespace: string().optional(),
11453
11477
  collection: string(),
@@ -13378,6 +13402,68 @@ method(LogEntrySchema, _void(), { kind: "mutation" }), method(object({
13378
13402
  limit: number().optional(),
13379
13403
  tags: record(string(), string()).optional()
13380
13404
  }), array(LogEntrySchema).readonly());
13405
+ var LoadContributionSchema = object({
13406
+ role: _enum([
13407
+ "decode",
13408
+ "transcode",
13409
+ "recording",
13410
+ "streaming",
13411
+ "detection"
13412
+ ]),
13413
+ /**
13414
+ * The NUMERIC device id — the same value every log line carries as
13415
+ * `tags.deviceId`. `null` means this cost genuinely belongs to no single
13416
+ * camera (a shared pool), NOT that the contributor forgot to look it up: a
13417
+ * contributor that cannot name its camera must not emit the entry at all,
13418
+ * because an unnamed per-camera entry is indistinguishable from a shared one
13419
+ * and would quietly turn one camera's cost into everybody's.
13420
+ */
13421
+ deviceId: number().int().positive().nullable(),
13422
+ attribution: _enum([
13423
+ "measured",
13424
+ "accounted",
13425
+ "unattributable"
13426
+ ]),
13427
+ /**
13428
+ * What ONE entry is, in the contributor's own words — `615/high`,
13429
+ * `617/native`, `cuda:0 shared pool`. Free text because the unit differs per
13430
+ * family and inventing a common one would lose the only information that
13431
+ * makes two entries for the same camera distinguishable.
13432
+ */
13433
+ unit: string(),
13434
+ /**
13435
+ * The OS process this cost lives in, when there is one. Present so a
13436
+ * consumer can (a) tell two generations of the same unit apart across a
13437
+ * restart, and (b) subtract claimed processes from the node's process
13438
+ * snapshot to see what NOBODY claimed. Absent for an entry that owns no
13439
+ * process of its own.
13440
+ */
13441
+ pid: number().int().positive().optional(),
13442
+ /**
13443
+ * When this generation started. The pid's incarnation marker: a consumer
13444
+ * differencing {@link LoadContributionSchema.shape.cpuSeconds} must drop the
13445
+ * window when this changes, because the counter restarted from zero in a new
13446
+ * process.
13447
+ */
13448
+ startedAtMs: number().optional(),
13449
+ /**
13450
+ * CUMULATIVE CPU seconds this unit has consumed since it started — user +
13451
+ * system, read from the child's own `/proc/<pid>/stat` at the moment the
13452
+ * contribution is asked for.
13453
+ *
13454
+ * Cumulative and not a rate on purpose: a rate needs a window, a window
13455
+ * needs a sampler, and a new per-node sampler is the defect half of
13456
+ * `docs/architecture/load-ledger.md` documents. A counter can be differenced
13457
+ * by whoever already keeps a history; a rate cannot be un-averaged.
13458
+ *
13459
+ * Absent — never zero — on a node with no `/proc`, on a read failure, and on
13460
+ * an entry with no process.
13461
+ */
13462
+ cpuSeconds: number().optional(),
13463
+ /** Resident bytes of this unit's process, same source and same rules. */
13464
+ rssBytes: number().optional()
13465
+ });
13466
+ method(_void(), array(LoadContributionSchema).readonly());
13381
13467
  /**
13382
13468
  * `login-method` — collection cap through which auth addons contribute
13383
13469
  * their pre-auth login surfaces to the login page. This is the SINGLE,
@@ -13581,8 +13667,7 @@ var NodeProcessSchema = object({
13581
13667
  classification: _enum([
13582
13668
  "root",
13583
13669
  "managed",
13584
- "system",
13585
- "ghost"
13670
+ "system"
13586
13671
  ]),
13587
13672
  /** `$process` addon binding when `managed`, else null. */
13588
13673
  addonId: string().nullable(),
@@ -13590,22 +13675,39 @@ var NodeProcessSchema = object({
13590
13675
  nodeId: string().nullable(),
13591
13676
  /** Truncated command line. */
13592
13677
  command: string(),
13678
+ /**
13679
+ * `ps pcpu` — CPU averaged over the process's WHOLE LIFETIME, not a rate.
13680
+ * On a runner up for days it barely moves. Fine as a column, useless as a
13681
+ * series: use `cpuMainPercent + cpuGcPercent` for anything time-varying.
13682
+ */
13593
13683
  cpuPercent: number(),
13594
13684
  memoryRssBytes: number(),
13685
+ /**
13686
+ * Instantaneous CPU% of the process's own threads over the last
13687
+ * process-snapshot window, from a `/proc/<pid>/task/*` tick delta.
13688
+ *
13689
+ * `null` = UNKNOWN, never zero: no previous sample yet (first tick after
13690
+ * boot), the pid was recycled, or this node is not Linux.
13691
+ */
13692
+ cpuMainPercent: number().nullable(),
13693
+ /**
13694
+ * Instantaneous CPU% of V8's `V8Worker` platform pool over the same window.
13695
+ *
13696
+ * This is the number that rewrote the 2026-08-27 diagnosis — hub-main 73%,
13697
+ * `stream-broker` 61% (`docs/architecture/load-ledger.md`). A CPU chart that
13698
+ * does not separate it from `cpuMainPercent` shows "busy" where the truth is
13699
+ * "allocating too much".
13700
+ *
13701
+ * Concurrent GC is the dominant tenant of that pool but not the only one
13702
+ * (background compilation runs there too), so it is reported as
13703
+ * "GC / V8 helpers" rather than as pure collection time. `null` has the same
13704
+ * meaning as on `cpuMainPercent`.
13705
+ */
13706
+ cpuGcPercent: number().nullable(),
13707
+ /** Threads seen in the tick scan. `null` under the same conditions. */
13708
+ threadCount: number().nullable(),
13595
13709
  /** Wall-clock uptime (seconds). Parsed from `ps etime`. */
13596
- uptimeSec: number(),
13597
- /** True when ancestor walk reaches `ppid=1` (reparented to init/launchd). */
13598
- orphaned: boolean()
13599
- });
13600
- var KillProcessInputSchema = object({
13601
- pid: number(),
13602
- /** Force = SIGKILL. Default is SIGTERM. */
13603
- force: boolean().optional()
13604
- });
13605
- var KillProcessResultSchema = object({
13606
- success: boolean(),
13607
- reason: string().optional(),
13608
- signal: _enum(["SIGTERM", "SIGKILL"]).optional()
13710
+ uptimeSec: number()
13609
13711
  });
13610
13712
  var DumpHeapSnapshotInputSchema = object({
13611
13713
  /** The addon whose runner should dump a heap snapshot. */
@@ -13618,6 +13720,104 @@ var DumpHeapSnapshotResultSchema = object({
13618
13720
  pid: number().optional(),
13619
13721
  reason: string().optional()
13620
13722
  });
13723
+ /**
13724
+ * One point of one function's series.
13725
+ *
13726
+ * The unsuffixed fields are the bucket's **MAXIMUM**, and that choice is the
13727
+ * point of the whole surface. The two obvious reductions both lie: a mean per
13728
+ * bucket smears a spike away, and taking every Nth sample skips it outright.
13729
+ * Either would give us a tool built to find peaks that does not show peaks.
13730
+ * `...Min` carries the other end, `samples` says how many raw snapshots folded
13731
+ * into the bucket, and a mean stays derivable where it is wanted.
13732
+ *
13733
+ * An UNREDUCED point is a one-sample bucket: `samples === 1` and each `...Min`
13734
+ * equals its unsuffixed twin. Reduced and unreduced are the same shape, so a
13735
+ * caller cannot tell which it received — which is what "one reader" means.
13736
+ */
13737
+ var LoadPointSchema = object({
13738
+ /** Bucket START, or the snapshot's own timestamp when unreduced. */
13739
+ atMs: number(),
13740
+ /** Raw snapshots in this bucket. Never 0 — AN EMPTY BUCKET IS ABSENT. */
13741
+ samples: number().int(),
13742
+ /**
13743
+ * `null` = UNKNOWN and it PROPAGATES: a bucket is null unless every process
13744
+ * of every snapshot in it reported a thread split. A partial sum is a
13745
+ * smaller number that looks exactly as real as a complete one.
13746
+ */
13747
+ cpuMainPercent: number().nullable(),
13748
+ cpuMainPercentMin: number().nullable(),
13749
+ cpuGcPercent: number().nullable(),
13750
+ cpuGcPercentMin: number().nullable(),
13751
+ /** Lifetime-average CPU%, summed. Always known — and never a rate. */
13752
+ cpuLifetimePercent: number(),
13753
+ cpuLifetimePercentMin: number(),
13754
+ memoryRssBytes: number(),
13755
+ memoryRssBytesMin: number(),
13756
+ processCount: number().int(),
13757
+ processCountMin: number().int()
13758
+ });
13759
+ /** One function's series. `key` is an addonId, `__root__` or `__unattributed__`. */
13760
+ var LoadFunctionSeriesSchema = object({
13761
+ key: string(),
13762
+ kind: _enum([
13763
+ "addon",
13764
+ "root",
13765
+ "unattributed"
13766
+ ]),
13767
+ /** Oldest-first. A missing interval is MISSING — never zero-filled. */
13768
+ points: array(LoadPointSchema).readonly()
13769
+ });
13770
+ var NodeLoadSeriesSchema = object({
13771
+ nodeId: string(),
13772
+ /** One entry per function seen in the window, heaviest-first. */
13773
+ series: array(LoadFunctionSeriesSchema).readonly(),
13774
+ /**
13775
+ * Width of one returned bucket, in ms. Equals the sampling cadence when no
13776
+ * reduction was needed — so a caller can always say what one point covers
13777
+ * without having to know whether it was reduced.
13778
+ */
13779
+ bucketMs: number(),
13780
+ /** Raw snapshots that went into this answer, across both tiers. */
13781
+ retainedSamples: number(),
13782
+ /** Oldest snapshot represented, or `null` when nothing is retained. */
13783
+ oldestAtMs: number().nullable(),
13784
+ /** The fixed sampling cadence in force on the cluster, in ms. */
13785
+ cadenceMs: number(),
13786
+ /**
13787
+ * Did the DURABLE tier contribute? `false` means the answer is the hot ring
13788
+ * alone — an agent (which holds no table), or a store that refused.
13789
+ * Reported because "the last hour" and "the last six hours" are different
13790
+ * questions and an operator must not have to guess which was answered.
13791
+ */
13792
+ durable: boolean()
13793
+ });
13794
+ var GetLoadSeriesInputSchema = object({
13795
+ /**
13796
+ * The node whose series is wanted.
13797
+ *
13798
+ * NOT named `nodeId`: the generated cap router strips a top-level
13799
+ * `nodeId` from every method input and uses it to ROUTE the call to
13800
+ * that node's provider (`generated-cap-routers.ts`). A series target
13801
+ * called `nodeId` would silently become a routing pin and never reach
13802
+ * the provider. The hub holds every node it hears from, so the
13803
+ * ordinary call is unpinned — answered by the hub, for any node.
13804
+ */
13805
+ forNodeId: string(),
13806
+ /**
13807
+ * EXCLUSIVE lower bound. A caller passes the newest `atMs` it already
13808
+ * holds and receives only what it is missing, so seeding a live chart
13809
+ * from this method cannot double a point already drawn.
13810
+ */
13811
+ sinceMs: number().optional(),
13812
+ /**
13813
+ * Most points the caller wants PER FUNCTION. The window is reduced to fit,
13814
+ * preserving min and max per bucket.
13815
+ *
13816
+ * Absent means NO reduction — legitimate for a short window and a trap for a
13817
+ * long one, which is why a chart passes its own pixel width.
13818
+ */
13819
+ maxPoints: number().int().positive().optional()
13820
+ });
13621
13821
  var SystemMetricsSchema = object({
13622
13822
  cpuPercent: number(),
13623
13823
  memoryPercent: number(),
@@ -13628,10 +13828,7 @@ var SystemMetricsSchema = object({
13628
13828
  gpuPercent: number().optional(),
13629
13829
  gpuMemoryPercent: number().optional()
13630
13830
  });
13631
- method(_void(), SystemResourceSnapshotSchema), method(_void(), SystemResourceSnapshotSchema.nullable()), method(_void(), SystemMetricsSchema), method(object({ dirPath: string() }), DiskSpaceInfoSchema), method(_void(), MetricsGpuInfoSchema.nullable()), method(_void(), number().nullable()), method(object({ pids: array(number()) }), array(PidResourceStatsSchema)), method(_void(), array(AddonInstanceSchema).readonly()), method(object({ addonId: string() }), PidResourceStatsSchema.nullable()), method(_void(), array(NodeProcessSchema).readonly()), method(KillProcessInputSchema, KillProcessResultSchema, {
13632
- kind: "mutation",
13633
- auth: "admin"
13634
- }), method(DumpHeapSnapshotInputSchema, DumpHeapSnapshotResultSchema, {
13831
+ method(_void(), SystemResourceSnapshotSchema), method(_void(), SystemResourceSnapshotSchema.nullable()), method(_void(), SystemMetricsSchema), method(object({ dirPath: string() }), DiskSpaceInfoSchema), method(_void(), MetricsGpuInfoSchema.nullable()), method(_void(), number().nullable()), method(object({ pids: array(number()) }), array(PidResourceStatsSchema)), method(_void(), array(AddonInstanceSchema).readonly()), method(object({ addonId: string() }), PidResourceStatsSchema.nullable()), method(_void(), array(NodeProcessSchema).readonly()), method(GetLoadSeriesInputSchema, NodeLoadSeriesSchema), method(DumpHeapSnapshotInputSchema, DumpHeapSnapshotResultSchema, {
13635
13832
  kind: "mutation",
13636
13833
  auth: "admin"
13637
13834
  });
@@ -29073,6 +29270,15 @@ var LoggingSettingsPatchSchema = object({
29073
29270
  * authority over the whole hierarchy and answers for every layer, so the
29074
29271
  * layer selector needs a name the transport does not already own.
29075
29272
  */
29273
+ /**
29274
+ * One contribution, plus WHO reported it.
29275
+ *
29276
+ * The addon and node are added by the hub as it enumerates providers, never by
29277
+ * the contributor: an addon reporting its own identity could report somebody
29278
+ * else's, and the whole point of this surface is that no claim is made by
29279
+ * anyone but its owner.
29280
+ */
29281
+ var ReportedLoadContributionSchema = LoadContributionSchema.extend({ addonId: string() });
29076
29282
  var GetLoggingSettingsInputSchema = object({
29077
29283
  scopeNodeId: string().optional(),
29078
29284
  /**
@@ -29131,7 +29337,7 @@ method(_void(), FeatureManifestSchema), method(_void(), HealthStatusSchema), met
29131
29337
  }), method(_void(), SiteLocationStatusSchema, {
29132
29338
  kind: "mutation",
29133
29339
  auth: "admin"
29134
- }), method(_void(), RequestCensusStatusSchema, { auth: "admin" }), method(GetLoggingSettingsInputSchema, LoggingSettingsStateSchema, { auth: "admin" }), method(SetLoggingSettingsInputSchema, LoggingSettingsStateSchema, {
29340
+ }), method(_void(), RequestCensusStatusSchema, { auth: "admin" }), method(_void(), array(ReportedLoadContributionSchema).readonly(), { auth: "admin" }), method(GetLoggingSettingsInputSchema, LoggingSettingsStateSchema, { auth: "admin" }), method(SetLoggingSettingsInputSchema, LoggingSettingsStateSchema, {
29135
29341
  kind: "mutation",
29136
29342
  auth: "admin"
29137
29343
  });
@@ -32221,6 +32427,12 @@ Object.freeze({
32221
32427
  addonId: null,
32222
32428
  access: "create"
32223
32429
  },
32430
+ "dataStoreProvider.insertMany": {
32431
+ capName: "data-store-provider",
32432
+ capScope: "system",
32433
+ addonId: null,
32434
+ access: "create"
32435
+ },
32224
32436
  "dataStoreProvider.isEmpty": {
32225
32437
  capName: "data-store-provider",
32226
32438
  capScope: "system",
@@ -33535,6 +33747,12 @@ Object.freeze({
33535
33747
  addonId: null,
33536
33748
  access: "create"
33537
33749
  },
33750
+ "loadContribution.list": {
33751
+ capName: "load-contribution",
33752
+ capScope: "system",
33753
+ addonId: null,
33754
+ access: "view"
33755
+ },
33538
33756
  "localNetwork.downloadCa": {
33539
33757
  capName: "local-network",
33540
33758
  capScope: "system",
@@ -33835,17 +34053,17 @@ Object.freeze({
33835
34053
  addonId: null,
33836
34054
  access: "view"
33837
34055
  },
33838
- "metricsProvider.getProcessStats": {
34056
+ "metricsProvider.getLoadSeries": {
33839
34057
  capName: "metrics-provider",
33840
34058
  capScope: "system",
33841
34059
  addonId: null,
33842
34060
  access: "view"
33843
34061
  },
33844
- "metricsProvider.killProcess": {
34062
+ "metricsProvider.getProcessStats": {
33845
34063
  capName: "metrics-provider",
33846
34064
  capScope: "system",
33847
34065
  addonId: null,
33848
- access: "create"
34066
+ access: "view"
33849
34067
  },
33850
34068
  "metricsProvider.listAddonInstances": {
33851
34069
  capName: "metrics-provider",
@@ -35857,6 +36075,12 @@ Object.freeze({
35857
36075
  addonId: null,
35858
36076
  access: "create"
35859
36077
  },
36078
+ "settingsStore.insertMany": {
36079
+ capName: "settings-store",
36080
+ capScope: "system",
36081
+ addonId: null,
36082
+ access: "create"
36083
+ },
35860
36084
  "settingsStore.isEmpty": {
35861
36085
  capName: "settings-store",
35862
36086
  capScope: "system",
@@ -36469,6 +36693,12 @@ Object.freeze({
36469
36693
  addonId: null,
36470
36694
  access: "create"
36471
36695
  },
36696
+ "system.getLoadContributions": {
36697
+ capName: "system",
36698
+ capScope: "system",
36699
+ addonId: null,
36700
+ access: "view"
36701
+ },
36472
36702
  "system.getLoggingSettings": {
36473
36703
  capName: "system",
36474
36704
  capScope: "system",
package/dist/addon.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import net from "node:net";
2
- //#region ../types/dist/event-category-CIa_iT6b.mjs
2
+ //#region ../types/dist/event-category-BZL-fdNj.mjs
3
3
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
4
4
  EventCategory["SystemBoot"] = "system.boot";
5
5
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -436,7 +436,7 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
436
436
  EventCategory["MetricsNodeResourcesSnapshot"] = "metrics.node-resources-snapshot";
437
437
  /**
438
438
  * Periodic per-node process-tree snapshot (camstack-related pids
439
- * with ghost / managed / root classification). Emitted ~0.2 Hz by
439
+ * with root / managed / system classification). Emitted ~0.2 Hz by
440
440
  * the metrics-provider addon. Drives the Cluster → Processes tab
441
441
  * without polling `metricsProvider.listNodeProcesses`.
442
442
  */
@@ -11260,6 +11260,19 @@ var SettingsRecordSchema = object({
11260
11260
  data: record(string(), unknown())
11261
11261
  });
11262
11262
  /**
11263
+ * One record of a BULK insert — {@link SettingsRecordSchema} with the id made
11264
+ * optional.
11265
+ *
11266
+ * A separate schema rather than loosening the shared one: every other method
11267
+ * on this cap addresses a row BY its id, and making that field optional
11268
+ * everywhere would turn a forgotten key into a silently generated one on
11269
+ * `update` and `delete` as well.
11270
+ */
11271
+ var BulkRecordSchema = object({
11272
+ id: string().optional(),
11273
+ data: record(string(), unknown())
11274
+ });
11275
+ /**
11263
11276
  * Column declaration for a structured (SQL-backed) collection.
11264
11277
  *
11265
11278
  * Logical types — the backend translates each to the matching SQLite
@@ -11316,6 +11329,10 @@ method(object({
11316
11329
  collection: string(),
11317
11330
  record: SettingsRecordSchema
11318
11331
  }), _void(), { kind: "mutation" }), method(object({
11332
+ namespace: string().optional(),
11333
+ collection: string(),
11334
+ records: array(BulkRecordSchema).readonly()
11335
+ }), object({ inserted: number().int() }), { kind: "mutation" }), method(object({
11319
11336
  namespace: string().optional(),
11320
11337
  collection: string(),
11321
11338
  id: string(),
@@ -11424,6 +11441,13 @@ method(_void(), EngineInfoSchema, { auth: "admin" }), method(object({
11424
11441
  }), _void(), {
11425
11442
  kind: "mutation",
11426
11443
  auth: "admin"
11444
+ }), method(object({
11445
+ namespace: string().optional(),
11446
+ collection: string(),
11447
+ records: array(BulkRecordSchema).readonly()
11448
+ }), object({ inserted: number().int() }), {
11449
+ kind: "mutation",
11450
+ auth: "admin"
11427
11451
  }), method(object({
11428
11452
  namespace: string().optional(),
11429
11453
  collection: string(),
@@ -13354,6 +13378,68 @@ method(LogEntrySchema, _void(), { kind: "mutation" }), method(object({
13354
13378
  limit: number().optional(),
13355
13379
  tags: record(string(), string()).optional()
13356
13380
  }), array(LogEntrySchema).readonly());
13381
+ var LoadContributionSchema = object({
13382
+ role: _enum([
13383
+ "decode",
13384
+ "transcode",
13385
+ "recording",
13386
+ "streaming",
13387
+ "detection"
13388
+ ]),
13389
+ /**
13390
+ * The NUMERIC device id — the same value every log line carries as
13391
+ * `tags.deviceId`. `null` means this cost genuinely belongs to no single
13392
+ * camera (a shared pool), NOT that the contributor forgot to look it up: a
13393
+ * contributor that cannot name its camera must not emit the entry at all,
13394
+ * because an unnamed per-camera entry is indistinguishable from a shared one
13395
+ * and would quietly turn one camera's cost into everybody's.
13396
+ */
13397
+ deviceId: number().int().positive().nullable(),
13398
+ attribution: _enum([
13399
+ "measured",
13400
+ "accounted",
13401
+ "unattributable"
13402
+ ]),
13403
+ /**
13404
+ * What ONE entry is, in the contributor's own words — `615/high`,
13405
+ * `617/native`, `cuda:0 shared pool`. Free text because the unit differs per
13406
+ * family and inventing a common one would lose the only information that
13407
+ * makes two entries for the same camera distinguishable.
13408
+ */
13409
+ unit: string(),
13410
+ /**
13411
+ * The OS process this cost lives in, when there is one. Present so a
13412
+ * consumer can (a) tell two generations of the same unit apart across a
13413
+ * restart, and (b) subtract claimed processes from the node's process
13414
+ * snapshot to see what NOBODY claimed. Absent for an entry that owns no
13415
+ * process of its own.
13416
+ */
13417
+ pid: number().int().positive().optional(),
13418
+ /**
13419
+ * When this generation started. The pid's incarnation marker: a consumer
13420
+ * differencing {@link LoadContributionSchema.shape.cpuSeconds} must drop the
13421
+ * window when this changes, because the counter restarted from zero in a new
13422
+ * process.
13423
+ */
13424
+ startedAtMs: number().optional(),
13425
+ /**
13426
+ * CUMULATIVE CPU seconds this unit has consumed since it started — user +
13427
+ * system, read from the child's own `/proc/<pid>/stat` at the moment the
13428
+ * contribution is asked for.
13429
+ *
13430
+ * Cumulative and not a rate on purpose: a rate needs a window, a window
13431
+ * needs a sampler, and a new per-node sampler is the defect half of
13432
+ * `docs/architecture/load-ledger.md` documents. A counter can be differenced
13433
+ * by whoever already keeps a history; a rate cannot be un-averaged.
13434
+ *
13435
+ * Absent — never zero — on a node with no `/proc`, on a read failure, and on
13436
+ * an entry with no process.
13437
+ */
13438
+ cpuSeconds: number().optional(),
13439
+ /** Resident bytes of this unit's process, same source and same rules. */
13440
+ rssBytes: number().optional()
13441
+ });
13442
+ method(_void(), array(LoadContributionSchema).readonly());
13357
13443
  /**
13358
13444
  * `login-method` — collection cap through which auth addons contribute
13359
13445
  * their pre-auth login surfaces to the login page. This is the SINGLE,
@@ -13557,8 +13643,7 @@ var NodeProcessSchema = object({
13557
13643
  classification: _enum([
13558
13644
  "root",
13559
13645
  "managed",
13560
- "system",
13561
- "ghost"
13646
+ "system"
13562
13647
  ]),
13563
13648
  /** `$process` addon binding when `managed`, else null. */
13564
13649
  addonId: string().nullable(),
@@ -13566,22 +13651,39 @@ var NodeProcessSchema = object({
13566
13651
  nodeId: string().nullable(),
13567
13652
  /** Truncated command line. */
13568
13653
  command: string(),
13654
+ /**
13655
+ * `ps pcpu` — CPU averaged over the process's WHOLE LIFETIME, not a rate.
13656
+ * On a runner up for days it barely moves. Fine as a column, useless as a
13657
+ * series: use `cpuMainPercent + cpuGcPercent` for anything time-varying.
13658
+ */
13569
13659
  cpuPercent: number(),
13570
13660
  memoryRssBytes: number(),
13661
+ /**
13662
+ * Instantaneous CPU% of the process's own threads over the last
13663
+ * process-snapshot window, from a `/proc/<pid>/task/*` tick delta.
13664
+ *
13665
+ * `null` = UNKNOWN, never zero: no previous sample yet (first tick after
13666
+ * boot), the pid was recycled, or this node is not Linux.
13667
+ */
13668
+ cpuMainPercent: number().nullable(),
13669
+ /**
13670
+ * Instantaneous CPU% of V8's `V8Worker` platform pool over the same window.
13671
+ *
13672
+ * This is the number that rewrote the 2026-08-27 diagnosis — hub-main 73%,
13673
+ * `stream-broker` 61% (`docs/architecture/load-ledger.md`). A CPU chart that
13674
+ * does not separate it from `cpuMainPercent` shows "busy" where the truth is
13675
+ * "allocating too much".
13676
+ *
13677
+ * Concurrent GC is the dominant tenant of that pool but not the only one
13678
+ * (background compilation runs there too), so it is reported as
13679
+ * "GC / V8 helpers" rather than as pure collection time. `null` has the same
13680
+ * meaning as on `cpuMainPercent`.
13681
+ */
13682
+ cpuGcPercent: number().nullable(),
13683
+ /** Threads seen in the tick scan. `null` under the same conditions. */
13684
+ threadCount: number().nullable(),
13571
13685
  /** Wall-clock uptime (seconds). Parsed from `ps etime`. */
13572
- uptimeSec: number(),
13573
- /** True when ancestor walk reaches `ppid=1` (reparented to init/launchd). */
13574
- orphaned: boolean()
13575
- });
13576
- var KillProcessInputSchema = object({
13577
- pid: number(),
13578
- /** Force = SIGKILL. Default is SIGTERM. */
13579
- force: boolean().optional()
13580
- });
13581
- var KillProcessResultSchema = object({
13582
- success: boolean(),
13583
- reason: string().optional(),
13584
- signal: _enum(["SIGTERM", "SIGKILL"]).optional()
13686
+ uptimeSec: number()
13585
13687
  });
13586
13688
  var DumpHeapSnapshotInputSchema = object({
13587
13689
  /** The addon whose runner should dump a heap snapshot. */
@@ -13594,6 +13696,104 @@ var DumpHeapSnapshotResultSchema = object({
13594
13696
  pid: number().optional(),
13595
13697
  reason: string().optional()
13596
13698
  });
13699
+ /**
13700
+ * One point of one function's series.
13701
+ *
13702
+ * The unsuffixed fields are the bucket's **MAXIMUM**, and that choice is the
13703
+ * point of the whole surface. The two obvious reductions both lie: a mean per
13704
+ * bucket smears a spike away, and taking every Nth sample skips it outright.
13705
+ * Either would give us a tool built to find peaks that does not show peaks.
13706
+ * `...Min` carries the other end, `samples` says how many raw snapshots folded
13707
+ * into the bucket, and a mean stays derivable where it is wanted.
13708
+ *
13709
+ * An UNREDUCED point is a one-sample bucket: `samples === 1` and each `...Min`
13710
+ * equals its unsuffixed twin. Reduced and unreduced are the same shape, so a
13711
+ * caller cannot tell which it received — which is what "one reader" means.
13712
+ */
13713
+ var LoadPointSchema = object({
13714
+ /** Bucket START, or the snapshot's own timestamp when unreduced. */
13715
+ atMs: number(),
13716
+ /** Raw snapshots in this bucket. Never 0 — AN EMPTY BUCKET IS ABSENT. */
13717
+ samples: number().int(),
13718
+ /**
13719
+ * `null` = UNKNOWN and it PROPAGATES: a bucket is null unless every process
13720
+ * of every snapshot in it reported a thread split. A partial sum is a
13721
+ * smaller number that looks exactly as real as a complete one.
13722
+ */
13723
+ cpuMainPercent: number().nullable(),
13724
+ cpuMainPercentMin: number().nullable(),
13725
+ cpuGcPercent: number().nullable(),
13726
+ cpuGcPercentMin: number().nullable(),
13727
+ /** Lifetime-average CPU%, summed. Always known — and never a rate. */
13728
+ cpuLifetimePercent: number(),
13729
+ cpuLifetimePercentMin: number(),
13730
+ memoryRssBytes: number(),
13731
+ memoryRssBytesMin: number(),
13732
+ processCount: number().int(),
13733
+ processCountMin: number().int()
13734
+ });
13735
+ /** One function's series. `key` is an addonId, `__root__` or `__unattributed__`. */
13736
+ var LoadFunctionSeriesSchema = object({
13737
+ key: string(),
13738
+ kind: _enum([
13739
+ "addon",
13740
+ "root",
13741
+ "unattributed"
13742
+ ]),
13743
+ /** Oldest-first. A missing interval is MISSING — never zero-filled. */
13744
+ points: array(LoadPointSchema).readonly()
13745
+ });
13746
+ var NodeLoadSeriesSchema = object({
13747
+ nodeId: string(),
13748
+ /** One entry per function seen in the window, heaviest-first. */
13749
+ series: array(LoadFunctionSeriesSchema).readonly(),
13750
+ /**
13751
+ * Width of one returned bucket, in ms. Equals the sampling cadence when no
13752
+ * reduction was needed — so a caller can always say what one point covers
13753
+ * without having to know whether it was reduced.
13754
+ */
13755
+ bucketMs: number(),
13756
+ /** Raw snapshots that went into this answer, across both tiers. */
13757
+ retainedSamples: number(),
13758
+ /** Oldest snapshot represented, or `null` when nothing is retained. */
13759
+ oldestAtMs: number().nullable(),
13760
+ /** The fixed sampling cadence in force on the cluster, in ms. */
13761
+ cadenceMs: number(),
13762
+ /**
13763
+ * Did the DURABLE tier contribute? `false` means the answer is the hot ring
13764
+ * alone — an agent (which holds no table), or a store that refused.
13765
+ * Reported because "the last hour" and "the last six hours" are different
13766
+ * questions and an operator must not have to guess which was answered.
13767
+ */
13768
+ durable: boolean()
13769
+ });
13770
+ var GetLoadSeriesInputSchema = object({
13771
+ /**
13772
+ * The node whose series is wanted.
13773
+ *
13774
+ * NOT named `nodeId`: the generated cap router strips a top-level
13775
+ * `nodeId` from every method input and uses it to ROUTE the call to
13776
+ * that node's provider (`generated-cap-routers.ts`). A series target
13777
+ * called `nodeId` would silently become a routing pin and never reach
13778
+ * the provider. The hub holds every node it hears from, so the
13779
+ * ordinary call is unpinned — answered by the hub, for any node.
13780
+ */
13781
+ forNodeId: string(),
13782
+ /**
13783
+ * EXCLUSIVE lower bound. A caller passes the newest `atMs` it already
13784
+ * holds and receives only what it is missing, so seeding a live chart
13785
+ * from this method cannot double a point already drawn.
13786
+ */
13787
+ sinceMs: number().optional(),
13788
+ /**
13789
+ * Most points the caller wants PER FUNCTION. The window is reduced to fit,
13790
+ * preserving min and max per bucket.
13791
+ *
13792
+ * Absent means NO reduction — legitimate for a short window and a trap for a
13793
+ * long one, which is why a chart passes its own pixel width.
13794
+ */
13795
+ maxPoints: number().int().positive().optional()
13796
+ });
13597
13797
  var SystemMetricsSchema = object({
13598
13798
  cpuPercent: number(),
13599
13799
  memoryPercent: number(),
@@ -13604,10 +13804,7 @@ var SystemMetricsSchema = object({
13604
13804
  gpuPercent: number().optional(),
13605
13805
  gpuMemoryPercent: number().optional()
13606
13806
  });
13607
- method(_void(), SystemResourceSnapshotSchema), method(_void(), SystemResourceSnapshotSchema.nullable()), method(_void(), SystemMetricsSchema), method(object({ dirPath: string() }), DiskSpaceInfoSchema), method(_void(), MetricsGpuInfoSchema.nullable()), method(_void(), number().nullable()), method(object({ pids: array(number()) }), array(PidResourceStatsSchema)), method(_void(), array(AddonInstanceSchema).readonly()), method(object({ addonId: string() }), PidResourceStatsSchema.nullable()), method(_void(), array(NodeProcessSchema).readonly()), method(KillProcessInputSchema, KillProcessResultSchema, {
13608
- kind: "mutation",
13609
- auth: "admin"
13610
- }), method(DumpHeapSnapshotInputSchema, DumpHeapSnapshotResultSchema, {
13807
+ method(_void(), SystemResourceSnapshotSchema), method(_void(), SystemResourceSnapshotSchema.nullable()), method(_void(), SystemMetricsSchema), method(object({ dirPath: string() }), DiskSpaceInfoSchema), method(_void(), MetricsGpuInfoSchema.nullable()), method(_void(), number().nullable()), method(object({ pids: array(number()) }), array(PidResourceStatsSchema)), method(_void(), array(AddonInstanceSchema).readonly()), method(object({ addonId: string() }), PidResourceStatsSchema.nullable()), method(_void(), array(NodeProcessSchema).readonly()), method(GetLoadSeriesInputSchema, NodeLoadSeriesSchema), method(DumpHeapSnapshotInputSchema, DumpHeapSnapshotResultSchema, {
13611
13808
  kind: "mutation",
13612
13809
  auth: "admin"
13613
13810
  });
@@ -29049,6 +29246,15 @@ var LoggingSettingsPatchSchema = object({
29049
29246
  * authority over the whole hierarchy and answers for every layer, so the
29050
29247
  * layer selector needs a name the transport does not already own.
29051
29248
  */
29249
+ /**
29250
+ * One contribution, plus WHO reported it.
29251
+ *
29252
+ * The addon and node are added by the hub as it enumerates providers, never by
29253
+ * the contributor: an addon reporting its own identity could report somebody
29254
+ * else's, and the whole point of this surface is that no claim is made by
29255
+ * anyone but its owner.
29256
+ */
29257
+ var ReportedLoadContributionSchema = LoadContributionSchema.extend({ addonId: string() });
29052
29258
  var GetLoggingSettingsInputSchema = object({
29053
29259
  scopeNodeId: string().optional(),
29054
29260
  /**
@@ -29107,7 +29313,7 @@ method(_void(), FeatureManifestSchema), method(_void(), HealthStatusSchema), met
29107
29313
  }), method(_void(), SiteLocationStatusSchema, {
29108
29314
  kind: "mutation",
29109
29315
  auth: "admin"
29110
- }), method(_void(), RequestCensusStatusSchema, { auth: "admin" }), method(GetLoggingSettingsInputSchema, LoggingSettingsStateSchema, { auth: "admin" }), method(SetLoggingSettingsInputSchema, LoggingSettingsStateSchema, {
29316
+ }), method(_void(), RequestCensusStatusSchema, { auth: "admin" }), method(_void(), array(ReportedLoadContributionSchema).readonly(), { auth: "admin" }), method(GetLoggingSettingsInputSchema, LoggingSettingsStateSchema, { auth: "admin" }), method(SetLoggingSettingsInputSchema, LoggingSettingsStateSchema, {
29111
29317
  kind: "mutation",
29112
29318
  auth: "admin"
29113
29319
  });
@@ -32197,6 +32403,12 @@ Object.freeze({
32197
32403
  addonId: null,
32198
32404
  access: "create"
32199
32405
  },
32406
+ "dataStoreProvider.insertMany": {
32407
+ capName: "data-store-provider",
32408
+ capScope: "system",
32409
+ addonId: null,
32410
+ access: "create"
32411
+ },
32200
32412
  "dataStoreProvider.isEmpty": {
32201
32413
  capName: "data-store-provider",
32202
32414
  capScope: "system",
@@ -33511,6 +33723,12 @@ Object.freeze({
33511
33723
  addonId: null,
33512
33724
  access: "create"
33513
33725
  },
33726
+ "loadContribution.list": {
33727
+ capName: "load-contribution",
33728
+ capScope: "system",
33729
+ addonId: null,
33730
+ access: "view"
33731
+ },
33514
33732
  "localNetwork.downloadCa": {
33515
33733
  capName: "local-network",
33516
33734
  capScope: "system",
@@ -33811,17 +34029,17 @@ Object.freeze({
33811
34029
  addonId: null,
33812
34030
  access: "view"
33813
34031
  },
33814
- "metricsProvider.getProcessStats": {
34032
+ "metricsProvider.getLoadSeries": {
33815
34033
  capName: "metrics-provider",
33816
34034
  capScope: "system",
33817
34035
  addonId: null,
33818
34036
  access: "view"
33819
34037
  },
33820
- "metricsProvider.killProcess": {
34038
+ "metricsProvider.getProcessStats": {
33821
34039
  capName: "metrics-provider",
33822
34040
  capScope: "system",
33823
34041
  addonId: null,
33824
- access: "create"
34042
+ access: "view"
33825
34043
  },
33826
34044
  "metricsProvider.listAddonInstances": {
33827
34045
  capName: "metrics-provider",
@@ -35833,6 +36051,12 @@ Object.freeze({
35833
36051
  addonId: null,
35834
36052
  access: "create"
35835
36053
  },
36054
+ "settingsStore.insertMany": {
36055
+ capName: "settings-store",
36056
+ capScope: "system",
36057
+ addonId: null,
36058
+ access: "create"
36059
+ },
35836
36060
  "settingsStore.isEmpty": {
35837
36061
  capName: "settings-store",
35838
36062
  capScope: "system",
@@ -36445,6 +36669,12 @@ Object.freeze({
36445
36669
  addonId: null,
36446
36670
  access: "create"
36447
36671
  },
36672
+ "system.getLoadContributions": {
36673
+ capName: "system",
36674
+ capScope: "system",
36675
+ addonId: null,
36676
+ access: "view"
36677
+ },
36448
36678
  "system.getLoggingSettings": {
36449
36679
  capName: "system",
36450
36680
  capScope: "system",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-rtsp",
3
- "version": "1.2.35",
3
+ "version": "1.2.37",
4
4
  "description": "Generic RTSP camera device provider addon for CamStack",
5
5
  "keywords": [
6
6
  "camstack",