@camstack/addon-training 0.1.22 → 0.1.24

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 (42) hide show
  1. package/dist/MaskShapeCanvas-Kfg9dl6B.mjs +686 -0
  2. package/dist/MotionZonesSettings-0RO2vXPR.mjs +292 -0
  3. package/dist/{PrivacyMaskSettings-DDaIx7j5.mjs → PrivacyMaskSettings-DQUoMnuu.mjs} +45 -70
  4. package/dist/ReactKonva-DGuYUN0L.mjs +5416 -0
  5. package/dist/{SceneMonitorEditor-CuJ7xjyd.mjs → SceneMonitorEditor-C3FOjEom.mjs} +311 -311
  6. package/dist/_stub.js +16625 -7160
  7. package/dist/{_virtual_mf-localSharedImportMap___mfe_internal__addon_training_page-DJDgoXBt.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_training_page-BxPcEUyP.mjs} +2 -2
  8. package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-OmGE1nuE.mjs +26 -0
  9. package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare___mf_0_tanstack_mf_1_react_mf_2_query__loadShare__.js-DpjirGmB.mjs +89 -0
  10. package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare___mf_0_trpc_mf_1_client__loadShare__.js-CFCVuRAs.mjs +58 -0
  11. package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare___mf_0_trpc_mf_1_react_mf_2_query__loadShare__.js-BkvDudqY.mjs +62 -0
  12. package/dist/{_virtual_mf___mfe_internal__addon_training_page__loadShare__react__loadShare__.js-BT_wL8s3.mjs → _virtual_mf___mfe_internal__addon_training_page__loadShare__react__loadShare__.js-DeDbF7NI.mjs} +1 -1
  13. package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare__react_mf_1_jsx_mf_2_runtime__loadShare__.js-DnrbBvrw.mjs +34 -0
  14. package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare__react_mf_2_dom__loadShare__.js-DAZkHxxU.mjs +45 -0
  15. package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare__react_mf_2_dom_mf_1_client__loadShare__.js-CHqN9NLt.mjs +34 -0
  16. package/dist/{dist-DhCvklZW.mjs → dist-CoNkmm69.mjs} +24 -12
  17. package/dist/{dist-Dd6EAdVX.js → dist-e1vfYY_l.js} +59 -11
  18. package/dist/grid-2x2-Dip9973H.mjs +21 -0
  19. package/dist/{hostInit-DR-St7pA.mjs → hostInit-DESLun4m.mjs} +1 -1
  20. package/dist/index.js +1 -1
  21. package/dist/lib-CVGFTwe0.mjs +7770 -0
  22. package/dist/orchestrator/training.addon.js +8 -1
  23. package/dist/orchestrator/training.addon.mjs +8 -1
  24. package/dist/{player-overlays-DUZMtmvk.mjs → player-overlays-ChonJUSb.mjs} +32 -10
  25. package/dist/providers/modal/training-modal.addon.js +233 -53
  26. package/dist/providers/modal/training-modal.addon.mjs +233 -53
  27. package/dist/remoteEntry.js +1 -1
  28. package/dist/{responsive-C7QsFtTb.mjs → responsive-vGH-n9E5.mjs} +42 -38
  29. package/dist/{scene-monitor-copy-BtffdnnW.mjs → scene-monitor-copy-Bv7SdZp4.mjs} +4 -4
  30. package/dist/{square-e5Ytjod_.mjs → square-CT7zu_EB.mjs} +29 -4
  31. package/dist/{trash-2-Clte6zIF.mjs → trash-2-JjHVW2_2.mjs} +1 -1
  32. package/dist/{virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_training_page__remoteEntry_js-dy7yMOdw.mjs → virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_training_page__remoteEntry_js-BZV1gmqf.mjs} +399 -390
  33. package/package.json +1 -1
  34. package/dist/MaskShapeCanvas-BokARvOj.mjs +0 -13806
  35. package/dist/MotionZonesSettings-DshSNzpp.mjs +0 -310
  36. package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-D7T4QEtw.mjs +0 -26
  37. package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare___mf_0_tanstack_mf_1_react_mf_2_query__loadShare__.js-BSOdwqcC.mjs +0 -26
  38. package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare___mf_0_trpc_mf_1_client__loadShare__.js-B3rryujf.mjs +0 -25
  39. package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare___mf_0_trpc_mf_1_react_mf_2_query__loadShare__.js-nL4MGFRP.mjs +0 -26
  40. package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare__react_mf_1_jsx_mf_2_runtime__loadShare__.js-DDBEvLdo.mjs +0 -26
  41. package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare__react_mf_2_dom__loadShare__.js-CK-LlgOt.mjs +0 -26
  42. package/dist/_virtual_mf___mfe_internal__addon_training_page__loadShare__react_mf_2_dom_mf_1_client__loadShare__.js-gTIQrhKs.mjs +0 -25
@@ -1,4 +1,4 @@
1
- import { c as trainingProviderCapability, d as number, f as object, l as BaseAddon, m as string, p as record, u as boolean } from "../../dist-DhCvklZW.mjs";
1
+ import { _ as number, b as string, c as trainingProviderCapability, d as arrayItemFieldPath, f as globalSecretScope, g as boolean, h as toSecretFieldView, l as BaseAddon, m as isSecretMarker, p as isSecretClear, u as SECRET_CLEAR, v as object, y as record } from "../../dist-CoNkmm69.mjs";
2
2
  import { createRequire } from "node:module";
3
3
  import path, { dirname, posix } from "node:path";
4
4
  import { createHash, createPrivateKey, createPublicKey, createSign, randomBytes, randomUUID } from "node:crypto";
@@ -39,14 +39,43 @@ var __copyProps = (to, from, except, desc) => {
39
39
  var __toCommonJS = (mod) => __hasOwnProp.call(mod, "module.exports") ? mod["module.exports"] : __copyProps(__defProp({}, "__esModule", { value: true }), mod);
40
40
  var __require = /* @__PURE__ */ createRequire(import.meta.url);
41
41
  //#endregion
42
- //#region src/providers/modal/modal-entries.ts
42
+ //#region src/providers/modal/entry-secret-view.ts
43
43
  /**
44
- * Modal provider entries — one credentials + defaults row per operator
45
- * account. Pure helpers so the store is unit-tested without BaseAddon.
44
+ * Build the {@link SecretFieldView} the Providers edit form needs for an
45
+ * entry's token secret.
46
46
  *
47
- * A pre-multi-entry config (flat tokenId/tokenSecret on the addon) migrates
48
- * to a single entry named {@link DEFAULT_MODAL_ENTRY_NAME}.
47
+ * `readStoredGlobalKey` / `this.config` answer VALUES (D798), never markers —
48
+ * so `toSecretFieldView(plaintext)` alone yields an inline view (`$secret:
49
+ * null`) and `SecretFieldControl` cannot reveal. When the secret is set we
50
+ * prefer the deterministic keychain ref (`ctx.secrets.ref`) so the eye can
51
+ * call `keychain-admin.reveal` (D789).
49
52
  */
53
+ /** View for one entry row, or `null` when nothing is stored. */
54
+ function entryTokenSecretView(tokenSecret, secrets, entryId) {
55
+ if (isSecretMarker(tokenSecret)) return toSecretFieldView(tokenSecret);
56
+ const plain = typeof tokenSecret === "string" ? tokenSecret.trim() : "";
57
+ if (plain === "") return null;
58
+ if (secrets === void 0) return toSecretFieldView(plain);
59
+ return {
60
+ $secret: secrets.ref(globalSecretScope(), arrayItemFieldPath("entries", entryId, "tokenSecret")),
61
+ v: 1,
62
+ set: true
63
+ };
64
+ }
65
+ /** View for the legacy flat `tokenSecret` (pre-multi-entry Default). */
66
+ function flatTokenSecretView(tokenSecret, secrets) {
67
+ if (isSecretMarker(tokenSecret)) return toSecretFieldView(tokenSecret);
68
+ const plain = typeof tokenSecret === "string" ? tokenSecret.trim() : "";
69
+ if (plain === "") return null;
70
+ if (secrets === void 0) return toSecretFieldView(plain);
71
+ return {
72
+ $secret: secrets.ref(globalSecretScope(), "tokenSecret"),
73
+ v: 1,
74
+ set: true
75
+ };
76
+ }
77
+ //#endregion
78
+ //#region src/providers/modal/modal-entries.ts
50
79
  var MODAL_TYPE_ID = "modal";
51
80
  var DEFAULT_MODAL_ENTRY_NAME = "Default";
52
81
  var MODAL_ICON_ASSET = "assets/training-modal/icon.svg";
@@ -57,22 +86,44 @@ var DEFAULT_GRACE = 24;
57
86
  function legacyConfigured(config) {
58
87
  return (config.tokenId ?? "").trim() !== "" || (config.tokenSecret ?? "").trim() !== "";
59
88
  }
89
+ /**
90
+ * Keychain / secretStatePaths may omit an empty `tokenSecret` from a stored
91
+ * row (writing `''` is KEEP, not "store empty"). Readers must never see
92
+ * `undefined` and then call `.trim()`.
93
+ */
94
+ function secretAsString(value) {
95
+ return typeof value === "string" ? value : "";
96
+ }
97
+ function normalizeModalEntry(entry) {
98
+ return {
99
+ id: entry.id,
100
+ name: entry.name ?? "Default",
101
+ tokenId: entry.tokenId ?? "",
102
+ tokenSecret: secretAsString(entry.tokenSecret),
103
+ environment: entry.environment ?? "",
104
+ gpuType: entry.gpuType ?? DEFAULT_GPU,
105
+ region: entry.region ?? "",
106
+ costCapUsd: entry.costCapUsd ?? DEFAULT_COST,
107
+ maxRuntimeHours: entry.maxRuntimeHours ?? DEFAULT_HOURS,
108
+ failedDatasetGraceHours: entry.failedDatasetGraceHours ?? DEFAULT_GRACE
109
+ };
110
+ }
60
111
  /** Entries the operator sees — synthesises Default from legacy flat fields. */
61
112
  function effectiveModalEntries(config) {
62
- if (config.entries.length > 0) return config.entries;
113
+ if (config.entries.length > 0) return config.entries.map((e) => normalizeModalEntry(e));
63
114
  if (!legacyConfigured(config)) return [];
64
- return [{
115
+ return [normalizeModalEntry({
65
116
  id: "legacy-default",
66
117
  name: DEFAULT_MODAL_ENTRY_NAME,
67
- tokenId: config.tokenId ?? "",
68
- tokenSecret: config.tokenSecret ?? "",
69
- environment: config.environment ?? "",
70
- gpuType: config.gpuType ?? DEFAULT_GPU,
71
- region: config.region ?? "",
72
- costCapUsd: config.costCapUsd ?? DEFAULT_COST,
73
- maxRuntimeHours: config.maxRuntimeHours ?? DEFAULT_HOURS,
74
- failedDatasetGraceHours: config.failedDatasetGraceHours ?? DEFAULT_GRACE
75
- }];
118
+ tokenId: config.tokenId,
119
+ tokenSecret: config.tokenSecret,
120
+ environment: config.environment,
121
+ gpuType: config.gpuType,
122
+ region: config.region,
123
+ costCapUsd: config.costCapUsd,
124
+ maxRuntimeHours: config.maxRuntimeHours,
125
+ failedDatasetGraceHours: config.failedDatasetGraceHours
126
+ })];
76
127
  }
77
128
  function findModalEntry(config, entryId) {
78
129
  return effectiveModalEntries(config).find((e) => e.id === entryId) ?? null;
@@ -277,20 +328,6 @@ function trainerDockerfileUrl(repo, revision) {
277
328
  return `https://huggingface.co/${repo}/resolve/${revision}/Dockerfile`;
278
329
  }
279
330
  //#endregion
280
- //#region src/providers/modal/modal-gateway.ts
281
- var MODAL_APP_NAME = "camstack-training";
282
- var MODAL_CACHE_VOLUME = "camstack-training-cache";
283
- /** A small public image with `sh` and `cat`, for the staging / collector sandboxes. */
284
- var MODAL_TOOLS_IMAGE = "alpine:3.20";
285
- var ModalAuthError = class extends Error {
286
- reason;
287
- constructor(reason, message) {
288
- super(message);
289
- this.reason = reason;
290
- this.name = "ModalAuthError";
291
- }
292
- };
293
- //#endregion
294
331
  //#region src/providers/modal/modal-pricing.ts
295
332
  var MODAL_GPUS = [
296
333
  {
@@ -368,6 +405,96 @@ function modalPricePerSecond(gpuType, region) {
368
405
  return gpu === void 0 ? 0 : gpu.usdPerHour * multiplier / 3600;
369
406
  }
370
407
  //#endregion
408
+ //#region src/providers/modal/modal-entry-schema.ts
409
+ var MODAL_ENTRY_CONFIG_SCHEMA = { sections: [{
410
+ id: "credentials",
411
+ title: "Credentials",
412
+ fields: [
413
+ {
414
+ type: "text",
415
+ key: "tokenId",
416
+ label: "Token id",
417
+ placeholder: "ak-…"
418
+ },
419
+ {
420
+ type: "password",
421
+ key: "tokenSecret",
422
+ label: "Token secret",
423
+ placeholder: "as-…",
424
+ showToggle: true
425
+ },
426
+ {
427
+ type: "text",
428
+ key: "environment",
429
+ label: "Environment",
430
+ placeholder: "Optional workspace environment"
431
+ }
432
+ ]
433
+ }, {
434
+ id: "defaults",
435
+ title: "Defaults",
436
+ fields: [
437
+ {
438
+ type: "select",
439
+ key: "gpuType",
440
+ label: "GPU",
441
+ default: "L4",
442
+ options: MODAL_GPUS.map((g) => ({
443
+ value: g.id,
444
+ label: g.label
445
+ }))
446
+ },
447
+ {
448
+ type: "select",
449
+ key: "region",
450
+ label: "Region",
451
+ default: "",
452
+ options: MODAL_REGIONS.map((r) => ({
453
+ value: r.id,
454
+ label: r.label
455
+ }))
456
+ },
457
+ {
458
+ type: "number",
459
+ key: "costCapUsd",
460
+ label: "Cost cap (USD)",
461
+ default: 5,
462
+ min: 0,
463
+ step: .5
464
+ },
465
+ {
466
+ type: "number",
467
+ key: "maxRuntimeHours",
468
+ label: "Max runtime (hours)",
469
+ default: 4,
470
+ min: .1,
471
+ step: .5
472
+ },
473
+ {
474
+ type: "number",
475
+ key: "failedDatasetGraceHours",
476
+ label: "Failed-job dataset grace (hours)",
477
+ default: 24,
478
+ min: 0,
479
+ step: 1
480
+ }
481
+ ]
482
+ }] };
483
+ //#endregion
484
+ //#region src/providers/modal/modal-gateway.ts
485
+ var MODAL_APP_NAME = "camstack-training";
486
+ var MODAL_CACHE_VOLUME = "camstack-training-cache";
487
+ /** A small public image with `sh` and `cat`, for the staging / collector sandboxes. */
488
+ var MODAL_TOOLS_IMAGE = "alpine:3.20";
489
+ var ModalAuthError = class extends Error {
490
+ reason;
491
+ constructor(reason, message) {
492
+ super(message);
493
+ this.reason = reason;
494
+ this.name = "ModalAuthError";
495
+ }
496
+ };
497
+ //#endregion
371
498
  //#region src/providers/modal/modal-provider.ts
372
499
  /**
373
500
  * The Modal `training-provider` (D807), over {@link ModalGateway}.
@@ -409,12 +536,16 @@ var ModalTrainingProvider = class {
409
536
  constructor(deps) {
410
537
  this.deps = deps;
411
538
  }
412
- describe = async () => this.deps.listEntries().map((entry) => this.descriptorOf(entry));
539
+ describe = async () => {
540
+ const views = await this.deps.secretViews();
541
+ return this.deps.listEntries().map((entry) => this.descriptorOf(entry, views.get(entry.id) ?? null));
542
+ };
413
543
  describeTypes = async () => [{
414
544
  typeId: MODAL_TYPE_ID,
415
545
  label: "Modal",
416
546
  iconAsset: MODAL_ICON_ASSET,
417
- addonId: this.deps.addonId
547
+ addonId: this.deps.addonId,
548
+ configSchema: MODAL_ENTRY_CONFIG_SCHEMA
418
549
  }];
419
550
  listEntries = async () => this.deps.listEntries().map((entry) => ({
420
551
  entryId: entry.id,
@@ -425,10 +556,11 @@ var ModalTrainingProvider = class {
425
556
  }));
426
557
  createEntry = async (input) => this.deps.createEntry(input);
427
558
  updateEntry = async (input) => {
559
+ const secret = input.tokenSecret === void 0 ? {} : isSecretClear(input.tokenSecret) ? { clearTokenSecret: true } : input.tokenSecret === "" ? {} : { tokenSecret: input.tokenSecret };
428
560
  await this.deps.updateEntry(input.entryId, {
429
561
  name: input.name,
430
562
  ...input.tokenId !== void 0 ? { tokenId: input.tokenId } : {},
431
- ...input.tokenSecret !== void 0 ? { tokenSecret: input.tokenSecret } : {},
563
+ ...secret,
432
564
  ...input.environment !== void 0 ? { environment: input.environment } : {},
433
565
  ...input.gpuType !== void 0 ? { gpuType: input.gpuType } : {},
434
566
  ...input.region !== void 0 ? { region: input.region } : {},
@@ -715,9 +847,15 @@ var ModalTrainingProvider = class {
715
847
  }))];
716
848
  };
717
849
  entryConfigured(entry) {
718
- return entry.tokenId.trim() !== "" && entry.tokenSecret.trim() !== "";
850
+ const secret = typeof entry.tokenSecret === "string" ? entry.tokenSecret : "";
851
+ return (entry.tokenId ?? "").trim() !== "" && secret.trim() !== "";
719
852
  }
720
- descriptorOf(entry) {
853
+ descriptorOf(entry, tokenSecretView) {
854
+ const gpuType = entry.gpuType ?? "L4";
855
+ const region = entry.region ?? "";
856
+ const costCapUsd = entry.costCapUsd ?? 5;
857
+ const maxRuntimeHours = entry.maxRuntimeHours ?? 4;
858
+ const failedDatasetGraceHours = entry.failedDatasetGraceHours ?? 24;
721
859
  return {
722
860
  addonId: this.deps.addonId,
723
861
  entryId: entry.id,
@@ -734,15 +872,22 @@ var ModalTrainingProvider = class {
734
872
  dataResidencyNote: "Modal keeps the frames on a Volume of your workspace for the length of the job; the training container sees them only while it runs.",
735
873
  configured: this.entryConfigured(entry),
736
874
  defaults: {
737
- gpuType: entry.gpuType,
738
- region: entry.region,
739
- costCapUsd: entry.costCapUsd,
740
- maxRuntimeSec: Math.round(entry.maxRuntimeHours * 3600),
741
- failedDatasetGraceHours: entry.failedDatasetGraceHours
875
+ gpuType,
876
+ region,
877
+ costCapUsd,
878
+ maxRuntimeSec: Math.round(maxRuntimeHours * 3600),
879
+ failedDatasetGraceHours
742
880
  },
743
- tokenId: entry.tokenId,
744
- environment: entry.environment,
745
- hasTokenSecret: entry.tokenSecret.trim() !== ""
881
+ formValues: {
882
+ tokenId: entry.tokenId ?? "",
883
+ tokenSecret: tokenSecretView ?? "",
884
+ environment: entry.environment ?? "",
885
+ gpuType,
886
+ region,
887
+ costCapUsd,
888
+ maxRuntimeHours,
889
+ failedDatasetGraceHours
890
+ }
746
891
  };
747
892
  }
748
893
  requireGateway(entryId) {
@@ -88616,9 +88761,15 @@ var TrainingModalAddon = class extends BaseAddon {
88616
88761
  }
88617
88762
  async onInitialize() {
88618
88763
  let next = this.config;
88619
- if (next.entries.length === 0) next = migrateLegacyModalConfig(next, () => randomUUID());
88764
+ let migratedLegacy = false;
88765
+ if (next.entries.length === 0) {
88766
+ const migrated = migrateLegacyModalConfig(next, () => randomUUID());
88767
+ migratedLegacy = migrated !== next;
88768
+ next = migrated;
88769
+ }
88620
88770
  next = ensureModalEntryIds(next, () => randomUUID());
88621
88771
  if (next !== this.config) await this.updateGlobalSettings(next);
88772
+ if (migratedLegacy) await this.clearSecrets(["tokenSecret"]);
88622
88773
  this.ledgerState = this.state(LEDGER_KEY, LedgerSchema, {});
88623
88774
  const peer = this.ctx.peerBytes;
88624
88775
  if (peer === void 0) throw new Error("training-modal needs the peer-bytes facility");
@@ -88634,17 +88785,27 @@ var TrainingModalAddon = class extends BaseAddon {
88634
88785
  return { entryId: result.entryId };
88635
88786
  },
88636
88787
  updateEntry: async (entryId, patch) => {
88637
- const result = updateModalEntry(this.config, entryId, patch);
88788
+ const { clearTokenSecret, ...rest } = patch;
88789
+ const result = updateModalEntry(this.config, entryId, rest);
88638
88790
  if (!result.ok) throw new Error(`cannot update entry: ${result.reason}`);
88639
- await this.updateGlobalSettings(result.config);
88791
+ if (clearTokenSecret === true) await this.updateGlobalSettings({
88792
+ ...result.config,
88793
+ entries: result.config.entries.map((entry) => entry.id === entryId ? {
88794
+ ...entry,
88795
+ tokenSecret: SECRET_CLEAR
88796
+ } : entry)
88797
+ });
88798
+ else await this.updateGlobalSettings(result.config);
88640
88799
  this.closeGateway(entryId);
88641
88800
  },
88642
88801
  deleteEntry: async (entryId) => {
88643
88802
  const result = deleteModalEntry(this.config, entryId);
88644
88803
  if (!result.ok) throw new Error(`cannot delete entry: ${result.reason}`);
88645
88804
  await this.updateGlobalSettings(result.config);
88805
+ await this.clearSecrets(["tokenSecret"]);
88646
88806
  this.closeGateway(entryId);
88647
88807
  },
88808
+ secretViews: () => this.readEntrySecretViews(),
88648
88809
  ledger: this.ledger(),
88649
88810
  peer,
88650
88811
  fetchText,
@@ -88653,7 +88814,10 @@ var TrainingModalAddon = class extends BaseAddon {
88653
88814
  });
88654
88815
  this.ctx.logger.info("Modal training provider ready", { meta: {
88655
88816
  entries: effectiveModalEntries(this.config).length,
88656
- configured: effectiveModalEntries(this.config).some((e) => e.tokenId.trim() !== "" && e.tokenSecret.trim() !== "")
88817
+ configured: effectiveModalEntries(this.config).some((e) => {
88818
+ const secret = typeof e.tokenSecret === "string" ? e.tokenSecret : "";
88819
+ return (e.tokenId ?? "").trim() !== "" && secret.trim() !== "";
88820
+ })
88657
88821
  } });
88658
88822
  return { providers: [{
88659
88823
  capability: trainingProviderCapability,
@@ -88671,15 +88835,18 @@ var TrainingModalAddon = class extends BaseAddon {
88671
88835
  gatewayFor(entryId) {
88672
88836
  const entry = findModalEntry(this.config, entryId);
88673
88837
  if (entry === null) return null;
88674
- if (entry.tokenId.trim() === "" || entry.tokenSecret.trim() === "") return null;
88675
- const key = `${entry.tokenId}\u0000${entry.environment}`;
88838
+ const tokenId = (entry.tokenId ?? "").trim();
88839
+ const tokenSecret = (typeof entry.tokenSecret === "string" ? entry.tokenSecret : "").trim();
88840
+ if (tokenId === "" || tokenSecret === "") return null;
88841
+ const environment = (entry.environment ?? "").trim();
88842
+ const key = `${tokenId}\u0000${environment}`;
88676
88843
  const cached = this.gateways.get(entryId);
88677
88844
  if (cached !== void 0 && cached.key === key) return cached.gateway;
88678
88845
  cached?.gateway.close();
88679
88846
  const gateway = new ModalSdkGateway({
88680
- tokenId: entry.tokenId.trim(),
88681
- tokenSecret: entry.tokenSecret.trim(),
88682
- environment: entry.environment.trim()
88847
+ tokenId,
88848
+ tokenSecret,
88849
+ environment
88683
88850
  });
88684
88851
  this.gateways.set(entryId, {
88685
88852
  key,
@@ -88693,6 +88860,19 @@ var TrainingModalAddon = class extends BaseAddon {
88693
88860
  cached.gateway.close();
88694
88861
  this.gateways.delete(entryId);
88695
88862
  }
88863
+ /**
88864
+ * Keychain views for the Providers edit form. Addon-facing reads answer
88865
+ * VALUES (D798), so we cannot recover markers from `readStoredGlobalKey`.
88866
+ * When a secret is present on the resolved entry we emit the deterministic
88867
+ * keychain ref (`ctx.secrets.ref`) so `SecretFieldControl` can reveal.
88868
+ */
88869
+ async readEntrySecretViews() {
88870
+ const map = /* @__PURE__ */ new Map();
88871
+ const secrets = this.ctx.secrets;
88872
+ for (const entry of effectiveModalEntries(this.config)) map.set(entry.id, entryTokenSecretView(entry.tokenSecret, secrets, entry.id));
88873
+ map.set("legacy-default", flatTokenSecretView(this.config.tokenSecret, secrets));
88874
+ return map;
88875
+ }
88696
88876
  ledger() {
88697
88877
  const state = () => {
88698
88878
  if (this.ledgerState === null) throw new Error("training-modal ledger not initialised");
@@ -1,2 +1,2 @@
1
- import { n as e, t } from "./virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_training_page__remoteEntry_js-dy7yMOdw.mjs";
1
+ import { n as e, t } from "./virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_training_page__remoteEntry_js-BZV1gmqf.mjs";
2
2
  export { t as get, e as init };
@@ -1,8 +1,8 @@
1
- import { _ as e, b as t, c as n, g as r, l as i, m as a, n as o, r as s, t as c, u as l } from "./_virtual_mf___mfe_internal__addon_training_page__loadShare__react__loadShare__.js-BT_wL8s3.mjs";
2
- import { i as u } from "./_virtual_mf___mfe_internal__addon_training_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-D7T4QEtw.mjs";
3
- import "./_virtual_mf___mfe_internal__addon_training_page__loadShare__react_mf_1_jsx_mf_2_runtime__loadShare__.js-DDBEvLdo.mjs";
1
+ import { S as e, _ as t, c as n, l as r, m as i, n as a, r as o, t as s, u as c, v as l } from "./_virtual_mf___mfe_internal__addon_training_page__loadShare__react__loadShare__.js-DeDbF7NI.mjs";
2
+ import { h as u } from "./_virtual_mf___mfe_internal__addon_training_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-OmGE1nuE.mjs";
3
+ import "./_virtual_mf___mfe_internal__addon_training_page__loadShare__react_mf_1_jsx_mf_2_runtime__loadShare__.js-DnrbBvrw.mjs";
4
4
  //#region ../../node_modules/lucide-react/dist/esm/shared/src/utils/mergeClasses.js
5
- t();
5
+ e();
6
6
  var d = (...e) => e.filter((e, t, n) => !!e && e.trim() !== "" && n.indexOf(e) === t).join(" ").trim(), f = (e) => e.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase(), p = (e) => e.replace(/^([A-Z])|[\s-_]+(\w)/g, (e, t, n) => n ? n.toUpperCase() : t.toLowerCase()), m = (e) => {
7
7
  let t = p(e);
8
8
  return t.charAt(0).toUpperCase() + t.slice(1);
@@ -19,7 +19,7 @@ var d = (...e) => e.filter((e, t, n) => !!e && e.trim() !== "" && n.indexOf(e) =
19
19
  }, g = (e) => {
20
20
  for (let t in e) if (t.startsWith("aria-") || t === "role" || t === "title") return !0;
21
21
  return !1;
22
- }, _ = s(({ color: e = "currentColor", size: t = 24, strokeWidth: n = 2, absoluteStrokeWidth: r, className: i = "", children: a, iconNode: s, ...c }, l) => o("svg", {
22
+ }, _ = o(({ color: e = "currentColor", size: t = 24, strokeWidth: n = 2, absoluteStrokeWidth: r, className: i = "", children: o, iconNode: s, ...c }, l) => a("svg", {
23
23
  ref: l,
24
24
  ...h,
25
25
  width: t,
@@ -27,14 +27,14 @@ var d = (...e) => e.filter((e, t, n) => !!e && e.trim() !== "" && n.indexOf(e) =
27
27
  stroke: e,
28
28
  strokeWidth: r ? Number(n) * 24 / Number(t) : n,
29
29
  className: d("lucide", i),
30
- ...!a && !g(c) && { "aria-hidden": "true" },
30
+ ...!o && !g(c) && { "aria-hidden": "true" },
31
31
  ...c
32
- }, [...s.map(([e, t]) => o(e, t)), ...Array.isArray(a) ? a : [a]]));
32
+ }, [...s.map(([e, t]) => a(e, t)), ...Array.isArray(o) ? o : [o]]));
33
33
  //#endregion
34
34
  //#region ../../node_modules/lucide-react/dist/esm/createLucideIcon.js
35
- t();
35
+ e();
36
36
  var v = (e, t) => {
37
- let n = s(({ className: n, ...r }, i) => o(_, {
37
+ let n = o(({ className: n, ...r }, i) => a(_, {
38
38
  ref: i,
39
39
  iconNode: t,
40
40
  className: d(`lucide-${f(m(e))}`, `lucide-${e}`, n),
@@ -44,65 +44,69 @@ var v = (e, t) => {
44
44
  };
45
45
  //#endregion
46
46
  //#region ../ui-library/src/lib/shared-context.ts
47
- t();
47
+ e();
48
48
  function y(e, t) {
49
- if (typeof globalThis > "u") return c(t);
49
+ if (typeof globalThis > "u") return s(t);
50
50
  let n = globalThis.__camstackSharedContexts, r = n ?? /* @__PURE__ */ new Map();
51
51
  n || (globalThis.__camstackSharedContexts = r);
52
52
  let i = r.get(e);
53
53
  if (i) return i;
54
- let a = c(t);
54
+ let a = s(t);
55
55
  return r.set(e, a), a;
56
56
  }
57
57
  //#endregion
58
58
  //#region ../ui-library/src/contexts/system-context.tsx
59
- t();
59
+ e();
60
60
  var b = y("camstack:system", null);
61
61
  function x() {
62
- let e = i(b);
62
+ let e = r(b);
63
63
  if (!e) throw Error("useSystem(): no <SystemProvider> in tree");
64
64
  return e;
65
65
  }
66
66
  //#endregion
67
67
  //#region ../ui-library/src/hooks/use-device-proxy.ts
68
- t();
68
+ e();
69
69
  var S = "capability.binding-changed";
70
- function C(e, t) {
71
- let [n, i] = r(null);
72
- return l(() => {
73
- if (t === null) {
74
- i(null);
70
+ function C(e, n) {
71
+ let [r, a] = t(null);
72
+ return c(() => {
73
+ if (n === null) {
74
+ a(null);
75
75
  return;
76
76
  }
77
- let n = !1, r = async () => {
77
+ let t = !1, r = async () => {
78
78
  try {
79
- let r = await e.deviceManager.getBindings.query({ deviceId: t });
80
- n || i(r);
79
+ let r = await e.deviceManager.getBindings.query({ deviceId: n });
80
+ t || a(r);
81
81
  } catch {
82
- n || i((e) => e);
82
+ t || a((e) => e);
83
83
  }
84
84
  };
85
85
  r();
86
- let a = e.live?.onEvent.subscribe({ category: S }, { onData: (e) => {
87
- let n = e.data?.source;
88
- if (!n) {
86
+ let i = e.live?.onEvent.subscribe({ category: S }, { onData: (e) => {
87
+ let t = e.data?.source;
88
+ if (!t) {
89
89
  r();
90
90
  return;
91
91
  }
92
- n.type === "device" && n.id === t && r();
92
+ t.type === "device" && t.id === n && r();
93
93
  } });
94
94
  return () => {
95
- n = !0, a?.unsubscribe();
95
+ t = !0, i?.unsubscribe();
96
96
  };
97
- }, [e, t]), a(() => n ? u(e, n) : null, [e, n]);
97
+ }, [e, n]), i(() => r ? u(e, r) : null, [e, r]);
98
98
  }
99
- function w(t) {
100
- let r = n((e) => t ? t.subscribe(() => e()) : () => void 0, [t]), i = n(() => t?.value, [t]);
101
- return e(r, i, i);
99
+ function w(e) {
100
+ let t = n((t) => e ? e.subscribe(() => t()) : () => void 0, [e]), r = n(() => e?.value, [e]);
101
+ return l(t, r, r);
102
+ }
103
+ function T(e, t, n) {
104
+ let r = C(e, t);
105
+ return w(r ? n(r.state) : void 0);
102
106
  }
103
107
  //#endregion
104
108
  //#region ../ui-library/src/lib/cap-error.ts
105
- function T(e) {
109
+ function E(e) {
106
110
  if (typeof e != "object" || !e) return null;
107
111
  let t = Reflect.get(e, "data");
108
112
  if (typeof t == "object" && t) {
@@ -111,12 +115,12 @@ function T(e) {
111
115
  }
112
116
  return null;
113
117
  }
114
- function E(e) {
115
- let t = T(e);
118
+ function D(e) {
119
+ let t = E(e);
116
120
  return t === null ? (e instanceof Error ? e.message : String(e)).includes("provider not available") : t === "no-provider" || t === "node-offline";
117
121
  }
118
122
  //#endregion
119
123
  //#region ../ui-library/src/lib/responsive.ts
120
- var D = "rounded-lg border border-border bg-surface overflow-hidden", O = "border-b border-border px-3 sm:px-4 py-1.5 sm:py-2", k = "p-2 sm:p-3 lg:p-4", A = "grid grid-cols-2 sm:grid-cols-2 lg:grid-cols-4", j = "flex min-w-0 flex-col gap-0.5 py-1.5 sm:flex-row sm:items-center", M = "min-w-0 text-[11px] leading-tight text-foreground-subtle sm:w-32 sm:shrink-0 sm:pr-2", N = "flex w-full min-w-0 items-center gap-1 sm:flex-1", P = "min-w-0 break-all text-xs text-foreground sm:truncate", F = "text-[10px] sm:text-[11px] font-semibold text-foreground uppercase tracking-wider", I = "text-[10px] text-foreground-subtle", L = "inline-flex items-center gap-1 rounded-full border px-1.5 py-0.5 text-[10px] font-medium transition-colors", R = "border-primary/50 bg-primary/15 text-primary", z = "border-border bg-surface text-foreground-subtle hover:bg-surface-hover";
124
+ var O = "rounded-lg border border-border bg-surface overflow-hidden", k = "border-b border-border px-3 sm:px-4 py-1.5 sm:py-2", A = "p-2 sm:p-3 lg:p-4", j = "grid grid-cols-2 sm:grid-cols-2 lg:grid-cols-4", M = "flex min-w-0 flex-col gap-0.5 py-1.5 sm:flex-row sm:items-center", N = "min-w-0 text-[11px] leading-tight text-foreground-subtle sm:w-32 sm:shrink-0 sm:pr-2", P = "flex w-full min-w-0 items-center gap-1 sm:flex-1", F = "min-w-0 break-all text-xs text-foreground sm:truncate", I = "text-[10px] sm:text-[11px] font-semibold text-foreground uppercase tracking-wider", L = "text-[10px] text-foreground-subtle", R = "inline-flex items-center gap-1 rounded-full border px-1.5 py-0.5 text-[10px] font-medium transition-colors", z = "border-primary/50 bg-primary/15 text-primary", B = "border-border bg-surface text-foreground-subtle hover:bg-surface-hover";
121
125
  //#endregion
122
- export { x as _, k as a, j as c, P as d, I as f, w as g, C as h, A as i, M as l, E as m, L as n, D as o, F as p, z as r, O as s, R as t, N as u, y as v, v as y };
126
+ export { w as _, A as a, v as b, M as c, F as d, L as f, T as g, C as h, j as i, N as l, D as m, R as n, O as o, I as p, B as r, k as s, z as t, P as u, x as v, y };
@@ -1,5 +1,5 @@
1
- import { b as e, c as t, g as n, m as r } from "./_virtual_mf___mfe_internal__addon_training_page__loadShare__react__loadShare__.js-BT_wL8s3.mjs";
2
- import { y as i } from "./responsive-C7QsFtTb.mjs";
1
+ import { S as e, _ as t, c as n, m as r } from "./_virtual_mf___mfe_internal__addon_training_page__loadShare__react__loadShare__.js-DeDbF7NI.mjs";
2
+ import { b as i } from "./responsive-vGH-n9E5.mjs";
3
3
  var a = i("camera", [["path", {
4
4
  d: "M13.997 4a2 2 0 0 1 1.76 1.05l.486.9A2 2 0 0 0 18.003 7H20a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V9a2 2 0 0 1 2-2h1.997a2 2 0 0 0 1.759-1.048l.489-.904A2 2 0 0 1 10.004 4z",
5
5
  key: "18u6gg"
@@ -89,7 +89,7 @@ function g(e) {
89
89
  //#region ../ui-library/src/hooks/use-device-snapshot.ts
90
90
  var _ = "/addon/snapshot/media";
91
91
  function v(e, i = {}) {
92
- let { width: a, baseUrl: o } = i, [s, c] = n(0);
92
+ let { width: a, baseUrl: o } = i, [s, c] = t(0);
93
93
  return {
94
94
  src: r(() => {
95
95
  if (e === null || e <= 0) return null;
@@ -104,7 +104,7 @@ function v(e, i = {}) {
104
104
  s
105
105
  ]),
106
106
  loading: !1,
107
- refresh: t(() => {
107
+ refresh: n(() => {
108
108
  c((e) => e + 1);
109
109
  }, [])
110
110
  };
@@ -1,4 +1,4 @@
1
- import { y as e } from "./responsive-C7QsFtTb.mjs";
1
+ import { b as e } from "./responsive-vGH-n9E5.mjs";
2
2
  var t = e("eye-off", [
3
3
  ["path", {
4
4
  d: "M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49",
@@ -16,7 +16,32 @@ var t = e("eye-off", [
16
16
  d: "m2 2 20 20",
17
17
  key: "1ooewy"
18
18
  }]
19
- ]), n = e("mic", [
19
+ ]), n = e("mic-off", [
20
+ ["path", {
21
+ d: "M12 19v3",
22
+ key: "npa21l"
23
+ }],
24
+ ["path", {
25
+ d: "M15 9.34V5a3 3 0 0 0-5.68-1.33",
26
+ key: "1gzdoj"
27
+ }],
28
+ ["path", {
29
+ d: "M16.95 16.95A7 7 0 0 1 5 12v-2",
30
+ key: "cqa7eg"
31
+ }],
32
+ ["path", {
33
+ d: "M18.89 13.23A7 7 0 0 0 19 12v-2",
34
+ key: "16hl24"
35
+ }],
36
+ ["path", {
37
+ d: "m2 2 20 20",
38
+ key: "1ooewy"
39
+ }],
40
+ ["path", {
41
+ d: "M9 9v3a3 3 0 0 0 5.12 2.12",
42
+ key: "r2i35w"
43
+ }]
44
+ ]), r = e("mic", [
20
45
  ["path", {
21
46
  d: "M12 19v3",
22
47
  key: "npa21l"
@@ -33,7 +58,7 @@ var t = e("eye-off", [
33
58
  rx: "3",
34
59
  key: "s6n7sd"
35
60
  }]
36
- ]), r = e("square", [["rect", {
61
+ ]), i = e("square", [["rect", {
37
62
  width: "18",
38
63
  height: "18",
39
64
  x: "3",
@@ -42,4 +67,4 @@ var t = e("eye-off", [
42
67
  key: "afitv7"
43
68
  }]]);
44
69
  //#endregion
45
- export { n, t as r, r as t };
70
+ export { t as i, r as n, n as r, i as t };
@@ -1,4 +1,4 @@
1
- import { y as e } from "./responsive-C7QsFtTb.mjs";
1
+ import { b as e } from "./responsive-vGH-n9E5.mjs";
2
2
  var t = e("trash-2", [
3
3
  ["path", {
4
4
  d: "M10 11v6",