sliccy 6.43.0 → 6.44.0

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 (155) hide show
  1. package/dist/node-server/electron-controller.d.ts +34 -2
  2. package/dist/node-server/electron-controller.js +21 -4
  3. package/dist/node-server/index.js +8 -0
  4. package/dist/ui/assets/{account-store-BzC0x752.js → account-store-BfqIrMMe.js} +30 -30
  5. package/dist/ui/assets/account-store-BkG4BDQC.js +42 -0
  6. package/dist/ui/assets/{adobe-KfCyFC0w.js → adobe-AHM3MRvp.js} +1 -1
  7. package/dist/ui/assets/{adobe-CoeG8AXw.js → adobe-C6T_0i0A.js} +1 -1
  8. package/dist/ui/assets/{anthropic-messages-CwKCE8PD.js → anthropic-messages-CTRXVqwn.js} +2 -2
  9. package/dist/ui/assets/{anthropic-messages-DPd961JX.js → anthropic-messages-EYoOyCX6.js} +2 -2
  10. package/dist/ui/assets/{apply-layout-Bt4lk2Me.js → apply-layout-DPvksNi2.js} +1 -1
  11. package/dist/ui/assets/{apps-4osfSnfB.js → apps-3MvdDBMc.js} +1 -1
  12. package/dist/ui/assets/{azure-openai-B8P4TPnO.js → azure-openai-ChaObvN0.js} +1 -1
  13. package/dist/ui/assets/{azure-openai-Bmb5Ncn6.js → azure-openai-DauBJZ6w.js} +1 -1
  14. package/dist/ui/assets/azure-openai-responses-DhklLm0Z.js +1 -0
  15. package/dist/ui/assets/azure-openai-responses-eJTO6o5G.js +1 -0
  16. package/dist/ui/assets/bedrock-camp-BfNg24Ce.js +1 -0
  17. package/dist/ui/assets/bedrock-camp-DMGplF70.js +1 -0
  18. package/dist/ui/assets/{cerebras-DXkRDNk9.js → cerebras-B1M_Nhi8.js} +1 -1
  19. package/dist/ui/assets/{cerebras-DTX8p8iF.js → cerebras-M2wuTTRu.js} +1 -1
  20. package/dist/ui/assets/compat-C0CyHyoL.js +2 -0
  21. package/dist/ui/assets/{composer-speech-CNhvMpkj.js → composer-speech-DjrdK6qX.js} +1 -1
  22. package/dist/ui/assets/{connect-surface-EVVLAHmG.js → connect-surface-C1kBb_wz.js} +1 -1
  23. package/dist/ui/assets/{context-compaction-DDaM9TWa.js → context-compaction-MXRS4Kb2.js} +1 -1
  24. package/dist/ui/assets/{ensure-speech-assets-Djt8o5f7.js → ensure-speech-assets-DO-sSGi6.js} +1 -1
  25. package/dist/ui/assets/{error-body-CqsCxuQ4.js → error-body-pkrba6pf.js} +1 -1
  26. package/dist/ui/assets/fs-CEdcSaaF.js +2 -0
  27. package/dist/ui/assets/fs-CwhZvLDc.js +1 -0
  28. package/dist/ui/assets/{github-copilot-BYeR_g6J.js → github-copilot-DzYB2zAw.js} +1 -1
  29. package/dist/ui/assets/{github-copilot-CVI88qdz.js → github-copilot-q5qtLl1S.js} +1 -1
  30. package/dist/ui/assets/{github-TCKAE5Uh.js → github-h8ItWdXm.js} +1 -1
  31. package/dist/ui/assets/{github-install-BuPC3YZw.js → github-install-DIeJprV5.js} +1 -1
  32. package/dist/ui/assets/github-xXbjvj_q.js +2 -0
  33. package/dist/ui/assets/{github-zip-Dlg-Q2ue.js → github-zip-DSYHJoT0.js} +1 -1
  34. package/dist/ui/assets/google-generative-ai-DEcgNsJh.js +1 -0
  35. package/dist/ui/assets/google-generative-ai-u7R_TH9o.js +1 -0
  36. package/dist/ui/assets/google-shared-BPNUreTT.js +371 -0
  37. package/dist/ui/assets/google-shared-CjO3-4_Q.js +11 -0
  38. package/dist/ui/assets/google-vertex-CTrzlewG.js +1 -0
  39. package/dist/ui/assets/google-vertex-bmq-ZPFH.js +1 -0
  40. package/dist/ui/assets/{hear-krvcqhL7.js → hear-CorI8zW2.js} +1 -1
  41. package/dist/ui/assets/{hear-C4KEOBVf.js → hear-DyYjYZXw.js} +1 -1
  42. package/dist/ui/assets/{kernel-worker-DEHxwjq6.js → kernel-worker-BksrbsiK.js} +117 -117
  43. package/dist/ui/assets/{kokoro-engine-CiPWAMSR.js → kokoro-engine-u_9YkV7P.js} +1 -1
  44. package/dist/ui/assets/{legacy-api-aliases-DAkrHYf9.js → legacy-api-aliases-C0CAIWhd.js} +1 -1
  45. package/dist/ui/assets/{legacy-api-aliases-BVP0Ho8x.js → legacy-api-aliases-qI5FdR49.js} +1 -1
  46. package/dist/ui/assets/{local-llm-D8ts0-Qm.js → local-llm-B1inFenw.js} +1 -1
  47. package/dist/ui/assets/{local-llm-CB_9Ui8j.js → local-llm-Bi8giqeq.js} +1 -1
  48. package/dist/ui/assets/{main-CYhcxAYn.js → main-BgdEVXnN.js} +3 -3
  49. package/dist/ui/assets/{mistral-conversations-Cyp2kssI.js → mistral-conversations-CunWHeDt.js} +2 -2
  50. package/dist/ui/assets/{mistral-conversations-gFwkX5N9.js → mistral-conversations-DWRsBsfa.js} +1 -1
  51. package/dist/ui/assets/models-BSkXF4T6.js +1 -0
  52. package/dist/ui/assets/{mount-Wax857ht.js → mount-BhXjPSMe.js} +1 -1
  53. package/dist/ui/assets/{mount-Dh40D48l.js → mount-DsBbQvRx.js} +2 -2
  54. package/dist/ui/assets/{mount-recovery-D3-N1o_E.js → mount-recovery-DapDhhBv.js} +1 -1
  55. package/dist/ui/assets/{new-session-PVPeVFQc.js → new-session-D0GziV3t.js} +2 -2
  56. package/dist/ui/assets/{oauth-bootstrap-onRgf3Is.js → oauth-bootstrap-exJhjKek.js} +2 -2
  57. package/dist/ui/assets/{openai-codex-DgZ9eDkQ.js → openai-codex-B5d5fatr.js} +1 -1
  58. package/dist/ui/assets/{openai-codex-DF2vOI8z.js → openai-codex-_wi2GlfO.js} +1 -1
  59. package/dist/ui/assets/openai-codex-responses-8wXA5Dto.js +7 -0
  60. package/dist/ui/assets/openai-codex-responses-BYAXyTDg.js +7 -0
  61. package/dist/ui/assets/openai-completions-CfjF1o-N.js +5 -0
  62. package/dist/ui/assets/openai-completions-DAIm60Lb.js +5 -0
  63. package/dist/ui/assets/openai-responses-01Q5Zv3q.js +1 -0
  64. package/dist/ui/assets/openai-responses-B7rl8DAX.js +1 -0
  65. package/dist/ui/assets/{openai-responses-shared-uSSusU2w.js → openai-responses-shared-B_T0yMQn.js} +3 -3
  66. package/dist/ui/assets/{openai-responses-shared-DajOm-sC.js → openai-responses-shared-BrIGUa2e.js} +3 -3
  67. package/dist/ui/assets/{openrouter-KaXerwGG.js → openrouter-DF11pL27.js} +1 -1
  68. package/dist/ui/assets/{openrouter-BbF3Yuh_.js → openrouter-PxN34b-T.js} +1 -1
  69. package/dist/ui/assets/{openrouter-images-7cFnqg4_.js → openrouter-images-CeBDTy7a.js} +1 -1
  70. package/dist/ui/assets/{openrouter-images-eEy7Fej8.js → openrouter-images-JzygwjVz.js} +1 -1
  71. package/dist/ui/assets/{openrouter-models-gCCUSdgw.js → openrouter-models-BVfLgK5R.js} +1 -1
  72. package/dist/ui/assets/{openrouter-models-DmontTTG.js → openrouter-models-Ds9BfRxR.js} +1 -1
  73. package/dist/ui/assets/{openrouter-oauth-CyGkjg56.js → openrouter-oauth-6UZDhQTB.js} +1 -1
  74. package/dist/ui/assets/{openrouter-oauth-Dx8hVsUq.js → openrouter-oauth-DQLx11_A.js} +1 -1
  75. package/dist/ui/assets/openrouter.models-CrhNqqEN.js +1 -0
  76. package/dist/ui/assets/openrouter.models-DkPWoMvu.js +1 -0
  77. package/dist/ui/assets/{panel-rpc-handlers-B7p25iL1.js → panel-rpc-handlers-CDZ2M3GK.js} +2 -2
  78. package/dist/ui/assets/{provider-C3zSzTlr.js → provider-Bw_Z5wgp.js} +1 -1
  79. package/dist/ui/assets/{provider-CdACKvd3.js → provider-Cg9DqCH6.js} +2 -2
  80. package/dist/ui/assets/{provider-settings-B8PQoEsb.js → provider-settings-0ASsdEo7.js} +1 -1
  81. package/dist/ui/assets/{provider-settings-DBbKsRoG.js → provider-settings-CqsZtmc2.js} +1 -1
  82. package/dist/ui/assets/provider-store-access-BJPtEdx_.js +2 -0
  83. package/dist/ui/assets/provider-store-access-Zeas5UVO.js +1 -0
  84. package/dist/ui/assets/{providers-CQOF0OxI.js → providers-D2SzyuS_.js} +2 -2
  85. package/dist/ui/assets/{providers-DW9h25Xk.js → providers-DTkQsdaJ.js} +1 -1
  86. package/dist/ui/assets/{quick-llm-YdXmDgWO.js → quick-llm-B1IKnoro.js} +1 -1
  87. package/dist/ui/assets/{recovery-screen-BBq0CbOW.js → recovery-screen-vCthBaZL.js} +1 -1
  88. package/dist/ui/assets/{redirect-uri-BtFxK4OI.js → redirect-uri-pK4MGnYj.js} +1 -1
  89. package/dist/ui/assets/{session-freezer-D2xY_37i.js → session-freezer-CWeTl5Ug.js} +3 -3
  90. package/dist/ui/assets/{setup-feature-flags-remote-Dq70lhlj.js → setup-feature-flags-remote-DCnULnlG.js} +1 -1
  91. package/dist/ui/assets/{setup-standalone-prelude-TJXZI1xV.js → setup-standalone-prelude-CFakSgWH.js} +1 -1
  92. package/dist/ui/assets/{setup-sudo-DqKSTbxO.js → setup-sudo-DLsSOUDP.js} +2 -2
  93. package/dist/ui/assets/sidecar-merge-ChbmI6Wr.js +1 -0
  94. package/dist/ui/assets/sidecar-merge-DP5Rveo5.js +1 -0
  95. package/dist/ui/assets/sidecar-repair-CfVdKYNb.js +1 -0
  96. package/dist/ui/assets/sidecar-repair-cn5xY6Gb.js +1 -0
  97. package/dist/ui/assets/{skills-BXWN2lD6.js → skills-BAv4QH3_.js} +1 -1
  98. package/dist/ui/assets/{speak-DLj1bEBh.js → speak-3ERYo9mh.js} +1 -1
  99. package/dist/ui/assets/{speak-BqGkX52J.js → speak-BJfvdDl7.js} +1 -1
  100. package/dist/ui/assets/{store-C-oC5Dsv.js → store-DmIA09wr.js} +1 -1
  101. package/dist/ui/assets/{store-DsiNO53b.js → store-VHFEG-KZ.js} +1 -1
  102. package/dist/ui/assets/{sudo-BIuk1k1q.js → sudo-DMWEEnXF.js} +1 -1
  103. package/dist/ui/assets/transform-messages-DEFauvrq.js +1 -0
  104. package/dist/ui/assets/transform-messages-XkZ1QnTb.js +1 -0
  105. package/dist/ui/assets/{transformers-env-CflaNVb-.js → transformers-env-B2igCBi6.js} +1 -1
  106. package/dist/ui/assets/{transformers-env-XCYT1oxA.js → transformers-env-DU9KkwRf.js} +1 -1
  107. package/dist/ui/assets/{upgrade-detection-DrziRNRB.js → upgrade-detection-kOnlsa6m.js} +1 -1
  108. package/dist/ui/assets/{voice-reply-AGGoZ9Ey.js → voice-reply-DuabCBM2.js} +1 -1
  109. package/dist/ui/assets/{wc-extension-VX3ZakVl.js → wc-extension-Csg9tKxf.js} +2 -2
  110. package/dist/ui/assets/{wc-follower-DzPdgiZN.js → wc-follower-C5ErFyaa.js} +3 -3
  111. package/dist/ui/assets/{wc-live-B5H5aWbX.js → wc-live-DiqRwfJl.js} +3 -3
  112. package/dist/ui/assets/{wc-nav-DYKStk4A.js → wc-nav-_JOvFwfI.js} +2 -2
  113. package/dist/ui/assets/{wc-onboarding-fMXbJHE6.js → wc-onboarding-BSs6x2FR.js} +2 -2
  114. package/dist/ui/assets/{wc-placeholder-zyLzZm58.js → wc-placeholder-UxILszwu.js} +2 -2
  115. package/dist/ui/assets/{wc-settings-BXhukZUh.js → wc-settings-CzWoxwvc.js} +2 -2
  116. package/dist/ui/assets/{wc-shell-C5zb79_R.js → wc-shell-FLfdSQyK.js} +7 -7
  117. package/dist/ui/assets/{wc-sprinkles-DBXkVV3r.js → wc-sprinkles-CCAwa0Z7.js} +2 -2
  118. package/dist/ui/assets/{wc-tray-DyqmeJQK.js → wc-tray-DV5jBUwL.js} +2 -2
  119. package/dist/ui/assets/{whisper-engine-i7jnYUoj.js → whisper-engine-DKSa8auO.js} +1 -1
  120. package/dist/ui/assets/{whisper-session-hMgosjVG.js → whisper-session-CnbZ_WW2.js} +2 -2
  121. package/dist/ui/assets/{xai-grok-DxaYAHiB.js → xai-grok-BANdowXb.js} +1 -1
  122. package/dist/ui/assets/{xai-grok-CGVh0Pwi.js → xai-grok-DgvHKcEu.js} +1 -1
  123. package/dist/ui/index.html +12 -12
  124. package/dist/ui/packages/webapp/index.html +12 -12
  125. package/package.json +2 -2
  126. package/dist/ui/assets/account-store-C1tZH-mA.js +0 -42
  127. package/dist/ui/assets/azure-openai-responses-CtOKUN00.js +0 -1
  128. package/dist/ui/assets/azure-openai-responses-oRGXQA3K.js +0 -1
  129. package/dist/ui/assets/bedrock-camp-BDCjQMZx.js +0 -1
  130. package/dist/ui/assets/bedrock-camp-CFmElpzZ.js +0 -1
  131. package/dist/ui/assets/compat-Bn8HnC3L.js +0 -2
  132. package/dist/ui/assets/fs-DJwfGyA1.js +0 -2
  133. package/dist/ui/assets/fs-DOqDOgs2.js +0 -1
  134. package/dist/ui/assets/github-t4MIUh5J.js +0 -2
  135. package/dist/ui/assets/google-generative-ai-BL_SqY5W.js +0 -1
  136. package/dist/ui/assets/google-generative-ai-DDF2tpZq.js +0 -1
  137. package/dist/ui/assets/google-shared-DPuPo5mO.js +0 -11
  138. package/dist/ui/assets/google-shared-biiFuSpC.js +0 -371
  139. package/dist/ui/assets/google-vertex-CobhNXpX.js +0 -1
  140. package/dist/ui/assets/google-vertex-VXUUgM7o.js +0 -1
  141. package/dist/ui/assets/models-DgdVqaw5.js +0 -1
  142. package/dist/ui/assets/openai-codex-responses-BJOy6BEd.js +0 -7
  143. package/dist/ui/assets/openai-codex-responses-BfT5s3yO.js +0 -7
  144. package/dist/ui/assets/openai-completions-CmslRX3-.js +0 -5
  145. package/dist/ui/assets/openai-completions-DDas47cy.js +0 -5
  146. package/dist/ui/assets/openai-responses-CHXkcom_.js +0 -1
  147. package/dist/ui/assets/openai-responses-DWlnQ-B0.js +0 -1
  148. package/dist/ui/assets/openrouter.models-Byp0hyfF.js +0 -1
  149. package/dist/ui/assets/openrouter.models-C8HitxAG.js +0 -1
  150. package/dist/ui/assets/provider-store-access-ChzjVdqD.js +0 -1
  151. package/dist/ui/assets/provider-store-access-Dcy68Vs8.js +0 -2
  152. package/dist/ui/assets/sidecar-repair-B31h6Aw0.js +0 -1
  153. package/dist/ui/assets/sidecar-repair-DVW7uarV.js +0 -1
  154. package/dist/ui/assets/transform-messages-D27pVLZ-.js +0 -1
  155. package/dist/ui/assets/transform-messages-DgR3h-Ck.js +0 -1
@@ -28,13 +28,35 @@ export declare function resolveOverlayThinBridge(env: Record<string, string | un
28
28
  export interface ThinOverlayUrlOptions extends ThinBridgeConfig {
29
29
  role: OverlayRole;
30
30
  activeTab?: string;
31
+ /**
32
+ * Explicit tray intent for the overlay URL, three-valued:
33
+ *
34
+ * - a normalized join URL (`--join`) → `tray=<url>`: the hosted webapp
35
+ * resolves it via `resolveFollowerJoinUrl` and attaches to the running
36
+ * leader as a tray FOLLOWER instead of minting its own tray — omitting
37
+ * it was the bug that made every egress-allowed Electron app silently
38
+ * become a second leader.
39
+ * - the EMPTY string → `tray=` (empty): explicit "no tray" intent. The
40
+ * webapp treats any present `tray` param as explicit intent, which
41
+ * blocks `resolveFollowerJoinUrl`'s localStorage fallback — without it,
42
+ * the join URL the leader tab persists into the shared sliccy.ai
43
+ * storage would re-enter through that fallback and boot every
44
+ * auto-follow tab as ANOTHER tray follower (N followers for one
45
+ * multi-window app).
46
+ * - absent/null → no `tray` param at all; storage-based re-follow stays
47
+ * possible. Reserved for the SLICC Electron float's own window
48
+ * (`electron-main.ts`), whose stored-tray reattach is intentional.
49
+ */
50
+ trayJoinUrl?: string | null;
31
51
  }
32
52
  /**
33
53
  * Build the hosted launcher URL for an overlay injection. Mirrors the
34
54
  * standalone Path A launch-URL shape (`bridge`, `bridgeToken` query
35
- * params) with one Electron-specific addition: a `role` param that pins
55
+ * params) with two Electron-specific additions: a `role` param that pins
36
56
  * the first injected tab as the leader and marks every subsequent tab as
37
- * an auto-follow follower.
57
+ * an auto-follow follower, and — on a `--join` launch — the same
58
+ * `tray=<join url>` param the Chrome join path emits so the pinned tab
59
+ * attaches to the running leader as a tray follower.
38
60
  */
39
61
  export declare function buildThinOverlayAppUrl(opts: ThinOverlayUrlOptions): string;
40
62
  /**
@@ -206,6 +228,16 @@ export declare class ElectronOverlayInjector {
206
228
  thinBridge: ThinBridgeConfig;
207
229
  /** Start the headless CDP-over-CDP follower when egress-block is detected. */
208
230
  onEgressBlocked?: (targetUrl: string) => void;
231
+ /**
232
+ * Normalized tray join URL (`--join`); rides the LEADER-role overlay URL
233
+ * only, so the app's pinned first tab attaches to the running leader as
234
+ * ONE tray follower. In-app auto-follow tabs instead carry an explicitly
235
+ * EMPTY `tray=` — the leader tab persists the join URL into the shared
236
+ * sliccy.ai localStorage, and without explicit no-tray intent the
237
+ * `resolveFollowerJoinUrl` storage fallback would boot every extra
238
+ * window as ANOTHER tray follower (N followers for one app).
239
+ */
240
+ trayJoinUrl?: string | null;
209
241
  }): Promise<ElectronOverlayInjector>;
210
242
  /**
211
243
  * Test-only factory: skips bundle loading and lets tests drive the per-target
@@ -9,6 +9,7 @@ import { WebSocket } from 'ws';
9
9
  import { inflateSync } from 'zlib';
10
10
  import { BRIDGE_TOKEN_QUERY_PARAM, BRIDGE_WS_QUERY_PARAM } from './bridge-security.js';
11
11
  import { buildElectronAppLaunchSpec, buildElectronOverlayBootstrapScript, getElectronOverlayEntryDistPath, selectBestOverlayTargets, } from './electron-runtime.js';
12
+ import { TRAY_QUERY_PARAM } from './tray-url-shared.js';
12
13
  const execFile = promisify(nodeExecFile);
13
14
  const ELECTRON_OVERLAY_SYNC_INTERVAL_MS = 1500;
14
15
  /**
@@ -40,9 +41,11 @@ export function resolveOverlayThinBridge(env, bridgeToken, servePort) {
40
41
  /**
41
42
  * Build the hosted launcher URL for an overlay injection. Mirrors the
42
43
  * standalone Path A launch-URL shape (`bridge`, `bridgeToken` query
43
- * params) with one Electron-specific addition: a `role` param that pins
44
+ * params) with two Electron-specific additions: a `role` param that pins
44
45
  * the first injected tab as the leader and marks every subsequent tab as
45
- * an auto-follow follower.
46
+ * an auto-follow follower, and — on a `--join` launch — the same
47
+ * `tray=<join url>` param the Chrome join path emits so the pinned tab
48
+ * attaches to the running leader as a tray follower.
46
49
  */
47
50
  export function buildThinOverlayAppUrl(opts) {
48
51
  const url = new URL(ELECTRON_OVERLAY_APP_PATH, opts.hostedLeaderOrigin);
@@ -52,6 +55,9 @@ export function buildThinOverlayAppUrl(opts) {
52
55
  if (opts.activeTab && opts.activeTab !== 'chat') {
53
56
  url.searchParams.set('tab', opts.activeTab);
54
57
  }
58
+ if (opts.trayJoinUrl != null) {
59
+ url.searchParams.set(TRAY_QUERY_PARAM, opts.trayJoinUrl);
60
+ }
55
61
  return url.toString();
56
62
  }
57
63
  /**
@@ -616,11 +622,22 @@ export class ElectronOverlayInjector {
616
622
  const thinBootstraps = {
617
623
  leader: buildElectronOverlayBootstrapScript({
618
624
  bundleSource,
619
- appUrl: buildThinOverlayAppUrl({ ...options.thinBridge, role: BRIDGE_ROLE_LEADER }),
625
+ appUrl: buildThinOverlayAppUrl({
626
+ ...options.thinBridge,
627
+ role: BRIDGE_ROLE_LEADER,
628
+ // Explicit intent in BOTH cases: join URL → follow; no join →
629
+ // empty tray= so a stored join URL from an earlier launch can't
630
+ // hijack a plain --electron launch into follower mode.
631
+ trayJoinUrl: options.trayJoinUrl ?? '',
632
+ }),
620
633
  }),
621
634
  follower: buildElectronOverlayBootstrapScript({
622
635
  bundleSource,
623
- appUrl: buildThinOverlayAppUrl({ ...options.thinBridge, role: BRIDGE_ROLE_FOLLOWER }),
636
+ appUrl: buildThinOverlayAppUrl({
637
+ ...options.thinBridge,
638
+ role: BRIDGE_ROLE_FOLLOWER,
639
+ trayJoinUrl: '',
640
+ }),
624
641
  }),
625
642
  status: buildElectronOverlayBootstrapScript({
626
643
  bundleSource,
@@ -47,6 +47,7 @@ import { SecretProxyManager } from './secrets/proxy-manager.js';
47
47
  import { readOrCreateSessionId } from './secrets/session-id-file.js';
48
48
  import { registerSecretsReloadEndpoint } from './secrets-reload-endpoint.js';
49
49
  import { registerSudoApproveEndpoint } from './sudo/endpoint.js';
50
+ import { parseTrayJoinUrl } from './tray-url-shared.js';
50
51
  const Dirname = fileURLToPath(new URL('.', import.meta.url));
51
52
  const PROJECT_ROOT = resolve(Dirname, '..', '..');
52
53
  // ---------------------------------------------------------------------------
@@ -848,6 +849,13 @@ async function startOverlayInjector(state, cdpPort, servePort) {
848
849
  servePort,
849
850
  projectRoot: PROJECT_ROOT,
850
851
  thinBridge,
852
+ // Hand `--join` to the overlay webapp as the same `tray=<join url>`
853
+ // contract the Chrome join path emits, so an egress-ALLOWED app
854
+ // attaches to the running leader as a tray follower. Without this the
855
+ // overlay boots in electron-overlay mode and mints its own tray as a
856
+ // second leader. (The egress-BLOCKED hook below joins via the headless
857
+ // WebRTC follower instead — the overlay never loads there.)
858
+ trayJoinUrl: parseTrayJoinUrl(state.discoveredTrayJoinUrl)?.joinUrl ?? null,
851
859
  // When the app blocks renderer egress (hosted overlay can't load), expose
852
860
  // its CDP to the tray leader via the headless follower instead.
853
861
  onEgressBlocked: () => {