@camstack/addon-model-studio 1.1.49 → 1.1.51

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 (18) hide show
  1. package/dist/{MotionZonesSettings-nSvd3wgP.mjs → MotionZonesSettings-C0cFDSjW.mjs} +2 -2
  2. package/dist/{PrivacyMaskSettings-DpUECTGc.mjs → PrivacyMaskSettings-B0xou5VT.mjs} +4 -4
  3. package/dist/{SceneMonitorEditor-BYUThwmI.mjs → SceneMonitorEditor-CM4NQvb5.mjs} +3 -3
  4. package/dist/_stub.js +12 -12
  5. package/dist/{_virtual_mf-localSharedImportMap___mfe_internal__addon_model_studio_page-BrFWLLUB.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_model_studio_page-Co3sb2DR.mjs} +4 -4
  6. package/dist/_virtual_mf___mfe_internal__addon_model_studio_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-CE4txY-m.mjs +26 -0
  7. package/dist/{hostInit-GLZyh6hk.mjs → hostInit-CK6zsVKu.mjs} +3 -3
  8. package/dist/model-studio.addon.js +285 -150
  9. package/dist/model-studio.addon.mjs +280 -143
  10. package/dist/{player-overlays-DxPiRDNZ.mjs → player-overlays-p43mMwWT.mjs} +1 -1
  11. package/dist/remoteEntry.js +1 -1
  12. package/dist/{responsive-ChIDJ7ve.mjs → responsive-BWVkSjgC.mjs} +1 -1
  13. package/dist/{square-CpAXUT52.mjs → square-DNWB0Fvw.mjs} +1 -1
  14. package/dist/{trash-2-siK2nOpd.mjs → trash-2-BKgeax2l.mjs} +1 -1
  15. package/dist/{use-device-snapshot-CLLnyzyW.mjs → use-device-snapshot-CkQG2lkA.mjs} +1 -1
  16. package/dist/{virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_model_studio_page__remoteEntry_js-D-6VGno6.mjs → virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_model_studio_page__remoteEntry_js-DOi9vT32.mjs} +1 -1
  17. package/package.json +3 -2
  18. package/dist/_virtual_mf___mfe_internal__addon_model_studio_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-D5YltPmo.mjs +0 -26
@@ -6,103 +6,10 @@ import fs from "node:fs";
6
6
  import os from "node:os";
7
7
  import * as path$1 from "node:path";
8
8
  import path from "node:path";
9
- import { promisify } from "node:util";
10
- import { brotliCompress, gzip } from "node:zlib";
9
+ import { downloadFile } from "@camstack/system/addon-utils";
11
10
  //#region \0rolldown/runtime.js
12
11
  var __require = /* @__PURE__ */ createRequire(import.meta.url);
13
12
  //#endregion
14
- //#region ../system/dist/file-data-plane-BhKdxJgf.mjs
15
- /** Build fetch headers, including HF auth token for huggingface.co URLs */
16
- function buildHeaders(url) {
17
- const headers = { "User-Agent": "CamStack/1.0" };
18
- const hfToken = process.env["HF_TOKEN"] ?? process.env["HUGGING_FACE_HUB_TOKEN"];
19
- if (hfToken && url.includes("huggingface.co")) headers["Authorization"] = `Bearer ${hfToken}`;
20
- return headers;
21
- }
22
- var DEFAULT_MAX_REDIRECTS = 5;
23
- function normalizeDownloadOptions(third) {
24
- if (typeof third === "function") return { onProgress: third };
25
- return third ?? {};
26
- }
27
- function isRedirectStatus(status) {
28
- return status === 301 || status === 302 || status === 303 || status === 307 || status === 308;
29
- }
30
- function resolveRedirectUrl(current, location) {
31
- return new URL(location, current);
32
- }
33
- async function downloadFile(url, destPath, onProgressOrOptions) {
34
- if (fs$1.existsSync(destPath)) return destPath;
35
- const opts = normalizeDownloadOptions(onProgressOrOptions);
36
- const fetchImpl = opts.fetchImpl ?? fetch;
37
- const maxRedirects = opts.maxRedirects ?? DEFAULT_MAX_REDIRECTS;
38
- fs$1.mkdirSync(path$1.dirname(destPath), { recursive: true });
39
- const tmpPath = destPath + ".downloading";
40
- try {
41
- let current = url;
42
- const seen = /* @__PURE__ */ new Set();
43
- let response;
44
- const manual = opts.redirectPolicy !== void 0;
45
- for (let hop = 0; hop <= maxRedirects; hop++) {
46
- const parsed = new URL(current);
47
- if (opts.redirectPolicy) opts.redirectPolicy(parsed, hop);
48
- if (seen.has(parsed.href)) throw new Error(`Redirect loop detected at ${parsed.href}`);
49
- seen.add(parsed.href);
50
- const controller = opts.timeoutMs !== void 0 ? new AbortController() : void 0;
51
- const timer = controller && opts.timeoutMs !== void 0 ? setTimeout(() => controller.abort(), opts.timeoutMs) : void 0;
52
- try {
53
- response = await fetchImpl(current, {
54
- redirect: manual ? "manual" : "follow",
55
- headers: buildHeaders(current),
56
- ...controller ? { signal: controller.signal } : {}
57
- });
58
- } finally {
59
- if (timer) clearTimeout(timer);
60
- }
61
- if (manual && isRedirectStatus(response.status)) {
62
- const location = response.headers.get("location");
63
- if (!location) throw new Error(`Redirect ${response.status} missing Location header`);
64
- if (hop >= maxRedirects) throw new Error(`Too many redirects (max ${maxRedirects}) downloading ${url}`);
65
- current = resolveRedirectUrl(current, location).href;
66
- continue;
67
- }
68
- break;
69
- }
70
- if (!response) throw new Error(`No response downloading ${url}`);
71
- if (manual && isRedirectStatus(response.status)) throw new Error(`Too many redirects (max ${maxRedirects}) downloading ${url}`);
72
- if (!response.ok) throw new Error(`HTTP ${response.status} downloading ${url}`);
73
- if (!response.body) throw new Error(`No response body from ${url}`);
74
- const total = parseInt(response.headers.get("content-length") ?? "0", 10);
75
- let downloaded = 0;
76
- const fileStream = fs$1.createWriteStream(tmpPath);
77
- const reader = response.body.getReader();
78
- try {
79
- for (;;) {
80
- const { done, value } = await reader.read();
81
- if (done || !value) break;
82
- downloaded += value.length;
83
- if (opts.maxBytes !== void 0 && downloaded > opts.maxBytes) throw new Error(`Downloaded ${downloaded} bytes exceeds the ${opts.maxBytes}-byte limit`);
84
- fileStream.write(value);
85
- opts.onProgress?.(downloaded, total);
86
- }
87
- } finally {
88
- fileStream.end();
89
- await new Promise((resolve, reject) => {
90
- fileStream.on("finish", resolve);
91
- fileStream.on("error", reject);
92
- });
93
- }
94
- fs$1.renameSync(tmpPath, destPath);
95
- return destPath;
96
- } catch (err) {
97
- try {
98
- fs$1.unlinkSync(tmpPath);
99
- } catch {}
100
- throw err;
101
- }
102
- }
103
- promisify(brotliCompress);
104
- promisify(gzip);
105
- //#endregion
106
13
  //#region src/scrypted/scrypted-download-policy.ts
107
14
  /**
108
15
  * Strict per-hop allow-list for Scrypted catalog downloads.
@@ -595,7 +502,7 @@ async function importScryptedCatalogModel(input, deps) {
595
502
  }
596
503
  }
597
504
  //#endregion
598
- //#region ../types/dist/event-category-CIa_iT6b.mjs
505
+ //#region ../types/dist/event-category-BZL-fdNj.mjs
599
506
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
600
507
  EventCategory["SystemBoot"] = "system.boot";
601
508
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -1032,7 +939,7 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
1032
939
  EventCategory["MetricsNodeResourcesSnapshot"] = "metrics.node-resources-snapshot";
1033
940
  /**
1034
941
  * Periodic per-node process-tree snapshot (camstack-related pids
1035
- * with ghost / managed / root classification). Emitted ~0.2 Hz by
942
+ * with root / managed / system classification). Emitted ~0.2 Hz by
1036
943
  * the metrics-provider addon. Drives the Cluster → Processes tab
1037
944
  * without polling `metricsProvider.listNodeProcesses`.
1038
945
  */
@@ -4315,7 +4222,7 @@ function initializeContext(params) {
4315
4222
  external: params?.external ?? void 0
4316
4223
  };
4317
4224
  }
4318
- function process$1(schema, ctx, _params = {
4225
+ function process(schema, ctx, _params = {
4319
4226
  path: [],
4320
4227
  schemaPath: []
4321
4228
  }) {
@@ -4352,7 +4259,7 @@ function process$1(schema, ctx, _params = {
4352
4259
  const parent = schema._zod.parent;
4353
4260
  if (parent) {
4354
4261
  if (!result.ref) result.ref = parent;
4355
- process$1(parent, ctx, params);
4262
+ process(parent, ctx, params);
4356
4263
  ctx.seen.get(parent).isParent = true;
4357
4264
  }
4358
4265
  }
@@ -4572,7 +4479,7 @@ var createToJSONSchemaMethod = (schema, processors = {}) => (params) => {
4572
4479
  ...params,
4573
4480
  processors
4574
4481
  });
4575
- process$1(schema, ctx);
4482
+ process(schema, ctx);
4576
4483
  extractDefs(ctx, schema);
4577
4484
  return finalize(ctx, schema);
4578
4485
  };
@@ -4584,7 +4491,7 @@ var createStandardJSONSchemaMethod = (schema, io, processors = {}) => (params) =
4584
4491
  io,
4585
4492
  processors
4586
4493
  });
4587
- process$1(schema, ctx);
4494
+ process(schema, ctx);
4588
4495
  extractDefs(ctx, schema);
4589
4496
  return finalize(ctx, schema);
4590
4497
  };
@@ -4698,7 +4605,7 @@ var arrayProcessor = (schema, ctx, _json, params) => {
4698
4605
  if (typeof minimum === "number") json.minItems = minimum;
4699
4606
  if (typeof maximum === "number") json.maxItems = maximum;
4700
4607
  json.type = "array";
4701
- json.items = process$1(def.element, ctx, {
4608
+ json.items = process(def.element, ctx, {
4702
4609
  ...params,
4703
4610
  path: [...params.path, "items"]
4704
4611
  });
@@ -4709,7 +4616,7 @@ var objectProcessor = (schema, ctx, _json, params) => {
4709
4616
  json.type = "object";
4710
4617
  json.properties = {};
4711
4618
  const shape = def.shape;
4712
- for (const key in shape) json.properties[key] = process$1(shape[key], ctx, {
4619
+ for (const key in shape) json.properties[key] = process(shape[key], ctx, {
4713
4620
  ...params,
4714
4621
  path: [
4715
4622
  ...params.path,
@@ -4727,7 +4634,7 @@ var objectProcessor = (schema, ctx, _json, params) => {
4727
4634
  if (def.catchall?._zod.def.type === "never") json.additionalProperties = false;
4728
4635
  else if (!def.catchall) {
4729
4636
  if (ctx.io === "output") json.additionalProperties = false;
4730
- } else if (def.catchall) json.additionalProperties = process$1(def.catchall, ctx, {
4637
+ } else if (def.catchall) json.additionalProperties = process(def.catchall, ctx, {
4731
4638
  ...params,
4732
4639
  path: [...params.path, "additionalProperties"]
4733
4640
  });
@@ -4735,7 +4642,7 @@ var objectProcessor = (schema, ctx, _json, params) => {
4735
4642
  var unionProcessor = (schema, ctx, json, params) => {
4736
4643
  const def = schema._zod.def;
4737
4644
  const isExclusive = def.inclusive === false;
4738
- const options = def.options.map((x, i) => process$1(x, ctx, {
4645
+ const options = def.options.map((x, i) => process(x, ctx, {
4739
4646
  ...params,
4740
4647
  path: [
4741
4648
  ...params.path,
@@ -4748,7 +4655,7 @@ var unionProcessor = (schema, ctx, json, params) => {
4748
4655
  };
4749
4656
  var intersectionProcessor = (schema, ctx, json, params) => {
4750
4657
  const def = schema._zod.def;
4751
- const a = process$1(def.left, ctx, {
4658
+ const a = process(def.left, ctx, {
4752
4659
  ...params,
4753
4660
  path: [
4754
4661
  ...params.path,
@@ -4756,7 +4663,7 @@ var intersectionProcessor = (schema, ctx, json, params) => {
4756
4663
  0
4757
4664
  ]
4758
4665
  });
4759
- const b = process$1(def.right, ctx, {
4666
+ const b = process(def.right, ctx, {
4760
4667
  ...params,
4761
4668
  path: [
4762
4669
  ...params.path,
@@ -4773,7 +4680,7 @@ var tupleProcessor = (schema, ctx, _json, params) => {
4773
4680
  json.type = "array";
4774
4681
  const prefixPath = ctx.target === "draft-2020-12" ? "prefixItems" : "items";
4775
4682
  const restPath = ctx.target === "draft-2020-12" ? "items" : ctx.target === "openapi-3.0" ? "items" : "additionalItems";
4776
- const prefixItems = def.items.map((x, i) => process$1(x, ctx, {
4683
+ const prefixItems = def.items.map((x, i) => process(x, ctx, {
4777
4684
  ...params,
4778
4685
  path: [
4779
4686
  ...params.path,
@@ -4781,7 +4688,7 @@ var tupleProcessor = (schema, ctx, _json, params) => {
4781
4688
  i
4782
4689
  ]
4783
4690
  }));
4784
- const rest = def.rest ? process$1(def.rest, ctx, {
4691
+ const rest = def.rest ? process(def.rest, ctx, {
4785
4692
  ...params,
4786
4693
  path: [
4787
4694
  ...params.path,
@@ -4812,7 +4719,7 @@ var recordProcessor = (schema, ctx, _json, params) => {
4812
4719
  const keyType = def.keyType;
4813
4720
  const patterns = keyType._zod.bag?.patterns;
4814
4721
  if (def.mode === "loose" && patterns && patterns.size > 0) {
4815
- const valueSchema = process$1(def.valueType, ctx, {
4722
+ const valueSchema = process(def.valueType, ctx, {
4816
4723
  ...params,
4817
4724
  path: [
4818
4725
  ...params.path,
@@ -4823,11 +4730,11 @@ var recordProcessor = (schema, ctx, _json, params) => {
4823
4730
  json.patternProperties = {};
4824
4731
  for (const pattern of patterns) json.patternProperties[pattern.source] = valueSchema;
4825
4732
  } else {
4826
- if (ctx.target === "draft-07" || ctx.target === "draft-2020-12") json.propertyNames = process$1(def.keyType, ctx, {
4733
+ if (ctx.target === "draft-07" || ctx.target === "draft-2020-12") json.propertyNames = process(def.keyType, ctx, {
4827
4734
  ...params,
4828
4735
  path: [...params.path, "propertyNames"]
4829
4736
  });
4830
- json.additionalProperties = process$1(def.valueType, ctx, {
4737
+ json.additionalProperties = process(def.valueType, ctx, {
4831
4738
  ...params,
4832
4739
  path: [...params.path, "additionalProperties"]
4833
4740
  });
@@ -4840,7 +4747,7 @@ var recordProcessor = (schema, ctx, _json, params) => {
4840
4747
  };
4841
4748
  var nullableProcessor = (schema, ctx, json, params) => {
4842
4749
  const def = schema._zod.def;
4843
- const inner = process$1(def.innerType, ctx, params);
4750
+ const inner = process(def.innerType, ctx, params);
4844
4751
  const seen = ctx.seen.get(schema);
4845
4752
  if (ctx.target === "openapi-3.0") {
4846
4753
  seen.ref = def.innerType;
@@ -4849,27 +4756,27 @@ var nullableProcessor = (schema, ctx, json, params) => {
4849
4756
  };
4850
4757
  var nonoptionalProcessor = (schema, ctx, _json, params) => {
4851
4758
  const def = schema._zod.def;
4852
- process$1(def.innerType, ctx, params);
4759
+ process(def.innerType, ctx, params);
4853
4760
  const seen = ctx.seen.get(schema);
4854
4761
  seen.ref = def.innerType;
4855
4762
  };
4856
4763
  var defaultProcessor = (schema, ctx, json, params) => {
4857
4764
  const def = schema._zod.def;
4858
- process$1(def.innerType, ctx, params);
4765
+ process(def.innerType, ctx, params);
4859
4766
  const seen = ctx.seen.get(schema);
4860
4767
  seen.ref = def.innerType;
4861
4768
  json.default = JSON.parse(JSON.stringify(def.defaultValue));
4862
4769
  };
4863
4770
  var prefaultProcessor = (schema, ctx, json, params) => {
4864
4771
  const def = schema._zod.def;
4865
- process$1(def.innerType, ctx, params);
4772
+ process(def.innerType, ctx, params);
4866
4773
  const seen = ctx.seen.get(schema);
4867
4774
  seen.ref = def.innerType;
4868
4775
  if (ctx.io === "input") json._prefault = JSON.parse(JSON.stringify(def.defaultValue));
4869
4776
  };
4870
4777
  var catchProcessor = (schema, ctx, json, params) => {
4871
4778
  const def = schema._zod.def;
4872
- process$1(def.innerType, ctx, params);
4779
+ process(def.innerType, ctx, params);
4873
4780
  const seen = ctx.seen.get(schema);
4874
4781
  seen.ref = def.innerType;
4875
4782
  let catchValue;
@@ -4884,26 +4791,26 @@ var pipeProcessor = (schema, ctx, _json, params) => {
4884
4791
  const def = schema._zod.def;
4885
4792
  const inIsTransform = def.in._zod.traits.has("$ZodTransform");
4886
4793
  const innerType = ctx.io === "input" ? inIsTransform ? def.out : def.in : def.out;
4887
- process$1(innerType, ctx, params);
4794
+ process(innerType, ctx, params);
4888
4795
  const seen = ctx.seen.get(schema);
4889
4796
  seen.ref = innerType;
4890
4797
  };
4891
4798
  var readonlyProcessor = (schema, ctx, json, params) => {
4892
4799
  const def = schema._zod.def;
4893
- process$1(def.innerType, ctx, params);
4800
+ process(def.innerType, ctx, params);
4894
4801
  const seen = ctx.seen.get(schema);
4895
4802
  seen.ref = def.innerType;
4896
4803
  json.readOnly = true;
4897
4804
  };
4898
4805
  var optionalProcessor = (schema, ctx, _json, params) => {
4899
4806
  const def = schema._zod.def;
4900
- process$1(def.innerType, ctx, params);
4807
+ process(def.innerType, ctx, params);
4901
4808
  const seen = ctx.seen.get(schema);
4902
4809
  seen.ref = def.innerType;
4903
4810
  };
4904
4811
  var lazyProcessor = (schema, ctx, _json, params) => {
4905
4812
  const innerType = schema._zod.innerType;
4906
- process$1(innerType, ctx, params);
4813
+ process(innerType, ctx, params);
4907
4814
  const seen = ctx.seen.get(schema);
4908
4815
  seen.ref = innerType;
4909
4816
  };
@@ -11821,6 +11728,19 @@ var SettingsRecordSchema = object({
11821
11728
  data: record(string(), unknown())
11822
11729
  });
11823
11730
  /**
11731
+ * One record of a BULK insert — {@link SettingsRecordSchema} with the id made
11732
+ * optional.
11733
+ *
11734
+ * A separate schema rather than loosening the shared one: every other method
11735
+ * on this cap addresses a row BY its id, and making that field optional
11736
+ * everywhere would turn a forgotten key into a silently generated one on
11737
+ * `update` and `delete` as well.
11738
+ */
11739
+ var BulkRecordSchema = object({
11740
+ id: string().optional(),
11741
+ data: record(string(), unknown())
11742
+ });
11743
+ /**
11824
11744
  * Column declaration for a structured (SQL-backed) collection.
11825
11745
  *
11826
11746
  * Logical types — the backend translates each to the matching SQLite
@@ -11877,6 +11797,10 @@ method(object({
11877
11797
  collection: string(),
11878
11798
  record: SettingsRecordSchema
11879
11799
  }), _void(), { kind: "mutation" }), method(object({
11800
+ namespace: string().optional(),
11801
+ collection: string(),
11802
+ records: array(BulkRecordSchema).readonly()
11803
+ }), object({ inserted: number().int() }), { kind: "mutation" }), method(object({
11880
11804
  namespace: string().optional(),
11881
11805
  collection: string(),
11882
11806
  id: string(),
@@ -11985,6 +11909,13 @@ method(_void(), EngineInfoSchema, { auth: "admin" }), method(object({
11985
11909
  }), _void(), {
11986
11910
  kind: "mutation",
11987
11911
  auth: "admin"
11912
+ }), method(object({
11913
+ namespace: string().optional(),
11914
+ collection: string(),
11915
+ records: array(BulkRecordSchema).readonly()
11916
+ }), object({ inserted: number().int() }), {
11917
+ kind: "mutation",
11918
+ auth: "admin"
11988
11919
  }), method(object({
11989
11920
  namespace: string().optional(),
11990
11921
  collection: string(),
@@ -13753,6 +13684,68 @@ method(LogEntrySchema, _void(), { kind: "mutation" }), method(object({
13753
13684
  limit: number().optional(),
13754
13685
  tags: record(string(), string()).optional()
13755
13686
  }), array(LogEntrySchema).readonly());
13687
+ var LoadContributionSchema = object({
13688
+ role: _enum([
13689
+ "decode",
13690
+ "transcode",
13691
+ "recording",
13692
+ "streaming",
13693
+ "detection"
13694
+ ]),
13695
+ /**
13696
+ * The NUMERIC device id — the same value every log line carries as
13697
+ * `tags.deviceId`. `null` means this cost genuinely belongs to no single
13698
+ * camera (a shared pool), NOT that the contributor forgot to look it up: a
13699
+ * contributor that cannot name its camera must not emit the entry at all,
13700
+ * because an unnamed per-camera entry is indistinguishable from a shared one
13701
+ * and would quietly turn one camera's cost into everybody's.
13702
+ */
13703
+ deviceId: number().int().positive().nullable(),
13704
+ attribution: _enum([
13705
+ "measured",
13706
+ "accounted",
13707
+ "unattributable"
13708
+ ]),
13709
+ /**
13710
+ * What ONE entry is, in the contributor's own words — `615/high`,
13711
+ * `617/native`, `cuda:0 shared pool`. Free text because the unit differs per
13712
+ * family and inventing a common one would lose the only information that
13713
+ * makes two entries for the same camera distinguishable.
13714
+ */
13715
+ unit: string(),
13716
+ /**
13717
+ * The OS process this cost lives in, when there is one. Present so a
13718
+ * consumer can (a) tell two generations of the same unit apart across a
13719
+ * restart, and (b) subtract claimed processes from the node's process
13720
+ * snapshot to see what NOBODY claimed. Absent for an entry that owns no
13721
+ * process of its own.
13722
+ */
13723
+ pid: number().int().positive().optional(),
13724
+ /**
13725
+ * When this generation started. The pid's incarnation marker: a consumer
13726
+ * differencing {@link LoadContributionSchema.shape.cpuSeconds} must drop the
13727
+ * window when this changes, because the counter restarted from zero in a new
13728
+ * process.
13729
+ */
13730
+ startedAtMs: number().optional(),
13731
+ /**
13732
+ * CUMULATIVE CPU seconds this unit has consumed since it started — user +
13733
+ * system, read from the child's own `/proc/<pid>/stat` at the moment the
13734
+ * contribution is asked for.
13735
+ *
13736
+ * Cumulative and not a rate on purpose: a rate needs a window, a window
13737
+ * needs a sampler, and a new per-node sampler is the defect half of
13738
+ * `docs/architecture/load-ledger.md` documents. A counter can be differenced
13739
+ * by whoever already keeps a history; a rate cannot be un-averaged.
13740
+ *
13741
+ * Absent — never zero — on a node with no `/proc`, on a read failure, and on
13742
+ * an entry with no process.
13743
+ */
13744
+ cpuSeconds: number().optional(),
13745
+ /** Resident bytes of this unit's process, same source and same rules. */
13746
+ rssBytes: number().optional()
13747
+ });
13748
+ method(_void(), array(LoadContributionSchema).readonly());
13756
13749
  /**
13757
13750
  * `login-method` — collection cap through which auth addons contribute
13758
13751
  * their pre-auth login surfaces to the login page. This is the SINGLE,
@@ -13956,8 +13949,7 @@ var NodeProcessSchema = object({
13956
13949
  classification: _enum([
13957
13950
  "root",
13958
13951
  "managed",
13959
- "system",
13960
- "ghost"
13952
+ "system"
13961
13953
  ]),
13962
13954
  /** `$process` addon binding when `managed`, else null. */
13963
13955
  addonId: string().nullable(),
@@ -13965,22 +13957,39 @@ var NodeProcessSchema = object({
13965
13957
  nodeId: string().nullable(),
13966
13958
  /** Truncated command line. */
13967
13959
  command: string(),
13960
+ /**
13961
+ * `ps pcpu` — CPU averaged over the process's WHOLE LIFETIME, not a rate.
13962
+ * On a runner up for days it barely moves. Fine as a column, useless as a
13963
+ * series: use `cpuMainPercent + cpuGcPercent` for anything time-varying.
13964
+ */
13968
13965
  cpuPercent: number(),
13969
13966
  memoryRssBytes: number(),
13967
+ /**
13968
+ * Instantaneous CPU% of the process's own threads over the last
13969
+ * process-snapshot window, from a `/proc/<pid>/task/*` tick delta.
13970
+ *
13971
+ * `null` = UNKNOWN, never zero: no previous sample yet (first tick after
13972
+ * boot), the pid was recycled, or this node is not Linux.
13973
+ */
13974
+ cpuMainPercent: number().nullable(),
13975
+ /**
13976
+ * Instantaneous CPU% of V8's `V8Worker` platform pool over the same window.
13977
+ *
13978
+ * This is the number that rewrote the 2026-08-27 diagnosis — hub-main 73%,
13979
+ * `stream-broker` 61% (`docs/architecture/load-ledger.md`). A CPU chart that
13980
+ * does not separate it from `cpuMainPercent` shows "busy" where the truth is
13981
+ * "allocating too much".
13982
+ *
13983
+ * Concurrent GC is the dominant tenant of that pool but not the only one
13984
+ * (background compilation runs there too), so it is reported as
13985
+ * "GC / V8 helpers" rather than as pure collection time. `null` has the same
13986
+ * meaning as on `cpuMainPercent`.
13987
+ */
13988
+ cpuGcPercent: number().nullable(),
13989
+ /** Threads seen in the tick scan. `null` under the same conditions. */
13990
+ threadCount: number().nullable(),
13970
13991
  /** Wall-clock uptime (seconds). Parsed from `ps etime`. */
13971
- uptimeSec: number(),
13972
- /** True when ancestor walk reaches `ppid=1` (reparented to init/launchd). */
13973
- orphaned: boolean()
13974
- });
13975
- var KillProcessInputSchema = object({
13976
- pid: number(),
13977
- /** Force = SIGKILL. Default is SIGTERM. */
13978
- force: boolean().optional()
13979
- });
13980
- var KillProcessResultSchema = object({
13981
- success: boolean(),
13982
- reason: string().optional(),
13983
- signal: _enum(["SIGTERM", "SIGKILL"]).optional()
13992
+ uptimeSec: number()
13984
13993
  });
13985
13994
  var DumpHeapSnapshotInputSchema = object({
13986
13995
  /** The addon whose runner should dump a heap snapshot. */
@@ -13993,6 +14002,104 @@ var DumpHeapSnapshotResultSchema = object({
13993
14002
  pid: number().optional(),
13994
14003
  reason: string().optional()
13995
14004
  });
14005
+ /**
14006
+ * One point of one function's series.
14007
+ *
14008
+ * The unsuffixed fields are the bucket's **MAXIMUM**, and that choice is the
14009
+ * point of the whole surface. The two obvious reductions both lie: a mean per
14010
+ * bucket smears a spike away, and taking every Nth sample skips it outright.
14011
+ * Either would give us a tool built to find peaks that does not show peaks.
14012
+ * `...Min` carries the other end, `samples` says how many raw snapshots folded
14013
+ * into the bucket, and a mean stays derivable where it is wanted.
14014
+ *
14015
+ * An UNREDUCED point is a one-sample bucket: `samples === 1` and each `...Min`
14016
+ * equals its unsuffixed twin. Reduced and unreduced are the same shape, so a
14017
+ * caller cannot tell which it received — which is what "one reader" means.
14018
+ */
14019
+ var LoadPointSchema = object({
14020
+ /** Bucket START, or the snapshot's own timestamp when unreduced. */
14021
+ atMs: number(),
14022
+ /** Raw snapshots in this bucket. Never 0 — AN EMPTY BUCKET IS ABSENT. */
14023
+ samples: number().int(),
14024
+ /**
14025
+ * `null` = UNKNOWN and it PROPAGATES: a bucket is null unless every process
14026
+ * of every snapshot in it reported a thread split. A partial sum is a
14027
+ * smaller number that looks exactly as real as a complete one.
14028
+ */
14029
+ cpuMainPercent: number().nullable(),
14030
+ cpuMainPercentMin: number().nullable(),
14031
+ cpuGcPercent: number().nullable(),
14032
+ cpuGcPercentMin: number().nullable(),
14033
+ /** Lifetime-average CPU%, summed. Always known — and never a rate. */
14034
+ cpuLifetimePercent: number(),
14035
+ cpuLifetimePercentMin: number(),
14036
+ memoryRssBytes: number(),
14037
+ memoryRssBytesMin: number(),
14038
+ processCount: number().int(),
14039
+ processCountMin: number().int()
14040
+ });
14041
+ /** One function's series. `key` is an addonId, `__root__` or `__unattributed__`. */
14042
+ var LoadFunctionSeriesSchema = object({
14043
+ key: string(),
14044
+ kind: _enum([
14045
+ "addon",
14046
+ "root",
14047
+ "unattributed"
14048
+ ]),
14049
+ /** Oldest-first. A missing interval is MISSING — never zero-filled. */
14050
+ points: array(LoadPointSchema).readonly()
14051
+ });
14052
+ var NodeLoadSeriesSchema = object({
14053
+ nodeId: string(),
14054
+ /** One entry per function seen in the window, heaviest-first. */
14055
+ series: array(LoadFunctionSeriesSchema).readonly(),
14056
+ /**
14057
+ * Width of one returned bucket, in ms. Equals the sampling cadence when no
14058
+ * reduction was needed — so a caller can always say what one point covers
14059
+ * without having to know whether it was reduced.
14060
+ */
14061
+ bucketMs: number(),
14062
+ /** Raw snapshots that went into this answer, across both tiers. */
14063
+ retainedSamples: number(),
14064
+ /** Oldest snapshot represented, or `null` when nothing is retained. */
14065
+ oldestAtMs: number().nullable(),
14066
+ /** The fixed sampling cadence in force on the cluster, in ms. */
14067
+ cadenceMs: number(),
14068
+ /**
14069
+ * Did the DURABLE tier contribute? `false` means the answer is the hot ring
14070
+ * alone — an agent (which holds no table), or a store that refused.
14071
+ * Reported because "the last hour" and "the last six hours" are different
14072
+ * questions and an operator must not have to guess which was answered.
14073
+ */
14074
+ durable: boolean()
14075
+ });
14076
+ var GetLoadSeriesInputSchema = object({
14077
+ /**
14078
+ * The node whose series is wanted.
14079
+ *
14080
+ * NOT named `nodeId`: the generated cap router strips a top-level
14081
+ * `nodeId` from every method input and uses it to ROUTE the call to
14082
+ * that node's provider (`generated-cap-routers.ts`). A series target
14083
+ * called `nodeId` would silently become a routing pin and never reach
14084
+ * the provider. The hub holds every node it hears from, so the
14085
+ * ordinary call is unpinned — answered by the hub, for any node.
14086
+ */
14087
+ forNodeId: string(),
14088
+ /**
14089
+ * EXCLUSIVE lower bound. A caller passes the newest `atMs` it already
14090
+ * holds and receives only what it is missing, so seeding a live chart
14091
+ * from this method cannot double a point already drawn.
14092
+ */
14093
+ sinceMs: number().optional(),
14094
+ /**
14095
+ * Most points the caller wants PER FUNCTION. The window is reduced to fit,
14096
+ * preserving min and max per bucket.
14097
+ *
14098
+ * Absent means NO reduction — legitimate for a short window and a trap for a
14099
+ * long one, which is why a chart passes its own pixel width.
14100
+ */
14101
+ maxPoints: number().int().positive().optional()
14102
+ });
13996
14103
  var SystemMetricsSchema = object({
13997
14104
  cpuPercent: number(),
13998
14105
  memoryPercent: number(),
@@ -14003,10 +14110,7 @@ var SystemMetricsSchema = object({
14003
14110
  gpuPercent: number().optional(),
14004
14111
  gpuMemoryPercent: number().optional()
14005
14112
  });
14006
- 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, {
14007
- kind: "mutation",
14008
- auth: "admin"
14009
- }), method(DumpHeapSnapshotInputSchema, DumpHeapSnapshotResultSchema, {
14113
+ 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, {
14010
14114
  kind: "mutation",
14011
14115
  auth: "admin"
14012
14116
  });
@@ -27315,6 +27419,15 @@ var LoggingSettingsPatchSchema = object({
27315
27419
  * authority over the whole hierarchy and answers for every layer, so the
27316
27420
  * layer selector needs a name the transport does not already own.
27317
27421
  */
27422
+ /**
27423
+ * One contribution, plus WHO reported it.
27424
+ *
27425
+ * The addon and node are added by the hub as it enumerates providers, never by
27426
+ * the contributor: an addon reporting its own identity could report somebody
27427
+ * else's, and the whole point of this surface is that no claim is made by
27428
+ * anyone but its owner.
27429
+ */
27430
+ var ReportedLoadContributionSchema = LoadContributionSchema.extend({ addonId: string() });
27318
27431
  var GetLoggingSettingsInputSchema = object({
27319
27432
  scopeNodeId: string().optional(),
27320
27433
  /**
@@ -27373,7 +27486,7 @@ method(_void(), FeatureManifestSchema), method(_void(), HealthStatusSchema), met
27373
27486
  }), method(_void(), SiteLocationStatusSchema, {
27374
27487
  kind: "mutation",
27375
27488
  auth: "admin"
27376
- }), method(_void(), RequestCensusStatusSchema, { auth: "admin" }), method(GetLoggingSettingsInputSchema, LoggingSettingsStateSchema, { auth: "admin" }), method(SetLoggingSettingsInputSchema, LoggingSettingsStateSchema, {
27489
+ }), method(_void(), RequestCensusStatusSchema, { auth: "admin" }), method(_void(), array(ReportedLoadContributionSchema).readonly(), { auth: "admin" }), method(GetLoggingSettingsInputSchema, LoggingSettingsStateSchema, { auth: "admin" }), method(SetLoggingSettingsInputSchema, LoggingSettingsStateSchema, {
27377
27490
  kind: "mutation",
27378
27491
  auth: "admin"
27379
27492
  });
@@ -28989,6 +29102,12 @@ Object.freeze({
28989
29102
  addonId: null,
28990
29103
  access: "create"
28991
29104
  },
29105
+ "dataStoreProvider.insertMany": {
29106
+ capName: "data-store-provider",
29107
+ capScope: "system",
29108
+ addonId: null,
29109
+ access: "create"
29110
+ },
28992
29111
  "dataStoreProvider.isEmpty": {
28993
29112
  capName: "data-store-provider",
28994
29113
  capScope: "system",
@@ -30303,6 +30422,12 @@ Object.freeze({
30303
30422
  addonId: null,
30304
30423
  access: "create"
30305
30424
  },
30425
+ "loadContribution.list": {
30426
+ capName: "load-contribution",
30427
+ capScope: "system",
30428
+ addonId: null,
30429
+ access: "view"
30430
+ },
30306
30431
  "localNetwork.downloadCa": {
30307
30432
  capName: "local-network",
30308
30433
  capScope: "system",
@@ -30603,17 +30728,17 @@ Object.freeze({
30603
30728
  addonId: null,
30604
30729
  access: "view"
30605
30730
  },
30606
- "metricsProvider.getProcessStats": {
30731
+ "metricsProvider.getLoadSeries": {
30607
30732
  capName: "metrics-provider",
30608
30733
  capScope: "system",
30609
30734
  addonId: null,
30610
30735
  access: "view"
30611
30736
  },
30612
- "metricsProvider.killProcess": {
30737
+ "metricsProvider.getProcessStats": {
30613
30738
  capName: "metrics-provider",
30614
30739
  capScope: "system",
30615
30740
  addonId: null,
30616
- access: "create"
30741
+ access: "view"
30617
30742
  },
30618
30743
  "metricsProvider.listAddonInstances": {
30619
30744
  capName: "metrics-provider",
@@ -32625,6 +32750,12 @@ Object.freeze({
32625
32750
  addonId: null,
32626
32751
  access: "create"
32627
32752
  },
32753
+ "settingsStore.insertMany": {
32754
+ capName: "settings-store",
32755
+ capScope: "system",
32756
+ addonId: null,
32757
+ access: "create"
32758
+ },
32628
32759
  "settingsStore.isEmpty": {
32629
32760
  capName: "settings-store",
32630
32761
  capScope: "system",
@@ -33237,6 +33368,12 @@ Object.freeze({
33237
33368
  addonId: null,
33238
33369
  access: "create"
33239
33370
  },
33371
+ "system.getLoadContributions": {
33372
+ capName: "system",
33373
+ capScope: "system",
33374
+ addonId: null,
33375
+ access: "view"
33376
+ },
33240
33377
  "system.getLoggingSettings": {
33241
33378
  capName: "system",
33242
33379
  capScope: "system",