@camstack/addon-export-hap 1.2.46 → 1.2.48

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 node_fs = require("node:fs");
44
44
  node_fs = __toESM(node_fs, 1);
45
45
  let node_child_process = require("node:child_process");
46
46
  let node_fs_promises = require("node:fs/promises");
47
- node_fs_promises = __toESM(node_fs_promises);
47
+ node_fs_promises = __toESM(node_fs_promises, 1);
48
48
  let node_dgram = require("node:dgram");
49
49
  let node_os = require("node:os");
50
50
  //#region src/exposed-entry.ts
@@ -84,7 +84,7 @@ function carryForward(base, existing, keys) {
84
84
  return out;
85
85
  }
86
86
  //#endregion
87
- //#region ../types/dist/event-category-CIa_iT6b.mjs
87
+ //#region ../types/dist/event-category-BZL-fdNj.mjs
88
88
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
89
89
  EventCategory["SystemBoot"] = "system.boot";
90
90
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -521,7 +521,7 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
521
521
  EventCategory["MetricsNodeResourcesSnapshot"] = "metrics.node-resources-snapshot";
522
522
  /**
523
523
  * Periodic per-node process-tree snapshot (camstack-related pids
524
- * with ghost / managed / root classification). Emitted ~0.2 Hz by
524
+ * with root / managed / system classification). Emitted ~0.2 Hz by
525
525
  * the metrics-provider addon. Drives the Cluster → Processes tab
526
526
  * without polling `metricsProvider.listNodeProcesses`.
527
527
  */
@@ -11846,6 +11846,19 @@ var SettingsRecordSchema = object({
11846
11846
  data: record(string(), unknown())
11847
11847
  });
11848
11848
  /**
11849
+ * One record of a BULK insert — {@link SettingsRecordSchema} with the id made
11850
+ * optional.
11851
+ *
11852
+ * A separate schema rather than loosening the shared one: every other method
11853
+ * on this cap addresses a row BY its id, and making that field optional
11854
+ * everywhere would turn a forgotten key into a silently generated one on
11855
+ * `update` and `delete` as well.
11856
+ */
11857
+ var BulkRecordSchema = object({
11858
+ id: string().optional(),
11859
+ data: record(string(), unknown())
11860
+ });
11861
+ /**
11849
11862
  * Column declaration for a structured (SQL-backed) collection.
11850
11863
  *
11851
11864
  * Logical types — the backend translates each to the matching SQLite
@@ -11902,6 +11915,10 @@ method(object({
11902
11915
  collection: string(),
11903
11916
  record: SettingsRecordSchema
11904
11917
  }), _void(), { kind: "mutation" }), method(object({
11918
+ namespace: string().optional(),
11919
+ collection: string(),
11920
+ records: array(BulkRecordSchema).readonly()
11921
+ }), object({ inserted: number().int() }), { kind: "mutation" }), method(object({
11905
11922
  namespace: string().optional(),
11906
11923
  collection: string(),
11907
11924
  id: string(),
@@ -12010,6 +12027,13 @@ method(_void(), EngineInfoSchema, { auth: "admin" }), method(object({
12010
12027
  }), _void(), {
12011
12028
  kind: "mutation",
12012
12029
  auth: "admin"
12030
+ }), method(object({
12031
+ namespace: string().optional(),
12032
+ collection: string(),
12033
+ records: array(BulkRecordSchema).readonly()
12034
+ }), object({ inserted: number().int() }), {
12035
+ kind: "mutation",
12036
+ auth: "admin"
12013
12037
  }), method(object({
12014
12038
  namespace: string().optional(),
12015
12039
  collection: string(),
@@ -13859,6 +13883,68 @@ method(LogEntrySchema, _void(), { kind: "mutation" }), method(object({
13859
13883
  limit: number().optional(),
13860
13884
  tags: record(string(), string()).optional()
13861
13885
  }), array(LogEntrySchema).readonly());
13886
+ var LoadContributionSchema = object({
13887
+ role: _enum([
13888
+ "decode",
13889
+ "transcode",
13890
+ "recording",
13891
+ "streaming",
13892
+ "detection"
13893
+ ]),
13894
+ /**
13895
+ * The NUMERIC device id — the same value every log line carries as
13896
+ * `tags.deviceId`. `null` means this cost genuinely belongs to no single
13897
+ * camera (a shared pool), NOT that the contributor forgot to look it up: a
13898
+ * contributor that cannot name its camera must not emit the entry at all,
13899
+ * because an unnamed per-camera entry is indistinguishable from a shared one
13900
+ * and would quietly turn one camera's cost into everybody's.
13901
+ */
13902
+ deviceId: number().int().positive().nullable(),
13903
+ attribution: _enum([
13904
+ "measured",
13905
+ "accounted",
13906
+ "unattributable"
13907
+ ]),
13908
+ /**
13909
+ * What ONE entry is, in the contributor's own words — `615/high`,
13910
+ * `617/native`, `cuda:0 shared pool`. Free text because the unit differs per
13911
+ * family and inventing a common one would lose the only information that
13912
+ * makes two entries for the same camera distinguishable.
13913
+ */
13914
+ unit: string(),
13915
+ /**
13916
+ * The OS process this cost lives in, when there is one. Present so a
13917
+ * consumer can (a) tell two generations of the same unit apart across a
13918
+ * restart, and (b) subtract claimed processes from the node's process
13919
+ * snapshot to see what NOBODY claimed. Absent for an entry that owns no
13920
+ * process of its own.
13921
+ */
13922
+ pid: number().int().positive().optional(),
13923
+ /**
13924
+ * When this generation started. The pid's incarnation marker: a consumer
13925
+ * differencing {@link LoadContributionSchema.shape.cpuSeconds} must drop the
13926
+ * window when this changes, because the counter restarted from zero in a new
13927
+ * process.
13928
+ */
13929
+ startedAtMs: number().optional(),
13930
+ /**
13931
+ * CUMULATIVE CPU seconds this unit has consumed since it started — user +
13932
+ * system, read from the child's own `/proc/<pid>/stat` at the moment the
13933
+ * contribution is asked for.
13934
+ *
13935
+ * Cumulative and not a rate on purpose: a rate needs a window, a window
13936
+ * needs a sampler, and a new per-node sampler is the defect half of
13937
+ * `docs/architecture/load-ledger.md` documents. A counter can be differenced
13938
+ * by whoever already keeps a history; a rate cannot be un-averaged.
13939
+ *
13940
+ * Absent — never zero — on a node with no `/proc`, on a read failure, and on
13941
+ * an entry with no process.
13942
+ */
13943
+ cpuSeconds: number().optional(),
13944
+ /** Resident bytes of this unit's process, same source and same rules. */
13945
+ rssBytes: number().optional()
13946
+ });
13947
+ method(_void(), array(LoadContributionSchema).readonly());
13862
13948
  /**
13863
13949
  * `login-method` — collection cap through which auth addons contribute
13864
13950
  * their pre-auth login surfaces to the login page. This is the SINGLE,
@@ -14062,8 +14148,7 @@ var NodeProcessSchema = object({
14062
14148
  classification: _enum([
14063
14149
  "root",
14064
14150
  "managed",
14065
- "system",
14066
- "ghost"
14151
+ "system"
14067
14152
  ]),
14068
14153
  /** `$process` addon binding when `managed`, else null. */
14069
14154
  addonId: string().nullable(),
@@ -14071,22 +14156,39 @@ var NodeProcessSchema = object({
14071
14156
  nodeId: string().nullable(),
14072
14157
  /** Truncated command line. */
14073
14158
  command: string(),
14159
+ /**
14160
+ * `ps pcpu` — CPU averaged over the process's WHOLE LIFETIME, not a rate.
14161
+ * On a runner up for days it barely moves. Fine as a column, useless as a
14162
+ * series: use `cpuMainPercent + cpuGcPercent` for anything time-varying.
14163
+ */
14074
14164
  cpuPercent: number(),
14075
14165
  memoryRssBytes: number(),
14166
+ /**
14167
+ * Instantaneous CPU% of the process's own threads over the last
14168
+ * process-snapshot window, from a `/proc/<pid>/task/*` tick delta.
14169
+ *
14170
+ * `null` = UNKNOWN, never zero: no previous sample yet (first tick after
14171
+ * boot), the pid was recycled, or this node is not Linux.
14172
+ */
14173
+ cpuMainPercent: number().nullable(),
14174
+ /**
14175
+ * Instantaneous CPU% of V8's `V8Worker` platform pool over the same window.
14176
+ *
14177
+ * This is the number that rewrote the 2026-08-27 diagnosis — hub-main 73%,
14178
+ * `stream-broker` 61% (`docs/architecture/load-ledger.md`). A CPU chart that
14179
+ * does not separate it from `cpuMainPercent` shows "busy" where the truth is
14180
+ * "allocating too much".
14181
+ *
14182
+ * Concurrent GC is the dominant tenant of that pool but not the only one
14183
+ * (background compilation runs there too), so it is reported as
14184
+ * "GC / V8 helpers" rather than as pure collection time. `null` has the same
14185
+ * meaning as on `cpuMainPercent`.
14186
+ */
14187
+ cpuGcPercent: number().nullable(),
14188
+ /** Threads seen in the tick scan. `null` under the same conditions. */
14189
+ threadCount: number().nullable(),
14076
14190
  /** Wall-clock uptime (seconds). Parsed from `ps etime`. */
14077
- uptimeSec: number(),
14078
- /** True when ancestor walk reaches `ppid=1` (reparented to init/launchd). */
14079
- orphaned: boolean()
14080
- });
14081
- var KillProcessInputSchema = object({
14082
- pid: number(),
14083
- /** Force = SIGKILL. Default is SIGTERM. */
14084
- force: boolean().optional()
14085
- });
14086
- var KillProcessResultSchema = object({
14087
- success: boolean(),
14088
- reason: string().optional(),
14089
- signal: _enum(["SIGTERM", "SIGKILL"]).optional()
14191
+ uptimeSec: number()
14090
14192
  });
14091
14193
  var DumpHeapSnapshotInputSchema = object({
14092
14194
  /** The addon whose runner should dump a heap snapshot. */
@@ -14099,6 +14201,104 @@ var DumpHeapSnapshotResultSchema = object({
14099
14201
  pid: number().optional(),
14100
14202
  reason: string().optional()
14101
14203
  });
14204
+ /**
14205
+ * One point of one function's series.
14206
+ *
14207
+ * The unsuffixed fields are the bucket's **MAXIMUM**, and that choice is the
14208
+ * point of the whole surface. The two obvious reductions both lie: a mean per
14209
+ * bucket smears a spike away, and taking every Nth sample skips it outright.
14210
+ * Either would give us a tool built to find peaks that does not show peaks.
14211
+ * `...Min` carries the other end, `samples` says how many raw snapshots folded
14212
+ * into the bucket, and a mean stays derivable where it is wanted.
14213
+ *
14214
+ * An UNREDUCED point is a one-sample bucket: `samples === 1` and each `...Min`
14215
+ * equals its unsuffixed twin. Reduced and unreduced are the same shape, so a
14216
+ * caller cannot tell which it received — which is what "one reader" means.
14217
+ */
14218
+ var LoadPointSchema = object({
14219
+ /** Bucket START, or the snapshot's own timestamp when unreduced. */
14220
+ atMs: number(),
14221
+ /** Raw snapshots in this bucket. Never 0 — AN EMPTY BUCKET IS ABSENT. */
14222
+ samples: number().int(),
14223
+ /**
14224
+ * `null` = UNKNOWN and it PROPAGATES: a bucket is null unless every process
14225
+ * of every snapshot in it reported a thread split. A partial sum is a
14226
+ * smaller number that looks exactly as real as a complete one.
14227
+ */
14228
+ cpuMainPercent: number().nullable(),
14229
+ cpuMainPercentMin: number().nullable(),
14230
+ cpuGcPercent: number().nullable(),
14231
+ cpuGcPercentMin: number().nullable(),
14232
+ /** Lifetime-average CPU%, summed. Always known — and never a rate. */
14233
+ cpuLifetimePercent: number(),
14234
+ cpuLifetimePercentMin: number(),
14235
+ memoryRssBytes: number(),
14236
+ memoryRssBytesMin: number(),
14237
+ processCount: number().int(),
14238
+ processCountMin: number().int()
14239
+ });
14240
+ /** One function's series. `key` is an addonId, `__root__` or `__unattributed__`. */
14241
+ var LoadFunctionSeriesSchema = object({
14242
+ key: string(),
14243
+ kind: _enum([
14244
+ "addon",
14245
+ "root",
14246
+ "unattributed"
14247
+ ]),
14248
+ /** Oldest-first. A missing interval is MISSING — never zero-filled. */
14249
+ points: array(LoadPointSchema).readonly()
14250
+ });
14251
+ var NodeLoadSeriesSchema = object({
14252
+ nodeId: string(),
14253
+ /** One entry per function seen in the window, heaviest-first. */
14254
+ series: array(LoadFunctionSeriesSchema).readonly(),
14255
+ /**
14256
+ * Width of one returned bucket, in ms. Equals the sampling cadence when no
14257
+ * reduction was needed — so a caller can always say what one point covers
14258
+ * without having to know whether it was reduced.
14259
+ */
14260
+ bucketMs: number(),
14261
+ /** Raw snapshots that went into this answer, across both tiers. */
14262
+ retainedSamples: number(),
14263
+ /** Oldest snapshot represented, or `null` when nothing is retained. */
14264
+ oldestAtMs: number().nullable(),
14265
+ /** The fixed sampling cadence in force on the cluster, in ms. */
14266
+ cadenceMs: number(),
14267
+ /**
14268
+ * Did the DURABLE tier contribute? `false` means the answer is the hot ring
14269
+ * alone — an agent (which holds no table), or a store that refused.
14270
+ * Reported because "the last hour" and "the last six hours" are different
14271
+ * questions and an operator must not have to guess which was answered.
14272
+ */
14273
+ durable: boolean()
14274
+ });
14275
+ var GetLoadSeriesInputSchema = object({
14276
+ /**
14277
+ * The node whose series is wanted.
14278
+ *
14279
+ * NOT named `nodeId`: the generated cap router strips a top-level
14280
+ * `nodeId` from every method input and uses it to ROUTE the call to
14281
+ * that node's provider (`generated-cap-routers.ts`). A series target
14282
+ * called `nodeId` would silently become a routing pin and never reach
14283
+ * the provider. The hub holds every node it hears from, so the
14284
+ * ordinary call is unpinned — answered by the hub, for any node.
14285
+ */
14286
+ forNodeId: string(),
14287
+ /**
14288
+ * EXCLUSIVE lower bound. A caller passes the newest `atMs` it already
14289
+ * holds and receives only what it is missing, so seeding a live chart
14290
+ * from this method cannot double a point already drawn.
14291
+ */
14292
+ sinceMs: number().optional(),
14293
+ /**
14294
+ * Most points the caller wants PER FUNCTION. The window is reduced to fit,
14295
+ * preserving min and max per bucket.
14296
+ *
14297
+ * Absent means NO reduction — legitimate for a short window and a trap for a
14298
+ * long one, which is why a chart passes its own pixel width.
14299
+ */
14300
+ maxPoints: number().int().positive().optional()
14301
+ });
14102
14302
  var SystemMetricsSchema = object({
14103
14303
  cpuPercent: number(),
14104
14304
  memoryPercent: number(),
@@ -14109,10 +14309,7 @@ var SystemMetricsSchema = object({
14109
14309
  gpuPercent: number().optional(),
14110
14310
  gpuMemoryPercent: number().optional()
14111
14311
  });
14112
- 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, {
14113
- kind: "mutation",
14114
- auth: "admin"
14115
- }), method(DumpHeapSnapshotInputSchema, DumpHeapSnapshotResultSchema, {
14312
+ 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, {
14116
14313
  kind: "mutation",
14117
14314
  auth: "admin"
14118
14315
  });
@@ -27472,6 +27669,15 @@ var LoggingSettingsPatchSchema = object({
27472
27669
  * authority over the whole hierarchy and answers for every layer, so the
27473
27670
  * layer selector needs a name the transport does not already own.
27474
27671
  */
27672
+ /**
27673
+ * One contribution, plus WHO reported it.
27674
+ *
27675
+ * The addon and node are added by the hub as it enumerates providers, never by
27676
+ * the contributor: an addon reporting its own identity could report somebody
27677
+ * else's, and the whole point of this surface is that no claim is made by
27678
+ * anyone but its owner.
27679
+ */
27680
+ var ReportedLoadContributionSchema = LoadContributionSchema.extend({ addonId: string() });
27475
27681
  var GetLoggingSettingsInputSchema = object({
27476
27682
  scopeNodeId: string().optional(),
27477
27683
  /**
@@ -27530,7 +27736,7 @@ method(_void(), FeatureManifestSchema), method(_void(), HealthStatusSchema), met
27530
27736
  }), method(_void(), SiteLocationStatusSchema, {
27531
27737
  kind: "mutation",
27532
27738
  auth: "admin"
27533
- }), method(_void(), RequestCensusStatusSchema, { auth: "admin" }), method(GetLoggingSettingsInputSchema, LoggingSettingsStateSchema, { auth: "admin" }), method(SetLoggingSettingsInputSchema, LoggingSettingsStateSchema, {
27739
+ }), method(_void(), RequestCensusStatusSchema, { auth: "admin" }), method(_void(), array(ReportedLoadContributionSchema).readonly(), { auth: "admin" }), method(GetLoggingSettingsInputSchema, LoggingSettingsStateSchema, { auth: "admin" }), method(SetLoggingSettingsInputSchema, LoggingSettingsStateSchema, {
27534
27740
  kind: "mutation",
27535
27741
  auth: "admin"
27536
27742
  });
@@ -29162,6 +29368,12 @@ Object.freeze({
29162
29368
  addonId: null,
29163
29369
  access: "create"
29164
29370
  },
29371
+ "dataStoreProvider.insertMany": {
29372
+ capName: "data-store-provider",
29373
+ capScope: "system",
29374
+ addonId: null,
29375
+ access: "create"
29376
+ },
29165
29377
  "dataStoreProvider.isEmpty": {
29166
29378
  capName: "data-store-provider",
29167
29379
  capScope: "system",
@@ -30476,6 +30688,12 @@ Object.freeze({
30476
30688
  addonId: null,
30477
30689
  access: "create"
30478
30690
  },
30691
+ "loadContribution.list": {
30692
+ capName: "load-contribution",
30693
+ capScope: "system",
30694
+ addonId: null,
30695
+ access: "view"
30696
+ },
30479
30697
  "localNetwork.downloadCa": {
30480
30698
  capName: "local-network",
30481
30699
  capScope: "system",
@@ -30776,17 +30994,17 @@ Object.freeze({
30776
30994
  addonId: null,
30777
30995
  access: "view"
30778
30996
  },
30779
- "metricsProvider.getProcessStats": {
30997
+ "metricsProvider.getLoadSeries": {
30780
30998
  capName: "metrics-provider",
30781
30999
  capScope: "system",
30782
31000
  addonId: null,
30783
31001
  access: "view"
30784
31002
  },
30785
- "metricsProvider.killProcess": {
31003
+ "metricsProvider.getProcessStats": {
30786
31004
  capName: "metrics-provider",
30787
31005
  capScope: "system",
30788
31006
  addonId: null,
30789
- access: "create"
31007
+ access: "view"
30790
31008
  },
30791
31009
  "metricsProvider.listAddonInstances": {
30792
31010
  capName: "metrics-provider",
@@ -32798,6 +33016,12 @@ Object.freeze({
32798
33016
  addonId: null,
32799
33017
  access: "create"
32800
33018
  },
33019
+ "settingsStore.insertMany": {
33020
+ capName: "settings-store",
33021
+ capScope: "system",
33022
+ addonId: null,
33023
+ access: "create"
33024
+ },
32801
33025
  "settingsStore.isEmpty": {
32802
33026
  capName: "settings-store",
32803
33027
  capScope: "system",
@@ -33410,6 +33634,12 @@ Object.freeze({
33410
33634
  addonId: null,
33411
33635
  access: "create"
33412
33636
  },
33637
+ "system.getLoadContributions": {
33638
+ capName: "system",
33639
+ capScope: "system",
33640
+ addonId: null,
33641
+ access: "view"
33642
+ },
33413
33643
  "system.getLoggingSettings": {
33414
33644
  capName: "system",
33415
33645
  capScope: "system",
@@ -72,7 +72,7 @@ function carryForward(base, existing, keys) {
72
72
  return out;
73
73
  }
74
74
  //#endregion
75
- //#region ../types/dist/event-category-CIa_iT6b.mjs
75
+ //#region ../types/dist/event-category-BZL-fdNj.mjs
76
76
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
77
77
  EventCategory["SystemBoot"] = "system.boot";
78
78
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -509,7 +509,7 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
509
509
  EventCategory["MetricsNodeResourcesSnapshot"] = "metrics.node-resources-snapshot";
510
510
  /**
511
511
  * Periodic per-node process-tree snapshot (camstack-related pids
512
- * with ghost / managed / root classification). Emitted ~0.2 Hz by
512
+ * with root / managed / system classification). Emitted ~0.2 Hz by
513
513
  * the metrics-provider addon. Drives the Cluster → Processes tab
514
514
  * without polling `metricsProvider.listNodeProcesses`.
515
515
  */
@@ -11834,6 +11834,19 @@ var SettingsRecordSchema = object({
11834
11834
  data: record(string(), unknown())
11835
11835
  });
11836
11836
  /**
11837
+ * One record of a BULK insert — {@link SettingsRecordSchema} with the id made
11838
+ * optional.
11839
+ *
11840
+ * A separate schema rather than loosening the shared one: every other method
11841
+ * on this cap addresses a row BY its id, and making that field optional
11842
+ * everywhere would turn a forgotten key into a silently generated one on
11843
+ * `update` and `delete` as well.
11844
+ */
11845
+ var BulkRecordSchema = object({
11846
+ id: string().optional(),
11847
+ data: record(string(), unknown())
11848
+ });
11849
+ /**
11837
11850
  * Column declaration for a structured (SQL-backed) collection.
11838
11851
  *
11839
11852
  * Logical types — the backend translates each to the matching SQLite
@@ -11890,6 +11903,10 @@ method(object({
11890
11903
  collection: string(),
11891
11904
  record: SettingsRecordSchema
11892
11905
  }), _void(), { kind: "mutation" }), method(object({
11906
+ namespace: string().optional(),
11907
+ collection: string(),
11908
+ records: array(BulkRecordSchema).readonly()
11909
+ }), object({ inserted: number().int() }), { kind: "mutation" }), method(object({
11893
11910
  namespace: string().optional(),
11894
11911
  collection: string(),
11895
11912
  id: string(),
@@ -11998,6 +12015,13 @@ method(_void(), EngineInfoSchema, { auth: "admin" }), method(object({
11998
12015
  }), _void(), {
11999
12016
  kind: "mutation",
12000
12017
  auth: "admin"
12018
+ }), method(object({
12019
+ namespace: string().optional(),
12020
+ collection: string(),
12021
+ records: array(BulkRecordSchema).readonly()
12022
+ }), object({ inserted: number().int() }), {
12023
+ kind: "mutation",
12024
+ auth: "admin"
12001
12025
  }), method(object({
12002
12026
  namespace: string().optional(),
12003
12027
  collection: string(),
@@ -13847,6 +13871,68 @@ method(LogEntrySchema, _void(), { kind: "mutation" }), method(object({
13847
13871
  limit: number().optional(),
13848
13872
  tags: record(string(), string()).optional()
13849
13873
  }), array(LogEntrySchema).readonly());
13874
+ var LoadContributionSchema = object({
13875
+ role: _enum([
13876
+ "decode",
13877
+ "transcode",
13878
+ "recording",
13879
+ "streaming",
13880
+ "detection"
13881
+ ]),
13882
+ /**
13883
+ * The NUMERIC device id — the same value every log line carries as
13884
+ * `tags.deviceId`. `null` means this cost genuinely belongs to no single
13885
+ * camera (a shared pool), NOT that the contributor forgot to look it up: a
13886
+ * contributor that cannot name its camera must not emit the entry at all,
13887
+ * because an unnamed per-camera entry is indistinguishable from a shared one
13888
+ * and would quietly turn one camera's cost into everybody's.
13889
+ */
13890
+ deviceId: number().int().positive().nullable(),
13891
+ attribution: _enum([
13892
+ "measured",
13893
+ "accounted",
13894
+ "unattributable"
13895
+ ]),
13896
+ /**
13897
+ * What ONE entry is, in the contributor's own words — `615/high`,
13898
+ * `617/native`, `cuda:0 shared pool`. Free text because the unit differs per
13899
+ * family and inventing a common one would lose the only information that
13900
+ * makes two entries for the same camera distinguishable.
13901
+ */
13902
+ unit: string(),
13903
+ /**
13904
+ * The OS process this cost lives in, when there is one. Present so a
13905
+ * consumer can (a) tell two generations of the same unit apart across a
13906
+ * restart, and (b) subtract claimed processes from the node's process
13907
+ * snapshot to see what NOBODY claimed. Absent for an entry that owns no
13908
+ * process of its own.
13909
+ */
13910
+ pid: number().int().positive().optional(),
13911
+ /**
13912
+ * When this generation started. The pid's incarnation marker: a consumer
13913
+ * differencing {@link LoadContributionSchema.shape.cpuSeconds} must drop the
13914
+ * window when this changes, because the counter restarted from zero in a new
13915
+ * process.
13916
+ */
13917
+ startedAtMs: number().optional(),
13918
+ /**
13919
+ * CUMULATIVE CPU seconds this unit has consumed since it started — user +
13920
+ * system, read from the child's own `/proc/<pid>/stat` at the moment the
13921
+ * contribution is asked for.
13922
+ *
13923
+ * Cumulative and not a rate on purpose: a rate needs a window, a window
13924
+ * needs a sampler, and a new per-node sampler is the defect half of
13925
+ * `docs/architecture/load-ledger.md` documents. A counter can be differenced
13926
+ * by whoever already keeps a history; a rate cannot be un-averaged.
13927
+ *
13928
+ * Absent — never zero — on a node with no `/proc`, on a read failure, and on
13929
+ * an entry with no process.
13930
+ */
13931
+ cpuSeconds: number().optional(),
13932
+ /** Resident bytes of this unit's process, same source and same rules. */
13933
+ rssBytes: number().optional()
13934
+ });
13935
+ method(_void(), array(LoadContributionSchema).readonly());
13850
13936
  /**
13851
13937
  * `login-method` — collection cap through which auth addons contribute
13852
13938
  * their pre-auth login surfaces to the login page. This is the SINGLE,
@@ -14050,8 +14136,7 @@ var NodeProcessSchema = object({
14050
14136
  classification: _enum([
14051
14137
  "root",
14052
14138
  "managed",
14053
- "system",
14054
- "ghost"
14139
+ "system"
14055
14140
  ]),
14056
14141
  /** `$process` addon binding when `managed`, else null. */
14057
14142
  addonId: string().nullable(),
@@ -14059,22 +14144,39 @@ var NodeProcessSchema = object({
14059
14144
  nodeId: string().nullable(),
14060
14145
  /** Truncated command line. */
14061
14146
  command: string(),
14147
+ /**
14148
+ * `ps pcpu` — CPU averaged over the process's WHOLE LIFETIME, not a rate.
14149
+ * On a runner up for days it barely moves. Fine as a column, useless as a
14150
+ * series: use `cpuMainPercent + cpuGcPercent` for anything time-varying.
14151
+ */
14062
14152
  cpuPercent: number(),
14063
14153
  memoryRssBytes: number(),
14154
+ /**
14155
+ * Instantaneous CPU% of the process's own threads over the last
14156
+ * process-snapshot window, from a `/proc/<pid>/task/*` tick delta.
14157
+ *
14158
+ * `null` = UNKNOWN, never zero: no previous sample yet (first tick after
14159
+ * boot), the pid was recycled, or this node is not Linux.
14160
+ */
14161
+ cpuMainPercent: number().nullable(),
14162
+ /**
14163
+ * Instantaneous CPU% of V8's `V8Worker` platform pool over the same window.
14164
+ *
14165
+ * This is the number that rewrote the 2026-08-27 diagnosis — hub-main 73%,
14166
+ * `stream-broker` 61% (`docs/architecture/load-ledger.md`). A CPU chart that
14167
+ * does not separate it from `cpuMainPercent` shows "busy" where the truth is
14168
+ * "allocating too much".
14169
+ *
14170
+ * Concurrent GC is the dominant tenant of that pool but not the only one
14171
+ * (background compilation runs there too), so it is reported as
14172
+ * "GC / V8 helpers" rather than as pure collection time. `null` has the same
14173
+ * meaning as on `cpuMainPercent`.
14174
+ */
14175
+ cpuGcPercent: number().nullable(),
14176
+ /** Threads seen in the tick scan. `null` under the same conditions. */
14177
+ threadCount: number().nullable(),
14064
14178
  /** Wall-clock uptime (seconds). Parsed from `ps etime`. */
14065
- uptimeSec: number(),
14066
- /** True when ancestor walk reaches `ppid=1` (reparented to init/launchd). */
14067
- orphaned: boolean()
14068
- });
14069
- var KillProcessInputSchema = object({
14070
- pid: number(),
14071
- /** Force = SIGKILL. Default is SIGTERM. */
14072
- force: boolean().optional()
14073
- });
14074
- var KillProcessResultSchema = object({
14075
- success: boolean(),
14076
- reason: string().optional(),
14077
- signal: _enum(["SIGTERM", "SIGKILL"]).optional()
14179
+ uptimeSec: number()
14078
14180
  });
14079
14181
  var DumpHeapSnapshotInputSchema = object({
14080
14182
  /** The addon whose runner should dump a heap snapshot. */
@@ -14087,6 +14189,104 @@ var DumpHeapSnapshotResultSchema = object({
14087
14189
  pid: number().optional(),
14088
14190
  reason: string().optional()
14089
14191
  });
14192
+ /**
14193
+ * One point of one function's series.
14194
+ *
14195
+ * The unsuffixed fields are the bucket's **MAXIMUM**, and that choice is the
14196
+ * point of the whole surface. The two obvious reductions both lie: a mean per
14197
+ * bucket smears a spike away, and taking every Nth sample skips it outright.
14198
+ * Either would give us a tool built to find peaks that does not show peaks.
14199
+ * `...Min` carries the other end, `samples` says how many raw snapshots folded
14200
+ * into the bucket, and a mean stays derivable where it is wanted.
14201
+ *
14202
+ * An UNREDUCED point is a one-sample bucket: `samples === 1` and each `...Min`
14203
+ * equals its unsuffixed twin. Reduced and unreduced are the same shape, so a
14204
+ * caller cannot tell which it received — which is what "one reader" means.
14205
+ */
14206
+ var LoadPointSchema = object({
14207
+ /** Bucket START, or the snapshot's own timestamp when unreduced. */
14208
+ atMs: number(),
14209
+ /** Raw snapshots in this bucket. Never 0 — AN EMPTY BUCKET IS ABSENT. */
14210
+ samples: number().int(),
14211
+ /**
14212
+ * `null` = UNKNOWN and it PROPAGATES: a bucket is null unless every process
14213
+ * of every snapshot in it reported a thread split. A partial sum is a
14214
+ * smaller number that looks exactly as real as a complete one.
14215
+ */
14216
+ cpuMainPercent: number().nullable(),
14217
+ cpuMainPercentMin: number().nullable(),
14218
+ cpuGcPercent: number().nullable(),
14219
+ cpuGcPercentMin: number().nullable(),
14220
+ /** Lifetime-average CPU%, summed. Always known — and never a rate. */
14221
+ cpuLifetimePercent: number(),
14222
+ cpuLifetimePercentMin: number(),
14223
+ memoryRssBytes: number(),
14224
+ memoryRssBytesMin: number(),
14225
+ processCount: number().int(),
14226
+ processCountMin: number().int()
14227
+ });
14228
+ /** One function's series. `key` is an addonId, `__root__` or `__unattributed__`. */
14229
+ var LoadFunctionSeriesSchema = object({
14230
+ key: string(),
14231
+ kind: _enum([
14232
+ "addon",
14233
+ "root",
14234
+ "unattributed"
14235
+ ]),
14236
+ /** Oldest-first. A missing interval is MISSING — never zero-filled. */
14237
+ points: array(LoadPointSchema).readonly()
14238
+ });
14239
+ var NodeLoadSeriesSchema = object({
14240
+ nodeId: string(),
14241
+ /** One entry per function seen in the window, heaviest-first. */
14242
+ series: array(LoadFunctionSeriesSchema).readonly(),
14243
+ /**
14244
+ * Width of one returned bucket, in ms. Equals the sampling cadence when no
14245
+ * reduction was needed — so a caller can always say what one point covers
14246
+ * without having to know whether it was reduced.
14247
+ */
14248
+ bucketMs: number(),
14249
+ /** Raw snapshots that went into this answer, across both tiers. */
14250
+ retainedSamples: number(),
14251
+ /** Oldest snapshot represented, or `null` when nothing is retained. */
14252
+ oldestAtMs: number().nullable(),
14253
+ /** The fixed sampling cadence in force on the cluster, in ms. */
14254
+ cadenceMs: number(),
14255
+ /**
14256
+ * Did the DURABLE tier contribute? `false` means the answer is the hot ring
14257
+ * alone — an agent (which holds no table), or a store that refused.
14258
+ * Reported because "the last hour" and "the last six hours" are different
14259
+ * questions and an operator must not have to guess which was answered.
14260
+ */
14261
+ durable: boolean()
14262
+ });
14263
+ var GetLoadSeriesInputSchema = object({
14264
+ /**
14265
+ * The node whose series is wanted.
14266
+ *
14267
+ * NOT named `nodeId`: the generated cap router strips a top-level
14268
+ * `nodeId` from every method input and uses it to ROUTE the call to
14269
+ * that node's provider (`generated-cap-routers.ts`). A series target
14270
+ * called `nodeId` would silently become a routing pin and never reach
14271
+ * the provider. The hub holds every node it hears from, so the
14272
+ * ordinary call is unpinned — answered by the hub, for any node.
14273
+ */
14274
+ forNodeId: string(),
14275
+ /**
14276
+ * EXCLUSIVE lower bound. A caller passes the newest `atMs` it already
14277
+ * holds and receives only what it is missing, so seeding a live chart
14278
+ * from this method cannot double a point already drawn.
14279
+ */
14280
+ sinceMs: number().optional(),
14281
+ /**
14282
+ * Most points the caller wants PER FUNCTION. The window is reduced to fit,
14283
+ * preserving min and max per bucket.
14284
+ *
14285
+ * Absent means NO reduction — legitimate for a short window and a trap for a
14286
+ * long one, which is why a chart passes its own pixel width.
14287
+ */
14288
+ maxPoints: number().int().positive().optional()
14289
+ });
14090
14290
  var SystemMetricsSchema = object({
14091
14291
  cpuPercent: number(),
14092
14292
  memoryPercent: number(),
@@ -14097,10 +14297,7 @@ var SystemMetricsSchema = object({
14097
14297
  gpuPercent: number().optional(),
14098
14298
  gpuMemoryPercent: number().optional()
14099
14299
  });
14100
- 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, {
14101
- kind: "mutation",
14102
- auth: "admin"
14103
- }), method(DumpHeapSnapshotInputSchema, DumpHeapSnapshotResultSchema, {
14300
+ 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, {
14104
14301
  kind: "mutation",
14105
14302
  auth: "admin"
14106
14303
  });
@@ -27460,6 +27657,15 @@ var LoggingSettingsPatchSchema = object({
27460
27657
  * authority over the whole hierarchy and answers for every layer, so the
27461
27658
  * layer selector needs a name the transport does not already own.
27462
27659
  */
27660
+ /**
27661
+ * One contribution, plus WHO reported it.
27662
+ *
27663
+ * The addon and node are added by the hub as it enumerates providers, never by
27664
+ * the contributor: an addon reporting its own identity could report somebody
27665
+ * else's, and the whole point of this surface is that no claim is made by
27666
+ * anyone but its owner.
27667
+ */
27668
+ var ReportedLoadContributionSchema = LoadContributionSchema.extend({ addonId: string() });
27463
27669
  var GetLoggingSettingsInputSchema = object({
27464
27670
  scopeNodeId: string().optional(),
27465
27671
  /**
@@ -27518,7 +27724,7 @@ method(_void(), FeatureManifestSchema), method(_void(), HealthStatusSchema), met
27518
27724
  }), method(_void(), SiteLocationStatusSchema, {
27519
27725
  kind: "mutation",
27520
27726
  auth: "admin"
27521
- }), method(_void(), RequestCensusStatusSchema, { auth: "admin" }), method(GetLoggingSettingsInputSchema, LoggingSettingsStateSchema, { auth: "admin" }), method(SetLoggingSettingsInputSchema, LoggingSettingsStateSchema, {
27727
+ }), method(_void(), RequestCensusStatusSchema, { auth: "admin" }), method(_void(), array(ReportedLoadContributionSchema).readonly(), { auth: "admin" }), method(GetLoggingSettingsInputSchema, LoggingSettingsStateSchema, { auth: "admin" }), method(SetLoggingSettingsInputSchema, LoggingSettingsStateSchema, {
27522
27728
  kind: "mutation",
27523
27729
  auth: "admin"
27524
27730
  });
@@ -29150,6 +29356,12 @@ Object.freeze({
29150
29356
  addonId: null,
29151
29357
  access: "create"
29152
29358
  },
29359
+ "dataStoreProvider.insertMany": {
29360
+ capName: "data-store-provider",
29361
+ capScope: "system",
29362
+ addonId: null,
29363
+ access: "create"
29364
+ },
29153
29365
  "dataStoreProvider.isEmpty": {
29154
29366
  capName: "data-store-provider",
29155
29367
  capScope: "system",
@@ -30464,6 +30676,12 @@ Object.freeze({
30464
30676
  addonId: null,
30465
30677
  access: "create"
30466
30678
  },
30679
+ "loadContribution.list": {
30680
+ capName: "load-contribution",
30681
+ capScope: "system",
30682
+ addonId: null,
30683
+ access: "view"
30684
+ },
30467
30685
  "localNetwork.downloadCa": {
30468
30686
  capName: "local-network",
30469
30687
  capScope: "system",
@@ -30764,17 +30982,17 @@ Object.freeze({
30764
30982
  addonId: null,
30765
30983
  access: "view"
30766
30984
  },
30767
- "metricsProvider.getProcessStats": {
30985
+ "metricsProvider.getLoadSeries": {
30768
30986
  capName: "metrics-provider",
30769
30987
  capScope: "system",
30770
30988
  addonId: null,
30771
30989
  access: "view"
30772
30990
  },
30773
- "metricsProvider.killProcess": {
30991
+ "metricsProvider.getProcessStats": {
30774
30992
  capName: "metrics-provider",
30775
30993
  capScope: "system",
30776
30994
  addonId: null,
30777
- access: "create"
30995
+ access: "view"
30778
30996
  },
30779
30997
  "metricsProvider.listAddonInstances": {
30780
30998
  capName: "metrics-provider",
@@ -32786,6 +33004,12 @@ Object.freeze({
32786
33004
  addonId: null,
32787
33005
  access: "create"
32788
33006
  },
33007
+ "settingsStore.insertMany": {
33008
+ capName: "settings-store",
33009
+ capScope: "system",
33010
+ addonId: null,
33011
+ access: "create"
33012
+ },
32789
33013
  "settingsStore.isEmpty": {
32790
33014
  capName: "settings-store",
32791
33015
  capScope: "system",
@@ -33398,6 +33622,12 @@ Object.freeze({
33398
33622
  addonId: null,
33399
33623
  access: "create"
33400
33624
  },
33625
+ "system.getLoadContributions": {
33626
+ capName: "system",
33627
+ capScope: "system",
33628
+ addonId: null,
33629
+ access: "view"
33630
+ },
33401
33631
  "system.getLoggingSettings": {
33402
33632
  capName: "system",
33403
33633
  capScope: "system",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-export-hap",
3
- "version": "1.2.46",
3
+ "version": "1.2.48",
4
4
  "description": "HomeKit (HAP) exporter for CamStack devices. Publishes each exposed device as its own HomeKit accessory: cameras and doorbells with SRTP streaming, HomeKit Secure Video, motion, two-way audio, PTZ and battery; switches, lights, locks and sensors through a capability→service table.",
5
5
  "keywords": [
6
6
  "camstack",