local-operator-ui 0.39.4 → 0.39.5

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 (92) hide show
  1. package/out/main/index.js +346 -36
  2. package/out/preload/index.js +12 -0
  3. package/out/renderer/assets/{_basePickBy-DpOw3Tny.js → _basePickBy-BgM1I5lG.js} +1 -1
  4. package/out/renderer/assets/{_baseUniq-CloF1Z39.js → _baseUniq-Bmkgy85v.js} +1 -1
  5. package/out/renderer/assets/{agent-details-page-B-wOn-JJ.js → agent-details-page-Du26ZU6E.js} +1 -1
  6. package/out/renderer/assets/{agent-hub-page-kOIRpx4R.js → agent-hub-page-BwVMuSzt.js} +1 -1
  7. package/out/renderer/assets/{agents-page-A6mqclDx.js → agents-page-BhSbjEpr.js} +3 -3
  8. package/out/renderer/assets/{arc-C-USYSJX.js → arc-3zNC_x2n.js} +1 -1
  9. package/out/renderer/assets/{architectureDiagram-IEHRJDOE-BStVetpz.js → architectureDiagram-IEHRJDOE-CtDg0QNg.js} +1 -1
  10. package/out/renderer/assets/{blockDiagram-JOT3LUYC-DFraQTdY.js → blockDiagram-JOT3LUYC-4XryKcIu.js} +1 -1
  11. package/out/renderer/assets/{book-open-CbkGl_K7.js → book-open-lnC7oth0.js} +1 -1
  12. package/out/renderer/assets/browser-page-CsoEGi9k.js +1 -0
  13. package/out/renderer/assets/{browser-webauthn-prompt-CzS7qaIE.js → browser-webauthn-prompt-BTC3LWcr.js} +1 -1
  14. package/out/renderer/assets/{building-2-cVqkqSs_.js → building-2-CRI7K1ut.js} +1 -1
  15. package/out/renderer/assets/{c4Diagram-VJAJSXHY-Bpo5tV9E.js → c4Diagram-VJAJSXHY-n2cPdK4v.js} +1 -1
  16. package/out/renderer/assets/channel-MJ9Q5Gdp.js +1 -0
  17. package/out/renderer/assets/{chunk-4BMEZGHF-BvVdPPZL.js → chunk-4BMEZGHF-P7BOtABr.js} +1 -1
  18. package/out/renderer/assets/{chunk-A2AXSNBT-DtDHNfFN.js → chunk-A2AXSNBT-BmO2P02x.js} +1 -1
  19. package/out/renderer/assets/{chunk-AEK57VVT-Cy4jpw-R.js → chunk-AEK57VVT-KMJMGzZF.js} +1 -1
  20. package/out/renderer/assets/{chunk-D6G4REZN-DvaHPHsB.js → chunk-D6G4REZN-WA3nwEd_.js} +1 -1
  21. package/out/renderer/assets/{chunk-RZ5BOZE2-CEKwLFh6.js → chunk-RZ5BOZE2-C4md2pdG.js} +1 -1
  22. package/out/renderer/assets/{chunk-XZIHB7SX-CSpNkV4-.js → chunk-XZIHB7SX-MPSf1VFR.js} +1 -1
  23. package/out/renderer/assets/classDiagram-GIVACNV2-PYFoG-nl.js +1 -0
  24. package/out/renderer/assets/classDiagram-v2-COTLJTTW-PYFoG-nl.js +1 -0
  25. package/out/renderer/assets/clone-BWjAp2XI.js +1 -0
  26. package/out/renderer/assets/{console-mirror-3ddzbqxj.js → console-mirror-CnVv9rOt.js} +1 -1
  27. package/out/renderer/assets/{consoleCapture-CUH-HGgu.js → consoleCapture-B_hi3E9g.js} +1 -1
  28. package/out/renderer/assets/{conversation-input-sync-C16E6bmc.js → conversation-input-sync-CQ0nQbSV.js} +172 -172
  29. package/out/renderer/assets/{dagre-OKDRZEBW-CZM6WQD8.js → dagre-OKDRZEBW-QrYk8i27.js} +1 -1
  30. package/out/renderer/assets/{diagram-SSKATNLV-DhfdsL7X.js → diagram-SSKATNLV-CpIwEDtE.js} +1 -1
  31. package/out/renderer/assets/{diagram-VNBRO52H-6SKM5YIe.js → diagram-VNBRO52H-DtHOhSDJ.js} +1 -1
  32. package/out/renderer/assets/{erDiagram-Q7BY3M3F-Dr-mAd-w.js → erDiagram-Q7BY3M3F-AEs8Bb_A.js} +1 -1
  33. package/out/renderer/assets/{error-boundary-BQkbSeb-.js → error-boundary-CU2PiR3H.js} +3 -3
  34. package/out/renderer/assets/{flowDiagram-4HSFHLVR-XzjnYaiy.js → flowDiagram-4HSFHLVR-CliaNR7R.js} +1 -1
  35. package/out/renderer/assets/{ganttDiagram-APWFNJXF-BiDYLq2r.js → ganttDiagram-APWFNJXF-Br5lLrlI.js} +1 -1
  36. package/out/renderer/assets/{gitGraphDiagram-7IBYFJ6S-CHG8kjsH.js → gitGraphDiagram-7IBYFJ6S-D68CT6c8.js} +1 -1
  37. package/out/renderer/assets/{graph-CCrDrJrv.js → graph-LIDYSJHC.js} +1 -1
  38. package/out/renderer/assets/{hash-m3f0Pwzh.js → hash-5VU7fofJ.js} +1 -1
  39. package/out/renderer/assets/index-B_mT8ft1.js +57 -0
  40. package/out/renderer/assets/index-BoQsbSXg.js +830 -0
  41. package/out/renderer/assets/{index-DQdKGxDM.js → index-BpJ3H71K.js} +1 -1
  42. package/out/renderer/assets/{index-D1rKdut2.js → index-Bpi83aqM.js} +1 -1
  43. package/out/renderer/assets/index-ZC-NNW64.css +1 -0
  44. package/out/renderer/assets/{infoDiagram-PH2N3AL5-Boc-74q5.js → infoDiagram-PH2N3AL5-U0UUgi63.js} +1 -1
  45. package/out/renderer/assets/{installer-DIGUKrBB.js → installer-9uv2KfFf.js} +1 -1
  46. package/out/renderer/assets/{journeyDiagram-U35MCT3I-D7_ElfaN.js → journeyDiagram-U35MCT3I-FFIRpntM.js} +1 -1
  47. package/out/renderer/assets/{kanban-definition-NDS4AKOZ-C6QsJ5yF.js → kanban-definition-NDS4AKOZ-BRpcp-A3.js} +1 -1
  48. package/out/renderer/assets/{layout-aAj5fMFf.js → layout-MxBLCasM.js} +1 -1
  49. package/out/renderer/assets/{legacy-agents-page-USk5n9oW.js → legacy-agents-page-D-vnYlfr.js} +1 -1
  50. package/out/renderer/assets/{library-page-D8DpGQTs.js → library-page-D5TOCNDL.js} +3 -3
  51. package/out/renderer/assets/{mermaid.core-3ySvSsav.js → mermaid.core-D0JYobPd.js} +5 -5
  52. package/out/renderer/assets/{mesh-page-DzMTk3NO.js → mesh-page-MMyOu2-i.js} +1 -1
  53. package/out/renderer/assets/{mindmap-definition-ALO5MXBD-B0nPGBao.js → mindmap-definition-ALO5MXBD-BSmr1_Tl.js} +1 -1
  54. package/out/renderer/assets/{mini-DFKXChgT.js → mini-DX97EGZ9.js} +1 -1
  55. package/out/renderer/assets/{notebook-pen-D0aUl8AG.js → notebook-pen-CaY2CqYY.js} +1 -1
  56. package/out/renderer/assets/{org-access-HADVafzg.js → org-access-D-BFcZvI.js} +1 -1
  57. package/out/renderer/assets/{org-surface-gate-DgSDgcYC.js → org-surface-gate-BmRiAyd4.js} +1 -1
  58. package/out/renderer/assets/{page-header-gQzwRfwk.js → page-header-B078STNU.js} +1 -1
  59. package/out/renderer/assets/{pieDiagram-IB7DONF6-BiqgPuyx.js → pieDiagram-IB7DONF6-DkC-Pw7E.js} +1 -1
  60. package/out/renderer/assets/{projects-page-ZOe4bm_U.js → projects-page-2kYMpXGt.js} +1 -1
  61. package/out/renderer/assets/{publication-validation-hQvjDgK-.js → publication-validation-Cp6mINOP.js} +1 -1
  62. package/out/renderer/assets/{quadrantDiagram-7GDLP6J5-DIWtZVho.js → quadrantDiagram-7GDLP6J5-IVRMgBez.js} +1 -1
  63. package/out/renderer/assets/{radar-MK3ICKWK-2Q646pxQ.js → radar-MK3ICKWK-sedwCyEl.js} +1 -1
  64. package/out/renderer/assets/{radient-auth-buttons-CfbkjaWR.js → radient-auth-buttons-vFQgdlYP.js} +1 -1
  65. package/out/renderer/assets/{requirementDiagram-KVF5MWMF-BgM3WO01.js → requirementDiagram-KVF5MWMF-DwdfgrvA.js} +1 -1
  66. package/out/renderer/assets/{sankeyDiagram-QLVOVGJD-B0mmrM-5.js → sankeyDiagram-QLVOVGJD-BPvKdY7g.js} +1 -1
  67. package/out/renderer/assets/{schedules-page-CSLJTbio.js → schedules-page-BWxSAtp5.js} +1 -1
  68. package/out/renderer/assets/{sequenceDiagram-X6HHIX6F-D-_IaAU6.js → sequenceDiagram-X6HHIX6F-swhS4JaV.js} +1 -1
  69. package/out/renderer/assets/{settings-page-DMJjQldW.js → settings-page-CNeq8zEo.js} +1 -1
  70. package/out/renderer/assets/{smartart-Bko--HTI.js → smartart-h3hobM9P.js} +1 -1
  71. package/out/renderer/assets/{stateDiagram-DGXRK772-CuY0nRt2.js → stateDiagram-DGXRK772-DQjtzeCn.js} +1 -1
  72. package/out/renderer/assets/stateDiagram-v2-YXO3MK2T-BoHuPFVZ.js +1 -0
  73. package/out/renderer/assets/{team-bridge-page-BSiDGZ0J.js → team-bridge-page-DwXTOl4x.js} +1 -1
  74. package/out/renderer/assets/{timeline-definition-BDJGKUSR-CRyMxdHE.js → timeline-definition-BDJGKUSR-BE4DUnJN.js} +1 -1
  75. package/out/renderer/assets/{ui-preferences-store-Bop4_ZlF.js → ui-preferences-store-DUB1goHr.js} +1 -1
  76. package/out/renderer/assets/{use-download-agent-mutation-C8Fg7G5t.js → use-download-agent-mutation-C_zKpXBu.js} +1 -1
  77. package/out/renderer/assets/{use-session-snapshot-Bg0gSZ12.js → use-session-snapshot-B6UGWZI5.js} +1 -1
  78. package/out/renderer/assets/{xychartDiagram-VJFVF3MP-CEgHjMik.js → xychartDiagram-VJFVF3MP-D6nHKfw6.js} +1 -1
  79. package/out/renderer/console-capture.html +5 -5
  80. package/out/renderer/index.html +7 -7
  81. package/out/renderer/installer.html +4 -4
  82. package/out/renderer/mini.html +7 -7
  83. package/package.json +2 -2
  84. package/out/renderer/assets/browser-page-BZouue9V.js +0 -1
  85. package/out/renderer/assets/channel-Dw6-NFJz.js +0 -1
  86. package/out/renderer/assets/classDiagram-GIVACNV2-CadtvAj7.js +0 -1
  87. package/out/renderer/assets/classDiagram-v2-COTLJTTW-CadtvAj7.js +0 -1
  88. package/out/renderer/assets/clone-Bfys-Y9K.js +0 -1
  89. package/out/renderer/assets/index-DGTlmx84.js +0 -57
  90. package/out/renderer/assets/index-DULvJq2X.js +0 -830
  91. package/out/renderer/assets/index-Dyn0TMCv.css +0 -1
  92. package/out/renderer/assets/stateDiagram-v2-YXO3MK2T-rk6LIoPS.js +0 -1
package/out/main/index.js CHANGED
@@ -28839,6 +28839,7 @@ const ADDRESS_LIST_ROWS_MAX = 5;
28839
28839
  const ADDRESS_LIST_MAX_HEIGHT_DIP = 212;
28840
28840
  const ADDRESS_LIST_NOTICE_HEIGHT_DIP = 104;
28841
28841
  const ADDRESS_LIST_ANCHOR_GAP_MAX = 24;
28842
+ const ADDRESS_LIST_MIN_WIDTH_DIP = 240;
28842
28843
  const ADDRESS_LIST_MAX_PAYLOAD_BYTES = 16 * 1024;
28843
28844
  const ADDRESS_LIST_MAX_TEXT = 512;
28844
28845
  const ADDRESS_LIST_MAX_TITLE = 256;
@@ -28853,7 +28854,7 @@ const NOTICE_KINDS = [
28853
28854
  ];
28854
28855
  const HOSTILE_STRING = /[\p{Cc}\u2028\u2029\u202A-\u202E\u2066-\u2069]/gu;
28855
28856
  const COLOR = /^(#[0-9a-f]{6}|rgb\(\d{1,3}, ?\d{1,3}, ?\d{1,3}\))$/i;
28856
- const PROJECTION_KEYS = /* @__PURE__ */ new Set([
28857
+ const PROJECTION_KEYS_V1 = /* @__PURE__ */ new Set([
28857
28858
  "v",
28858
28859
  "seq",
28859
28860
  "tabId",
@@ -28867,6 +28868,20 @@ const PROJECTION_KEYS = /* @__PURE__ */ new Set([
28867
28868
  "dir",
28868
28869
  "theme"
28869
28870
  ]);
28871
+ const PROJECTION_KEYS_V2 = /* @__PURE__ */ new Set([
28872
+ "v",
28873
+ "seq",
28874
+ "tabId",
28875
+ "visible",
28876
+ "pageRect",
28877
+ "anchor",
28878
+ "active",
28879
+ "view",
28880
+ "label",
28881
+ "dir",
28882
+ "theme"
28883
+ ]);
28884
+ const ANCHOR_KEYS = ["x", "width"];
28870
28885
  const RECT_KEYS = ["x", "y", "width", "height"];
28871
28886
  const THEME_KEYS = [
28872
28887
  "elevated",
@@ -28947,10 +28962,10 @@ function sanitizeProjection(raw) {
28947
28962
  return { ok: false, reason: "payload_too_large" };
28948
28963
  }
28949
28964
  if (!isRecord$1(raw)) return { ok: false, reason: "not_an_object" };
28950
- if (!hasOnlyKeys(raw, PROJECTION_KEYS)) {
28951
- return { ok: false, reason: "unknown_key" };
28952
- }
28953
- if (raw.v !== 1) return { ok: false, reason: "bad_version" };
28965
+ if (raw.v !== 1 && raw.v !== 2) return { ok: false, reason: "bad_version" };
28966
+ const version = raw.v;
28967
+ const keys = version === 2 ? PROJECTION_KEYS_V2 : PROJECTION_KEYS_V1;
28968
+ if (!hasOnlyKeys(raw, keys)) return { ok: false, reason: "unknown_key" };
28954
28969
  if (!Number.isInteger(raw.seq) || raw.seq < 1) {
28955
28970
  return { ok: false, reason: "bad_seq" };
28956
28971
  }
@@ -28959,15 +28974,29 @@ function sanitizeProjection(raw) {
28959
28974
  return { ok: false, reason: "bad_visible" };
28960
28975
  }
28961
28976
  if (!raw.visible) {
28977
+ const empty = { x: 0, y: 0, width: 0, height: 0 };
28962
28978
  return {
28963
28979
  ok: true,
28964
- projection: {
28980
+ projection: version === 2 ? {
28981
+ v: 2,
28982
+ seq: raw.seq,
28983
+ tabId: raw.tabId,
28984
+ visible: false,
28985
+ pageRect: empty,
28986
+ anchor: { x: 0, width: 0 },
28987
+ active: -1,
28988
+ view: { kind: "notice", notice: "empty", text: "" },
28989
+ label: "",
28990
+ dir: "ltr",
28991
+ theme: null,
28992
+ themeFact: "absent"
28993
+ } : {
28965
28994
  v: 1,
28966
28995
  seq: raw.seq,
28967
28996
  tabId: raw.tabId,
28968
28997
  visible: false,
28969
- pageRect: { x: 0, y: 0, width: 0, height: 0 },
28970
- field: { x: 0, y: 0, width: 0, height: 0 },
28998
+ pageRect: empty,
28999
+ field: empty,
28971
29000
  listTop: 0,
28972
29001
  active: -1,
28973
29002
  view: { kind: "notice", notice: "empty", text: "" },
@@ -28979,14 +29008,30 @@ function sanitizeProjection(raw) {
28979
29008
  };
28980
29009
  }
28981
29010
  const pageRect = rect(raw.pageRect);
28982
- const field = rect(raw.field);
28983
- if (pageRect === null || field === null) {
28984
- return { ok: false, reason: "bad_rect" };
28985
- }
28986
- const listTop = finite(raw.listTop);
28987
- if (listTop === null) return { ok: false, reason: "bad_list_top" };
28988
- if (field.width <= 0 || field.height <= 0) {
28989
- return { ok: false, reason: "bad_field" };
29011
+ if (pageRect === null) return { ok: false, reason: "bad_rect" };
29012
+ let field = null;
29013
+ let listTop = 0;
29014
+ let anchor = null;
29015
+ if (version === 2) {
29016
+ if (!isRecord$1(raw.anchor) || !hasOnlyKeys(raw.anchor, ANCHOR_KEYS)) {
29017
+ return { ok: false, reason: "bad_anchor" };
29018
+ }
29019
+ const x = finite(raw.anchor.x);
29020
+ const width = finite(raw.anchor.width);
29021
+ if (x === null || width === null) {
29022
+ return { ok: false, reason: "bad_anchor" };
29023
+ }
29024
+ if (width <= 0) return { ok: false, reason: "bad_anchor" };
29025
+ anchor = { x, width };
29026
+ } else {
29027
+ field = rect(raw.field);
29028
+ if (field === null) return { ok: false, reason: "bad_rect" };
29029
+ const top = finite(raw.listTop);
29030
+ if (top === null) return { ok: false, reason: "bad_list_top" };
29031
+ listTop = top;
29032
+ if (field.width <= 0 || field.height <= 0) {
29033
+ return { ok: false, reason: "bad_field" };
29034
+ }
28990
29035
  }
28991
29036
  if (!Number.isInteger(raw.active)) return { ok: false, reason: "bad_active" };
28992
29037
  const active = raw.active;
@@ -29026,6 +29071,27 @@ function sanitizeProjection(raw) {
29026
29071
  return { ok: false, reason: "bad_dir" };
29027
29072
  }
29028
29073
  const { theme, fact } = sanitizeTheme(raw.theme);
29074
+ if (version === 2) {
29075
+ if (anchor === null) return { ok: false, reason: "bad_anchor" };
29076
+ return {
29077
+ ok: true,
29078
+ projection: {
29079
+ v: 2,
29080
+ seq: raw.seq,
29081
+ tabId: raw.tabId,
29082
+ visible: true,
29083
+ pageRect,
29084
+ anchor,
29085
+ active,
29086
+ view,
29087
+ label,
29088
+ dir: raw.dir,
29089
+ theme,
29090
+ themeFact: fact
29091
+ }
29092
+ };
29093
+ }
29094
+ if (field === null) return { ok: false, reason: "bad_rect" };
29029
29095
  return {
29030
29096
  ok: true,
29031
29097
  projection: {
@@ -29079,6 +29145,26 @@ function addressListBoundsFor(field, listTop, view, owner) {
29079
29145
  if (bottom - top !== height) return null;
29080
29146
  return { x: left, y: top, width: right - left, height };
29081
29147
  }
29148
+ function addressListBoundsV2For(anchor, pageRect, view, owner) {
29149
+ const ax = int32$1(anchor.x);
29150
+ const aw = int32$1(anchor.width);
29151
+ const px = int32$1(pageRect.x);
29152
+ const pw = int32$1(pageRect.width);
29153
+ const py = int32$1(pageRect.y);
29154
+ const ownerWidth = int32$1(owner.width);
29155
+ const ownerHeight = int32$1(owner.height);
29156
+ if (ax === null || aw === null || px === null || pw === null || py === null || ownerWidth === null || ownerHeight === null) {
29157
+ return null;
29158
+ }
29159
+ if (aw <= 0 || pw <= 0 || ownerWidth <= 0 || ownerHeight <= 0) return null;
29160
+ const left = Math.max(0, Math.max(ax, px));
29161
+ const right = Math.min(ownerWidth, Math.min(ax + aw, px + pw));
29162
+ if (right - left < ADDRESS_LIST_MIN_WIDTH_DIP) return null;
29163
+ const height = addressListHeightFor(view);
29164
+ if (height > ADDRESS_LIST_MAX_HEIGHT_DIP) return null;
29165
+ if (py < 0 || py + height > ownerHeight) return null;
29166
+ return { x: left, y: py, width: right - left, height };
29167
+ }
29082
29168
  function addressListRowIndexAt(view, offsetY) {
29083
29169
  if (view.kind !== "rows") return null;
29084
29170
  if (!Number.isFinite(offsetY)) return null;
@@ -29391,6 +29477,10 @@ function layoutKeyOf(snapshot2) {
29391
29477
  const rect2 = snapshot2.contentRect;
29392
29478
  return `${snapshot2.activeTabId}:${snapshot2.presented ? 1 : 0}:${rect2 ? `${rect2.x},${rect2.y},${rect2.width},${rect2.height}` : "null"}`;
29393
29479
  }
29480
+ function layoutContentKeyOf(snapshot2) {
29481
+ const rect2 = snapshot2.contentRect;
29482
+ return `${snapshot2.activeTabId}:${rect2 ? `${rect2.x},${rect2.y},${rect2.width},${rect2.height}` : "null"}`;
29483
+ }
29394
29484
  function sameRect(a, b) {
29395
29485
  if (b === null) return false;
29396
29486
  return a.x === b.x && a.y === b.y && a.width === b.width && a.height === b.height;
@@ -29437,6 +29527,7 @@ class AddressOverlayController {
29437
29527
  createView;
29438
29528
  javascript;
29439
29529
  onEvent;
29530
+ onHealthChange;
29440
29531
  readinessTimeoutMs;
29441
29532
  log;
29442
29533
  now;
@@ -29452,6 +29543,9 @@ class AddressOverlayController {
29452
29543
  lastShow;
29453
29544
  layout;
29454
29545
  layoutKey;
29546
+ /** The layout's content identity (tab + rect), the fact a product dismissal
29547
+ * is allowed to rest on; see `layoutContentKeyOf`. */
29548
+ layoutContentKey;
29455
29549
  boundTabId;
29456
29550
  domReady;
29457
29551
  finished;
@@ -29492,14 +29586,25 @@ class AddressOverlayController {
29492
29586
  /** The launch gate's `visible` fact, copied in so `facts()` can report it
29493
29587
  * without re-deriving the gate (which it must never do: one pure decision). */
29494
29588
  visibleMode;
29589
+ product;
29590
+ warmScheduled;
29495
29591
  lastRejected;
29496
29592
  projectQueue;
29593
+ /** The native page is hidden for a reason that says nothing about the popout
29594
+ * (the page menu suppresses it while its panel is open). The row stays
29595
+ * raised, so the child's paint stops and its "shown" state does not. */
29596
+ presentationSuspended;
29597
+ /** A projection that arrived while the page was suppressed. Applied on
29598
+ * resume rather than refused: a refusal would make the mirror re-project
29599
+ * every frame until the menu closed. */
29600
+ deferredProjection;
29497
29601
  constructor(deps) {
29498
29602
  this.window = deps.window;
29499
29603
  this.documentUrl = deps.documentUrl;
29500
29604
  this.createView = deps.createView ?? (() => createHardenedView({ javascript: deps.javascript === true }));
29501
29605
  this.javascript = deps.javascript === true;
29502
29606
  this.onEvent = deps.onEvent ?? null;
29607
+ this.onHealthChange = deps.onHealthChange ?? null;
29503
29608
  this.readinessTimeoutMs = deps.readinessTimeoutMs ?? ADDRESS_OVERLAY_READY_TIMEOUT_MS;
29504
29609
  this.log = deps.log ?? (() => {
29505
29610
  });
@@ -29521,6 +29626,7 @@ class AddressOverlayController {
29521
29626
  revision: 0
29522
29627
  };
29523
29628
  this.layoutKey = "none";
29629
+ this.layoutContentKey = "none";
29524
29630
  this.boundTabId = null;
29525
29631
  this.domReady = false;
29526
29632
  this.finished = false;
@@ -29552,8 +29658,12 @@ class AddressOverlayController {
29552
29658
  this.childFocusEvents = 0;
29553
29659
  this.childBlurEvents = 0;
29554
29660
  this.visibleMode = deps.visible === true;
29661
+ this.product = deps.product === true;
29662
+ this.warmScheduled = false;
29555
29663
  this.lastRejected = null;
29556
29664
  this.projectQueue = Promise.resolve();
29665
+ this.presentationSuspended = false;
29666
+ this.deferredProjection = null;
29557
29667
  this.attachOwnerListeners();
29558
29668
  }
29559
29669
  // ---- observer hooks ------------------------------------------------------
@@ -29561,25 +29671,41 @@ class AddressOverlayController {
29561
29671
  * The registry's post-layout hook. Called after every page layout pass,
29562
29672
  * including null and suppressed ones.
29563
29673
  *
29564
- * A changed key (tab, presentation or rectangle) hides and invalidates first:
29565
- * a moved page must never keep a stale rectangle floating over it, and a
29566
- * resized window invalidates old geometry until a fresh renderer rect
29567
- * arrives. An unchanged key is the background-page-creation case: the layout
29568
- * pass may have added a page above the child, so the child is re-added last
29569
- * and given the same rectangle. It never re-opens by itself; showing again is
29570
- * always an explicit probe call.
29674
+ * A changed key (tab, presentation or rectangle) is handled by ONE of two
29675
+ * rules, and the split is load-bearing (agent review round 1, MAJOR-1):
29676
+ * a CONTENT change (tab or rectangle) hides and invalidates, while a
29677
+ * PRESENTATION-only change is a suppression that belongs to someone else —
29678
+ * the page menu, which paints into the content rect — so it only stops the
29679
+ * child's paint and keeps the shown state. Collapsing the two made opening
29680
+ * the menu dismiss the popout it was opened from. An unchanged key is the
29681
+ * background-page-creation case: the layout pass may have added a page above
29682
+ * the child, so the child is re-added last and given the same rectangle. It
29683
+ * never re-opens by itself; showing again is always an explicit probe call.
29571
29684
  */
29572
29685
  onLayout(snapshot2) {
29573
29686
  if (this.disposed) return;
29574
29687
  const next = copyLayout(snapshot2);
29575
29688
  const nextKey = layoutKeyOf(next);
29576
29689
  const previousKey = this.layoutKey;
29690
+ const nextContentKey = layoutContentKeyOf(next);
29691
+ const previousContentKey = this.layoutContentKey;
29577
29692
  this.layout = next;
29578
29693
  this.layoutKey = nextKey;
29694
+ this.layoutContentKey = nextContentKey;
29579
29695
  if (previousKey !== nextKey) {
29696
+ const contentChanged = previousContentKey !== nextContentKey;
29697
+ if (!contentChanged) {
29698
+ if (next.presented) this.resumePresentation();
29699
+ else this.suspendPresentation();
29700
+ return;
29701
+ }
29580
29702
  this.hide("layout");
29703
+ if (this.product && previousKey !== "none") this.emitDismiss("layout");
29581
29704
  return;
29582
29705
  }
29706
+ if (this.product && next.presented && next.contentRect !== null) {
29707
+ this.ensureChild();
29708
+ }
29583
29709
  if (this.state !== "shown") return;
29584
29710
  const view = this.view;
29585
29711
  if (!view || this.viewUsable(view) === false) return;
@@ -29596,6 +29722,40 @@ class AddressOverlayController {
29596
29722
  this.log(`[browser] address overlay layout failed: ${String(error)}`);
29597
29723
  }
29598
29724
  }
29725
+ /** Hide the child's paint without dropping the popout's state; see `onLayout`. */
29726
+ suspendPresentation() {
29727
+ this.presentationSuspended = true;
29728
+ const view = this.view;
29729
+ if (!view || this.viewUsable(view) === false) return;
29730
+ try {
29731
+ view.setVisible(false);
29732
+ } catch {
29733
+ }
29734
+ }
29735
+ /** The page is back. Re-present the child from the bounds last applied, or
29736
+ * apply the projection that arrived while the page was hidden. */
29737
+ resumePresentation() {
29738
+ if (!this.presentationSuspended) return;
29739
+ this.presentationSuspended = false;
29740
+ const deferred = this.deferredProjection;
29741
+ this.deferredProjection = null;
29742
+ if (deferred !== null) {
29743
+ void this.project(deferred);
29744
+ return;
29745
+ }
29746
+ if (this.state !== "shown") return;
29747
+ const bounds = this.lastAppliedBounds ?? overlayBoundsFor(this.layout.contentRect, this.ownerSize());
29748
+ if (bounds === null) return;
29749
+ const view = this.view;
29750
+ if (!view || this.viewUsable(view) === false) return;
29751
+ try {
29752
+ view.setBounds(bounds);
29753
+ this.raiseChild(view);
29754
+ view.setVisible(true);
29755
+ } catch {
29756
+ this.releaseChild("layout_error");
29757
+ }
29758
+ }
29599
29759
  /** The bound page is going away. Dispose the child before the page release. */
29600
29760
  onTabReleased(tabId) {
29601
29761
  if (this.disposed) return;
@@ -29610,6 +29770,63 @@ class AddressOverlayController {
29610
29770
  if (this.boundTabId !== tabId) return;
29611
29771
  this.releaseChild("page-crash");
29612
29772
  }
29773
+ /**
29774
+ * The popout's current health, in the one shape the renderer reads.
29775
+ *
29776
+ * `suspend` is sticky for the app run: the child is either latched failed or
29777
+ * gone, and the restart that would clear it is a new process. A conditional
29778
+ * refusal (`zoomed`, `anchor_too_narrow`, `stale_*`) is NOT reported here —
29779
+ * those clear themselves, and the projection answer names them while they
29780
+ * last.
29781
+ */
29782
+ mode() {
29783
+ if (this.disposed) return { mode: "suspend", reason: "disposed" };
29784
+ if (this.failedReason)
29785
+ return { mode: "suspend", reason: this.failedReason };
29786
+ return { mode: "popout", reason: null };
29787
+ }
29788
+ /**
29789
+ * A main-decided dismissal (the page took focus, the bound tab's main frame
29790
+ * navigated, the tab went away). Idempotent: a second reason for a popout that
29791
+ * is already hidden sends nothing.
29792
+ */
29793
+ dismiss(reason) {
29794
+ if (this.disposed) return;
29795
+ this.hide(reason);
29796
+ if (this.product) this.emitDismiss(reason);
29797
+ }
29798
+ /** The page `tabId` took focus. Only the bound tab can dismiss its own list;
29799
+ * a background tab's focus event is not this popout's business. */
29800
+ dismissForTab(tabId, reason) {
29801
+ if (this.disposed) return;
29802
+ if (this.boundTabId !== null && this.boundTabId !== tabId) return;
29803
+ if (this.layout.activeTabId !== null && this.layout.activeTabId !== tabId)
29804
+ return;
29805
+ this.dismiss(reason);
29806
+ }
29807
+ /**
29808
+ * Warm the list child once the page has a presented layout, so the first
29809
+ * raise finds a loaded document instead of paying the load after Cmd+L. The
29810
+ * child is created hidden and stays hidden until a projection shows it.
29811
+ */
29812
+ ensureChild() {
29813
+ if (!this.product || this.view || this.failedReason || this.warmScheduled)
29814
+ return;
29815
+ const bounds = overlayBoundsFor(this.layout.contentRect, this.ownerSize());
29816
+ if (bounds === null || !this.layout.presented) return;
29817
+ this.warmScheduled = true;
29818
+ setTimeout(() => {
29819
+ this.warmScheduled = false;
29820
+ if (this.disposed || this.view || this.failedReason) return;
29821
+ if (!this.layout.presented) return;
29822
+ const rect2 = overlayBoundsFor(this.layout.contentRect, this.ownerSize());
29823
+ if (rect2 === null) return;
29824
+ if (this.createChild(rect2)) this.state = "loading";
29825
+ }, 0);
29826
+ }
29827
+ emitDismiss(reason) {
29828
+ this.onEvent?.({ type: "dismiss", reason });
29829
+ }
29613
29830
  // ---- probe surface ------------------------------------------------------
29614
29831
  async showOverlay() {
29615
29832
  if (this.showInFlight) return this.showInFlight;
@@ -29627,6 +29844,8 @@ class AddressOverlayController {
29627
29844
  }
29628
29845
  hide(reason = "hide") {
29629
29846
  if (this.disposed) return;
29847
+ this.presentationSuspended = false;
29848
+ this.deferredProjection = null;
29630
29849
  this.generation += 1;
29631
29850
  this.settleReady(false);
29632
29851
  this.hiddenReason = reason;
@@ -29793,6 +30012,15 @@ class AddressOverlayController {
29793
30012
  * controller, so a burst between frames costs one apply each in arrival order.
29794
30013
  */
29795
30014
  project(raw) {
30015
+ if (this.presentationSuspended) {
30016
+ this.deferredProjection = raw;
30017
+ return Promise.resolve({
30018
+ accepted: true,
30019
+ shown: false,
30020
+ reason: null,
30021
+ bounds: null
30022
+ });
30023
+ }
29796
30024
  const run = () => this.projectOnce(raw);
29797
30025
  const next = this.projectQueue.then(run, run);
29798
30026
  this.projectQueue = next.then(
@@ -29855,13 +30083,23 @@ class AddressOverlayController {
29855
30083
  if (!layout.presented || !sameRect(projection.pageRect, layout.contentRect)) {
29856
30084
  return this.refuseProjection("stale_layout");
29857
30085
  }
29858
- const bounds = addressListBoundsFor(
30086
+ const bounds = projection.v === 2 ? projection.anchor.width < ADDRESS_LIST_MIN_WIDTH_DIP ? null : addressListBoundsV2For(
30087
+ projection.anchor,
30088
+ projection.pageRect,
30089
+ projection.view,
30090
+ this.ownerSize()
30091
+ ) : addressListBoundsFor(
29859
30092
  projection.field,
29860
30093
  projection.listTop,
29861
30094
  projection.view,
29862
30095
  this.ownerSize()
29863
30096
  );
29864
- if (bounds === null) return this.refuseProjection("anchor_inconsistent");
30097
+ if (bounds === null) {
30098
+ const tooNarrow = projection.v === 2 && projection.anchor.width < ADDRESS_LIST_MIN_WIDTH_DIP;
30099
+ return this.refuseProjection(
30100
+ tooNarrow ? "anchor_too_narrow" : "anchor_inconsistent"
30101
+ );
30102
+ }
29865
30103
  this.generation += 1;
29866
30104
  const generation = this.generation;
29867
30105
  this.boundTabId = projection.tabId;
@@ -30307,6 +30545,7 @@ class AddressOverlayController {
30307
30545
  this.settleReady(false);
30308
30546
  this.destroyChild();
30309
30547
  this.log(`[browser] address overlay failed: ${reason}`);
30548
+ this.onHealthChange?.();
30310
30549
  }
30311
30550
  /** Recoverable: the child goes, a later explicit show may lazily recreate one. */
30312
30551
  releaseChild(reason) {
@@ -30319,6 +30558,7 @@ class AddressOverlayController {
30319
30558
  this.finished = false;
30320
30559
  this.loadStartedAt = null;
30321
30560
  this.log(`[browser] address overlay child released: ${reason}`);
30561
+ this.onHealthChange?.();
30322
30562
  }
30323
30563
  destroyChild() {
30324
30564
  const view = this.view;
@@ -35135,6 +35375,7 @@ const enUiBrowser = {
35135
35375
  "ui.browser.browser_url_bar.home_destination": "Home — go to the start page (blank)",
35136
35376
  "ui.browser.browser_url_bar.latest_download": "Open downloads folder — {name} was saved there",
35137
35377
  "ui.browser.browser_url_bar.newest_download": "Open downloads folder — {name} was the newest saved there ({count, plural, other {{count, number, ::group-off} this session}})",
35378
+ "ui.browser.browser_url_bar.page_menu": "Page options",
35138
35379
  "ui.browser.browser_url_bar.page_zoom_reset": "Page zoom {zoom, number, ::group-off}%, reset to 100%",
35139
35380
  "ui.browser.browser_url_bar.print_page": "Print page",
35140
35381
  "ui.browser.browser_url_bar.reload": "Reload",
@@ -38842,6 +39083,7 @@ const esUiBrowser = {
38842
39083
  "ui.browser.browser_url_bar.print_page": "Imprimir página",
38843
39084
  "ui.browser.browser_url_bar.forward": "Adelante",
38844
39085
  "ui.browser.browser_url_bar.reset_page_zoom_shortcut": "Restablecer zoom de la página ({shortcut})",
39086
+ "ui.browser.browser_url_bar.page_menu": "Opciones de página",
38845
39087
  "ui.browser.browser_url_bar.page_zoom_reset": "Zoom de la página al {zoom, number, ::group-off}%, restablecer al 100%",
38846
39088
  "ui.browser.browser_url_bar.stop_loading": "Detener carga",
38847
39089
  "ui.browser.browser_url_bar.reload": "Recargar",
@@ -42418,6 +42660,7 @@ const frUiBrowser = {
42418
42660
  "ui.browser.browser_url_bar.print_page": "Imprimer la page",
42419
42661
  "ui.browser.browser_url_bar.forward": "Avancer",
42420
42662
  "ui.browser.browser_url_bar.reset_page_zoom_shortcut": "Réinitialiser le zoom de la page ({shortcut})",
42663
+ "ui.browser.browser_url_bar.page_menu": "Options de la page",
42421
42664
  "ui.browser.browser_url_bar.page_zoom_reset": "Zoom de la page {zoom, number, ::group-off} %, réinitialiser à 100 %",
42422
42665
  "ui.browser.browser_url_bar.stop_loading": "Arrêter le chargement",
42423
42666
  "ui.browser.browser_url_bar.reload": "Recharger",
@@ -46015,6 +46258,7 @@ const hiUiBrowser = {
46015
46258
  "ui.browser.browser_url_bar.home_destination": "होम — शुरुआती पेज पर जाएँ (खाली)",
46016
46259
  "ui.browser.browser_url_bar.latest_download": "डाउनलोड फ़ोल्डर खोलें — {name} वहाँ सहेजी गई थी",
46017
46260
  "ui.browser.browser_url_bar.newest_download": "डाउनलोड फ़ोल्डर खोलें — {name} वहाँ सबसे हाल में सहेजी गई थी ({count, plural, other {इस सत्र में {count, number, ::group-off}}})",
46261
+ "ui.browser.browser_url_bar.page_menu": "पेज विकल्प",
46018
46262
  "ui.browser.browser_url_bar.page_zoom_reset": "पेज ज़ूम {zoom, number, ::group-off}%, 100% पर रीसेट करें",
46019
46263
  "ui.browser.browser_url_bar.print_page": "पेज प्रिंट करें",
46020
46264
  "ui.browser.browser_url_bar.reload": "फिर लोड करें",
@@ -49368,6 +49612,7 @@ const ruUiBrowser = {
49368
49612
  "ui.browser.browser_url_bar.home_destination": "Домой — перейти на стартовую страницу (пустую)",
49369
49613
  "ui.browser.browser_url_bar.latest_download": "Открыть папку загрузок — {name} сохранён туда",
49370
49614
  "ui.browser.browser_url_bar.newest_download": "Открыть папку загрузок — {name} сохранён туда последним ({count, plural, one {{count, number, ::group-off} за эту сессию} few {{count, number, ::group-off} за эту сессию} many {{count, number, ::group-off} за эту сессию} other {{count, number, ::group-off} за эту сессию}})",
49615
+ "ui.browser.browser_url_bar.page_menu": "Параметры страницы",
49371
49616
  "ui.browser.browser_url_bar.page_zoom_reset": "Масштаб страницы {zoom, number, ::group-off}%, сбросить до 100%",
49372
49617
  "ui.browser.browser_url_bar.print_page": "Печать страницы",
49373
49618
  "ui.browser.browser_url_bar.reload": "Перезагрузить",
@@ -52827,6 +53072,7 @@ const urUiBrowser = {
52827
53072
  "ui.browser.browser_url_bar.home_destination": "ابتدائی صفحہ — آغاز کے خالی صفحے پر جائیں",
52828
53073
  "ui.browser.browser_url_bar.latest_download": "ڈاؤن لوڈ فولڈر کھولیں — {name} وہاں محفوظ ہوئی",
52829
53074
  "ui.browser.browser_url_bar.newest_download": "ڈاؤن لوڈ فولڈر کھولیں — وہاں سب سے حال میں {name} محفوظ ہوئی ({count, plural, other {اس سیشن میں {count, number, ::group-off}}})",
53075
+ "ui.browser.browser_url_bar.page_menu": "صفحے کے اختیارات",
52830
53076
  "ui.browser.browser_url_bar.page_zoom_reset": "صفحے کا زوم {zoom, number, ::group-off}%، 100% پر ری سیٹ کریں",
52831
53077
  "ui.browser.browser_url_bar.print_page": "صفحہ پرنٹ کریں",
52832
53078
  "ui.browser.browser_url_bar.reload": "دوبارہ لوڈ کریں",
@@ -56200,6 +56446,7 @@ const viUiBrowser = {
56200
56446
  "ui.browser.browser_url_bar.home_destination": "Trang chủ — đến trang bắt đầu (trống)",
56201
56447
  "ui.browser.browser_url_bar.latest_download": "Mở thư mục tải xuống — {name} đã được lưu ở đó",
56202
56448
  "ui.browser.browser_url_bar.newest_download": "Mở thư mục tải xuống — {name} là tệp mới nhất được lưu ở đó ({count, plural, other {{count, number, ::group-off} trong phiên này}})",
56449
+ "ui.browser.browser_url_bar.page_menu": "Tùy chọn trang",
56203
56450
  "ui.browser.browser_url_bar.page_zoom_reset": "Thu phóng trang {zoom, number, ::group-off}%, đặt lại về 100%",
56204
56451
  "ui.browser.browser_url_bar.print_page": "In trang",
56205
56452
  "ui.browser.browser_url_bar.reload": "Tải lại",
@@ -59468,6 +59715,7 @@ const zhCNUiBrowser = {
59468
59715
  "ui.browser.browser_url_bar.home_destination": "主页——前往起始页(空白页)",
59469
59716
  "ui.browser.browser_url_bar.latest_download": "打开下载文件夹——{name}已保存于此",
59470
59717
  "ui.browser.browser_url_bar.newest_download": "打开下载文件夹——最新保存的文件为{name}(本次会话共{count, plural, other {{count, number, ::group-off}个}})",
59718
+ "ui.browser.browser_url_bar.page_menu": "页面选项",
59471
59719
  "ui.browser.browser_url_bar.page_zoom_reset": "页面缩放{zoom, number, ::group-off}%,重置为100%",
59472
59720
  "ui.browser.browser_url_bar.print_page": "打印页面",
59473
59721
  "ui.browser.browser_url_bar.reload": "重新加载",
@@ -66259,6 +66507,11 @@ class BrowserHost {
66259
66507
  facts;
66260
66508
  /** The session's per-origin storage clear, injected (see `BrowserHostOptions`). */
66261
66509
  forgetSiteData;
66510
+ /** S4b's popout health, read from the controller (or the launch's platform
66511
+ * answer when no controller exists). The strip reads this from the same
66512
+ * projection as the tabs, so the renderer has one source for "child or
66513
+ * fallback" and never guesses from a failed IPC call. */
66514
+ addressOverlayMode;
66262
66515
  /**
66263
66516
  * The last main-frame load failure per tab, cleared by the next load.
66264
66517
  *
@@ -66284,6 +66537,7 @@ class BrowserHost {
66284
66537
  this.tabAudio = new TabAudioTracker(() => this.onChanged());
66285
66538
  this.facts = options.facts;
66286
66539
  this.forgetSiteData = options.forgetSiteData;
66540
+ this.addressOverlayMode = options.addressOverlayMode ?? (() => ({ mode: "suspend", reason: "unavailable" }));
66287
66541
  }
66288
66542
  /** Answer one wire request. The only place a method name becomes an action. */
66289
66543
  async dispatch(method, params, requestId2) {
@@ -66564,6 +66818,7 @@ class BrowserHost {
66564
66818
  new Set(this.registry.snapshot().map((entry) => entry.tabId))
66565
66819
  );
66566
66820
  return {
66821
+ addressOverlay: this.addressOverlayMode(),
66567
66822
  pageControls: this.pageControls.state(active),
66568
66823
  tabs: this.chromeTabOrder.project(this.registry.snapshot()).map((entry, displayOrder) => ({
66569
66824
  ...this.chromeTabOrder.hasCustomOrder ? { displayOrder } : {},
@@ -68278,6 +68533,7 @@ function tabIdOrThrow(value, name) {
68278
68533
  return id2;
68279
68534
  }
68280
68535
  const CONTROL_CHARS = /[\p{Cc}]/u;
68536
+ const PRODUCT_ADDRESS_OVERLAY_EVENT = "browser-address-overlay-event";
68281
68537
  const BROWSER_IPC_CHANNELS = [
68282
68538
  "browser-state",
68283
68539
  "browser-set-chord-focus",
@@ -68291,6 +68547,7 @@ const BROWSER_IPC_CHANNELS = [
68291
68547
  "browser-close-tabs",
68292
68548
  "browser-activate-tab",
68293
68549
  "browser-address-history",
68550
+ "browser-address-overlay-project",
68294
68551
  "browser-navigate",
68295
68552
  "browser-home",
68296
68553
  "browser-reload",
@@ -68591,6 +68848,21 @@ function registerBrowserIpc(options) {
68591
68848
  }
68592
68849
  );
68593
68850
  }
68851
+ if (options.addressOverlayProduct) {
68852
+ electron.ipcMain.handle(
68853
+ "browser-address-overlay-project",
68854
+ (event, payload) => {
68855
+ authorizeSender(event);
68856
+ const project = options.addressOverlayProduct;
68857
+ if (!project) {
68858
+ throw new Error(
68859
+ "address_overlay_unavailable: the overlay projection is not running."
68860
+ );
68861
+ }
68862
+ return project(payload);
68863
+ }
68864
+ );
68865
+ }
68594
68866
  if (options.addressOverlayProject) {
68595
68867
  electron.ipcMain.handle(
68596
68868
  DEV_DRIVER_ADDRESS_OVERLAY_PROJECT,
@@ -70588,6 +70860,17 @@ function startBrowserHost(options) {
70588
70860
  * then it reads the current attempt's callback through `bindings` (a retry
70589
70861
  * replaces it) rather than capturing a controller here.
70590
70862
  */
70863
+ ...options.addressOverlay?.product === true ? {
70864
+ addressOverlayProduct: (payload) => {
70865
+ const project = bindings.addressOverlayProject;
70866
+ if (!project) {
70867
+ throw new Error(
70868
+ "address_overlay_unavailable: the overlay controller is not running."
70869
+ );
70870
+ }
70871
+ return project(payload);
70872
+ }
70873
+ } : {},
70591
70874
  ...options.addressOverlay?.enabled ? {
70592
70875
  addressOverlayProbe: (action, argument) => {
70593
70876
  const probe = bindings.addressOverlayProbe;
@@ -70678,8 +70961,18 @@ async function initializeBrowserHost(options, bindings) {
70678
70961
  return view;
70679
70962
  }, wireView = function(view, tabId) {
70680
70963
  const contents = view.webContents;
70681
- contents.on("focus", () => host.setPageFocused(tabId, true));
70964
+ contents.on("focus", () => {
70965
+ host.setPageFocused(tabId, true);
70966
+ addressOverlay?.dismissForTab(tabId, "page_focus");
70967
+ });
70682
70968
  contents.on("blur", () => host.setPageFocused(tabId, false));
70969
+ contents.on(
70970
+ "did-start-navigation",
70971
+ (_event, _url, isInPlace, isMainFrame) => {
70972
+ if (isMainFrame && !isInPlace)
70973
+ addressOverlay?.dismissForTab(tabId, "navigation");
70974
+ }
70975
+ );
70683
70976
  const popupChildren = /* @__PURE__ */ new Set();
70684
70977
  contents.setWindowOpenHandler((details) => {
70685
70978
  const decision = decidePopup(
@@ -70999,21 +71292,26 @@ async function initializeBrowserHost(options, bindings) {
70999
71292
  const views = /* @__PURE__ */ new Map();
71000
71293
  const releases = /* @__PURE__ */ new Set();
71001
71294
  let stateWriter = null;
71295
+ let notifyAddressOverlayHealth = () => {
71296
+ };
71002
71297
  const addressOverlay = options.addressOverlay?.enabled === true ? new AddressOverlayController({
71003
71298
  window: options.window,
71004
71299
  documentUrl: options.addressOverlay.documentUrl,
71005
71300
  javascript: options.addressOverlay.list === true,
71006
71301
  visible: options.addressOverlay.visible === true,
71302
+ product: options.addressOverlay.product === true,
71007
71303
  // The only consumer of a validated row click: the owner window's own
71008
71304
  // renderer. Guarded because a stop can race a queued mouse event.
71009
71305
  onEvent: (event) => {
71010
- if (!options.window.isDestroyed()) {
71011
- options.window.webContents.send(
71012
- DEV_DRIVER_ADDRESS_OVERLAY_EVENT,
71013
- event
71014
- );
71015
- }
71306
+ if (options.window.isDestroyed()) return;
71307
+ options.window.webContents.send(
71308
+ options.addressOverlay?.product === true ? PRODUCT_ADDRESS_OVERLAY_EVENT : DEV_DRIVER_ADDRESS_OVERLAY_EVENT,
71309
+ event
71310
+ );
71016
71311
  },
71312
+ // The renderer reads Tier 1 out of the projection, so a child that
71313
+ // fails while the field is already raised must push one.
71314
+ onHealthChange: () => notifyAddressOverlayHealth(),
71017
71315
  log: log2,
71018
71316
  appMetrics: () => electron.app.getAppMetrics().map((metric) => ({
71019
71317
  pid: metric.pid,
@@ -71065,6 +71363,7 @@ async function initializeBrowserHost(options, bindings) {
71065
71363
  }
71066
71364
  captureSession();
71067
71365
  };
71366
+ notifyAddressOverlayHealth = notifyChanged;
71068
71367
  const registry = new TabRegistry(
71069
71368
  (_createOptions, tabId) => {
71070
71369
  const view = buildView(options.window);
@@ -71135,7 +71434,11 @@ async function initializeBrowserHost(options, bindings) {
71135
71434
  log: log2,
71136
71435
  onChanged: notifyChanged,
71137
71436
  facts: () => facts,
71138
- forgetSiteData: (origin) => clearOriginData(browserSession, origin)
71437
+ forgetSiteData: (origin) => clearOriginData(browserSession, origin),
71438
+ addressOverlayMode: () => addressOverlay ? addressOverlay.mode() : {
71439
+ mode: "suspend",
71440
+ reason: options.addressOverlay?.product === true ? "unavailable" : "platform"
71441
+ }
71139
71442
  });
71140
71443
  const ownsChrome = () => browserChromeOwnsChord({
71141
71444
  logicalFocus: host.chordFocus,
@@ -82715,6 +83018,12 @@ const addressOverlayGate = resolveAddressOverlayGate({
82715
83018
  windowMode: windowLaunch.mode,
82716
83019
  packaged: electron.app.isPackaged
82717
83020
  });
83021
+ const addressOverlayProduct = process.platform === "darwin" && !addressOverlayGate.enabled;
83022
+ if (addressOverlayProduct) {
83023
+ console.log(
83024
+ "[address-overlay] product chrome armed (darwin): popout field over the tab strip, native list child"
83025
+ );
83026
+ }
82718
83027
  if (addressOverlayGate.asked) {
82719
83028
  console.log(
82720
83029
  addressOverlayGate.enabled ? addressOverlayGate.visible ? "[address-overlay] ARMED (S3 VISIBLE probe, inactive window, 120 s cap, no product path)" : `[address-overlay] ARMED (S${addressOverlayGate.list ? "2 probe: mirror list" : "1 probe: native child"}, no product path)` : `[address-overlay] not armed: ${addressOverlayGate.reason}`
@@ -83137,7 +83446,7 @@ electron.app.whenReady().then(async () => {
83137
83446
  });
83138
83447
  const rendererUrl = rendererDocumentUrl();
83139
83448
  const consoleCaptureUrl = consoleCaptureUrlFor(rendererUrl);
83140
- const addressOverlayDocumentUrl = addressOverlayGate.list ? addressListDocumentUrlFor(rendererUrl) : addressOverlayDocumentUrlFor(rendererUrl);
83449
+ const addressOverlayDocumentUrl = addressOverlayGate.list || addressOverlayProduct ? addressListDocumentUrlFor(rendererUrl) : addressOverlayDocumentUrlFor(rendererUrl);
83141
83450
  backendService.observeDesktopFeed(
83142
83451
  (frame) => {
83143
83452
  if (frame.type === "notification") {
@@ -83948,11 +84257,12 @@ electron.app.whenReady().then(async () => {
83948
84257
  consoleCaptureUrl,
83949
84258
  // S1: only a gated headless probe arm gets this option at all. The
83950
84259
  // URL is this app's own packaged document, not a caller's string.
83951
- ...addressOverlayGate.enabled ? {
84260
+ ...addressOverlayGate.enabled || addressOverlayProduct ? {
83952
84261
  addressOverlay: {
83953
84262
  enabled: true,
83954
- list: addressOverlayGate.list,
84263
+ list: addressOverlayGate.list || addressOverlayProduct,
83955
84264
  visible: addressOverlayGate.visible,
84265
+ product: addressOverlayProduct,
83956
84266
  documentUrl: addressOverlayDocumentUrl
83957
84267
  }
83958
84268
  } : {},