@camstack/addon-mqtt-broker 1.2.34 → 1.2.36

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.
@@ -44,7 +44,7 @@ let crypto$10 = __toESM(crypto$1, 1);
44
44
  crypto$1 = __toESM(crypto$1);
45
45
  let node_fs = require("node:fs");
46
46
  let node_path = require("node:path");
47
- //#region ../types/dist/event-category-CIa_iT6b.mjs
47
+ //#region ../types/dist/event-category-BZL-fdNj.mjs
48
48
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
49
49
  EventCategory["SystemBoot"] = "system.boot";
50
50
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -481,7 +481,7 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
481
481
  EventCategory["MetricsNodeResourcesSnapshot"] = "metrics.node-resources-snapshot";
482
482
  /**
483
483
  * Periodic per-node process-tree snapshot (camstack-related pids
484
- * with ghost / managed / root classification). Emitted ~0.2 Hz by
484
+ * with root / managed / system classification). Emitted ~0.2 Hz by
485
485
  * the metrics-provider addon. Drives the Cluster → Processes tab
486
486
  * without polling `metricsProvider.listNodeProcesses`.
487
487
  */
@@ -11204,6 +11204,19 @@ var SettingsRecordSchema = object({
11204
11204
  data: record(string(), unknown())
11205
11205
  });
11206
11206
  /**
11207
+ * One record of a BULK insert — {@link SettingsRecordSchema} with the id made
11208
+ * optional.
11209
+ *
11210
+ * A separate schema rather than loosening the shared one: every other method
11211
+ * on this cap addresses a row BY its id, and making that field optional
11212
+ * everywhere would turn a forgotten key into a silently generated one on
11213
+ * `update` and `delete` as well.
11214
+ */
11215
+ var BulkRecordSchema = object({
11216
+ id: string().optional(),
11217
+ data: record(string(), unknown())
11218
+ });
11219
+ /**
11207
11220
  * Column declaration for a structured (SQL-backed) collection.
11208
11221
  *
11209
11222
  * Logical types — the backend translates each to the matching SQLite
@@ -11260,6 +11273,10 @@ method(object({
11260
11273
  collection: string(),
11261
11274
  record: SettingsRecordSchema
11262
11275
  }), _void(), { kind: "mutation" }), method(object({
11276
+ namespace: string().optional(),
11277
+ collection: string(),
11278
+ records: array(BulkRecordSchema).readonly()
11279
+ }), object({ inserted: number().int() }), { kind: "mutation" }), method(object({
11263
11280
  namespace: string().optional(),
11264
11281
  collection: string(),
11265
11282
  id: string(),
@@ -11368,6 +11385,13 @@ method(_void(), EngineInfoSchema, { auth: "admin" }), method(object({
11368
11385
  }), _void(), {
11369
11386
  kind: "mutation",
11370
11387
  auth: "admin"
11388
+ }), method(object({
11389
+ namespace: string().optional(),
11390
+ collection: string(),
11391
+ records: array(BulkRecordSchema).readonly()
11392
+ }), object({ inserted: number().int() }), {
11393
+ kind: "mutation",
11394
+ auth: "admin"
11371
11395
  }), method(object({
11372
11396
  namespace: string().optional(),
11373
11397
  collection: string(),
@@ -13136,6 +13160,68 @@ method(LogEntrySchema, _void(), { kind: "mutation" }), method(object({
13136
13160
  limit: number().optional(),
13137
13161
  tags: record(string(), string()).optional()
13138
13162
  }), array(LogEntrySchema).readonly());
13163
+ var LoadContributionSchema = object({
13164
+ role: _enum([
13165
+ "decode",
13166
+ "transcode",
13167
+ "recording",
13168
+ "streaming",
13169
+ "detection"
13170
+ ]),
13171
+ /**
13172
+ * The NUMERIC device id — the same value every log line carries as
13173
+ * `tags.deviceId`. `null` means this cost genuinely belongs to no single
13174
+ * camera (a shared pool), NOT that the contributor forgot to look it up: a
13175
+ * contributor that cannot name its camera must not emit the entry at all,
13176
+ * because an unnamed per-camera entry is indistinguishable from a shared one
13177
+ * and would quietly turn one camera's cost into everybody's.
13178
+ */
13179
+ deviceId: number().int().positive().nullable(),
13180
+ attribution: _enum([
13181
+ "measured",
13182
+ "accounted",
13183
+ "unattributable"
13184
+ ]),
13185
+ /**
13186
+ * What ONE entry is, in the contributor's own words — `615/high`,
13187
+ * `617/native`, `cuda:0 shared pool`. Free text because the unit differs per
13188
+ * family and inventing a common one would lose the only information that
13189
+ * makes two entries for the same camera distinguishable.
13190
+ */
13191
+ unit: string(),
13192
+ /**
13193
+ * The OS process this cost lives in, when there is one. Present so a
13194
+ * consumer can (a) tell two generations of the same unit apart across a
13195
+ * restart, and (b) subtract claimed processes from the node's process
13196
+ * snapshot to see what NOBODY claimed. Absent for an entry that owns no
13197
+ * process of its own.
13198
+ */
13199
+ pid: number().int().positive().optional(),
13200
+ /**
13201
+ * When this generation started. The pid's incarnation marker: a consumer
13202
+ * differencing {@link LoadContributionSchema.shape.cpuSeconds} must drop the
13203
+ * window when this changes, because the counter restarted from zero in a new
13204
+ * process.
13205
+ */
13206
+ startedAtMs: number().optional(),
13207
+ /**
13208
+ * CUMULATIVE CPU seconds this unit has consumed since it started — user +
13209
+ * system, read from the child's own `/proc/<pid>/stat` at the moment the
13210
+ * contribution is asked for.
13211
+ *
13212
+ * Cumulative and not a rate on purpose: a rate needs a window, a window
13213
+ * needs a sampler, and a new per-node sampler is the defect half of
13214
+ * `docs/architecture/load-ledger.md` documents. A counter can be differenced
13215
+ * by whoever already keeps a history; a rate cannot be un-averaged.
13216
+ *
13217
+ * Absent — never zero — on a node with no `/proc`, on a read failure, and on
13218
+ * an entry with no process.
13219
+ */
13220
+ cpuSeconds: number().optional(),
13221
+ /** Resident bytes of this unit's process, same source and same rules. */
13222
+ rssBytes: number().optional()
13223
+ });
13224
+ method(_void(), array(LoadContributionSchema).readonly());
13139
13225
  /**
13140
13226
  * `login-method` — collection cap through which auth addons contribute
13141
13227
  * their pre-auth login surfaces to the login page. This is the SINGLE,
@@ -13339,8 +13425,7 @@ var NodeProcessSchema = object({
13339
13425
  classification: _enum([
13340
13426
  "root",
13341
13427
  "managed",
13342
- "system",
13343
- "ghost"
13428
+ "system"
13344
13429
  ]),
13345
13430
  /** `$process` addon binding when `managed`, else null. */
13346
13431
  addonId: string().nullable(),
@@ -13348,22 +13433,39 @@ var NodeProcessSchema = object({
13348
13433
  nodeId: string().nullable(),
13349
13434
  /** Truncated command line. */
13350
13435
  command: string(),
13436
+ /**
13437
+ * `ps pcpu` — CPU averaged over the process's WHOLE LIFETIME, not a rate.
13438
+ * On a runner up for days it barely moves. Fine as a column, useless as a
13439
+ * series: use `cpuMainPercent + cpuGcPercent` for anything time-varying.
13440
+ */
13351
13441
  cpuPercent: number(),
13352
13442
  memoryRssBytes: number(),
13443
+ /**
13444
+ * Instantaneous CPU% of the process's own threads over the last
13445
+ * process-snapshot window, from a `/proc/<pid>/task/*` tick delta.
13446
+ *
13447
+ * `null` = UNKNOWN, never zero: no previous sample yet (first tick after
13448
+ * boot), the pid was recycled, or this node is not Linux.
13449
+ */
13450
+ cpuMainPercent: number().nullable(),
13451
+ /**
13452
+ * Instantaneous CPU% of V8's `V8Worker` platform pool over the same window.
13453
+ *
13454
+ * This is the number that rewrote the 2026-08-27 diagnosis — hub-main 73%,
13455
+ * `stream-broker` 61% (`docs/architecture/load-ledger.md`). A CPU chart that
13456
+ * does not separate it from `cpuMainPercent` shows "busy" where the truth is
13457
+ * "allocating too much".
13458
+ *
13459
+ * Concurrent GC is the dominant tenant of that pool but not the only one
13460
+ * (background compilation runs there too), so it is reported as
13461
+ * "GC / V8 helpers" rather than as pure collection time. `null` has the same
13462
+ * meaning as on `cpuMainPercent`.
13463
+ */
13464
+ cpuGcPercent: number().nullable(),
13465
+ /** Threads seen in the tick scan. `null` under the same conditions. */
13466
+ threadCount: number().nullable(),
13353
13467
  /** Wall-clock uptime (seconds). Parsed from `ps etime`. */
13354
- uptimeSec: number(),
13355
- /** True when ancestor walk reaches `ppid=1` (reparented to init/launchd). */
13356
- orphaned: boolean()
13357
- });
13358
- var KillProcessInputSchema = object({
13359
- pid: number(),
13360
- /** Force = SIGKILL. Default is SIGTERM. */
13361
- force: boolean().optional()
13362
- });
13363
- var KillProcessResultSchema = object({
13364
- success: boolean(),
13365
- reason: string().optional(),
13366
- signal: _enum(["SIGTERM", "SIGKILL"]).optional()
13468
+ uptimeSec: number()
13367
13469
  });
13368
13470
  var DumpHeapSnapshotInputSchema = object({
13369
13471
  /** The addon whose runner should dump a heap snapshot. */
@@ -13376,6 +13478,104 @@ var DumpHeapSnapshotResultSchema = object({
13376
13478
  pid: number().optional(),
13377
13479
  reason: string().optional()
13378
13480
  });
13481
+ /**
13482
+ * One point of one function's series.
13483
+ *
13484
+ * The unsuffixed fields are the bucket's **MAXIMUM**, and that choice is the
13485
+ * point of the whole surface. The two obvious reductions both lie: a mean per
13486
+ * bucket smears a spike away, and taking every Nth sample skips it outright.
13487
+ * Either would give us a tool built to find peaks that does not show peaks.
13488
+ * `...Min` carries the other end, `samples` says how many raw snapshots folded
13489
+ * into the bucket, and a mean stays derivable where it is wanted.
13490
+ *
13491
+ * An UNREDUCED point is a one-sample bucket: `samples === 1` and each `...Min`
13492
+ * equals its unsuffixed twin. Reduced and unreduced are the same shape, so a
13493
+ * caller cannot tell which it received — which is what "one reader" means.
13494
+ */
13495
+ var LoadPointSchema = object({
13496
+ /** Bucket START, or the snapshot's own timestamp when unreduced. */
13497
+ atMs: number(),
13498
+ /** Raw snapshots in this bucket. Never 0 — AN EMPTY BUCKET IS ABSENT. */
13499
+ samples: number().int(),
13500
+ /**
13501
+ * `null` = UNKNOWN and it PROPAGATES: a bucket is null unless every process
13502
+ * of every snapshot in it reported a thread split. A partial sum is a
13503
+ * smaller number that looks exactly as real as a complete one.
13504
+ */
13505
+ cpuMainPercent: number().nullable(),
13506
+ cpuMainPercentMin: number().nullable(),
13507
+ cpuGcPercent: number().nullable(),
13508
+ cpuGcPercentMin: number().nullable(),
13509
+ /** Lifetime-average CPU%, summed. Always known — and never a rate. */
13510
+ cpuLifetimePercent: number(),
13511
+ cpuLifetimePercentMin: number(),
13512
+ memoryRssBytes: number(),
13513
+ memoryRssBytesMin: number(),
13514
+ processCount: number().int(),
13515
+ processCountMin: number().int()
13516
+ });
13517
+ /** One function's series. `key` is an addonId, `__root__` or `__unattributed__`. */
13518
+ var LoadFunctionSeriesSchema = object({
13519
+ key: string(),
13520
+ kind: _enum([
13521
+ "addon",
13522
+ "root",
13523
+ "unattributed"
13524
+ ]),
13525
+ /** Oldest-first. A missing interval is MISSING — never zero-filled. */
13526
+ points: array(LoadPointSchema).readonly()
13527
+ });
13528
+ var NodeLoadSeriesSchema = object({
13529
+ nodeId: string(),
13530
+ /** One entry per function seen in the window, heaviest-first. */
13531
+ series: array(LoadFunctionSeriesSchema).readonly(),
13532
+ /**
13533
+ * Width of one returned bucket, in ms. Equals the sampling cadence when no
13534
+ * reduction was needed — so a caller can always say what one point covers
13535
+ * without having to know whether it was reduced.
13536
+ */
13537
+ bucketMs: number(),
13538
+ /** Raw snapshots that went into this answer, across both tiers. */
13539
+ retainedSamples: number(),
13540
+ /** Oldest snapshot represented, or `null` when nothing is retained. */
13541
+ oldestAtMs: number().nullable(),
13542
+ /** The fixed sampling cadence in force on the cluster, in ms. */
13543
+ cadenceMs: number(),
13544
+ /**
13545
+ * Did the DURABLE tier contribute? `false` means the answer is the hot ring
13546
+ * alone — an agent (which holds no table), or a store that refused.
13547
+ * Reported because "the last hour" and "the last six hours" are different
13548
+ * questions and an operator must not have to guess which was answered.
13549
+ */
13550
+ durable: boolean()
13551
+ });
13552
+ var GetLoadSeriesInputSchema = object({
13553
+ /**
13554
+ * The node whose series is wanted.
13555
+ *
13556
+ * NOT named `nodeId`: the generated cap router strips a top-level
13557
+ * `nodeId` from every method input and uses it to ROUTE the call to
13558
+ * that node's provider (`generated-cap-routers.ts`). A series target
13559
+ * called `nodeId` would silently become a routing pin and never reach
13560
+ * the provider. The hub holds every node it hears from, so the
13561
+ * ordinary call is unpinned — answered by the hub, for any node.
13562
+ */
13563
+ forNodeId: string(),
13564
+ /**
13565
+ * EXCLUSIVE lower bound. A caller passes the newest `atMs` it already
13566
+ * holds and receives only what it is missing, so seeding a live chart
13567
+ * from this method cannot double a point already drawn.
13568
+ */
13569
+ sinceMs: number().optional(),
13570
+ /**
13571
+ * Most points the caller wants PER FUNCTION. The window is reduced to fit,
13572
+ * preserving min and max per bucket.
13573
+ *
13574
+ * Absent means NO reduction — legitimate for a short window and a trap for a
13575
+ * long one, which is why a chart passes its own pixel width.
13576
+ */
13577
+ maxPoints: number().int().positive().optional()
13578
+ });
13379
13579
  var SystemMetricsSchema = object({
13380
13580
  cpuPercent: number(),
13381
13581
  memoryPercent: number(),
@@ -13386,10 +13586,7 @@ var SystemMetricsSchema = object({
13386
13586
  gpuPercent: number().optional(),
13387
13587
  gpuMemoryPercent: number().optional()
13388
13588
  });
13389
- 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, {
13390
- kind: "mutation",
13391
- auth: "admin"
13392
- }), method(DumpHeapSnapshotInputSchema, DumpHeapSnapshotResultSchema, {
13589
+ 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, {
13393
13590
  kind: "mutation",
13394
13591
  auth: "admin"
13395
13592
  });
@@ -26711,6 +26908,15 @@ var LoggingSettingsPatchSchema = object({
26711
26908
  * authority over the whole hierarchy and answers for every layer, so the
26712
26909
  * layer selector needs a name the transport does not already own.
26713
26910
  */
26911
+ /**
26912
+ * One contribution, plus WHO reported it.
26913
+ *
26914
+ * The addon and node are added by the hub as it enumerates providers, never by
26915
+ * the contributor: an addon reporting its own identity could report somebody
26916
+ * else's, and the whole point of this surface is that no claim is made by
26917
+ * anyone but its owner.
26918
+ */
26919
+ var ReportedLoadContributionSchema = LoadContributionSchema.extend({ addonId: string() });
26714
26920
  var GetLoggingSettingsInputSchema = object({
26715
26921
  scopeNodeId: string().optional(),
26716
26922
  /**
@@ -26769,7 +26975,7 @@ method(_void(), FeatureManifestSchema), method(_void(), HealthStatusSchema), met
26769
26975
  }), method(_void(), SiteLocationStatusSchema, {
26770
26976
  kind: "mutation",
26771
26977
  auth: "admin"
26772
- }), method(_void(), RequestCensusStatusSchema, { auth: "admin" }), method(GetLoggingSettingsInputSchema, LoggingSettingsStateSchema, { auth: "admin" }), method(SetLoggingSettingsInputSchema, LoggingSettingsStateSchema, {
26978
+ }), method(_void(), RequestCensusStatusSchema, { auth: "admin" }), method(_void(), array(ReportedLoadContributionSchema).readonly(), { auth: "admin" }), method(GetLoggingSettingsInputSchema, LoggingSettingsStateSchema, { auth: "admin" }), method(SetLoggingSettingsInputSchema, LoggingSettingsStateSchema, {
26773
26979
  kind: "mutation",
26774
26980
  auth: "admin"
26775
26981
  });
@@ -28385,6 +28591,12 @@ Object.freeze({
28385
28591
  addonId: null,
28386
28592
  access: "create"
28387
28593
  },
28594
+ "dataStoreProvider.insertMany": {
28595
+ capName: "data-store-provider",
28596
+ capScope: "system",
28597
+ addonId: null,
28598
+ access: "create"
28599
+ },
28388
28600
  "dataStoreProvider.isEmpty": {
28389
28601
  capName: "data-store-provider",
28390
28602
  capScope: "system",
@@ -29699,6 +29911,12 @@ Object.freeze({
29699
29911
  addonId: null,
29700
29912
  access: "create"
29701
29913
  },
29914
+ "loadContribution.list": {
29915
+ capName: "load-contribution",
29916
+ capScope: "system",
29917
+ addonId: null,
29918
+ access: "view"
29919
+ },
29702
29920
  "localNetwork.downloadCa": {
29703
29921
  capName: "local-network",
29704
29922
  capScope: "system",
@@ -29999,17 +30217,17 @@ Object.freeze({
29999
30217
  addonId: null,
30000
30218
  access: "view"
30001
30219
  },
30002
- "metricsProvider.getProcessStats": {
30220
+ "metricsProvider.getLoadSeries": {
30003
30221
  capName: "metrics-provider",
30004
30222
  capScope: "system",
30005
30223
  addonId: null,
30006
30224
  access: "view"
30007
30225
  },
30008
- "metricsProvider.killProcess": {
30226
+ "metricsProvider.getProcessStats": {
30009
30227
  capName: "metrics-provider",
30010
30228
  capScope: "system",
30011
30229
  addonId: null,
30012
- access: "create"
30230
+ access: "view"
30013
30231
  },
30014
30232
  "metricsProvider.listAddonInstances": {
30015
30233
  capName: "metrics-provider",
@@ -32021,6 +32239,12 @@ Object.freeze({
32021
32239
  addonId: null,
32022
32240
  access: "create"
32023
32241
  },
32242
+ "settingsStore.insertMany": {
32243
+ capName: "settings-store",
32244
+ capScope: "system",
32245
+ addonId: null,
32246
+ access: "create"
32247
+ },
32024
32248
  "settingsStore.isEmpty": {
32025
32249
  capName: "settings-store",
32026
32250
  capScope: "system",
@@ -32633,6 +32857,12 @@ Object.freeze({
32633
32857
  addonId: null,
32634
32858
  access: "create"
32635
32859
  },
32860
+ "system.getLoadContributions": {
32861
+ capName: "system",
32862
+ capScope: "system",
32863
+ addonId: null,
32864
+ access: "view"
32865
+ },
32636
32866
  "system.getLoggingSettings": {
32637
32867
  capName: "system",
32638
32868
  capScope: "system",
@@ -39,7 +39,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
39
39
  var __toCommonJS = (mod) => __hasOwnProp.call(mod, "module.exports") ? mod["module.exports"] : __copyProps(__defProp({}, "__esModule", { value: true }), mod);
40
40
  var __require = /* @__PURE__ */ createRequire(import.meta.url);
41
41
  //#endregion
42
- //#region ../types/dist/event-category-CIa_iT6b.mjs
42
+ //#region ../types/dist/event-category-BZL-fdNj.mjs
43
43
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
44
44
  EventCategory["SystemBoot"] = "system.boot";
45
45
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -476,7 +476,7 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
476
476
  EventCategory["MetricsNodeResourcesSnapshot"] = "metrics.node-resources-snapshot";
477
477
  /**
478
478
  * Periodic per-node process-tree snapshot (camstack-related pids
479
- * with ghost / managed / root classification). Emitted ~0.2 Hz by
479
+ * with root / managed / system classification). Emitted ~0.2 Hz by
480
480
  * the metrics-provider addon. Drives the Cluster → Processes tab
481
481
  * without polling `metricsProvider.listNodeProcesses`.
482
482
  */
@@ -11199,6 +11199,19 @@ var SettingsRecordSchema = object({
11199
11199
  data: record(string(), unknown())
11200
11200
  });
11201
11201
  /**
11202
+ * One record of a BULK insert — {@link SettingsRecordSchema} with the id made
11203
+ * optional.
11204
+ *
11205
+ * A separate schema rather than loosening the shared one: every other method
11206
+ * on this cap addresses a row BY its id, and making that field optional
11207
+ * everywhere would turn a forgotten key into a silently generated one on
11208
+ * `update` and `delete` as well.
11209
+ */
11210
+ var BulkRecordSchema = object({
11211
+ id: string().optional(),
11212
+ data: record(string(), unknown())
11213
+ });
11214
+ /**
11202
11215
  * Column declaration for a structured (SQL-backed) collection.
11203
11216
  *
11204
11217
  * Logical types — the backend translates each to the matching SQLite
@@ -11255,6 +11268,10 @@ method(object({
11255
11268
  collection: string(),
11256
11269
  record: SettingsRecordSchema
11257
11270
  }), _void(), { kind: "mutation" }), method(object({
11271
+ namespace: string().optional(),
11272
+ collection: string(),
11273
+ records: array(BulkRecordSchema).readonly()
11274
+ }), object({ inserted: number().int() }), { kind: "mutation" }), method(object({
11258
11275
  namespace: string().optional(),
11259
11276
  collection: string(),
11260
11277
  id: string(),
@@ -11363,6 +11380,13 @@ method(_void(), EngineInfoSchema, { auth: "admin" }), method(object({
11363
11380
  }), _void(), {
11364
11381
  kind: "mutation",
11365
11382
  auth: "admin"
11383
+ }), method(object({
11384
+ namespace: string().optional(),
11385
+ collection: string(),
11386
+ records: array(BulkRecordSchema).readonly()
11387
+ }), object({ inserted: number().int() }), {
11388
+ kind: "mutation",
11389
+ auth: "admin"
11366
11390
  }), method(object({
11367
11391
  namespace: string().optional(),
11368
11392
  collection: string(),
@@ -13131,6 +13155,68 @@ method(LogEntrySchema, _void(), { kind: "mutation" }), method(object({
13131
13155
  limit: number().optional(),
13132
13156
  tags: record(string(), string()).optional()
13133
13157
  }), array(LogEntrySchema).readonly());
13158
+ var LoadContributionSchema = object({
13159
+ role: _enum([
13160
+ "decode",
13161
+ "transcode",
13162
+ "recording",
13163
+ "streaming",
13164
+ "detection"
13165
+ ]),
13166
+ /**
13167
+ * The NUMERIC device id — the same value every log line carries as
13168
+ * `tags.deviceId`. `null` means this cost genuinely belongs to no single
13169
+ * camera (a shared pool), NOT that the contributor forgot to look it up: a
13170
+ * contributor that cannot name its camera must not emit the entry at all,
13171
+ * because an unnamed per-camera entry is indistinguishable from a shared one
13172
+ * and would quietly turn one camera's cost into everybody's.
13173
+ */
13174
+ deviceId: number().int().positive().nullable(),
13175
+ attribution: _enum([
13176
+ "measured",
13177
+ "accounted",
13178
+ "unattributable"
13179
+ ]),
13180
+ /**
13181
+ * What ONE entry is, in the contributor's own words — `615/high`,
13182
+ * `617/native`, `cuda:0 shared pool`. Free text because the unit differs per
13183
+ * family and inventing a common one would lose the only information that
13184
+ * makes two entries for the same camera distinguishable.
13185
+ */
13186
+ unit: string(),
13187
+ /**
13188
+ * The OS process this cost lives in, when there is one. Present so a
13189
+ * consumer can (a) tell two generations of the same unit apart across a
13190
+ * restart, and (b) subtract claimed processes from the node's process
13191
+ * snapshot to see what NOBODY claimed. Absent for an entry that owns no
13192
+ * process of its own.
13193
+ */
13194
+ pid: number().int().positive().optional(),
13195
+ /**
13196
+ * When this generation started. The pid's incarnation marker: a consumer
13197
+ * differencing {@link LoadContributionSchema.shape.cpuSeconds} must drop the
13198
+ * window when this changes, because the counter restarted from zero in a new
13199
+ * process.
13200
+ */
13201
+ startedAtMs: number().optional(),
13202
+ /**
13203
+ * CUMULATIVE CPU seconds this unit has consumed since it started — user +
13204
+ * system, read from the child's own `/proc/<pid>/stat` at the moment the
13205
+ * contribution is asked for.
13206
+ *
13207
+ * Cumulative and not a rate on purpose: a rate needs a window, a window
13208
+ * needs a sampler, and a new per-node sampler is the defect half of
13209
+ * `docs/architecture/load-ledger.md` documents. A counter can be differenced
13210
+ * by whoever already keeps a history; a rate cannot be un-averaged.
13211
+ *
13212
+ * Absent — never zero — on a node with no `/proc`, on a read failure, and on
13213
+ * an entry with no process.
13214
+ */
13215
+ cpuSeconds: number().optional(),
13216
+ /** Resident bytes of this unit's process, same source and same rules. */
13217
+ rssBytes: number().optional()
13218
+ });
13219
+ method(_void(), array(LoadContributionSchema).readonly());
13134
13220
  /**
13135
13221
  * `login-method` — collection cap through which auth addons contribute
13136
13222
  * their pre-auth login surfaces to the login page. This is the SINGLE,
@@ -13334,8 +13420,7 @@ var NodeProcessSchema = object({
13334
13420
  classification: _enum([
13335
13421
  "root",
13336
13422
  "managed",
13337
- "system",
13338
- "ghost"
13423
+ "system"
13339
13424
  ]),
13340
13425
  /** `$process` addon binding when `managed`, else null. */
13341
13426
  addonId: string().nullable(),
@@ -13343,22 +13428,39 @@ var NodeProcessSchema = object({
13343
13428
  nodeId: string().nullable(),
13344
13429
  /** Truncated command line. */
13345
13430
  command: string(),
13431
+ /**
13432
+ * `ps pcpu` — CPU averaged over the process's WHOLE LIFETIME, not a rate.
13433
+ * On a runner up for days it barely moves. Fine as a column, useless as a
13434
+ * series: use `cpuMainPercent + cpuGcPercent` for anything time-varying.
13435
+ */
13346
13436
  cpuPercent: number(),
13347
13437
  memoryRssBytes: number(),
13438
+ /**
13439
+ * Instantaneous CPU% of the process's own threads over the last
13440
+ * process-snapshot window, from a `/proc/<pid>/task/*` tick delta.
13441
+ *
13442
+ * `null` = UNKNOWN, never zero: no previous sample yet (first tick after
13443
+ * boot), the pid was recycled, or this node is not Linux.
13444
+ */
13445
+ cpuMainPercent: number().nullable(),
13446
+ /**
13447
+ * Instantaneous CPU% of V8's `V8Worker` platform pool over the same window.
13448
+ *
13449
+ * This is the number that rewrote the 2026-08-27 diagnosis — hub-main 73%,
13450
+ * `stream-broker` 61% (`docs/architecture/load-ledger.md`). A CPU chart that
13451
+ * does not separate it from `cpuMainPercent` shows "busy" where the truth is
13452
+ * "allocating too much".
13453
+ *
13454
+ * Concurrent GC is the dominant tenant of that pool but not the only one
13455
+ * (background compilation runs there too), so it is reported as
13456
+ * "GC / V8 helpers" rather than as pure collection time. `null` has the same
13457
+ * meaning as on `cpuMainPercent`.
13458
+ */
13459
+ cpuGcPercent: number().nullable(),
13460
+ /** Threads seen in the tick scan. `null` under the same conditions. */
13461
+ threadCount: number().nullable(),
13348
13462
  /** Wall-clock uptime (seconds). Parsed from `ps etime`. */
13349
- uptimeSec: number(),
13350
- /** True when ancestor walk reaches `ppid=1` (reparented to init/launchd). */
13351
- orphaned: boolean()
13352
- });
13353
- var KillProcessInputSchema = object({
13354
- pid: number(),
13355
- /** Force = SIGKILL. Default is SIGTERM. */
13356
- force: boolean().optional()
13357
- });
13358
- var KillProcessResultSchema = object({
13359
- success: boolean(),
13360
- reason: string().optional(),
13361
- signal: _enum(["SIGTERM", "SIGKILL"]).optional()
13463
+ uptimeSec: number()
13362
13464
  });
13363
13465
  var DumpHeapSnapshotInputSchema = object({
13364
13466
  /** The addon whose runner should dump a heap snapshot. */
@@ -13371,6 +13473,104 @@ var DumpHeapSnapshotResultSchema = object({
13371
13473
  pid: number().optional(),
13372
13474
  reason: string().optional()
13373
13475
  });
13476
+ /**
13477
+ * One point of one function's series.
13478
+ *
13479
+ * The unsuffixed fields are the bucket's **MAXIMUM**, and that choice is the
13480
+ * point of the whole surface. The two obvious reductions both lie: a mean per
13481
+ * bucket smears a spike away, and taking every Nth sample skips it outright.
13482
+ * Either would give us a tool built to find peaks that does not show peaks.
13483
+ * `...Min` carries the other end, `samples` says how many raw snapshots folded
13484
+ * into the bucket, and a mean stays derivable where it is wanted.
13485
+ *
13486
+ * An UNREDUCED point is a one-sample bucket: `samples === 1` and each `...Min`
13487
+ * equals its unsuffixed twin. Reduced and unreduced are the same shape, so a
13488
+ * caller cannot tell which it received — which is what "one reader" means.
13489
+ */
13490
+ var LoadPointSchema = object({
13491
+ /** Bucket START, or the snapshot's own timestamp when unreduced. */
13492
+ atMs: number(),
13493
+ /** Raw snapshots in this bucket. Never 0 — AN EMPTY BUCKET IS ABSENT. */
13494
+ samples: number().int(),
13495
+ /**
13496
+ * `null` = UNKNOWN and it PROPAGATES: a bucket is null unless every process
13497
+ * of every snapshot in it reported a thread split. A partial sum is a
13498
+ * smaller number that looks exactly as real as a complete one.
13499
+ */
13500
+ cpuMainPercent: number().nullable(),
13501
+ cpuMainPercentMin: number().nullable(),
13502
+ cpuGcPercent: number().nullable(),
13503
+ cpuGcPercentMin: number().nullable(),
13504
+ /** Lifetime-average CPU%, summed. Always known — and never a rate. */
13505
+ cpuLifetimePercent: number(),
13506
+ cpuLifetimePercentMin: number(),
13507
+ memoryRssBytes: number(),
13508
+ memoryRssBytesMin: number(),
13509
+ processCount: number().int(),
13510
+ processCountMin: number().int()
13511
+ });
13512
+ /** One function's series. `key` is an addonId, `__root__` or `__unattributed__`. */
13513
+ var LoadFunctionSeriesSchema = object({
13514
+ key: string(),
13515
+ kind: _enum([
13516
+ "addon",
13517
+ "root",
13518
+ "unattributed"
13519
+ ]),
13520
+ /** Oldest-first. A missing interval is MISSING — never zero-filled. */
13521
+ points: array(LoadPointSchema).readonly()
13522
+ });
13523
+ var NodeLoadSeriesSchema = object({
13524
+ nodeId: string(),
13525
+ /** One entry per function seen in the window, heaviest-first. */
13526
+ series: array(LoadFunctionSeriesSchema).readonly(),
13527
+ /**
13528
+ * Width of one returned bucket, in ms. Equals the sampling cadence when no
13529
+ * reduction was needed — so a caller can always say what one point covers
13530
+ * without having to know whether it was reduced.
13531
+ */
13532
+ bucketMs: number(),
13533
+ /** Raw snapshots that went into this answer, across both tiers. */
13534
+ retainedSamples: number(),
13535
+ /** Oldest snapshot represented, or `null` when nothing is retained. */
13536
+ oldestAtMs: number().nullable(),
13537
+ /** The fixed sampling cadence in force on the cluster, in ms. */
13538
+ cadenceMs: number(),
13539
+ /**
13540
+ * Did the DURABLE tier contribute? `false` means the answer is the hot ring
13541
+ * alone — an agent (which holds no table), or a store that refused.
13542
+ * Reported because "the last hour" and "the last six hours" are different
13543
+ * questions and an operator must not have to guess which was answered.
13544
+ */
13545
+ durable: boolean()
13546
+ });
13547
+ var GetLoadSeriesInputSchema = object({
13548
+ /**
13549
+ * The node whose series is wanted.
13550
+ *
13551
+ * NOT named `nodeId`: the generated cap router strips a top-level
13552
+ * `nodeId` from every method input and uses it to ROUTE the call to
13553
+ * that node's provider (`generated-cap-routers.ts`). A series target
13554
+ * called `nodeId` would silently become a routing pin and never reach
13555
+ * the provider. The hub holds every node it hears from, so the
13556
+ * ordinary call is unpinned — answered by the hub, for any node.
13557
+ */
13558
+ forNodeId: string(),
13559
+ /**
13560
+ * EXCLUSIVE lower bound. A caller passes the newest `atMs` it already
13561
+ * holds and receives only what it is missing, so seeding a live chart
13562
+ * from this method cannot double a point already drawn.
13563
+ */
13564
+ sinceMs: number().optional(),
13565
+ /**
13566
+ * Most points the caller wants PER FUNCTION. The window is reduced to fit,
13567
+ * preserving min and max per bucket.
13568
+ *
13569
+ * Absent means NO reduction — legitimate for a short window and a trap for a
13570
+ * long one, which is why a chart passes its own pixel width.
13571
+ */
13572
+ maxPoints: number().int().positive().optional()
13573
+ });
13374
13574
  var SystemMetricsSchema = object({
13375
13575
  cpuPercent: number(),
13376
13576
  memoryPercent: number(),
@@ -13381,10 +13581,7 @@ var SystemMetricsSchema = object({
13381
13581
  gpuPercent: number().optional(),
13382
13582
  gpuMemoryPercent: number().optional()
13383
13583
  });
13384
- 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, {
13385
- kind: "mutation",
13386
- auth: "admin"
13387
- }), method(DumpHeapSnapshotInputSchema, DumpHeapSnapshotResultSchema, {
13584
+ 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, {
13388
13585
  kind: "mutation",
13389
13586
  auth: "admin"
13390
13587
  });
@@ -26706,6 +26903,15 @@ var LoggingSettingsPatchSchema = object({
26706
26903
  * authority over the whole hierarchy and answers for every layer, so the
26707
26904
  * layer selector needs a name the transport does not already own.
26708
26905
  */
26906
+ /**
26907
+ * One contribution, plus WHO reported it.
26908
+ *
26909
+ * The addon and node are added by the hub as it enumerates providers, never by
26910
+ * the contributor: an addon reporting its own identity could report somebody
26911
+ * else's, and the whole point of this surface is that no claim is made by
26912
+ * anyone but its owner.
26913
+ */
26914
+ var ReportedLoadContributionSchema = LoadContributionSchema.extend({ addonId: string() });
26709
26915
  var GetLoggingSettingsInputSchema = object({
26710
26916
  scopeNodeId: string().optional(),
26711
26917
  /**
@@ -26764,7 +26970,7 @@ method(_void(), FeatureManifestSchema), method(_void(), HealthStatusSchema), met
26764
26970
  }), method(_void(), SiteLocationStatusSchema, {
26765
26971
  kind: "mutation",
26766
26972
  auth: "admin"
26767
- }), method(_void(), RequestCensusStatusSchema, { auth: "admin" }), method(GetLoggingSettingsInputSchema, LoggingSettingsStateSchema, { auth: "admin" }), method(SetLoggingSettingsInputSchema, LoggingSettingsStateSchema, {
26973
+ }), method(_void(), RequestCensusStatusSchema, { auth: "admin" }), method(_void(), array(ReportedLoadContributionSchema).readonly(), { auth: "admin" }), method(GetLoggingSettingsInputSchema, LoggingSettingsStateSchema, { auth: "admin" }), method(SetLoggingSettingsInputSchema, LoggingSettingsStateSchema, {
26768
26974
  kind: "mutation",
26769
26975
  auth: "admin"
26770
26976
  });
@@ -28380,6 +28586,12 @@ Object.freeze({
28380
28586
  addonId: null,
28381
28587
  access: "create"
28382
28588
  },
28589
+ "dataStoreProvider.insertMany": {
28590
+ capName: "data-store-provider",
28591
+ capScope: "system",
28592
+ addonId: null,
28593
+ access: "create"
28594
+ },
28383
28595
  "dataStoreProvider.isEmpty": {
28384
28596
  capName: "data-store-provider",
28385
28597
  capScope: "system",
@@ -29694,6 +29906,12 @@ Object.freeze({
29694
29906
  addonId: null,
29695
29907
  access: "create"
29696
29908
  },
29909
+ "loadContribution.list": {
29910
+ capName: "load-contribution",
29911
+ capScope: "system",
29912
+ addonId: null,
29913
+ access: "view"
29914
+ },
29697
29915
  "localNetwork.downloadCa": {
29698
29916
  capName: "local-network",
29699
29917
  capScope: "system",
@@ -29994,17 +30212,17 @@ Object.freeze({
29994
30212
  addonId: null,
29995
30213
  access: "view"
29996
30214
  },
29997
- "metricsProvider.getProcessStats": {
30215
+ "metricsProvider.getLoadSeries": {
29998
30216
  capName: "metrics-provider",
29999
30217
  capScope: "system",
30000
30218
  addonId: null,
30001
30219
  access: "view"
30002
30220
  },
30003
- "metricsProvider.killProcess": {
30221
+ "metricsProvider.getProcessStats": {
30004
30222
  capName: "metrics-provider",
30005
30223
  capScope: "system",
30006
30224
  addonId: null,
30007
- access: "create"
30225
+ access: "view"
30008
30226
  },
30009
30227
  "metricsProvider.listAddonInstances": {
30010
30228
  capName: "metrics-provider",
@@ -32016,6 +32234,12 @@ Object.freeze({
32016
32234
  addonId: null,
32017
32235
  access: "create"
32018
32236
  },
32237
+ "settingsStore.insertMany": {
32238
+ capName: "settings-store",
32239
+ capScope: "system",
32240
+ addonId: null,
32241
+ access: "create"
32242
+ },
32019
32243
  "settingsStore.isEmpty": {
32020
32244
  capName: "settings-store",
32021
32245
  capScope: "system",
@@ -32628,6 +32852,12 @@ Object.freeze({
32628
32852
  addonId: null,
32629
32853
  access: "create"
32630
32854
  },
32855
+ "system.getLoadContributions": {
32856
+ capName: "system",
32857
+ capScope: "system",
32858
+ addonId: null,
32859
+ access: "view"
32860
+ },
32631
32861
  "system.getLoggingSettings": {
32632
32862
  capName: "system",
32633
32863
  capScope: "system",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-mqtt-broker",
3
- "version": "1.2.34",
3
+ "version": "1.2.36",
4
4
  "description": "MQTT broker registry addon for CamStack — manages external broker entries + an optional embedded aedes broker. Consumers spin up their own `mqtt.js` clients via the `mqtt-broker` cap.",
5
5
  "keywords": [
6
6
  "camstack",