@camstack/addon-provider-wyze 0.2.39 → 0.2.41

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
@@ -31,7 +31,7 @@ let net = require("net");
31
31
  net = __toESM(net, 1);
32
32
  let node_child_process = require("node:child_process");
33
33
  let node_tls = require("node:tls");
34
- //#region ../types/dist/event-category-CIa_iT6b.mjs
34
+ //#region ../types/dist/event-category-BZL-fdNj.mjs
35
35
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
36
36
  EventCategory["SystemBoot"] = "system.boot";
37
37
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -468,7 +468,7 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
468
468
  EventCategory["MetricsNodeResourcesSnapshot"] = "metrics.node-resources-snapshot";
469
469
  /**
470
470
  * Periodic per-node process-tree snapshot (camstack-related pids
471
- * with ghost / managed / root classification). Emitted ~0.2 Hz by
471
+ * with root / managed / system classification). Emitted ~0.2 Hz by
472
472
  * the metrics-provider addon. Drives the Cluster → Processes tab
473
473
  * without polling `metricsProvider.listNodeProcesses`.
474
474
  */
@@ -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(),
@@ -13371,6 +13395,68 @@ method(LogEntrySchema, _void(), { kind: "mutation" }), method(object({
13371
13395
  limit: number().optional(),
13372
13396
  tags: record(string(), string()).optional()
13373
13397
  }), array(LogEntrySchema).readonly());
13398
+ var LoadContributionSchema = object({
13399
+ role: _enum([
13400
+ "decode",
13401
+ "transcode",
13402
+ "recording",
13403
+ "streaming",
13404
+ "detection"
13405
+ ]),
13406
+ /**
13407
+ * The NUMERIC device id — the same value every log line carries as
13408
+ * `tags.deviceId`. `null` means this cost genuinely belongs to no single
13409
+ * camera (a shared pool), NOT that the contributor forgot to look it up: a
13410
+ * contributor that cannot name its camera must not emit the entry at all,
13411
+ * because an unnamed per-camera entry is indistinguishable from a shared one
13412
+ * and would quietly turn one camera's cost into everybody's.
13413
+ */
13414
+ deviceId: number().int().positive().nullable(),
13415
+ attribution: _enum([
13416
+ "measured",
13417
+ "accounted",
13418
+ "unattributable"
13419
+ ]),
13420
+ /**
13421
+ * What ONE entry is, in the contributor's own words — `615/high`,
13422
+ * `617/native`, `cuda:0 shared pool`. Free text because the unit differs per
13423
+ * family and inventing a common one would lose the only information that
13424
+ * makes two entries for the same camera distinguishable.
13425
+ */
13426
+ unit: string(),
13427
+ /**
13428
+ * The OS process this cost lives in, when there is one. Present so a
13429
+ * consumer can (a) tell two generations of the same unit apart across a
13430
+ * restart, and (b) subtract claimed processes from the node's process
13431
+ * snapshot to see what NOBODY claimed. Absent for an entry that owns no
13432
+ * process of its own.
13433
+ */
13434
+ pid: number().int().positive().optional(),
13435
+ /**
13436
+ * When this generation started. The pid's incarnation marker: a consumer
13437
+ * differencing {@link LoadContributionSchema.shape.cpuSeconds} must drop the
13438
+ * window when this changes, because the counter restarted from zero in a new
13439
+ * process.
13440
+ */
13441
+ startedAtMs: number().optional(),
13442
+ /**
13443
+ * CUMULATIVE CPU seconds this unit has consumed since it started — user +
13444
+ * system, read from the child's own `/proc/<pid>/stat` at the moment the
13445
+ * contribution is asked for.
13446
+ *
13447
+ * Cumulative and not a rate on purpose: a rate needs a window, a window
13448
+ * needs a sampler, and a new per-node sampler is the defect half of
13449
+ * `docs/architecture/load-ledger.md` documents. A counter can be differenced
13450
+ * by whoever already keeps a history; a rate cannot be un-averaged.
13451
+ *
13452
+ * Absent — never zero — on a node with no `/proc`, on a read failure, and on
13453
+ * an entry with no process.
13454
+ */
13455
+ cpuSeconds: number().optional(),
13456
+ /** Resident bytes of this unit's process, same source and same rules. */
13457
+ rssBytes: number().optional()
13458
+ });
13459
+ method(_void(), array(LoadContributionSchema).readonly());
13374
13460
  /**
13375
13461
  * `login-method` — collection cap through which auth addons contribute
13376
13462
  * their pre-auth login surfaces to the login page. This is the SINGLE,
@@ -13574,8 +13660,7 @@ var NodeProcessSchema = object({
13574
13660
  classification: _enum([
13575
13661
  "root",
13576
13662
  "managed",
13577
- "system",
13578
- "ghost"
13663
+ "system"
13579
13664
  ]),
13580
13665
  /** `$process` addon binding when `managed`, else null. */
13581
13666
  addonId: string().nullable(),
@@ -13583,22 +13668,39 @@ var NodeProcessSchema = object({
13583
13668
  nodeId: string().nullable(),
13584
13669
  /** Truncated command line. */
13585
13670
  command: string(),
13671
+ /**
13672
+ * `ps pcpu` — CPU averaged over the process's WHOLE LIFETIME, not a rate.
13673
+ * On a runner up for days it barely moves. Fine as a column, useless as a
13674
+ * series: use `cpuMainPercent + cpuGcPercent` for anything time-varying.
13675
+ */
13586
13676
  cpuPercent: number(),
13587
13677
  memoryRssBytes: number(),
13678
+ /**
13679
+ * Instantaneous CPU% of the process's own threads over the last
13680
+ * process-snapshot window, from a `/proc/<pid>/task/*` tick delta.
13681
+ *
13682
+ * `null` = UNKNOWN, never zero: no previous sample yet (first tick after
13683
+ * boot), the pid was recycled, or this node is not Linux.
13684
+ */
13685
+ cpuMainPercent: number().nullable(),
13686
+ /**
13687
+ * Instantaneous CPU% of V8's `V8Worker` platform pool over the same window.
13688
+ *
13689
+ * This is the number that rewrote the 2026-08-27 diagnosis — hub-main 73%,
13690
+ * `stream-broker` 61% (`docs/architecture/load-ledger.md`). A CPU chart that
13691
+ * does not separate it from `cpuMainPercent` shows "busy" where the truth is
13692
+ * "allocating too much".
13693
+ *
13694
+ * Concurrent GC is the dominant tenant of that pool but not the only one
13695
+ * (background compilation runs there too), so it is reported as
13696
+ * "GC / V8 helpers" rather than as pure collection time. `null` has the same
13697
+ * meaning as on `cpuMainPercent`.
13698
+ */
13699
+ cpuGcPercent: number().nullable(),
13700
+ /** Threads seen in the tick scan. `null` under the same conditions. */
13701
+ threadCount: number().nullable(),
13588
13702
  /** Wall-clock uptime (seconds). Parsed from `ps etime`. */
13589
- uptimeSec: number(),
13590
- /** True when ancestor walk reaches `ppid=1` (reparented to init/launchd). */
13591
- orphaned: boolean()
13592
- });
13593
- var KillProcessInputSchema = object({
13594
- pid: number(),
13595
- /** Force = SIGKILL. Default is SIGTERM. */
13596
- force: boolean().optional()
13597
- });
13598
- var KillProcessResultSchema = object({
13599
- success: boolean(),
13600
- reason: string().optional(),
13601
- signal: _enum(["SIGTERM", "SIGKILL"]).optional()
13703
+ uptimeSec: number()
13602
13704
  });
13603
13705
  var DumpHeapSnapshotInputSchema = object({
13604
13706
  /** The addon whose runner should dump a heap snapshot. */
@@ -13611,6 +13713,104 @@ var DumpHeapSnapshotResultSchema = object({
13611
13713
  pid: number().optional(),
13612
13714
  reason: string().optional()
13613
13715
  });
13716
+ /**
13717
+ * One point of one function's series.
13718
+ *
13719
+ * The unsuffixed fields are the bucket's **MAXIMUM**, and that choice is the
13720
+ * point of the whole surface. The two obvious reductions both lie: a mean per
13721
+ * bucket smears a spike away, and taking every Nth sample skips it outright.
13722
+ * Either would give us a tool built to find peaks that does not show peaks.
13723
+ * `...Min` carries the other end, `samples` says how many raw snapshots folded
13724
+ * into the bucket, and a mean stays derivable where it is wanted.
13725
+ *
13726
+ * An UNREDUCED point is a one-sample bucket: `samples === 1` and each `...Min`
13727
+ * equals its unsuffixed twin. Reduced and unreduced are the same shape, so a
13728
+ * caller cannot tell which it received — which is what "one reader" means.
13729
+ */
13730
+ var LoadPointSchema = object({
13731
+ /** Bucket START, or the snapshot's own timestamp when unreduced. */
13732
+ atMs: number(),
13733
+ /** Raw snapshots in this bucket. Never 0 — AN EMPTY BUCKET IS ABSENT. */
13734
+ samples: number().int(),
13735
+ /**
13736
+ * `null` = UNKNOWN and it PROPAGATES: a bucket is null unless every process
13737
+ * of every snapshot in it reported a thread split. A partial sum is a
13738
+ * smaller number that looks exactly as real as a complete one.
13739
+ */
13740
+ cpuMainPercent: number().nullable(),
13741
+ cpuMainPercentMin: number().nullable(),
13742
+ cpuGcPercent: number().nullable(),
13743
+ cpuGcPercentMin: number().nullable(),
13744
+ /** Lifetime-average CPU%, summed. Always known — and never a rate. */
13745
+ cpuLifetimePercent: number(),
13746
+ cpuLifetimePercentMin: number(),
13747
+ memoryRssBytes: number(),
13748
+ memoryRssBytesMin: number(),
13749
+ processCount: number().int(),
13750
+ processCountMin: number().int()
13751
+ });
13752
+ /** One function's series. `key` is an addonId, `__root__` or `__unattributed__`. */
13753
+ var LoadFunctionSeriesSchema = object({
13754
+ key: string(),
13755
+ kind: _enum([
13756
+ "addon",
13757
+ "root",
13758
+ "unattributed"
13759
+ ]),
13760
+ /** Oldest-first. A missing interval is MISSING — never zero-filled. */
13761
+ points: array(LoadPointSchema).readonly()
13762
+ });
13763
+ var NodeLoadSeriesSchema = object({
13764
+ nodeId: string(),
13765
+ /** One entry per function seen in the window, heaviest-first. */
13766
+ series: array(LoadFunctionSeriesSchema).readonly(),
13767
+ /**
13768
+ * Width of one returned bucket, in ms. Equals the sampling cadence when no
13769
+ * reduction was needed — so a caller can always say what one point covers
13770
+ * without having to know whether it was reduced.
13771
+ */
13772
+ bucketMs: number(),
13773
+ /** Raw snapshots that went into this answer, across both tiers. */
13774
+ retainedSamples: number(),
13775
+ /** Oldest snapshot represented, or `null` when nothing is retained. */
13776
+ oldestAtMs: number().nullable(),
13777
+ /** The fixed sampling cadence in force on the cluster, in ms. */
13778
+ cadenceMs: number(),
13779
+ /**
13780
+ * Did the DURABLE tier contribute? `false` means the answer is the hot ring
13781
+ * alone — an agent (which holds no table), or a store that refused.
13782
+ * Reported because "the last hour" and "the last six hours" are different
13783
+ * questions and an operator must not have to guess which was answered.
13784
+ */
13785
+ durable: boolean()
13786
+ });
13787
+ var GetLoadSeriesInputSchema = object({
13788
+ /**
13789
+ * The node whose series is wanted.
13790
+ *
13791
+ * NOT named `nodeId`: the generated cap router strips a top-level
13792
+ * `nodeId` from every method input and uses it to ROUTE the call to
13793
+ * that node's provider (`generated-cap-routers.ts`). A series target
13794
+ * called `nodeId` would silently become a routing pin and never reach
13795
+ * the provider. The hub holds every node it hears from, so the
13796
+ * ordinary call is unpinned — answered by the hub, for any node.
13797
+ */
13798
+ forNodeId: string(),
13799
+ /**
13800
+ * EXCLUSIVE lower bound. A caller passes the newest `atMs` it already
13801
+ * holds and receives only what it is missing, so seeding a live chart
13802
+ * from this method cannot double a point already drawn.
13803
+ */
13804
+ sinceMs: number().optional(),
13805
+ /**
13806
+ * Most points the caller wants PER FUNCTION. The window is reduced to fit,
13807
+ * preserving min and max per bucket.
13808
+ *
13809
+ * Absent means NO reduction — legitimate for a short window and a trap for a
13810
+ * long one, which is why a chart passes its own pixel width.
13811
+ */
13812
+ maxPoints: number().int().positive().optional()
13813
+ });
13614
13814
  var SystemMetricsSchema = object({
13615
13815
  cpuPercent: number(),
13616
13816
  memoryPercent: number(),
@@ -13621,10 +13821,7 @@ var SystemMetricsSchema = object({
13621
13821
  gpuPercent: number().optional(),
13622
13822
  gpuMemoryPercent: number().optional()
13623
13823
  });
13624
- 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, {
13625
- kind: "mutation",
13626
- auth: "admin"
13627
- }), method(DumpHeapSnapshotInputSchema, DumpHeapSnapshotResultSchema, {
13824
+ 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, {
13628
13825
  kind: "mutation",
13629
13826
  auth: "admin"
13630
13827
  });
@@ -29066,6 +29263,15 @@ var LoggingSettingsPatchSchema = object({
29066
29263
  * authority over the whole hierarchy and answers for every layer, so the
29067
29264
  * layer selector needs a name the transport does not already own.
29068
29265
  */
29266
+ /**
29267
+ * One contribution, plus WHO reported it.
29268
+ *
29269
+ * The addon and node are added by the hub as it enumerates providers, never by
29270
+ * the contributor: an addon reporting its own identity could report somebody
29271
+ * else's, and the whole point of this surface is that no claim is made by
29272
+ * anyone but its owner.
29273
+ */
29274
+ var ReportedLoadContributionSchema = LoadContributionSchema.extend({ addonId: string() });
29069
29275
  var GetLoggingSettingsInputSchema = object({
29070
29276
  scopeNodeId: string().optional(),
29071
29277
  /**
@@ -29124,7 +29330,7 @@ method(_void(), FeatureManifestSchema), method(_void(), HealthStatusSchema), met
29124
29330
  }), method(_void(), SiteLocationStatusSchema, {
29125
29331
  kind: "mutation",
29126
29332
  auth: "admin"
29127
- }), method(_void(), RequestCensusStatusSchema, { auth: "admin" }), method(GetLoggingSettingsInputSchema, LoggingSettingsStateSchema, { auth: "admin" }), method(SetLoggingSettingsInputSchema, LoggingSettingsStateSchema, {
29333
+ }), method(_void(), RequestCensusStatusSchema, { auth: "admin" }), method(_void(), array(ReportedLoadContributionSchema).readonly(), { auth: "admin" }), method(GetLoggingSettingsInputSchema, LoggingSettingsStateSchema, { auth: "admin" }), method(SetLoggingSettingsInputSchema, LoggingSettingsStateSchema, {
29128
29334
  kind: "mutation",
29129
29335
  auth: "admin"
29130
29336
  });
@@ -32148,6 +32354,12 @@ Object.freeze({
32148
32354
  addonId: null,
32149
32355
  access: "create"
32150
32356
  },
32357
+ "dataStoreProvider.insertMany": {
32358
+ capName: "data-store-provider",
32359
+ capScope: "system",
32360
+ addonId: null,
32361
+ access: "create"
32362
+ },
32151
32363
  "dataStoreProvider.isEmpty": {
32152
32364
  capName: "data-store-provider",
32153
32365
  capScope: "system",
@@ -33462,6 +33674,12 @@ Object.freeze({
33462
33674
  addonId: null,
33463
33675
  access: "create"
33464
33676
  },
33677
+ "loadContribution.list": {
33678
+ capName: "load-contribution",
33679
+ capScope: "system",
33680
+ addonId: null,
33681
+ access: "view"
33682
+ },
33465
33683
  "localNetwork.downloadCa": {
33466
33684
  capName: "local-network",
33467
33685
  capScope: "system",
@@ -33762,17 +33980,17 @@ Object.freeze({
33762
33980
  addonId: null,
33763
33981
  access: "view"
33764
33982
  },
33765
- "metricsProvider.getProcessStats": {
33983
+ "metricsProvider.getLoadSeries": {
33766
33984
  capName: "metrics-provider",
33767
33985
  capScope: "system",
33768
33986
  addonId: null,
33769
33987
  access: "view"
33770
33988
  },
33771
- "metricsProvider.killProcess": {
33989
+ "metricsProvider.getProcessStats": {
33772
33990
  capName: "metrics-provider",
33773
33991
  capScope: "system",
33774
33992
  addonId: null,
33775
- access: "create"
33993
+ access: "view"
33776
33994
  },
33777
33995
  "metricsProvider.listAddonInstances": {
33778
33996
  capName: "metrics-provider",
@@ -35784,6 +36002,12 @@ Object.freeze({
35784
36002
  addonId: null,
35785
36003
  access: "create"
35786
36004
  },
36005
+ "settingsStore.insertMany": {
36006
+ capName: "settings-store",
36007
+ capScope: "system",
36008
+ addonId: null,
36009
+ access: "create"
36010
+ },
35787
36011
  "settingsStore.isEmpty": {
35788
36012
  capName: "settings-store",
35789
36013
  capScope: "system",
@@ -36396,6 +36620,12 @@ Object.freeze({
36396
36620
  addonId: null,
36397
36621
  access: "create"
36398
36622
  },
36623
+ "system.getLoadContributions": {
36624
+ capName: "system",
36625
+ capScope: "system",
36626
+ addonId: null,
36627
+ access: "view"
36628
+ },
36399
36629
  "system.getLoggingSettings": {
36400
36630
  capName: "system",
36401
36631
  capScope: "system",
package/dist/addon.mjs CHANGED
@@ -10,7 +10,7 @@ import { getCACertificates, setDefaultCACertificates } from "node:tls";
10
10
  //#region \0rolldown/runtime.js
11
11
  var __require$1 = /* @__PURE__ */ createRequire(import.meta.url);
12
12
  //#endregion
13
- //#region ../types/dist/event-category-CIa_iT6b.mjs
13
+ //#region ../types/dist/event-category-BZL-fdNj.mjs
14
14
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
15
15
  EventCategory["SystemBoot"] = "system.boot";
16
16
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -447,7 +447,7 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
447
447
  EventCategory["MetricsNodeResourcesSnapshot"] = "metrics.node-resources-snapshot";
448
448
  /**
449
449
  * Periodic per-node process-tree snapshot (camstack-related pids
450
- * with ghost / managed / root classification). Emitted ~0.2 Hz by
450
+ * with root / managed / system classification). Emitted ~0.2 Hz by
451
451
  * the metrics-provider addon. Drives the Cluster → Processes tab
452
452
  * without polling `metricsProvider.listNodeProcesses`.
453
453
  */
@@ -11239,6 +11239,19 @@ var SettingsRecordSchema = object({
11239
11239
  data: record(string(), unknown())
11240
11240
  });
11241
11241
  /**
11242
+ * One record of a BULK insert — {@link SettingsRecordSchema} with the id made
11243
+ * optional.
11244
+ *
11245
+ * A separate schema rather than loosening the shared one: every other method
11246
+ * on this cap addresses a row BY its id, and making that field optional
11247
+ * everywhere would turn a forgotten key into a silently generated one on
11248
+ * `update` and `delete` as well.
11249
+ */
11250
+ var BulkRecordSchema = object({
11251
+ id: string().optional(),
11252
+ data: record(string(), unknown())
11253
+ });
11254
+ /**
11242
11255
  * Column declaration for a structured (SQL-backed) collection.
11243
11256
  *
11244
11257
  * Logical types — the backend translates each to the matching SQLite
@@ -11295,6 +11308,10 @@ method(object({
11295
11308
  collection: string(),
11296
11309
  record: SettingsRecordSchema
11297
11310
  }), _void(), { kind: "mutation" }), method(object({
11311
+ namespace: string().optional(),
11312
+ collection: string(),
11313
+ records: array(BulkRecordSchema).readonly()
11314
+ }), object({ inserted: number().int() }), { kind: "mutation" }), method(object({
11298
11315
  namespace: string().optional(),
11299
11316
  collection: string(),
11300
11317
  id: string(),
@@ -11403,6 +11420,13 @@ method(_void(), EngineInfoSchema, { auth: "admin" }), method(object({
11403
11420
  }), _void(), {
11404
11421
  kind: "mutation",
11405
11422
  auth: "admin"
11423
+ }), method(object({
11424
+ namespace: string().optional(),
11425
+ collection: string(),
11426
+ records: array(BulkRecordSchema).readonly()
11427
+ }), object({ inserted: number().int() }), {
11428
+ kind: "mutation",
11429
+ auth: "admin"
11406
11430
  }), method(object({
11407
11431
  namespace: string().optional(),
11408
11432
  collection: string(),
@@ -13350,6 +13374,68 @@ method(LogEntrySchema, _void(), { kind: "mutation" }), method(object({
13350
13374
  limit: number().optional(),
13351
13375
  tags: record(string(), string()).optional()
13352
13376
  }), array(LogEntrySchema).readonly());
13377
+ var LoadContributionSchema = object({
13378
+ role: _enum([
13379
+ "decode",
13380
+ "transcode",
13381
+ "recording",
13382
+ "streaming",
13383
+ "detection"
13384
+ ]),
13385
+ /**
13386
+ * The NUMERIC device id — the same value every log line carries as
13387
+ * `tags.deviceId`. `null` means this cost genuinely belongs to no single
13388
+ * camera (a shared pool), NOT that the contributor forgot to look it up: a
13389
+ * contributor that cannot name its camera must not emit the entry at all,
13390
+ * because an unnamed per-camera entry is indistinguishable from a shared one
13391
+ * and would quietly turn one camera's cost into everybody's.
13392
+ */
13393
+ deviceId: number().int().positive().nullable(),
13394
+ attribution: _enum([
13395
+ "measured",
13396
+ "accounted",
13397
+ "unattributable"
13398
+ ]),
13399
+ /**
13400
+ * What ONE entry is, in the contributor's own words — `615/high`,
13401
+ * `617/native`, `cuda:0 shared pool`. Free text because the unit differs per
13402
+ * family and inventing a common one would lose the only information that
13403
+ * makes two entries for the same camera distinguishable.
13404
+ */
13405
+ unit: string(),
13406
+ /**
13407
+ * The OS process this cost lives in, when there is one. Present so a
13408
+ * consumer can (a) tell two generations of the same unit apart across a
13409
+ * restart, and (b) subtract claimed processes from the node's process
13410
+ * snapshot to see what NOBODY claimed. Absent for an entry that owns no
13411
+ * process of its own.
13412
+ */
13413
+ pid: number().int().positive().optional(),
13414
+ /**
13415
+ * When this generation started. The pid's incarnation marker: a consumer
13416
+ * differencing {@link LoadContributionSchema.shape.cpuSeconds} must drop the
13417
+ * window when this changes, because the counter restarted from zero in a new
13418
+ * process.
13419
+ */
13420
+ startedAtMs: number().optional(),
13421
+ /**
13422
+ * CUMULATIVE CPU seconds this unit has consumed since it started — user +
13423
+ * system, read from the child's own `/proc/<pid>/stat` at the moment the
13424
+ * contribution is asked for.
13425
+ *
13426
+ * Cumulative and not a rate on purpose: a rate needs a window, a window
13427
+ * needs a sampler, and a new per-node sampler is the defect half of
13428
+ * `docs/architecture/load-ledger.md` documents. A counter can be differenced
13429
+ * by whoever already keeps a history; a rate cannot be un-averaged.
13430
+ *
13431
+ * Absent — never zero — on a node with no `/proc`, on a read failure, and on
13432
+ * an entry with no process.
13433
+ */
13434
+ cpuSeconds: number().optional(),
13435
+ /** Resident bytes of this unit's process, same source and same rules. */
13436
+ rssBytes: number().optional()
13437
+ });
13438
+ method(_void(), array(LoadContributionSchema).readonly());
13353
13439
  /**
13354
13440
  * `login-method` — collection cap through which auth addons contribute
13355
13441
  * their pre-auth login surfaces to the login page. This is the SINGLE,
@@ -13553,8 +13639,7 @@ var NodeProcessSchema = object({
13553
13639
  classification: _enum([
13554
13640
  "root",
13555
13641
  "managed",
13556
- "system",
13557
- "ghost"
13642
+ "system"
13558
13643
  ]),
13559
13644
  /** `$process` addon binding when `managed`, else null. */
13560
13645
  addonId: string().nullable(),
@@ -13562,22 +13647,39 @@ var NodeProcessSchema = object({
13562
13647
  nodeId: string().nullable(),
13563
13648
  /** Truncated command line. */
13564
13649
  command: string(),
13650
+ /**
13651
+ * `ps pcpu` — CPU averaged over the process's WHOLE LIFETIME, not a rate.
13652
+ * On a runner up for days it barely moves. Fine as a column, useless as a
13653
+ * series: use `cpuMainPercent + cpuGcPercent` for anything time-varying.
13654
+ */
13565
13655
  cpuPercent: number(),
13566
13656
  memoryRssBytes: number(),
13657
+ /**
13658
+ * Instantaneous CPU% of the process's own threads over the last
13659
+ * process-snapshot window, from a `/proc/<pid>/task/*` tick delta.
13660
+ *
13661
+ * `null` = UNKNOWN, never zero: no previous sample yet (first tick after
13662
+ * boot), the pid was recycled, or this node is not Linux.
13663
+ */
13664
+ cpuMainPercent: number().nullable(),
13665
+ /**
13666
+ * Instantaneous CPU% of V8's `V8Worker` platform pool over the same window.
13667
+ *
13668
+ * This is the number that rewrote the 2026-08-27 diagnosis — hub-main 73%,
13669
+ * `stream-broker` 61% (`docs/architecture/load-ledger.md`). A CPU chart that
13670
+ * does not separate it from `cpuMainPercent` shows "busy" where the truth is
13671
+ * "allocating too much".
13672
+ *
13673
+ * Concurrent GC is the dominant tenant of that pool but not the only one
13674
+ * (background compilation runs there too), so it is reported as
13675
+ * "GC / V8 helpers" rather than as pure collection time. `null` has the same
13676
+ * meaning as on `cpuMainPercent`.
13677
+ */
13678
+ cpuGcPercent: number().nullable(),
13679
+ /** Threads seen in the tick scan. `null` under the same conditions. */
13680
+ threadCount: number().nullable(),
13567
13681
  /** Wall-clock uptime (seconds). Parsed from `ps etime`. */
13568
- uptimeSec: number(),
13569
- /** True when ancestor walk reaches `ppid=1` (reparented to init/launchd). */
13570
- orphaned: boolean()
13571
- });
13572
- var KillProcessInputSchema = object({
13573
- pid: number(),
13574
- /** Force = SIGKILL. Default is SIGTERM. */
13575
- force: boolean().optional()
13576
- });
13577
- var KillProcessResultSchema = object({
13578
- success: boolean(),
13579
- reason: string().optional(),
13580
- signal: _enum(["SIGTERM", "SIGKILL"]).optional()
13682
+ uptimeSec: number()
13581
13683
  });
13582
13684
  var DumpHeapSnapshotInputSchema = object({
13583
13685
  /** The addon whose runner should dump a heap snapshot. */
@@ -13590,6 +13692,104 @@ var DumpHeapSnapshotResultSchema = object({
13590
13692
  pid: number().optional(),
13591
13693
  reason: string().optional()
13592
13694
  });
13695
+ /**
13696
+ * One point of one function's series.
13697
+ *
13698
+ * The unsuffixed fields are the bucket's **MAXIMUM**, and that choice is the
13699
+ * point of the whole surface. The two obvious reductions both lie: a mean per
13700
+ * bucket smears a spike away, and taking every Nth sample skips it outright.
13701
+ * Either would give us a tool built to find peaks that does not show peaks.
13702
+ * `...Min` carries the other end, `samples` says how many raw snapshots folded
13703
+ * into the bucket, and a mean stays derivable where it is wanted.
13704
+ *
13705
+ * An UNREDUCED point is a one-sample bucket: `samples === 1` and each `...Min`
13706
+ * equals its unsuffixed twin. Reduced and unreduced are the same shape, so a
13707
+ * caller cannot tell which it received — which is what "one reader" means.
13708
+ */
13709
+ var LoadPointSchema = object({
13710
+ /** Bucket START, or the snapshot's own timestamp when unreduced. */
13711
+ atMs: number(),
13712
+ /** Raw snapshots in this bucket. Never 0 — AN EMPTY BUCKET IS ABSENT. */
13713
+ samples: number().int(),
13714
+ /**
13715
+ * `null` = UNKNOWN and it PROPAGATES: a bucket is null unless every process
13716
+ * of every snapshot in it reported a thread split. A partial sum is a
13717
+ * smaller number that looks exactly as real as a complete one.
13718
+ */
13719
+ cpuMainPercent: number().nullable(),
13720
+ cpuMainPercentMin: number().nullable(),
13721
+ cpuGcPercent: number().nullable(),
13722
+ cpuGcPercentMin: number().nullable(),
13723
+ /** Lifetime-average CPU%, summed. Always known — and never a rate. */
13724
+ cpuLifetimePercent: number(),
13725
+ cpuLifetimePercentMin: number(),
13726
+ memoryRssBytes: number(),
13727
+ memoryRssBytesMin: number(),
13728
+ processCount: number().int(),
13729
+ processCountMin: number().int()
13730
+ });
13731
+ /** One function's series. `key` is an addonId, `__root__` or `__unattributed__`. */
13732
+ var LoadFunctionSeriesSchema = object({
13733
+ key: string(),
13734
+ kind: _enum([
13735
+ "addon",
13736
+ "root",
13737
+ "unattributed"
13738
+ ]),
13739
+ /** Oldest-first. A missing interval is MISSING — never zero-filled. */
13740
+ points: array(LoadPointSchema).readonly()
13741
+ });
13742
+ var NodeLoadSeriesSchema = object({
13743
+ nodeId: string(),
13744
+ /** One entry per function seen in the window, heaviest-first. */
13745
+ series: array(LoadFunctionSeriesSchema).readonly(),
13746
+ /**
13747
+ * Width of one returned bucket, in ms. Equals the sampling cadence when no
13748
+ * reduction was needed — so a caller can always say what one point covers
13749
+ * without having to know whether it was reduced.
13750
+ */
13751
+ bucketMs: number(),
13752
+ /** Raw snapshots that went into this answer, across both tiers. */
13753
+ retainedSamples: number(),
13754
+ /** Oldest snapshot represented, or `null` when nothing is retained. */
13755
+ oldestAtMs: number().nullable(),
13756
+ /** The fixed sampling cadence in force on the cluster, in ms. */
13757
+ cadenceMs: number(),
13758
+ /**
13759
+ * Did the DURABLE tier contribute? `false` means the answer is the hot ring
13760
+ * alone — an agent (which holds no table), or a store that refused.
13761
+ * Reported because "the last hour" and "the last six hours" are different
13762
+ * questions and an operator must not have to guess which was answered.
13763
+ */
13764
+ durable: boolean()
13765
+ });
13766
+ var GetLoadSeriesInputSchema = object({
13767
+ /**
13768
+ * The node whose series is wanted.
13769
+ *
13770
+ * NOT named `nodeId`: the generated cap router strips a top-level
13771
+ * `nodeId` from every method input and uses it to ROUTE the call to
13772
+ * that node's provider (`generated-cap-routers.ts`). A series target
13773
+ * called `nodeId` would silently become a routing pin and never reach
13774
+ * the provider. The hub holds every node it hears from, so the
13775
+ * ordinary call is unpinned — answered by the hub, for any node.
13776
+ */
13777
+ forNodeId: string(),
13778
+ /**
13779
+ * EXCLUSIVE lower bound. A caller passes the newest `atMs` it already
13780
+ * holds and receives only what it is missing, so seeding a live chart
13781
+ * from this method cannot double a point already drawn.
13782
+ */
13783
+ sinceMs: number().optional(),
13784
+ /**
13785
+ * Most points the caller wants PER FUNCTION. The window is reduced to fit,
13786
+ * preserving min and max per bucket.
13787
+ *
13788
+ * Absent means NO reduction — legitimate for a short window and a trap for a
13789
+ * long one, which is why a chart passes its own pixel width.
13790
+ */
13791
+ maxPoints: number().int().positive().optional()
13792
+ });
13593
13793
  var SystemMetricsSchema = object({
13594
13794
  cpuPercent: number(),
13595
13795
  memoryPercent: number(),
@@ -13600,10 +13800,7 @@ var SystemMetricsSchema = object({
13600
13800
  gpuPercent: number().optional(),
13601
13801
  gpuMemoryPercent: number().optional()
13602
13802
  });
13603
- 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, {
13604
- kind: "mutation",
13605
- auth: "admin"
13606
- }), method(DumpHeapSnapshotInputSchema, DumpHeapSnapshotResultSchema, {
13803
+ 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, {
13607
13804
  kind: "mutation",
13608
13805
  auth: "admin"
13609
13806
  });
@@ -29045,6 +29242,15 @@ var LoggingSettingsPatchSchema = object({
29045
29242
  * authority over the whole hierarchy and answers for every layer, so the
29046
29243
  * layer selector needs a name the transport does not already own.
29047
29244
  */
29245
+ /**
29246
+ * One contribution, plus WHO reported it.
29247
+ *
29248
+ * The addon and node are added by the hub as it enumerates providers, never by
29249
+ * the contributor: an addon reporting its own identity could report somebody
29250
+ * else's, and the whole point of this surface is that no claim is made by
29251
+ * anyone but its owner.
29252
+ */
29253
+ var ReportedLoadContributionSchema = LoadContributionSchema.extend({ addonId: string() });
29048
29254
  var GetLoggingSettingsInputSchema = object({
29049
29255
  scopeNodeId: string().optional(),
29050
29256
  /**
@@ -29103,7 +29309,7 @@ method(_void(), FeatureManifestSchema), method(_void(), HealthStatusSchema), met
29103
29309
  }), method(_void(), SiteLocationStatusSchema, {
29104
29310
  kind: "mutation",
29105
29311
  auth: "admin"
29106
- }), method(_void(), RequestCensusStatusSchema, { auth: "admin" }), method(GetLoggingSettingsInputSchema, LoggingSettingsStateSchema, { auth: "admin" }), method(SetLoggingSettingsInputSchema, LoggingSettingsStateSchema, {
29312
+ }), method(_void(), RequestCensusStatusSchema, { auth: "admin" }), method(_void(), array(ReportedLoadContributionSchema).readonly(), { auth: "admin" }), method(GetLoggingSettingsInputSchema, LoggingSettingsStateSchema, { auth: "admin" }), method(SetLoggingSettingsInputSchema, LoggingSettingsStateSchema, {
29107
29313
  kind: "mutation",
29108
29314
  auth: "admin"
29109
29315
  });
@@ -32127,6 +32333,12 @@ Object.freeze({
32127
32333
  addonId: null,
32128
32334
  access: "create"
32129
32335
  },
32336
+ "dataStoreProvider.insertMany": {
32337
+ capName: "data-store-provider",
32338
+ capScope: "system",
32339
+ addonId: null,
32340
+ access: "create"
32341
+ },
32130
32342
  "dataStoreProvider.isEmpty": {
32131
32343
  capName: "data-store-provider",
32132
32344
  capScope: "system",
@@ -33441,6 +33653,12 @@ Object.freeze({
33441
33653
  addonId: null,
33442
33654
  access: "create"
33443
33655
  },
33656
+ "loadContribution.list": {
33657
+ capName: "load-contribution",
33658
+ capScope: "system",
33659
+ addonId: null,
33660
+ access: "view"
33661
+ },
33444
33662
  "localNetwork.downloadCa": {
33445
33663
  capName: "local-network",
33446
33664
  capScope: "system",
@@ -33741,17 +33959,17 @@ Object.freeze({
33741
33959
  addonId: null,
33742
33960
  access: "view"
33743
33961
  },
33744
- "metricsProvider.getProcessStats": {
33962
+ "metricsProvider.getLoadSeries": {
33745
33963
  capName: "metrics-provider",
33746
33964
  capScope: "system",
33747
33965
  addonId: null,
33748
33966
  access: "view"
33749
33967
  },
33750
- "metricsProvider.killProcess": {
33968
+ "metricsProvider.getProcessStats": {
33751
33969
  capName: "metrics-provider",
33752
33970
  capScope: "system",
33753
33971
  addonId: null,
33754
- access: "create"
33972
+ access: "view"
33755
33973
  },
33756
33974
  "metricsProvider.listAddonInstances": {
33757
33975
  capName: "metrics-provider",
@@ -35763,6 +35981,12 @@ Object.freeze({
35763
35981
  addonId: null,
35764
35982
  access: "create"
35765
35983
  },
35984
+ "settingsStore.insertMany": {
35985
+ capName: "settings-store",
35986
+ capScope: "system",
35987
+ addonId: null,
35988
+ access: "create"
35989
+ },
35766
35990
  "settingsStore.isEmpty": {
35767
35991
  capName: "settings-store",
35768
35992
  capScope: "system",
@@ -36375,6 +36599,12 @@ Object.freeze({
36375
36599
  addonId: null,
36376
36600
  access: "create"
36377
36601
  },
36602
+ "system.getLoadContributions": {
36603
+ capName: "system",
36604
+ capScope: "system",
36605
+ addonId: null,
36606
+ access: "view"
36607
+ },
36378
36608
  "system.getLoggingSettings": {
36379
36609
  capName: "system",
36380
36610
  capScope: "system",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-wyze",
3
- "version": "0.2.39",
3
+ "version": "0.2.41",
4
4
  "description": "Wyze camera device-provider addon for CamStack — wraps the @apocaliss92/wyze-bridge-js P2P/DTLS client, feeding the stream-broker via the pull-rfc4571 lazy-publish path (a structural twin of addon-provider-reolink)",
5
5
  "keywords": [
6
6
  "camstack",