@dimina-kit/devtools 0.4.0-dev.20260803105710 → 0.4.0-dev.20260828092243

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 (208) hide show
  1. package/dist/main/api.d.ts +1 -1
  2. package/dist/main/app/app.js +66 -2
  3. package/dist/main/index.bundle.js +1454 -540
  4. package/dist/main/ipc/index.d.ts +3 -0
  5. package/dist/main/ipc/index.js +3 -0
  6. package/dist/main/ipc/popover.js +1 -1
  7. package/dist/main/ipc/project-create.d.ts +15 -0
  8. package/dist/main/ipc/project-create.js +26 -0
  9. package/dist/main/ipc/projects.d.ts +1 -1
  10. package/dist/main/ipc/projects.js +11 -0
  11. package/dist/main/ipc/session.js +11 -0
  12. package/dist/main/ipc/settings.js +2 -1
  13. package/dist/main/ipc/simulator-module.d.ts +4 -3
  14. package/dist/main/ipc/simulator-module.js +4 -5
  15. package/dist/main/ipc/tooltip.d.ts +13 -0
  16. package/dist/main/ipc/tooltip.js +28 -0
  17. package/dist/main/ipc/views.d.ts +15 -1
  18. package/dist/main/ipc/views.js +61 -4
  19. package/dist/main/runtime/miniapp-runtime.d.ts +87 -19
  20. package/dist/main/services/layout/index.d.ts +11 -0
  21. package/dist/main/services/layout/index.js +23 -0
  22. package/dist/main/services/network-forward/frontend-dispatch.js +2 -1
  23. package/dist/main/services/notifications/renderer-notifier.d.ts +32 -1
  24. package/dist/main/services/notifications/renderer-notifier.js +29 -1
  25. package/dist/main/services/projects/project-repository.d.ts +4 -1
  26. package/dist/main/services/projects/project-repository.js +63 -5
  27. package/dist/main/services/simulator-current-page/index.d.ts +5 -3
  28. package/dist/main/services/simulator-current-page/index.js +8 -1
  29. package/dist/main/services/update/update-manager.d.ts +17 -3
  30. package/dist/main/services/update/update-manager.js +25 -6
  31. package/dist/main/services/views/clear-console-filter.d.ts +44 -0
  32. package/dist/main/services/views/clear-console-filter.js +86 -0
  33. package/dist/main/services/views/console-filter-test-fixtures.d.ts +94 -0
  34. package/dist/main/services/views/console-filter-test-fixtures.js +82 -0
  35. package/dist/main/services/views/console-filter.d.ts +79 -130
  36. package/dist/main/services/views/console-filter.js +140 -183
  37. package/dist/main/services/views/devtools-tabs.d.ts +24 -4
  38. package/dist/main/services/views/devtools-tabs.js +40 -21
  39. package/dist/main/services/views/host-dialog-port-channel.d.ts +18 -0
  40. package/dist/main/services/views/host-dialog-port-channel.js +15 -0
  41. package/dist/main/services/views/host-dialog-session-runtime.d.ts +10 -0
  42. package/dist/main/services/views/host-dialog-session-runtime.js +17 -0
  43. package/dist/main/services/views/host-dialog-view.d.ts +95 -0
  44. package/dist/main/services/views/host-dialog-view.js +147 -0
  45. package/dist/main/services/views/host-sidebar-port-channel.d.ts +18 -0
  46. package/dist/main/services/views/host-sidebar-port-channel.js +15 -0
  47. package/dist/main/services/views/host-sidebar-session-runtime.d.ts +10 -0
  48. package/dist/main/services/views/host-sidebar-session-runtime.js +17 -0
  49. package/dist/main/services/views/host-sidebar-view.d.ts +59 -0
  50. package/dist/main/services/views/host-sidebar-view.js +44 -0
  51. package/dist/main/services/views/host-slot-port-channel.d.ts +107 -0
  52. package/dist/main/services/views/host-slot-port-channel.js +261 -0
  53. package/dist/main/services/views/host-slot-session-runtime.d.ts +40 -0
  54. package/dist/main/services/views/host-slot-session-runtime.js +50 -0
  55. package/dist/main/services/views/host-slot-view.d.ts +109 -0
  56. package/dist/main/services/views/host-slot-view.js +147 -0
  57. package/dist/main/services/views/host-toolbar-port-channel.d.ts +6 -91
  58. package/dist/main/services/views/host-toolbar-port-channel.js +10 -243
  59. package/dist/main/services/views/host-toolbar-session-runtime.d.ts +5 -30
  60. package/dist/main/services/views/host-toolbar-session-runtime.js +9 -47
  61. package/dist/main/services/views/host-toolbar-view.d.ts +34 -7
  62. package/dist/main/services/views/host-toolbar-view.js +30 -237
  63. package/dist/main/services/views/managed-web-contents-view.d.ts +48 -0
  64. package/dist/main/services/views/managed-web-contents-view.js +123 -0
  65. package/dist/main/services/views/native-simulator-devtools-host.js +64 -45
  66. package/dist/main/services/views/native-simulator-view.js +6 -24
  67. package/dist/main/services/views/native-view-tree.d.ts +25 -0
  68. package/dist/main/services/views/native-view-tree.js +69 -0
  69. package/dist/main/services/views/overlay-panels-view.d.ts +50 -4
  70. package/dist/main/services/views/overlay-panels-view.js +226 -108
  71. package/dist/main/services/views/placement-reconciler.d.ts +18 -18
  72. package/dist/main/services/views/placement-reconciler.js +91 -29
  73. package/dist/main/services/views/placement-test-driver.d.ts +27 -0
  74. package/dist/main/services/views/placement-test-driver.js +29 -0
  75. package/dist/main/services/views/view-manager-devtools-host-test-fixtures.js +3 -1
  76. package/dist/main/services/views/view-manager.d.ts +14 -86
  77. package/dist/main/services/views/view-manager.js +41 -4
  78. package/dist/main/services/views/workbench-view.js +27 -20
  79. package/dist/main/services/workbench-coi-server.d.ts +11 -0
  80. package/dist/main/services/workbench-coi-server.js +32 -0
  81. package/dist/main/services/workspace/rebuild-status.d.ts +21 -8
  82. package/dist/main/services/workspace/rebuild-status.js +24 -8
  83. package/dist/main/utils/paths.d.ts +4 -0
  84. package/dist/main/utils/paths.js +4 -0
  85. package/dist/main/utils/sender-policy.d.ts +1 -1
  86. package/dist/main/utils/sender-policy.js +16 -1
  87. package/dist/main/utils/theme.d.ts +7 -2
  88. package/dist/main/utils/theme.js +8 -3
  89. package/dist/native-host/common/common.js +65 -62
  90. package/dist/native-host/container/pageFrame.css +1 -1
  91. package/dist/native-host/render/render.js +3226 -2898
  92. package/dist/native-host/service/service.js +2 -2
  93. package/dist/preload/runtime/host-dialog-advertiser.d.ts +22 -0
  94. package/dist/preload/runtime/host-dialog-advertiser.js +37 -0
  95. package/dist/preload/runtime/host-dialog-port.d.ts +44 -0
  96. package/dist/preload/runtime/host-dialog-port.js +53 -0
  97. package/dist/preload/runtime/host-dialog-runtime.d.ts +28 -0
  98. package/dist/preload/runtime/host-dialog-runtime.js +36 -0
  99. package/dist/preload/runtime/host-sidebar-advertiser.d.ts +19 -0
  100. package/dist/preload/runtime/host-sidebar-advertiser.js +35 -0
  101. package/dist/preload/runtime/host-sidebar-port.d.ts +44 -0
  102. package/dist/preload/runtime/host-sidebar-port.js +53 -0
  103. package/dist/preload/runtime/host-sidebar-runtime.d.ts +28 -0
  104. package/dist/preload/runtime/host-sidebar-runtime.js +36 -0
  105. package/dist/preload/runtime/host-slot-port-bridge.d.ts +18 -0
  106. package/dist/preload/runtime/host-slot-port-bridge.js +112 -0
  107. package/dist/preload/runtime/host-toolbar-advertiser.d.ts +5 -13
  108. package/dist/preload/runtime/host-toolbar-advertiser.js +18 -38
  109. package/dist/preload/runtime/host-toolbar-port.d.ts +9 -0
  110. package/dist/preload/runtime/host-toolbar-port.js +11 -95
  111. package/dist/preload/runtime/wait-for-slot-root.d.ts +20 -0
  112. package/dist/preload/runtime/wait-for-slot-root.js +52 -0
  113. package/dist/preload/windows/host-dialog-runtime.cjs +353 -0
  114. package/dist/preload/windows/host-dialog-runtime.cjs.map +7 -0
  115. package/dist/preload/windows/host-dialog-runtime.d.ts +2 -0
  116. package/dist/preload/windows/host-dialog-runtime.js +13 -0
  117. package/dist/preload/windows/host-sidebar-runtime.cjs +354 -0
  118. package/dist/preload/windows/host-sidebar-runtime.cjs.map +7 -0
  119. package/dist/preload/windows/host-sidebar-runtime.d.ts +2 -0
  120. package/dist/preload/windows/host-sidebar-runtime.js +13 -0
  121. package/dist/preload/windows/host-toolbar-runtime.cjs +134 -51
  122. package/dist/preload/windows/host-toolbar-runtime.cjs.map +3 -3
  123. package/dist/preload/windows/main.cjs +3176 -14
  124. package/dist/preload/windows/main.cjs.map +4 -4
  125. package/dist/preload/windows/main.css +428 -0
  126. package/dist/preload/windows/main.css.map +7 -0
  127. package/dist/preload/windows/simulator.cjs +5 -2
  128. package/dist/preload/windows/simulator.cjs.map +2 -2
  129. package/dist/preload/windows/simulator.js +5 -2
  130. package/dist/renderer/assets/button-DsNqZm7o.js +2 -0
  131. package/dist/renderer/assets/constants-D7DfVqMp.js +2 -0
  132. package/dist/renderer/assets/constants-D8zsejFq.js +2 -0
  133. package/dist/renderer/assets/createLucideIcon-CYJeT1ji.js +2 -0
  134. package/dist/renderer/assets/dialog-pT4qWmka.js +46 -0
  135. package/dist/renderer/assets/dist-o70xmpc1.js +2 -0
  136. package/dist/renderer/assets/hostSidebarDefault-NvGZlE9O.js +2 -0
  137. package/dist/renderer/assets/index-zErhG3ta.js +5 -0
  138. package/dist/renderer/assets/input-4QxTXMZN.js +2 -0
  139. package/dist/renderer/assets/ipc-channels-overlays-Blr5TNoB.js +2 -0
  140. package/dist/renderer/assets/jsx-runtime-B-3rq1y5.css +1 -0
  141. package/dist/renderer/assets/jsx-runtime-CqVdW3eg.js +9 -0
  142. package/dist/renderer/assets/popover-CJiSWwuE.js +2 -0
  143. package/dist/renderer/assets/project-api-DZ1Zi6EC.js +2 -0
  144. package/dist/renderer/assets/projectCreateDialog-DMWNhw_1.js +2 -0
  145. package/dist/renderer/assets/select-C86pNcsu.js +2 -0
  146. package/dist/renderer/assets/settings-BoI8mLT1.js +2 -0
  147. package/dist/renderer/assets/settings-api-Bs_g4NHs.js +2 -0
  148. package/dist/renderer/assets/settings-tab-bar-DHLLygqv.js +2 -0
  149. package/dist/renderer/assets/tooltip-BhAyY0T4.js +2 -0
  150. package/dist/renderer/assets/types-YYjkvane.js +2 -0
  151. package/dist/renderer/assets/updateDialog-DPum3wx1.js +2 -0
  152. package/dist/renderer/assets/utils-kfQov6Pa.js +2 -0
  153. package/dist/renderer/assets/view-api-DFhb2R8-.js +2 -0
  154. package/dist/renderer/assets/workbenchSettings-DrajRQUk.js +8 -0
  155. package/dist/renderer/entries/host-sidebar-default/index.html +21 -0
  156. package/dist/renderer/entries/main/index.html +15 -7
  157. package/dist/renderer/entries/popover/index.html +10 -6
  158. package/dist/renderer/entries/project-create-dialog/index.html +27 -0
  159. package/dist/renderer/entries/settings/index.html +10 -5
  160. package/dist/renderer/entries/tooltip/index.html +21 -0
  161. package/dist/renderer/entries/update-dialog/index.html +25 -0
  162. package/dist/renderer/entries/workbench-settings/index.html +11 -5
  163. package/dist/service-host/preload.cjs +10 -0
  164. package/dist/service-host/sync-impls/menu-button-geometry.js +1 -0
  165. package/dist/shared/constants.d.ts +22 -0
  166. package/dist/shared/constants.js +22 -0
  167. package/dist/shared/ipc-channels-overlays.d.ts +156 -0
  168. package/dist/shared/ipc-channels-overlays.js +186 -0
  169. package/dist/shared/ipc-channels.d.ts +1 -67
  170. package/dist/shared/ipc-channels.js +9 -81
  171. package/dist/shared/ipc-schemas.d.ts +52 -0
  172. package/dist/shared/ipc-schemas.js +64 -0
  173. package/dist/shared/simulator-route.d.ts +8 -0
  174. package/dist/shared/simulator-route.js +15 -0
  175. package/dist/shared/types.d.ts +17 -0
  176. package/dist/shared/view-ids.d.ts +9 -0
  177. package/dist/shared/view-ids.js +21 -0
  178. package/dist/simulator/assets/device-shell-CmtM1QxP.js +2 -0
  179. package/dist/simulator/assets/device-shell-iFZo1igL.css +1 -0
  180. package/dist/simulator/assets/{simulator-COIE6R49.js → simulator-CIobn3Mh.js} +6 -6
  181. package/dist/simulator/assets/{simulator-mini-app-BLn7XV8e.js → simulator-mini-app-CRe6n9br.js} +2 -2
  182. package/dist/simulator/assets/simulator-ui-BupATgKo.css +1 -0
  183. package/dist/simulator/assets/simulator-ui-C_cP602X.js +2 -0
  184. package/dist/simulator/simulator.html +3 -2
  185. package/dist/vscode-workbench/assets/__vite-browser-external-Bc1vizTf.js +1 -0
  186. package/dist/vscode-workbench/assets/{dist-oHcwN53f.js → dist-CMfmHflW.js} +3 -3
  187. package/dist/vscode-workbench/assets/{iconv-lite-umd-CLMLpdGm.js → iconv-lite-umd-Bx8CgaZq.js} +1 -1
  188. package/dist/vscode-workbench/assets/{index-BE3UJdoH.js → index-CdG6YWhW.js} +436 -436
  189. package/dist/vscode-workbench/assets/{jschardet-BICW8PLJ.js → jschardet-M0qgd2lN.js} +1 -1
  190. package/dist/vscode-workbench/index.html +21 -1
  191. package/package.json +9 -8
  192. package/dist/main/services/views/destroy-child-view.d.ts +0 -9
  193. package/dist/main/services/views/destroy-child-view.js +0 -23
  194. package/dist/renderer/assets/constants-EAMiwL9_.js +0 -2
  195. package/dist/renderer/assets/index-BBg3YI5b.js +0 -49
  196. package/dist/renderer/assets/input-xdmfv-eH.js +0 -2
  197. package/dist/renderer/assets/ipc-transport-B3EpmfNS.js +0 -9
  198. package/dist/renderer/assets/ipc-transport-Blac3sOj.css +0 -1
  199. package/dist/renderer/assets/popover-B88e2hkg.js +0 -2
  200. package/dist/renderer/assets/select-CD9CJyhI.js +0 -2
  201. package/dist/renderer/assets/settings-44hf0QtO.js +0 -2
  202. package/dist/renderer/assets/settings-api-pJKPuP1M.js +0 -2
  203. package/dist/renderer/assets/workbenchSettings-DKD5U1Ql.js +0 -8
  204. package/dist/simulator/assets/device-shell-Cw7c-IkG.js +0 -2
  205. package/dist/simulator/assets/device-shell-DbC5ccs8.css +0 -1
  206. package/dist/simulator/assets/jsx-runtime-DkKmJyBb.js +0 -2
  207. package/dist/simulator/device-shell/menu-button-geometry.js +0 -18
  208. package/dist/vscode-workbench/assets/__vite-browser-external-BON7qP59.js +0 -1
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/shared/constants.ts", "../../../src/preload/runtime/host-dialog-advertiser.ts", "../../../../view-anchor/src/measure-loop.ts", "../../../../view-anchor/src/size-advertiser.ts", "../../../src/shared/ipc-channels-overlays.ts", "../../../src/preload/runtime/wait-for-slot-root.ts", "../../../src/preload/runtime/host-slot-port-bridge.ts", "../../../src/preload/runtime/host-dialog-port.ts", "../../../src/preload/runtime/host-dialog-runtime.ts", "../../../src/preload/windows/host-dialog-runtime.ts"],
4
+ "sourcesContent": ["/** Shared cross-process constants for dimina-devtools. */\n\n/** Default Chrome DevTools Protocol (CDP) remote debugging port. */\nexport const DEFAULT_CDP_PORT = 9222\n\n/** Default scene value for mini-app launch. */\nexport const DEFAULT_SCENE = 1001\n\n/**\n * Fixed devtools toolbar header height (px). Single source of truth shared by\n * the main process (overlay view layout) and the renderer (toolbar/popover\n * layout). Not host-configurable \u2014 the deprecated\n * `WorkbenchAppConfig.headerHeight` is ignored; hosts that need their own\n * toolbar use the host toolbar WCV instead.\n */\nexport const HEADER_H = 40\n\n/**\n * Process-level argv marker injected (via `webPreferences.additionalArguments`)\n * into the host-toolbar WebContentsView. The session-registered toolbar-runtime\n * preload (`src/preload/runtime/host-toolbar-runtime.ts`) executes in EVERY\n * defaultSession renderer; its guard activates the height advertiser only when\n * `process.argv` carries this marker AND `process.isMainFrame` is true (the\n * marker is process-level, so subframes of the toolbar window see it too \u2014\n * both guard wings are required).\n */\nexport const HOST_TOOLBAR_RUNTIME_MARKER = '--dimina-host-toolbar'\n\n/**\n * Same guard-marker contract as {@link HOST_TOOLBAR_RUNTIME_MARKER}, for the\n * host-sidebar WebContentsView (`src/preload/runtime/host-sidebar-runtime.ts`).\n */\nexport const HOST_SIDEBAR_RUNTIME_MARKER = '--dimina-host-sidebar'\n\n/**\n * Same guard-marker contract as {@link HOST_TOOLBAR_RUNTIME_MARKER}, for the\n * host-dialog WebContentsView (`src/preload/runtime/host-dialog-runtime.ts`).\n */\nexport const HOST_DIALOG_RUNTIME_MARKER = '--dimina-host-dialog'\n\n/**\n * Intrinsic width (px) of devtools' own default host-sidebar content (the\n * project-category icon rail). Single source of truth shared by the renderer\n * (`host-sidebar-default.tsx`, which gives its `[data-host-sidebar-root]` this\n * exact width so the width advertiser reports it) and anything in main that\n * needs to reason about the default rail's size. The slot is NOT left pinned\n * at this width: main pushes it once as a seed and immediately returns the\n * slot to 'auto' (see `createDevtoolsRuntime`), so the rail \u2014 and any\n * downstream `loadURL`/`loadFile` content that replaces it \u2014 advertises its\n * own width from then on, exactly like any other host-sidebar content.\n */\nexport const HOST_SIDEBAR_DEFAULT_WIDTH = 56\n", "/**\n * Reverse size-advertiser preload for the host-controllable dialog\n * WebContentsView. Runs in that WCV's OWN renderer (the dialog content's\n * preload). Unlike the toolbar/sidebar (single-axis persistent strips), the\n * dialog self-sizes on BOTH axes \u2014 it has no renderer placeholder to anchor\n * against, so main centers it in the main window purely from what this\n * advertiser reports. Two independent `createSizeAdvertiser` instances (one\n * per axis) share the same root and the same outbound channel\n * (`HostDialogAdvertiseSize` carries `{ axis, extent }` for either axis); main\n * re-centers using whichever axes it has measured so far (see\n * `host-dialog-view.ts`'s `reportMeasuredExtent` / default-size fallback).\n */\n\nimport { ipcRenderer } from 'electron'\nimport { createSizeAdvertiser } from '@dimina-kit/view-anchor'\nimport { ViewChannel } from '../../shared/ipc-channels-overlays.js'\nimport { whenSlotRootReady } from './wait-for-slot-root.js'\n\n/**\n * Attach both axis advertisers to the dialog content's shrink-to-fit root\n * (`[data-host-dialog-root]`), waiting for it if necessary \u2014 the root may be\n * mounted asynchronously by a framework rather than present in the initial\n * HTML. That element MUST be shrink-to-fit on BOTH axes \u2014 same footgun as\n * the toolbar/sidebar (`createSizeAdvertiser`'s single-axis-ownership\n * requirement), just doubled.\n */\nexport function installHostDialogAdvertiserWhenReady(): void {\n whenSlotRootReady(\n '[data-host-dialog-root]',\n '[host-dialog-advertiser] no `[data-host-dialog-root]` element found \u2014 ' +\n 'not advertising a size yet. The dialog content must wrap itself in a ' +\n 'shrink-to-fit `[data-host-dialog-root]` element so its size is the ' +\n 'content size, not the host-given view size.',\n (root) => {\n const publish = (size: { axis: 'block' | 'inline'; extent: number }): void => {\n ipcRenderer.send(ViewChannel.HostDialogAdvertiseSize, size)\n }\n\n createSizeAdvertiser(root, { axis: 'block', publish })\n createSizeAdvertiser(root, { axis: 'inline', publish })\n },\n )\n}\n", "/**\n * Internal \u2014 the RAF-coalesced measure/dedupe/dispose engine behind the REVERSE\n * primitive `createSizeAdvertiser`.\n *\n * The forward `createViewAnchor` deliberately does NOT use this: it publishes\n * SYNCHRONOUSLY (a native overlay's `setBounds` already lands a cross-process\n * frame late, and a RAF stacked a second frame of visible trailing). The\n * reverse direction is different \u2014 it is a cross-process FEEDBACK loop\n * (advertise \u2192 host resizes the view \u2192 content re-measures \u2192 re-advertise), so\n * the RAF's one-publish-per-frame coalescing is a useful damper. The two\n * directions thus have different optimal emit timing; this engine serves only\n * the reverse.\n *\n * NOT exported from the package: it is pure mechanism with no knowledge of\n * direction, the DOM, `ResizeObserver`, or the structure of the value `T` it\n * carries. The wrapping primitive injects `produce` / `same` / `sink` and\n * drives the lifecycle.\n *\n * - `schedule()` \u2014 coalesce a burst of triggers into ONE RAF; the frame\n * body re-`produce()`s, dedupes against the last emit (`same`), and `sink`s.\n * Bails if inactive or disposed (stale-RAF safe).\n * - `emitNow(v)` \u2014 explicit synchronous emit (create / update path). Always\n * fires, bypassing the dedupe check, and refreshes the dedupe baseline.\n * - `setActive` \u2014 gate the observer stream; a queued frame bails on `!active`.\n * - `cancel` \u2014 drop any in-flight RAF.\n * - `dispose` \u2014 cancel + go inert; after dispose nothing emits again.\n */\nexport interface MeasureLoop<T> {\n schedule(): void\n emitNow(value: T): void\n setActive(on: boolean): void\n cancel(): void\n dispose(): void\n}\n\nexport function createMeasureLoop<T>(cfg: {\n /** Produce the value to emit in the RAF body. Return `null` to decline the\n * frame entirely (no dedupe, no sink, baseline untouched) \u2014 e.g. a\n * non-finite or unavailable measurement. */\n produce: () => T | null\n same: (a: T, b: T) => boolean\n sink: (value: T) => void\n}): MeasureLoop<T> {\n const { produce, same, sink } = cfg\n let rafId: number | null = null\n let active = false\n let disposed = false\n let last: T | null = null\n\n const cancel = (): void => {\n if (rafId !== null) {\n cancelAnimationFrame(rafId)\n rafId = null\n }\n }\n\n return {\n schedule(): void {\n if (disposed || !active || rafId !== null) return\n rafId = requestAnimationFrame(() => {\n rafId = null\n if (disposed || !active) return\n const value = produce()\n if (value === null) return // producer declined this frame\n // last-value dedupe: a frame whose produced value equals the last one\n // we emitted costs nothing (no IPC / setBounds).\n if (last !== null && same(value, last)) return\n last = value\n sink(value)\n })\n },\n emitNow(value: T): void {\n if (disposed) return\n last = value\n sink(value)\n },\n setActive(on: boolean): void {\n active = on\n },\n cancel,\n dispose(): void {\n if (disposed) return\n disposed = true\n cancel()\n },\n }\n}\n", "import type {\n AdvertisedSize,\n SizeAdvertiserOptions,\n SizeAdvertiserHandle,\n} from './types.js'\nimport { createMeasureLoop } from './measure-loop.js'\n\n/**\n * Reverse of `createViewAnchor`: runs in a downstream WebContentsView's own\n * renderer, measures the content's own size on ONE owned axis (from the\n * `ResizeObserver` border-box \u2014 no `getBoundingClientRect`, no forced reflow),\n * and advertises it via the injected `publish`. Shares the forward primitive's\n * measure/coalesce/dedupe/dispose engine (`createMeasureLoop`).\n *\n * The extent is `Math.round`ed and clamped to `>= 0`; non-finite measurements\n * drop the frame.\n *\n * FOOTGUN \u2014 `target` must be shrink-to-fit on the owned axis: its owned-axis\n * size must NOT be driven by the host-applied view size, or the cross-process\n * loop (advertise \u2192 host resizes view \u2192 remeasure) never converges (it\n * oscillates or stays \"stable but wrong\"). Measuring `<body>`/`<html>` is the\n * classic mistake \u2014 their size *is* the view size. See\n * `docs/bidirectional-design.md`'s single-axis-ownership and trust-boundary\n * sections.\n */\nexport function createSizeAdvertiser(\n target: HTMLElement,\n opts: SizeAdvertiserOptions,\n): SizeAdvertiserHandle {\n const axis = opts.axis // immutable for the advertiser's life\n let publish = opts.publish\n let observer: ResizeObserver | null = null\n let disposed = false\n // Latest border-box, stashed by the RO callback and read by `produce` in the\n // RAF body (keep the entry out of the shared, DOM-agnostic loop).\n let latest: ResizeObserverSize | null = null\n\n const produce = (): AdvertisedSize | null => {\n if (!latest) return null\n const raw = axis === 'block' ? latest.blockSize : latest.inlineSize\n if (!Number.isFinite(raw)) return null\n return { axis, extent: Math.max(0, Math.round(raw)) }\n }\n\n const loop = createMeasureLoop<AdvertisedSize>({\n produce,\n same: (a, b) => a.extent === b.extent, // axis is constant\n sink: (size) => publish(size),\n })\n\n const onResize: ResizeObserverCallback = (entries) => {\n const entry = entries[entries.length - 1]\n if (entry) {\n latest = entry.borderBoxSize?.[0] ?? entry.contentBoxSize?.[0] ?? latest\n }\n loop.schedule()\n }\n\n // One cheap, once-per-advertiser guard for the textbook feedback-loop footgun.\n const doc = target.ownerDocument\n if (target === doc.body || target === doc.documentElement) {\n console.warn(\n `[view-anchor] size-advertiser: <${target === doc.body ? 'body' : 'html'}>'s ` +\n `${axis} size is the host-given view size, not the content size \u2014 the ` +\n `advertiser will never shrink to content. Measure a shrink-to-fit wrapper. ` +\n `See bidirectional-design.md's single-axis-ownership section.`,\n )\n }\n\n loop.setActive(true)\n observer = new ResizeObserver(onResize)\n observer.observe(target)\n\n return {\n update(nextPublish: (size: AdvertisedSize) => void): void {\n if (disposed) return\n publish = nextPublish\n // Re-advertise the current size to the new sink immediately (mirrors the\n // forward anchor's re-publish on update) so the new channel is not left\n // sizeless until the next ResizeObserver tick.\n const cur = produce()\n if (cur) loop.emitNow(cur)\n },\n dispose(): void {\n if (disposed) return\n disposed = true\n loop.cancel()\n if (observer) {\n observer.disconnect()\n observer = null\n }\n loop.dispose()\n },\n }\n}\n", "/**\n * IPC channel name constants for dimina-devtools' overlay/panel\n * WebContentsViews \u2014 layout slots (host-toolbar/host-sidebar/host-dialog),\n * the popover, tooltip, project-create dialog and settings overlays, plus\n * the update flow. Split out of `ipc-channels.ts` (see that file's header)\n * once this group alone pushed it past the repo's file-length threshold \u2014\n * these constants share no runtime dependency on the rest of that file, so\n * the split is a pure line-count relief valve, not a behavior change.\n */\n\n// \u2500\u2500 Embedded views (renderer \u2192 main) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n//\n// The main window's React layout owns the *positions* of the editor +\n// simulator-DevTools WebContentsView overlays \u2014 each visible placeholder\n// `<div>` measures its client rect via ResizeObserver and pushes the\n// rectangle to the main process. The view manager caches the latest\n// payload per kind and applies it to the overlay; no payload means the\n// overlay is hidden.\n//\n// Payload (after schema validation): `{ x, y, width, height }` in CSS\n// pixels relative to the window's content area (origin = top-left,\n// not including the OS chrome).\nexport const ViewChannel = {\n /**\n * Reverse size-advertiser: the host-toolbar WCV's OWN renderer advertises its\n * intrinsic content height so main reserves exactly that much. Payload\n * `{ axis: 'block', extent }`. fire-and-forget (send), NOT invoke.\n */\n HostToolbarAdvertiseHeight: 'view:host-toolbar:advertise-height',\n /**\n * main \u2192 host-toolbar WCV renderer: per-load MessagePort handshake for the\n * gated narrow channel. On every toolbar `did-finish-load` main creates a\n * `MessageChannelMain` and transfers port2 here\n * (`wc.postMessage(HostToolbarPort, null, [port2])`); the session-resident\n * toolbar runtime preload receives it via `event.ports[0]` and bridges it to\n * the page as `window.diminaHostToolbar`. Envelope both directions:\n * `{ channel: string, payload: unknown }`.\n */\n HostToolbarPort: 'view:host-toolbar:port',\n /**\n * main \u2192 main-window renderer: push the reserved host-toolbar height so the\n * renderer placeholder div resizes (closing the dynamic-height loop).\n */\n HostToolbarHeightChanged: 'view:host-toolbar:height-changed',\n /**\n * main \u2190 main-window renderer (invoke): pull the last NOTIFIED toolbar\n * height retained in main. Mount-time replay companion to\n * `HostToolbarHeightChanged`: the push listener mounts with the project\n * view and the toolbar's size-advertiser deduplicates (never re-reports),\n * so a height pushed while no project view was mounted would otherwise be\n * lost forever (cold start on the project list races it; close-project \u2192\n * reopen hits it deterministically). No payload; resolves a number.\n */\n HostToolbarGetHeight: 'view:host-toolbar:get-height',\n /**\n * Reverse size-advertiser for the host-sidebar WCV, mirroring\n * `HostToolbarAdvertiseHeight` on the inline (width) axis instead of block.\n * Payload `{ axis: 'inline', extent }`. fire-and-forget (send), NOT invoke.\n */\n HostSidebarAdvertiseWidth: 'view:host-sidebar:advertise-width',\n /**\n * main \u2192 host-sidebar WCV renderer: per-load MessagePort handshake, same\n * contract as `HostToolbarPort` (see that entry).\n */\n HostSidebarPort: 'view:host-sidebar:port',\n /**\n * main \u2192 main-window renderer: push the reserved host-sidebar width so the\n * renderer placeholder div resizes, mirroring `HostToolbarHeightChanged`.\n */\n HostSidebarWidthChanged: 'view:host-sidebar:width-changed',\n /**\n * main \u2190 main-window renderer (invoke): pull the last NOTIFIED sidebar\n * width, mirroring `HostToolbarGetHeight`'s mount-time replay role.\n */\n HostSidebarGetWidth: 'view:host-sidebar:get-width',\n /**\n * main \u2192 main-window renderer: push the project category (`Project.type`)\n * selected in the host-sidebar's content \u2014 devtools' own default icon rail,\n * or any downstream replacement that sends on the same channel. No\n * pull/replay companion like `HostSidebarGetWidth`: the default category is\n * a stable initial value regardless of load-order, and nothing is ever sent\n * before the main-window renderer (and thus `ProjectListScreen`) is already\n * mounted.\n */\n HostSidebarCategorySelected: 'view:host-sidebar:category-selected',\n /**\n * Reverse size-advertiser for the host-dialog WCV. Unlike the toolbar/sidebar\n * (single-axis, `setBaseDesired`-placed strips), the dialog is a BOTH-AXES\n * overlay positioned by `setOverlayDesired` \u2014 main centers it in the main\n * window once it knows both dimensions. One channel carries either axis'\n * report (`{ axis: 'block' | 'inline', extent }`); the dialog's own content\n * advertises both from the same root (see `host-dialog-advertiser.ts`).\n * fire-and-forget (send), NOT invoke.\n *\n * No `HostDialogSizeChanged` / `HostDialogGetSize` counterparts: those exist\n * for toolbar/sidebar so a renderer-owned PLACEHOLDER can replay a size it\n * missed. The dialog has no such placeholder \u2014 it is a main-driven overlay\n * shown/hidden on demand (`hostDialog.show()`/`hide()`), so there is nothing\n * in the renderer to replay a size into.\n */\n HostDialogAdvertiseSize: 'view:host-dialog:advertise-size',\n /**\n * main \u2192 host-dialog WCV renderer: per-load MessagePort handshake, same\n * contract as `HostToolbarPort` (see that entry).\n */\n HostDialogPort: 'view:host-dialog:port',\n /**\n * Renderer \u2192 main: the window-level placement snapshot (one monotonic epoch\n * per commit tick, one generation per renderer lifetime) that drives the view\n * reconciler. The single source of truth for every managed native view's\n * bounds/visibility/z-order \u2014 supersedes the per-view bounds channels above.\n * invoke.\n */\n PlacementSnapshot: 'view:placement-snapshot',\n /**\n * main \u2190 main-window renderer (invoke): allocate a fresh placement\n * generation seed for this renderer bootstrap. See\n * renderer-placement-generation.ts for why the seed comes from main\n * (a wall-clock `Date.now()` seed is not guaranteed to exceed main's\n * still-standing high-water mark across two reloads that happen faster\n * than the clock's resolution). No payload; resolves a number.\n */\n AllocatePlacementGeneration: 'view:allocate-placement-generation',\n} as const\n\nexport interface ViewBounds {\n x: number\n y: number\n width: number\n height: number\n}\n\n// \u2500\u2500 Popover \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const PopoverChannel = {\n Show: 'popover:show',\n Hide: 'popover:hide',\n Relaunch: 'popover:relaunch',\n Closed: 'popover:closed',\n Init: 'popover:init',\n} as const\n\n// \u2500\u2500 Tooltip \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n//\n// A top-tier overlay WebContentsView (VIEW_LAYER.tooltip \u2014 see view-ids.ts),\n// NOT a DOM tooltip in the main renderer: any DOM-portaled floating UI (Radix\n// Tooltip) or the browser-native `title` attribute lives in the main\n// renderer's own paint surface, which every other WCV (simulator, editor,\n// settings, popover) renders on top of \u2014 CSS cannot reach across that\n// boundary. A trigger reports its anchor rect + label; main computes the\n// tooltip's screen bounds and shows/repositions/hides this overlay.\n\nexport const OverlayChannel = {\n Ready: 'overlay:ready',\n} as const\n\nexport const TooltipChannel = {\n Prepare: 'tooltip:prepare',\n Show: 'tooltip:show',\n Hide: 'tooltip:hide',\n Init: 'tooltip:init',\n Measured: 'tooltip:measured',\n} as const\n\n// \u2500\u2500 Project-create dialog \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n//\n// A top-tier overlay WebContentsView (VIEW_LAYER.dialog), NOT the Radix\n// `fixed inset-0` DOM portal it replaced \u2014 a DOM overlay paints inside the\n// main window's own renderer, so any native WebContentsView mounted on top\n// (simulator, host-toolbar, host-sidebar) occludes it. main.tsx fetches the\n// template catalog + base-dir defaults, then asks main to show this panel;\n// the panel relays submit/cancel back to main.tsx to run the existing\n// scaffold flow.\n\nexport const ProjectCreateChannel = {\n Show: 'projectCreate:show',\n Init: 'projectCreate:init',\n Submit: 'projectCreate:submit',\n Cancel: 'projectCreate:cancel',\n Submitted: 'projectCreate:submitted',\n} as const\n\n// \u2500\u2500 Embedded settings overlay \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const SettingsChannel = {\n SetVisible: 'settings:setVisible',\n ConfigChanged: 'settings:configChanged',\n ProjectSettingsChanged: 'settings:projectSettingsChanged',\n Init: 'settings:init',\n} as const\n\n// \u2500\u2500 Updates (UpdateManager) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n//\n// String values are FROZEN: shipped builds key off them. Add new entries\n// here, never rename existing ones.\nexport const UpdateChannel = {\n Check: 'updates:check',\n Download: 'updates:download',\n Install: 'updates:install',\n DownloadProgress: 'updates:downloadProgress',\n Available: 'updates:available',\n Close: 'updates:close',\n} as const\n", "/**\n * Shared readiness wait for a host-slot content's shrink-to-fit measurement\n * root (`[data-host-*-root]`). A one-shot `document.querySelector` at\n * `DOMContentLoaded` time only works when the root is present in the initial\n * HTML. Framework-rendered content (e.g. a React app) can mount its root\n * asynchronously, after `DOMContentLoaded` has already fired \u2014 a one-shot\n * check misses it permanently and the slot's width/height is never\n * advertised. This keeps watching via `MutationObserver` instead of assuming\n * a synchronous mount, without polling on a fixed delay.\n *\n * The \"root is missing\" warning exists for downstream authors who forgot the\n * element entirely, so it must not fire on the healthy async-mount path \u2014 a\n * warning printed on every normal load is noise that trains its readers to\n * ignore it. It is therefore withheld until the document has finished loading\n * (`window.load`, a real event rather than a guessed delay) with the root\n * still absent; the observer stays armed either way, so a root that mounts\n * even later is still picked up.\n */\nexport function whenSlotRootReady(\n selector: string,\n missingWarning: string,\n install: (root: HTMLElement) => void,\n): void {\n function attempt(): void {\n const root = document.querySelector<HTMLElement>(selector)\n if (root) {\n install(root)\n return\n }\n\n let installed = false\n const observer = new MutationObserver(() => {\n const lateRoot = document.querySelector<HTMLElement>(selector)\n if (!lateRoot) return\n observer.disconnect()\n installed = true\n install(lateRoot)\n })\n observer.observe(document.documentElement, { childList: true, subtree: true })\n\n const warnIfStillMissing = (): void => {\n if (!installed) console.warn(missingWarning)\n }\n if (document.readyState === 'complete') warnIfStillMissing()\n else window.addEventListener('load', warnIfStillMissing, { once: true })\n }\n\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', attempt, { once: true })\n } else {\n attempt()\n }\n}\n", "/**\n * Shared implementation behind every host-slot page bridge (toolbar/sidebar/\n * dialog): the MessagePort handshake, pending-queue-with-bounded-overflow,\n * handler registry and `{ send, onMessage }` contextBridge exposure are\n * IDENTICAL across slots \u2014 only the bridge key, handshake channel, queue cap\n * and overflow-warning label differ. Each slot's own `host-*-port.ts` stays\n * the frozen public surface (see its own \"PUBLIC SURFACE EVOLUTION RULE\"\n * doc-comment) and calls this factory with its own constants; this module has\n * no public-surface contract of its own.\n */\nimport { contextBridge, ipcRenderer } from 'electron'\n\nexport interface HostSlotPortBridgeOptions {\n /** contextBridge key the page-facing API is exposed under, e.g. 'diminaHostToolbar'. */\n bridgeKey: string\n /** main \u2192 renderer per-load handshake channel, e.g. ViewChannel.HostToolbarPort. */\n channel: string\n /** Cap on pre-handshake queued sends; overflow drops the NEWEST envelope. */\n pendingLimit: number\n /** Slot label used in the overflow console.warn, e.g. 'host-toolbar'. */\n label: string\n}\n\n/**\n * Subscribe the handshake channel and expose the page bridge. Call ONLY from\n * a passing per-slot runtime guard \u2014 a failing guard must leave zero\n * footprint (no bridge key, no IPC listener), so this factory itself does no\n * guard checking; the caller decides whether to call it at all.\n */\nexport function createHostSlotPortBridge(opts: HostSlotPortBridgeOptions): void {\n const { bridgeKey, channel, pendingLimit, label } = opts\n let activePort: MessagePort | null = null\n const pending: Array<{ channel: string; payload: unknown }> = []\n // One overflow warning per load (this installer runs once per document) \u2014\n // a runaway page send-loop must not get per-drop console spam.\n let warnedPendingOverflow = false\n const handlers: Array<{ channel: string; handler: (payload: unknown) => void }> = []\n\n // Entry-waist channel validation, parity with the main side's `onMessage`\n // guard (same TypeError, message names `channel`). Runs BEFORE any state is\n // touched (no queue slot, no registry entry), in both port states \u2014 a page\n // author's typo throws at the call site instead of vanishing into main's\n // silent inbound drop.\n function assertValidChannel(method: string, ch: unknown): asserts ch is string {\n if (typeof ch !== 'string' || ch === '') {\n throw new TypeError(`${bridgeKey}.${method}: channel must be a non-empty string`)\n }\n }\n\n const dispatch = (data: unknown): void => {\n // Defensive symmetry with main: drop anything that is not an object\n // envelope with a string channel \u2014 never throw in the dispatcher.\n if (typeof data !== 'object' || data === null) return\n const { channel: ch, payload } = data as { channel?: unknown; payload?: unknown }\n if (typeof ch !== 'string') return\n for (const entry of [...handlers]) {\n if (entry.channel === ch) entry.handler(payload)\n }\n }\n\n const onPortMessage = (event: MessageEvent): void => {\n dispatch(event.data)\n }\n\n ipcRenderer.on(channel, (event) => {\n const port = event.ports[0]\n if (!port) return\n // Same-load duplicate handshake: the LATER port wins. Main closed (or is\n // about to close) its end of the old pair \u2014 detach and stop writing to it.\n if (activePort) {\n try {\n activePort.removeEventListener('message', onPortMessage)\n activePort.close()\n } catch {\n /* already dead */\n }\n }\n activePort = port\n // addEventListener (not onmessage) keeps the handler removable on\n // re-handshake; it REQUIRES start() or inbound never delivers.\n port.addEventListener('message', onPortMessage)\n port.start()\n // Flush sends issued before the port arrived, in order.\n while (pending.length > 0) {\n const envelope = pending.shift()!\n port.postMessage(envelope)\n }\n })\n\n // EXACTLY { send, onMessage } \u2014 functions only; the port stays in the\n // isolated world.\n contextBridge.exposeInMainWorld(bridgeKey, {\n send(ch: string, payload: unknown): void {\n assertValidChannel('send', ch)\n const envelope = { channel: ch, payload }\n if (activePort) {\n activePort.postMessage(envelope)\n return\n }\n // Bounded queue: drop the NEWEST send on overflow (FIFO first-comers\n // survive), warn once per load, never throw into page code.\n if (pending.length >= pendingLimit) {\n if (!warnedPendingOverflow) {\n warnedPendingOverflow = true\n console.warn(\n `[dimina-devtools] ${label} pending queue full (${pendingLimit}); ` +\n 'dropping further pre-handshake send() calls until the port arrives',\n )\n }\n return\n }\n pending.push(envelope)\n },\n onMessage(ch: string, handler: (payload: unknown) => void): () => void {\n assertValidChannel('onMessage', ch)\n const entry = { channel: ch, handler }\n handlers.push(entry)\n return () => {\n const i = handlers.indexOf(entry)\n if (i >= 0) handlers.splice(i, 1)\n }\n },\n })\n}\n", "/**\n * Preload side of the host-dialog gated narrow channel.\n *\n * \u2500\u2500 PUBLIC SURFACE EVOLUTION RULE \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n * `window.diminaHostDialog` is a published page-facing API, typed by the\n * exported `DiminaHostDialogPageBridge` (src/main/runtime/miniapp-runtime.ts)\n * \u2014 arbitrary host dialog pages compile against it. Members may only be\n * ADDED, never changed: any semantic change to an existing member (signature,\n * return shape, queueing/throw behavior) ships under a NEW name instead.\n * Exception: security fixes / compliance corrections may change existing\n * member semantics, and MUST be called out in the release's version notes.\n * Keep the exported bridge type in lockstep with what is exposed here.\n *\n * Receives the per-load MessagePort main transfers on `did-finish-load`\n * (`ViewChannel.HostDialogPort`, `event.ports[0]`) and bridges it to the page\n * as `window.diminaHostDialog` \u2014 EXACTLY `{ send, onMessage }`, functions\n * only. The raw MessagePort never crosses into the main world: the page only\n * ever talks through these two functions, so the `{ channel, payload }`\n * envelope stays the single waist (same posture as the main side's\n * host-dialog-port-channel.ts).\n *\n * Ordering reality this module absorbs \u2014 identical to the toolbar's port\n * bridge (see host-toolbar-port.ts for the full rationale): pre-handshake\n * sends queue and bounded-drop, handlers register before the port exists and\n * re-attach across same-load re-handshakes, inbound dispatch drops malformed\n * envelopes without throwing.\n *\n * Shared implementation: see `host-slot-port-bridge.ts` (the toolbar/sidebar/\n * dialog port bridges are otherwise identical; only the constants below\n * differ).\n */\n\nimport { ViewChannel } from '../../shared/ipc-channels-overlays.js'\nimport { createHostSlotPortBridge } from './host-slot-port-bridge.js'\n\n/**\n * Cap on pre-handshake queued sends. Same rationale and value as\n * `HOST_TOOLBAR_PENDING_LIMIT` \u2014 overflow drops the NEWEST envelope, one\n * console.warn per load.\n */\nexport const HOST_DIALOG_PENDING_LIMIT = 128\n\n/**\n * Subscribe the handshake channel and expose the page bridge. Call ONLY from\n * a passing dialog-runtime guard (`activateHostDialogRuntime`) \u2014 a failing\n * guard must leave zero footprint (no bridge key, no IPC listener).\n */\nexport function installHostDialogPortBridge(): void {\n createHostSlotPortBridge({\n bridgeKey: 'diminaHostDialog',\n channel: ViewChannel.HostDialogPort,\n pendingLimit: HOST_DIALOG_PENDING_LIMIT,\n label: 'host-dialog',\n })\n}\n", "/**\n * Session-resident host-dialog framework runtime: GUARD + ACTIVATION.\n *\n * Same registration and guard shape as host-toolbar-runtime.ts (see that\n * module for the full rationale): registered once per process on\n * `session.defaultSession`, so it runs in EVERY defaultSession renderer;\n * this guard keeps it inert everywhere except the host-dialog WCV's main\n * frame, identified by `HOST_DIALOG_RUNTIME_MARKER` in that process' argv.\n */\n\nimport { HOST_DIALOG_RUNTIME_MARKER } from '../../shared/constants.js'\nimport { installHostDialogAdvertiserWhenReady } from './host-dialog-advertiser.js'\nimport { installHostDialogPortBridge } from './host-dialog-port.js'\n\n/**\n * Pure guard predicate: should the dialog runtime activate in a renderer with\n * this `argv` / `isMainFrame`? True only for the MAIN frame of a process whose\n * argv carries the `'--dimina-host-dialog'` marker.\n */\nexport function shouldActivateHostDialogRuntime(\n argv: readonly string[],\n isMainFrame: boolean,\n): boolean {\n return isMainFrame && argv.includes(HOST_DIALOG_RUNTIME_MARKER)\n}\n\n/**\n * Run the guard; only when it passes, install the dual-axis size advertiser\n * (`installHostDialogAdvertiserWhenReady`) and the narrow-channel page\n * bridge (`installHostDialogPortBridge` \u2014 `window.diminaHostDialog` +\n * the MessagePort handshake listener). Returns whether the runtime\n * activated. A failed guard installs NOTHING (zero footprint in non-dialog\n * windows and subframes: no advertiser, no bridge key, no IPC listener).\n */\nexport function activateHostDialogRuntime(env: {\n argv: readonly string[]\n isMainFrame: boolean\n}): boolean {\n if (!shouldActivateHostDialogRuntime(env.argv, env.isMainFrame)) return false\n installHostDialogAdvertiserWhenReady()\n installHostDialogPortBridge()\n return true\n}\n", "// Session-registered dialog-runtime preload entry.\n//\n// Bundled into a single CJS file (dist/preload/windows/host-dialog-runtime.cjs)\n// via build:preload and registered ONCE per process on `session.defaultSession`\n// (`registerPreloadScript({ type: 'frame', \u2026 })` \u2014 see\n// `src/main/services/views/host-dialog-session-runtime.ts`). It therefore runs\n// in EVERY defaultSession renderer; `activateHostDialogRuntime`'s guard\n// (`process.isMainFrame && process.argv.includes('--dimina-host-dialog')`)\n// makes it a zero-footprint no-op everywhere except the host-dialog WCV's\n// main frame, where it installs the reverse dual-axis size-advertiser.\nimport { activateHostDialogRuntime } from '../runtime/host-dialog-runtime.js'\n\nactivateHostDialogRuntime({ argv: process.argv, isMainFrame: process.isMainFrame })\n"],
5
+ "mappings": "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",
6
+ "names": ["import_electron"]
7
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=host-dialog-runtime.d.ts.map
@@ -0,0 +1,13 @@
1
+ // Session-registered dialog-runtime preload entry.
2
+ //
3
+ // Bundled into a single CJS file (dist/preload/windows/host-dialog-runtime.cjs)
4
+ // via build:preload and registered ONCE per process on `session.defaultSession`
5
+ // (`registerPreloadScript({ type: 'frame', … })` — see
6
+ // `src/main/services/views/host-dialog-session-runtime.ts`). It therefore runs
7
+ // in EVERY defaultSession renderer; `activateHostDialogRuntime`'s guard
8
+ // (`process.isMainFrame && process.argv.includes('--dimina-host-dialog')`)
9
+ // makes it a zero-footprint no-op everywhere except the host-dialog WCV's
10
+ // main frame, where it installs the reverse dual-axis size-advertiser.
11
+ import { activateHostDialogRuntime } from '../runtime/host-dialog-runtime.js';
12
+ activateHostDialogRuntime({ argv: process.argv, isMainFrame: process.isMainFrame });
13
+ //# sourceMappingURL=host-dialog-runtime.js.map
@@ -0,0 +1,354 @@
1
+ "use strict";
2
+
3
+ // src/shared/constants.ts
4
+ var HOST_SIDEBAR_RUNTIME_MARKER = "--dimina-host-sidebar";
5
+
6
+ // src/preload/runtime/host-sidebar-advertiser.ts
7
+ var import_electron = require("electron");
8
+
9
+ // ../view-anchor/src/measure-loop.ts
10
+ function createMeasureLoop(cfg) {
11
+ const { produce, same, sink } = cfg;
12
+ let rafId = null;
13
+ let active = false;
14
+ let disposed = false;
15
+ let last = null;
16
+ const cancel = () => {
17
+ if (rafId !== null) {
18
+ cancelAnimationFrame(rafId);
19
+ rafId = null;
20
+ }
21
+ };
22
+ return {
23
+ schedule() {
24
+ if (disposed || !active || rafId !== null) return;
25
+ rafId = requestAnimationFrame(() => {
26
+ rafId = null;
27
+ if (disposed || !active) return;
28
+ const value = produce();
29
+ if (value === null) return;
30
+ if (last !== null && same(value, last)) return;
31
+ last = value;
32
+ sink(value);
33
+ });
34
+ },
35
+ emitNow(value) {
36
+ if (disposed) return;
37
+ last = value;
38
+ sink(value);
39
+ },
40
+ setActive(on) {
41
+ active = on;
42
+ },
43
+ cancel,
44
+ dispose() {
45
+ if (disposed) return;
46
+ disposed = true;
47
+ cancel();
48
+ }
49
+ };
50
+ }
51
+
52
+ // ../view-anchor/src/size-advertiser.ts
53
+ function createSizeAdvertiser(target, opts) {
54
+ const axis = opts.axis;
55
+ let publish = opts.publish;
56
+ let observer = null;
57
+ let disposed = false;
58
+ let latest = null;
59
+ const produce = () => {
60
+ if (!latest) return null;
61
+ const raw = axis === "block" ? latest.blockSize : latest.inlineSize;
62
+ if (!Number.isFinite(raw)) return null;
63
+ return { axis, extent: Math.max(0, Math.round(raw)) };
64
+ };
65
+ const loop = createMeasureLoop({
66
+ produce,
67
+ same: (a, b) => a.extent === b.extent,
68
+ // axis is constant
69
+ sink: (size) => publish(size)
70
+ });
71
+ const onResize = (entries) => {
72
+ const entry = entries[entries.length - 1];
73
+ if (entry) {
74
+ latest = entry.borderBoxSize?.[0] ?? entry.contentBoxSize?.[0] ?? latest;
75
+ }
76
+ loop.schedule();
77
+ };
78
+ const doc = target.ownerDocument;
79
+ if (target === doc.body || target === doc.documentElement) {
80
+ console.warn(
81
+ `[view-anchor] size-advertiser: <${target === doc.body ? "body" : "html"}>'s ${axis} size is the host-given view size, not the content size \u2014 the advertiser will never shrink to content. Measure a shrink-to-fit wrapper. See bidirectional-design.md's single-axis-ownership section.`
82
+ );
83
+ }
84
+ loop.setActive(true);
85
+ observer = new ResizeObserver(onResize);
86
+ observer.observe(target);
87
+ return {
88
+ update(nextPublish) {
89
+ if (disposed) return;
90
+ publish = nextPublish;
91
+ const cur = produce();
92
+ if (cur) loop.emitNow(cur);
93
+ },
94
+ dispose() {
95
+ if (disposed) return;
96
+ disposed = true;
97
+ loop.cancel();
98
+ if (observer) {
99
+ observer.disconnect();
100
+ observer = null;
101
+ }
102
+ loop.dispose();
103
+ }
104
+ };
105
+ }
106
+
107
+ // src/shared/ipc-channels-overlays.ts
108
+ var ViewChannel = {
109
+ /**
110
+ * Reverse size-advertiser: the host-toolbar WCV's OWN renderer advertises its
111
+ * intrinsic content height so main reserves exactly that much. Payload
112
+ * `{ axis: 'block', extent }`. fire-and-forget (send), NOT invoke.
113
+ */
114
+ HostToolbarAdvertiseHeight: "view:host-toolbar:advertise-height",
115
+ /**
116
+ * main → host-toolbar WCV renderer: per-load MessagePort handshake for the
117
+ * gated narrow channel. On every toolbar `did-finish-load` main creates a
118
+ * `MessageChannelMain` and transfers port2 here
119
+ * (`wc.postMessage(HostToolbarPort, null, [port2])`); the session-resident
120
+ * toolbar runtime preload receives it via `event.ports[0]` and bridges it to
121
+ * the page as `window.diminaHostToolbar`. Envelope both directions:
122
+ * `{ channel: string, payload: unknown }`.
123
+ */
124
+ HostToolbarPort: "view:host-toolbar:port",
125
+ /**
126
+ * main → main-window renderer: push the reserved host-toolbar height so the
127
+ * renderer placeholder div resizes (closing the dynamic-height loop).
128
+ */
129
+ HostToolbarHeightChanged: "view:host-toolbar:height-changed",
130
+ /**
131
+ * main ← main-window renderer (invoke): pull the last NOTIFIED toolbar
132
+ * height retained in main. Mount-time replay companion to
133
+ * `HostToolbarHeightChanged`: the push listener mounts with the project
134
+ * view and the toolbar's size-advertiser deduplicates (never re-reports),
135
+ * so a height pushed while no project view was mounted would otherwise be
136
+ * lost forever (cold start on the project list races it; close-project →
137
+ * reopen hits it deterministically). No payload; resolves a number.
138
+ */
139
+ HostToolbarGetHeight: "view:host-toolbar:get-height",
140
+ /**
141
+ * Reverse size-advertiser for the host-sidebar WCV, mirroring
142
+ * `HostToolbarAdvertiseHeight` on the inline (width) axis instead of block.
143
+ * Payload `{ axis: 'inline', extent }`. fire-and-forget (send), NOT invoke.
144
+ */
145
+ HostSidebarAdvertiseWidth: "view:host-sidebar:advertise-width",
146
+ /**
147
+ * main → host-sidebar WCV renderer: per-load MessagePort handshake, same
148
+ * contract as `HostToolbarPort` (see that entry).
149
+ */
150
+ HostSidebarPort: "view:host-sidebar:port",
151
+ /**
152
+ * main → main-window renderer: push the reserved host-sidebar width so the
153
+ * renderer placeholder div resizes, mirroring `HostToolbarHeightChanged`.
154
+ */
155
+ HostSidebarWidthChanged: "view:host-sidebar:width-changed",
156
+ /**
157
+ * main ← main-window renderer (invoke): pull the last NOTIFIED sidebar
158
+ * width, mirroring `HostToolbarGetHeight`'s mount-time replay role.
159
+ */
160
+ HostSidebarGetWidth: "view:host-sidebar:get-width",
161
+ /**
162
+ * main → main-window renderer: push the project category (`Project.type`)
163
+ * selected in the host-sidebar's content — devtools' own default icon rail,
164
+ * or any downstream replacement that sends on the same channel. No
165
+ * pull/replay companion like `HostSidebarGetWidth`: the default category is
166
+ * a stable initial value regardless of load-order, and nothing is ever sent
167
+ * before the main-window renderer (and thus `ProjectListScreen`) is already
168
+ * mounted.
169
+ */
170
+ HostSidebarCategorySelected: "view:host-sidebar:category-selected",
171
+ /**
172
+ * Reverse size-advertiser for the host-dialog WCV. Unlike the toolbar/sidebar
173
+ * (single-axis, `setBaseDesired`-placed strips), the dialog is a BOTH-AXES
174
+ * overlay positioned by `setOverlayDesired` — main centers it in the main
175
+ * window once it knows both dimensions. One channel carries either axis'
176
+ * report (`{ axis: 'block' | 'inline', extent }`); the dialog's own content
177
+ * advertises both from the same root (see `host-dialog-advertiser.ts`).
178
+ * fire-and-forget (send), NOT invoke.
179
+ *
180
+ * No `HostDialogSizeChanged` / `HostDialogGetSize` counterparts: those exist
181
+ * for toolbar/sidebar so a renderer-owned PLACEHOLDER can replay a size it
182
+ * missed. The dialog has no such placeholder — it is a main-driven overlay
183
+ * shown/hidden on demand (`hostDialog.show()`/`hide()`), so there is nothing
184
+ * in the renderer to replay a size into.
185
+ */
186
+ HostDialogAdvertiseSize: "view:host-dialog:advertise-size",
187
+ /**
188
+ * main → host-dialog WCV renderer: per-load MessagePort handshake, same
189
+ * contract as `HostToolbarPort` (see that entry).
190
+ */
191
+ HostDialogPort: "view:host-dialog:port",
192
+ /**
193
+ * Renderer → main: the window-level placement snapshot (one monotonic epoch
194
+ * per commit tick, one generation per renderer lifetime) that drives the view
195
+ * reconciler. The single source of truth for every managed native view's
196
+ * bounds/visibility/z-order — supersedes the per-view bounds channels above.
197
+ * invoke.
198
+ */
199
+ PlacementSnapshot: "view:placement-snapshot",
200
+ /**
201
+ * main ← main-window renderer (invoke): allocate a fresh placement
202
+ * generation seed for this renderer bootstrap. See
203
+ * renderer-placement-generation.ts for why the seed comes from main
204
+ * (a wall-clock `Date.now()` seed is not guaranteed to exceed main's
205
+ * still-standing high-water mark across two reloads that happen faster
206
+ * than the clock's resolution). No payload; resolves a number.
207
+ */
208
+ AllocatePlacementGeneration: "view:allocate-placement-generation"
209
+ };
210
+
211
+ // src/preload/runtime/wait-for-slot-root.ts
212
+ function whenSlotRootReady(selector, missingWarning, install) {
213
+ function attempt() {
214
+ const root = document.querySelector(selector);
215
+ if (root) {
216
+ install(root);
217
+ return;
218
+ }
219
+ let installed = false;
220
+ const observer = new MutationObserver(() => {
221
+ const lateRoot = document.querySelector(selector);
222
+ if (!lateRoot) return;
223
+ observer.disconnect();
224
+ installed = true;
225
+ install(lateRoot);
226
+ });
227
+ observer.observe(document.documentElement, { childList: true, subtree: true });
228
+ const warnIfStillMissing = () => {
229
+ if (!installed) console.warn(missingWarning);
230
+ };
231
+ if (document.readyState === "complete") warnIfStillMissing();
232
+ else window.addEventListener("load", warnIfStillMissing, { once: true });
233
+ }
234
+ if (document.readyState === "loading") {
235
+ document.addEventListener("DOMContentLoaded", attempt, { once: true });
236
+ } else {
237
+ attempt();
238
+ }
239
+ }
240
+
241
+ // src/preload/runtime/host-sidebar-advertiser.ts
242
+ function installHostSidebarAdvertiserWhenReady() {
243
+ whenSlotRootReady(
244
+ "[data-host-sidebar-root]",
245
+ "[host-sidebar-advertiser] no `[data-host-sidebar-root]` element found \u2014 not advertising a width yet. The sidebar content must wrap itself in a shrink-to-fit `[data-host-sidebar-root]` element so its inline size is the content width, not the host-given view size.",
246
+ (root) => {
247
+ createSizeAdvertiser(root, {
248
+ axis: "inline",
249
+ publish: (size) => {
250
+ import_electron.ipcRenderer.send(ViewChannel.HostSidebarAdvertiseWidth, size);
251
+ }
252
+ });
253
+ }
254
+ );
255
+ }
256
+
257
+ // src/preload/runtime/host-slot-port-bridge.ts
258
+ var import_electron2 = require("electron");
259
+ function createHostSlotPortBridge(opts) {
260
+ const { bridgeKey, channel, pendingLimit, label } = opts;
261
+ let activePort = null;
262
+ const pending = [];
263
+ let warnedPendingOverflow = false;
264
+ const handlers = [];
265
+ function assertValidChannel(method, ch) {
266
+ if (typeof ch !== "string" || ch === "") {
267
+ throw new TypeError(`${bridgeKey}.${method}: channel must be a non-empty string`);
268
+ }
269
+ }
270
+ const dispatch = (data) => {
271
+ if (typeof data !== "object" || data === null) return;
272
+ const { channel: ch, payload } = data;
273
+ if (typeof ch !== "string") return;
274
+ for (const entry of [...handlers]) {
275
+ if (entry.channel === ch) entry.handler(payload);
276
+ }
277
+ };
278
+ const onPortMessage = (event) => {
279
+ dispatch(event.data);
280
+ };
281
+ import_electron2.ipcRenderer.on(channel, (event) => {
282
+ const port = event.ports[0];
283
+ if (!port) return;
284
+ if (activePort) {
285
+ try {
286
+ activePort.removeEventListener("message", onPortMessage);
287
+ activePort.close();
288
+ } catch {
289
+ }
290
+ }
291
+ activePort = port;
292
+ port.addEventListener("message", onPortMessage);
293
+ port.start();
294
+ while (pending.length > 0) {
295
+ const envelope = pending.shift();
296
+ port.postMessage(envelope);
297
+ }
298
+ });
299
+ import_electron2.contextBridge.exposeInMainWorld(bridgeKey, {
300
+ send(ch, payload) {
301
+ assertValidChannel("send", ch);
302
+ const envelope = { channel: ch, payload };
303
+ if (activePort) {
304
+ activePort.postMessage(envelope);
305
+ return;
306
+ }
307
+ if (pending.length >= pendingLimit) {
308
+ if (!warnedPendingOverflow) {
309
+ warnedPendingOverflow = true;
310
+ console.warn(
311
+ `[dimina-devtools] ${label} pending queue full (${pendingLimit}); dropping further pre-handshake send() calls until the port arrives`
312
+ );
313
+ }
314
+ return;
315
+ }
316
+ pending.push(envelope);
317
+ },
318
+ onMessage(ch, handler) {
319
+ assertValidChannel("onMessage", ch);
320
+ const entry = { channel: ch, handler };
321
+ handlers.push(entry);
322
+ return () => {
323
+ const i = handlers.indexOf(entry);
324
+ if (i >= 0) handlers.splice(i, 1);
325
+ };
326
+ }
327
+ });
328
+ }
329
+
330
+ // src/preload/runtime/host-sidebar-port.ts
331
+ var HOST_SIDEBAR_PENDING_LIMIT = 128;
332
+ function installHostSidebarPortBridge() {
333
+ createHostSlotPortBridge({
334
+ bridgeKey: "diminaHostSidebar",
335
+ channel: ViewChannel.HostSidebarPort,
336
+ pendingLimit: HOST_SIDEBAR_PENDING_LIMIT,
337
+ label: "host-sidebar"
338
+ });
339
+ }
340
+
341
+ // src/preload/runtime/host-sidebar-runtime.ts
342
+ function shouldActivateHostSidebarRuntime(argv, isMainFrame) {
343
+ return isMainFrame && argv.includes(HOST_SIDEBAR_RUNTIME_MARKER);
344
+ }
345
+ function activateHostSidebarRuntime(env) {
346
+ if (!shouldActivateHostSidebarRuntime(env.argv, env.isMainFrame)) return false;
347
+ installHostSidebarAdvertiserWhenReady();
348
+ installHostSidebarPortBridge();
349
+ return true;
350
+ }
351
+
352
+ // src/preload/windows/host-sidebar-runtime.ts
353
+ activateHostSidebarRuntime({ argv: process.argv, isMainFrame: process.isMainFrame });
354
+ //# sourceMappingURL=host-sidebar-runtime.cjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/shared/constants.ts", "../../../src/preload/runtime/host-sidebar-advertiser.ts", "../../../../view-anchor/src/measure-loop.ts", "../../../../view-anchor/src/size-advertiser.ts", "../../../src/shared/ipc-channels-overlays.ts", "../../../src/preload/runtime/wait-for-slot-root.ts", "../../../src/preload/runtime/host-slot-port-bridge.ts", "../../../src/preload/runtime/host-sidebar-port.ts", "../../../src/preload/runtime/host-sidebar-runtime.ts", "../../../src/preload/windows/host-sidebar-runtime.ts"],
4
+ "sourcesContent": ["/** Shared cross-process constants for dimina-devtools. */\n\n/** Default Chrome DevTools Protocol (CDP) remote debugging port. */\nexport const DEFAULT_CDP_PORT = 9222\n\n/** Default scene value for mini-app launch. */\nexport const DEFAULT_SCENE = 1001\n\n/**\n * Fixed devtools toolbar header height (px). Single source of truth shared by\n * the main process (overlay view layout) and the renderer (toolbar/popover\n * layout). Not host-configurable \u2014 the deprecated\n * `WorkbenchAppConfig.headerHeight` is ignored; hosts that need their own\n * toolbar use the host toolbar WCV instead.\n */\nexport const HEADER_H = 40\n\n/**\n * Process-level argv marker injected (via `webPreferences.additionalArguments`)\n * into the host-toolbar WebContentsView. The session-registered toolbar-runtime\n * preload (`src/preload/runtime/host-toolbar-runtime.ts`) executes in EVERY\n * defaultSession renderer; its guard activates the height advertiser only when\n * `process.argv` carries this marker AND `process.isMainFrame` is true (the\n * marker is process-level, so subframes of the toolbar window see it too \u2014\n * both guard wings are required).\n */\nexport const HOST_TOOLBAR_RUNTIME_MARKER = '--dimina-host-toolbar'\n\n/**\n * Same guard-marker contract as {@link HOST_TOOLBAR_RUNTIME_MARKER}, for the\n * host-sidebar WebContentsView (`src/preload/runtime/host-sidebar-runtime.ts`).\n */\nexport const HOST_SIDEBAR_RUNTIME_MARKER = '--dimina-host-sidebar'\n\n/**\n * Same guard-marker contract as {@link HOST_TOOLBAR_RUNTIME_MARKER}, for the\n * host-dialog WebContentsView (`src/preload/runtime/host-dialog-runtime.ts`).\n */\nexport const HOST_DIALOG_RUNTIME_MARKER = '--dimina-host-dialog'\n\n/**\n * Intrinsic width (px) of devtools' own default host-sidebar content (the\n * project-category icon rail). Single source of truth shared by the renderer\n * (`host-sidebar-default.tsx`, which gives its `[data-host-sidebar-root]` this\n * exact width so the width advertiser reports it) and anything in main that\n * needs to reason about the default rail's size. The slot is NOT left pinned\n * at this width: main pushes it once as a seed and immediately returns the\n * slot to 'auto' (see `createDevtoolsRuntime`), so the rail \u2014 and any\n * downstream `loadURL`/`loadFile` content that replaces it \u2014 advertises its\n * own width from then on, exactly like any other host-sidebar content.\n */\nexport const HOST_SIDEBAR_DEFAULT_WIDTH = 56\n", "/**\n * Reverse size-advertiser preload for the host-controllable sidebar\n * WebContentsView. Runs in that WCV's OWN renderer (the sidebar content's\n * preload), measures the sidebar's intrinsic inline (width) extent and sends it\n * to the main process. Main pushes the value back to the main-window renderer as\n * `HostSidebarWidthChanged`, which resizes the sidebar placeholder, re-measures\n * the forward anchor, and re-overlays this WCV \u2014 closing the dynamic-width loop\n * (see `@dimina-kit/view-anchor` `createSizeAdvertiser`).\n */\n\nimport { ipcRenderer } from 'electron'\nimport { createSizeAdvertiser } from '@dimina-kit/view-anchor'\nimport { ViewChannel } from '../../shared/ipc-channels-overlays.js'\nimport { whenSlotRootReady } from './wait-for-slot-root.js'\n\n/**\n * Attach the advertiser to the sidebar content's shrink-to-fit root\n * (`[data-host-sidebar-root]`), waiting for it if necessary \u2014 the root may be\n * mounted asynchronously by a framework (e.g. React) rather than present in\n * the initial HTML. That element MUST be shrink-to-fit on the inline axis \u2014\n * its width must reflect the content, not the host-applied view width, or the\n * cross-process loop never converges (`createSizeAdvertiser`'s footgun).\n */\nexport function installHostSidebarAdvertiserWhenReady(): void {\n whenSlotRootReady(\n '[data-host-sidebar-root]',\n '[host-sidebar-advertiser] no `[data-host-sidebar-root]` element found \u2014 ' +\n 'not advertising a width yet. The sidebar content must wrap itself in a ' +\n 'shrink-to-fit `[data-host-sidebar-root]` element so its inline size is ' +\n 'the content width, not the host-given view size.',\n (root) => {\n createSizeAdvertiser(root, {\n axis: 'inline',\n publish: (size) => {\n ipcRenderer.send(ViewChannel.HostSidebarAdvertiseWidth, size)\n },\n })\n },\n )\n}\n", "/**\n * Internal \u2014 the RAF-coalesced measure/dedupe/dispose engine behind the REVERSE\n * primitive `createSizeAdvertiser`.\n *\n * The forward `createViewAnchor` deliberately does NOT use this: it publishes\n * SYNCHRONOUSLY (a native overlay's `setBounds` already lands a cross-process\n * frame late, and a RAF stacked a second frame of visible trailing). The\n * reverse direction is different \u2014 it is a cross-process FEEDBACK loop\n * (advertise \u2192 host resizes the view \u2192 content re-measures \u2192 re-advertise), so\n * the RAF's one-publish-per-frame coalescing is a useful damper. The two\n * directions thus have different optimal emit timing; this engine serves only\n * the reverse.\n *\n * NOT exported from the package: it is pure mechanism with no knowledge of\n * direction, the DOM, `ResizeObserver`, or the structure of the value `T` it\n * carries. The wrapping primitive injects `produce` / `same` / `sink` and\n * drives the lifecycle.\n *\n * - `schedule()` \u2014 coalesce a burst of triggers into ONE RAF; the frame\n * body re-`produce()`s, dedupes against the last emit (`same`), and `sink`s.\n * Bails if inactive or disposed (stale-RAF safe).\n * - `emitNow(v)` \u2014 explicit synchronous emit (create / update path). Always\n * fires, bypassing the dedupe check, and refreshes the dedupe baseline.\n * - `setActive` \u2014 gate the observer stream; a queued frame bails on `!active`.\n * - `cancel` \u2014 drop any in-flight RAF.\n * - `dispose` \u2014 cancel + go inert; after dispose nothing emits again.\n */\nexport interface MeasureLoop<T> {\n schedule(): void\n emitNow(value: T): void\n setActive(on: boolean): void\n cancel(): void\n dispose(): void\n}\n\nexport function createMeasureLoop<T>(cfg: {\n /** Produce the value to emit in the RAF body. Return `null` to decline the\n * frame entirely (no dedupe, no sink, baseline untouched) \u2014 e.g. a\n * non-finite or unavailable measurement. */\n produce: () => T | null\n same: (a: T, b: T) => boolean\n sink: (value: T) => void\n}): MeasureLoop<T> {\n const { produce, same, sink } = cfg\n let rafId: number | null = null\n let active = false\n let disposed = false\n let last: T | null = null\n\n const cancel = (): void => {\n if (rafId !== null) {\n cancelAnimationFrame(rafId)\n rafId = null\n }\n }\n\n return {\n schedule(): void {\n if (disposed || !active || rafId !== null) return\n rafId = requestAnimationFrame(() => {\n rafId = null\n if (disposed || !active) return\n const value = produce()\n if (value === null) return // producer declined this frame\n // last-value dedupe: a frame whose produced value equals the last one\n // we emitted costs nothing (no IPC / setBounds).\n if (last !== null && same(value, last)) return\n last = value\n sink(value)\n })\n },\n emitNow(value: T): void {\n if (disposed) return\n last = value\n sink(value)\n },\n setActive(on: boolean): void {\n active = on\n },\n cancel,\n dispose(): void {\n if (disposed) return\n disposed = true\n cancel()\n },\n }\n}\n", "import type {\n AdvertisedSize,\n SizeAdvertiserOptions,\n SizeAdvertiserHandle,\n} from './types.js'\nimport { createMeasureLoop } from './measure-loop.js'\n\n/**\n * Reverse of `createViewAnchor`: runs in a downstream WebContentsView's own\n * renderer, measures the content's own size on ONE owned axis (from the\n * `ResizeObserver` border-box \u2014 no `getBoundingClientRect`, no forced reflow),\n * and advertises it via the injected `publish`. Shares the forward primitive's\n * measure/coalesce/dedupe/dispose engine (`createMeasureLoop`).\n *\n * The extent is `Math.round`ed and clamped to `>= 0`; non-finite measurements\n * drop the frame.\n *\n * FOOTGUN \u2014 `target` must be shrink-to-fit on the owned axis: its owned-axis\n * size must NOT be driven by the host-applied view size, or the cross-process\n * loop (advertise \u2192 host resizes view \u2192 remeasure) never converges (it\n * oscillates or stays \"stable but wrong\"). Measuring `<body>`/`<html>` is the\n * classic mistake \u2014 their size *is* the view size. See\n * `docs/bidirectional-design.md`'s single-axis-ownership and trust-boundary\n * sections.\n */\nexport function createSizeAdvertiser(\n target: HTMLElement,\n opts: SizeAdvertiserOptions,\n): SizeAdvertiserHandle {\n const axis = opts.axis // immutable for the advertiser's life\n let publish = opts.publish\n let observer: ResizeObserver | null = null\n let disposed = false\n // Latest border-box, stashed by the RO callback and read by `produce` in the\n // RAF body (keep the entry out of the shared, DOM-agnostic loop).\n let latest: ResizeObserverSize | null = null\n\n const produce = (): AdvertisedSize | null => {\n if (!latest) return null\n const raw = axis === 'block' ? latest.blockSize : latest.inlineSize\n if (!Number.isFinite(raw)) return null\n return { axis, extent: Math.max(0, Math.round(raw)) }\n }\n\n const loop = createMeasureLoop<AdvertisedSize>({\n produce,\n same: (a, b) => a.extent === b.extent, // axis is constant\n sink: (size) => publish(size),\n })\n\n const onResize: ResizeObserverCallback = (entries) => {\n const entry = entries[entries.length - 1]\n if (entry) {\n latest = entry.borderBoxSize?.[0] ?? entry.contentBoxSize?.[0] ?? latest\n }\n loop.schedule()\n }\n\n // One cheap, once-per-advertiser guard for the textbook feedback-loop footgun.\n const doc = target.ownerDocument\n if (target === doc.body || target === doc.documentElement) {\n console.warn(\n `[view-anchor] size-advertiser: <${target === doc.body ? 'body' : 'html'}>'s ` +\n `${axis} size is the host-given view size, not the content size \u2014 the ` +\n `advertiser will never shrink to content. Measure a shrink-to-fit wrapper. ` +\n `See bidirectional-design.md's single-axis-ownership section.`,\n )\n }\n\n loop.setActive(true)\n observer = new ResizeObserver(onResize)\n observer.observe(target)\n\n return {\n update(nextPublish: (size: AdvertisedSize) => void): void {\n if (disposed) return\n publish = nextPublish\n // Re-advertise the current size to the new sink immediately (mirrors the\n // forward anchor's re-publish on update) so the new channel is not left\n // sizeless until the next ResizeObserver tick.\n const cur = produce()\n if (cur) loop.emitNow(cur)\n },\n dispose(): void {\n if (disposed) return\n disposed = true\n loop.cancel()\n if (observer) {\n observer.disconnect()\n observer = null\n }\n loop.dispose()\n },\n }\n}\n", "/**\n * IPC channel name constants for dimina-devtools' overlay/panel\n * WebContentsViews \u2014 layout slots (host-toolbar/host-sidebar/host-dialog),\n * the popover, tooltip, project-create dialog and settings overlays, plus\n * the update flow. Split out of `ipc-channels.ts` (see that file's header)\n * once this group alone pushed it past the repo's file-length threshold \u2014\n * these constants share no runtime dependency on the rest of that file, so\n * the split is a pure line-count relief valve, not a behavior change.\n */\n\n// \u2500\u2500 Embedded views (renderer \u2192 main) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n//\n// The main window's React layout owns the *positions* of the editor +\n// simulator-DevTools WebContentsView overlays \u2014 each visible placeholder\n// `<div>` measures its client rect via ResizeObserver and pushes the\n// rectangle to the main process. The view manager caches the latest\n// payload per kind and applies it to the overlay; no payload means the\n// overlay is hidden.\n//\n// Payload (after schema validation): `{ x, y, width, height }` in CSS\n// pixels relative to the window's content area (origin = top-left,\n// not including the OS chrome).\nexport const ViewChannel = {\n /**\n * Reverse size-advertiser: the host-toolbar WCV's OWN renderer advertises its\n * intrinsic content height so main reserves exactly that much. Payload\n * `{ axis: 'block', extent }`. fire-and-forget (send), NOT invoke.\n */\n HostToolbarAdvertiseHeight: 'view:host-toolbar:advertise-height',\n /**\n * main \u2192 host-toolbar WCV renderer: per-load MessagePort handshake for the\n * gated narrow channel. On every toolbar `did-finish-load` main creates a\n * `MessageChannelMain` and transfers port2 here\n * (`wc.postMessage(HostToolbarPort, null, [port2])`); the session-resident\n * toolbar runtime preload receives it via `event.ports[0]` and bridges it to\n * the page as `window.diminaHostToolbar`. Envelope both directions:\n * `{ channel: string, payload: unknown }`.\n */\n HostToolbarPort: 'view:host-toolbar:port',\n /**\n * main \u2192 main-window renderer: push the reserved host-toolbar height so the\n * renderer placeholder div resizes (closing the dynamic-height loop).\n */\n HostToolbarHeightChanged: 'view:host-toolbar:height-changed',\n /**\n * main \u2190 main-window renderer (invoke): pull the last NOTIFIED toolbar\n * height retained in main. Mount-time replay companion to\n * `HostToolbarHeightChanged`: the push listener mounts with the project\n * view and the toolbar's size-advertiser deduplicates (never re-reports),\n * so a height pushed while no project view was mounted would otherwise be\n * lost forever (cold start on the project list races it; close-project \u2192\n * reopen hits it deterministically). No payload; resolves a number.\n */\n HostToolbarGetHeight: 'view:host-toolbar:get-height',\n /**\n * Reverse size-advertiser for the host-sidebar WCV, mirroring\n * `HostToolbarAdvertiseHeight` on the inline (width) axis instead of block.\n * Payload `{ axis: 'inline', extent }`. fire-and-forget (send), NOT invoke.\n */\n HostSidebarAdvertiseWidth: 'view:host-sidebar:advertise-width',\n /**\n * main \u2192 host-sidebar WCV renderer: per-load MessagePort handshake, same\n * contract as `HostToolbarPort` (see that entry).\n */\n HostSidebarPort: 'view:host-sidebar:port',\n /**\n * main \u2192 main-window renderer: push the reserved host-sidebar width so the\n * renderer placeholder div resizes, mirroring `HostToolbarHeightChanged`.\n */\n HostSidebarWidthChanged: 'view:host-sidebar:width-changed',\n /**\n * main \u2190 main-window renderer (invoke): pull the last NOTIFIED sidebar\n * width, mirroring `HostToolbarGetHeight`'s mount-time replay role.\n */\n HostSidebarGetWidth: 'view:host-sidebar:get-width',\n /**\n * main \u2192 main-window renderer: push the project category (`Project.type`)\n * selected in the host-sidebar's content \u2014 devtools' own default icon rail,\n * or any downstream replacement that sends on the same channel. No\n * pull/replay companion like `HostSidebarGetWidth`: the default category is\n * a stable initial value regardless of load-order, and nothing is ever sent\n * before the main-window renderer (and thus `ProjectListScreen`) is already\n * mounted.\n */\n HostSidebarCategorySelected: 'view:host-sidebar:category-selected',\n /**\n * Reverse size-advertiser for the host-dialog WCV. Unlike the toolbar/sidebar\n * (single-axis, `setBaseDesired`-placed strips), the dialog is a BOTH-AXES\n * overlay positioned by `setOverlayDesired` \u2014 main centers it in the main\n * window once it knows both dimensions. One channel carries either axis'\n * report (`{ axis: 'block' | 'inline', extent }`); the dialog's own content\n * advertises both from the same root (see `host-dialog-advertiser.ts`).\n * fire-and-forget (send), NOT invoke.\n *\n * No `HostDialogSizeChanged` / `HostDialogGetSize` counterparts: those exist\n * for toolbar/sidebar so a renderer-owned PLACEHOLDER can replay a size it\n * missed. The dialog has no such placeholder \u2014 it is a main-driven overlay\n * shown/hidden on demand (`hostDialog.show()`/`hide()`), so there is nothing\n * in the renderer to replay a size into.\n */\n HostDialogAdvertiseSize: 'view:host-dialog:advertise-size',\n /**\n * main \u2192 host-dialog WCV renderer: per-load MessagePort handshake, same\n * contract as `HostToolbarPort` (see that entry).\n */\n HostDialogPort: 'view:host-dialog:port',\n /**\n * Renderer \u2192 main: the window-level placement snapshot (one monotonic epoch\n * per commit tick, one generation per renderer lifetime) that drives the view\n * reconciler. The single source of truth for every managed native view's\n * bounds/visibility/z-order \u2014 supersedes the per-view bounds channels above.\n * invoke.\n */\n PlacementSnapshot: 'view:placement-snapshot',\n /**\n * main \u2190 main-window renderer (invoke): allocate a fresh placement\n * generation seed for this renderer bootstrap. See\n * renderer-placement-generation.ts for why the seed comes from main\n * (a wall-clock `Date.now()` seed is not guaranteed to exceed main's\n * still-standing high-water mark across two reloads that happen faster\n * than the clock's resolution). No payload; resolves a number.\n */\n AllocatePlacementGeneration: 'view:allocate-placement-generation',\n} as const\n\nexport interface ViewBounds {\n x: number\n y: number\n width: number\n height: number\n}\n\n// \u2500\u2500 Popover \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const PopoverChannel = {\n Show: 'popover:show',\n Hide: 'popover:hide',\n Relaunch: 'popover:relaunch',\n Closed: 'popover:closed',\n Init: 'popover:init',\n} as const\n\n// \u2500\u2500 Tooltip \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n//\n// A top-tier overlay WebContentsView (VIEW_LAYER.tooltip \u2014 see view-ids.ts),\n// NOT a DOM tooltip in the main renderer: any DOM-portaled floating UI (Radix\n// Tooltip) or the browser-native `title` attribute lives in the main\n// renderer's own paint surface, which every other WCV (simulator, editor,\n// settings, popover) renders on top of \u2014 CSS cannot reach across that\n// boundary. A trigger reports its anchor rect + label; main computes the\n// tooltip's screen bounds and shows/repositions/hides this overlay.\n\nexport const OverlayChannel = {\n Ready: 'overlay:ready',\n} as const\n\nexport const TooltipChannel = {\n Prepare: 'tooltip:prepare',\n Show: 'tooltip:show',\n Hide: 'tooltip:hide',\n Init: 'tooltip:init',\n Measured: 'tooltip:measured',\n} as const\n\n// \u2500\u2500 Project-create dialog \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n//\n// A top-tier overlay WebContentsView (VIEW_LAYER.dialog), NOT the Radix\n// `fixed inset-0` DOM portal it replaced \u2014 a DOM overlay paints inside the\n// main window's own renderer, so any native WebContentsView mounted on top\n// (simulator, host-toolbar, host-sidebar) occludes it. main.tsx fetches the\n// template catalog + base-dir defaults, then asks main to show this panel;\n// the panel relays submit/cancel back to main.tsx to run the existing\n// scaffold flow.\n\nexport const ProjectCreateChannel = {\n Show: 'projectCreate:show',\n Init: 'projectCreate:init',\n Submit: 'projectCreate:submit',\n Cancel: 'projectCreate:cancel',\n Submitted: 'projectCreate:submitted',\n} as const\n\n// \u2500\u2500 Embedded settings overlay \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const SettingsChannel = {\n SetVisible: 'settings:setVisible',\n ConfigChanged: 'settings:configChanged',\n ProjectSettingsChanged: 'settings:projectSettingsChanged',\n Init: 'settings:init',\n} as const\n\n// \u2500\u2500 Updates (UpdateManager) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n//\n// String values are FROZEN: shipped builds key off them. Add new entries\n// here, never rename existing ones.\nexport const UpdateChannel = {\n Check: 'updates:check',\n Download: 'updates:download',\n Install: 'updates:install',\n DownloadProgress: 'updates:downloadProgress',\n Available: 'updates:available',\n Close: 'updates:close',\n} as const\n", "/**\n * Shared readiness wait for a host-slot content's shrink-to-fit measurement\n * root (`[data-host-*-root]`). A one-shot `document.querySelector` at\n * `DOMContentLoaded` time only works when the root is present in the initial\n * HTML. Framework-rendered content (e.g. a React app) can mount its root\n * asynchronously, after `DOMContentLoaded` has already fired \u2014 a one-shot\n * check misses it permanently and the slot's width/height is never\n * advertised. This keeps watching via `MutationObserver` instead of assuming\n * a synchronous mount, without polling on a fixed delay.\n *\n * The \"root is missing\" warning exists for downstream authors who forgot the\n * element entirely, so it must not fire on the healthy async-mount path \u2014 a\n * warning printed on every normal load is noise that trains its readers to\n * ignore it. It is therefore withheld until the document has finished loading\n * (`window.load`, a real event rather than a guessed delay) with the root\n * still absent; the observer stays armed either way, so a root that mounts\n * even later is still picked up.\n */\nexport function whenSlotRootReady(\n selector: string,\n missingWarning: string,\n install: (root: HTMLElement) => void,\n): void {\n function attempt(): void {\n const root = document.querySelector<HTMLElement>(selector)\n if (root) {\n install(root)\n return\n }\n\n let installed = false\n const observer = new MutationObserver(() => {\n const lateRoot = document.querySelector<HTMLElement>(selector)\n if (!lateRoot) return\n observer.disconnect()\n installed = true\n install(lateRoot)\n })\n observer.observe(document.documentElement, { childList: true, subtree: true })\n\n const warnIfStillMissing = (): void => {\n if (!installed) console.warn(missingWarning)\n }\n if (document.readyState === 'complete') warnIfStillMissing()\n else window.addEventListener('load', warnIfStillMissing, { once: true })\n }\n\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', attempt, { once: true })\n } else {\n attempt()\n }\n}\n", "/**\n * Shared implementation behind every host-slot page bridge (toolbar/sidebar/\n * dialog): the MessagePort handshake, pending-queue-with-bounded-overflow,\n * handler registry and `{ send, onMessage }` contextBridge exposure are\n * IDENTICAL across slots \u2014 only the bridge key, handshake channel, queue cap\n * and overflow-warning label differ. Each slot's own `host-*-port.ts` stays\n * the frozen public surface (see its own \"PUBLIC SURFACE EVOLUTION RULE\"\n * doc-comment) and calls this factory with its own constants; this module has\n * no public-surface contract of its own.\n */\nimport { contextBridge, ipcRenderer } from 'electron'\n\nexport interface HostSlotPortBridgeOptions {\n /** contextBridge key the page-facing API is exposed under, e.g. 'diminaHostToolbar'. */\n bridgeKey: string\n /** main \u2192 renderer per-load handshake channel, e.g. ViewChannel.HostToolbarPort. */\n channel: string\n /** Cap on pre-handshake queued sends; overflow drops the NEWEST envelope. */\n pendingLimit: number\n /** Slot label used in the overflow console.warn, e.g. 'host-toolbar'. */\n label: string\n}\n\n/**\n * Subscribe the handshake channel and expose the page bridge. Call ONLY from\n * a passing per-slot runtime guard \u2014 a failing guard must leave zero\n * footprint (no bridge key, no IPC listener), so this factory itself does no\n * guard checking; the caller decides whether to call it at all.\n */\nexport function createHostSlotPortBridge(opts: HostSlotPortBridgeOptions): void {\n const { bridgeKey, channel, pendingLimit, label } = opts\n let activePort: MessagePort | null = null\n const pending: Array<{ channel: string; payload: unknown }> = []\n // One overflow warning per load (this installer runs once per document) \u2014\n // a runaway page send-loop must not get per-drop console spam.\n let warnedPendingOverflow = false\n const handlers: Array<{ channel: string; handler: (payload: unknown) => void }> = []\n\n // Entry-waist channel validation, parity with the main side's `onMessage`\n // guard (same TypeError, message names `channel`). Runs BEFORE any state is\n // touched (no queue slot, no registry entry), in both port states \u2014 a page\n // author's typo throws at the call site instead of vanishing into main's\n // silent inbound drop.\n function assertValidChannel(method: string, ch: unknown): asserts ch is string {\n if (typeof ch !== 'string' || ch === '') {\n throw new TypeError(`${bridgeKey}.${method}: channel must be a non-empty string`)\n }\n }\n\n const dispatch = (data: unknown): void => {\n // Defensive symmetry with main: drop anything that is not an object\n // envelope with a string channel \u2014 never throw in the dispatcher.\n if (typeof data !== 'object' || data === null) return\n const { channel: ch, payload } = data as { channel?: unknown; payload?: unknown }\n if (typeof ch !== 'string') return\n for (const entry of [...handlers]) {\n if (entry.channel === ch) entry.handler(payload)\n }\n }\n\n const onPortMessage = (event: MessageEvent): void => {\n dispatch(event.data)\n }\n\n ipcRenderer.on(channel, (event) => {\n const port = event.ports[0]\n if (!port) return\n // Same-load duplicate handshake: the LATER port wins. Main closed (or is\n // about to close) its end of the old pair \u2014 detach and stop writing to it.\n if (activePort) {\n try {\n activePort.removeEventListener('message', onPortMessage)\n activePort.close()\n } catch {\n /* already dead */\n }\n }\n activePort = port\n // addEventListener (not onmessage) keeps the handler removable on\n // re-handshake; it REQUIRES start() or inbound never delivers.\n port.addEventListener('message', onPortMessage)\n port.start()\n // Flush sends issued before the port arrived, in order.\n while (pending.length > 0) {\n const envelope = pending.shift()!\n port.postMessage(envelope)\n }\n })\n\n // EXACTLY { send, onMessage } \u2014 functions only; the port stays in the\n // isolated world.\n contextBridge.exposeInMainWorld(bridgeKey, {\n send(ch: string, payload: unknown): void {\n assertValidChannel('send', ch)\n const envelope = { channel: ch, payload }\n if (activePort) {\n activePort.postMessage(envelope)\n return\n }\n // Bounded queue: drop the NEWEST send on overflow (FIFO first-comers\n // survive), warn once per load, never throw into page code.\n if (pending.length >= pendingLimit) {\n if (!warnedPendingOverflow) {\n warnedPendingOverflow = true\n console.warn(\n `[dimina-devtools] ${label} pending queue full (${pendingLimit}); ` +\n 'dropping further pre-handshake send() calls until the port arrives',\n )\n }\n return\n }\n pending.push(envelope)\n },\n onMessage(ch: string, handler: (payload: unknown) => void): () => void {\n assertValidChannel('onMessage', ch)\n const entry = { channel: ch, handler }\n handlers.push(entry)\n return () => {\n const i = handlers.indexOf(entry)\n if (i >= 0) handlers.splice(i, 1)\n }\n },\n })\n}\n", "/**\n * Preload side of the host-sidebar gated narrow channel.\n *\n * \u2500\u2500 PUBLIC SURFACE EVOLUTION RULE \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n * `window.diminaHostSidebar` is a published page-facing API, typed by the\n * exported `DiminaHostSidebarPageBridge` (src/main/runtime/miniapp-runtime.ts)\n * \u2014 arbitrary host sidebar pages compile against it. Members may only be\n * ADDED, never changed: any semantic change to an existing member (signature,\n * return shape, queueing/throw behavior) ships under a NEW name instead.\n * Exception: security fixes / compliance corrections may change existing\n * member semantics, and MUST be called out in the release's version notes.\n * Keep the exported bridge type in lockstep with what is exposed here.\n *\n * Receives the per-load MessagePort main transfers on `did-finish-load`\n * (`ViewChannel.HostSidebarPort`, `event.ports[0]`) and bridges it to the page\n * as `window.diminaHostSidebar` \u2014 EXACTLY `{ send, onMessage }`, functions\n * only. The raw MessagePort never crosses into the main world: the page only\n * ever talks through these two functions, so the `{ channel, payload }`\n * envelope stays the single waist (same posture as the main side's\n * host-sidebar-port-channel.ts).\n *\n * Ordering reality this module absorbs \u2014 identical to the toolbar's port\n * bridge (see host-toolbar-port.ts for the full rationale): pre-handshake\n * sends queue and bounded-drop, handlers register before the port exists and\n * re-attach across same-load re-handshakes, inbound dispatch drops malformed\n * envelopes without throwing.\n *\n * Shared implementation: see `host-slot-port-bridge.ts` (the toolbar/sidebar/\n * dialog port bridges are otherwise identical; only the constants below\n * differ).\n */\n\nimport { ViewChannel } from '../../shared/ipc-channels-overlays.js'\nimport { createHostSlotPortBridge } from './host-slot-port-bridge.js'\n\n/**\n * Cap on pre-handshake queued sends. Same rationale and value as\n * `HOST_TOOLBAR_PENDING_LIMIT` \u2014 overflow drops the NEWEST envelope, one\n * console.warn per load.\n */\nexport const HOST_SIDEBAR_PENDING_LIMIT = 128\n\n/**\n * Subscribe the handshake channel and expose the page bridge. Call ONLY from\n * a passing sidebar-runtime guard (`activateHostSidebarRuntime`) \u2014 a failing\n * guard must leave zero footprint (no bridge key, no IPC listener).\n */\nexport function installHostSidebarPortBridge(): void {\n createHostSlotPortBridge({\n bridgeKey: 'diminaHostSidebar',\n channel: ViewChannel.HostSidebarPort,\n pendingLimit: HOST_SIDEBAR_PENDING_LIMIT,\n label: 'host-sidebar',\n })\n}\n", "/**\n * Session-resident host-sidebar framework runtime: GUARD + ACTIVATION.\n *\n * Same registration and guard shape as host-toolbar-runtime.ts (see that\n * module for the full rationale): registered once per process on\n * `session.defaultSession`, so it runs in EVERY defaultSession renderer;\n * this guard keeps it inert everywhere except the host-sidebar WCV's main\n * frame, identified by `HOST_SIDEBAR_RUNTIME_MARKER` in that process' argv.\n */\n\nimport { HOST_SIDEBAR_RUNTIME_MARKER } from '../../shared/constants.js'\nimport { installHostSidebarAdvertiserWhenReady } from './host-sidebar-advertiser.js'\nimport { installHostSidebarPortBridge } from './host-sidebar-port.js'\n\n/**\n * Pure guard predicate: should the sidebar runtime activate in a renderer with\n * this `argv` / `isMainFrame`? True only for the MAIN frame of a process whose\n * argv carries the `'--dimina-host-sidebar'` marker.\n */\nexport function shouldActivateHostSidebarRuntime(\n argv: readonly string[],\n isMainFrame: boolean,\n): boolean {\n return isMainFrame && argv.includes(HOST_SIDEBAR_RUNTIME_MARKER)\n}\n\n/**\n * Run the guard; only when it passes, install the width advertiser\n * (`installHostSidebarAdvertiserWhenReady`) and the narrow-channel page\n * bridge (`installHostSidebarPortBridge` \u2014 `window.diminaHostSidebar` +\n * the MessagePort handshake listener). Returns whether the runtime\n * activated. A failed guard installs NOTHING (zero footprint in non-sidebar\n * windows and subframes: no advertiser, no bridge key, no IPC listener).\n */\nexport function activateHostSidebarRuntime(env: {\n argv: readonly string[]\n isMainFrame: boolean\n}): boolean {\n if (!shouldActivateHostSidebarRuntime(env.argv, env.isMainFrame)) return false\n installHostSidebarAdvertiserWhenReady()\n installHostSidebarPortBridge()\n return true\n}\n", "// Session-registered sidebar-runtime preload entry.\n//\n// Bundled into a single CJS file (dist/preload/windows/host-sidebar-runtime.cjs)\n// via build:preload and registered ONCE per process on `session.defaultSession`\n// (`registerPreloadScript({ type: 'frame', \u2026 })` \u2014 see\n// `src/main/services/views/host-sidebar-session-runtime.ts`). It therefore runs\n// in EVERY defaultSession renderer; `activateHostSidebarRuntime`'s guard\n// (`process.isMainFrame && process.argv.includes('--dimina-host-sidebar')`)\n// makes it a zero-footprint no-op everywhere except the host-sidebar WCV's\n// main frame, where it installs the reverse size-advertiser.\nimport { activateHostSidebarRuntime } from '../runtime/host-sidebar-runtime.js'\n\nactivateHostSidebarRuntime({ argv: process.argv, isMainFrame: process.isMainFrame })\n"],
5
+ "mappings": "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",
6
+ "names": ["import_electron"]
7
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=host-sidebar-runtime.d.ts.map
@@ -0,0 +1,13 @@
1
+ // Session-registered sidebar-runtime preload entry.
2
+ //
3
+ // Bundled into a single CJS file (dist/preload/windows/host-sidebar-runtime.cjs)
4
+ // via build:preload and registered ONCE per process on `session.defaultSession`
5
+ // (`registerPreloadScript({ type: 'frame', … })` — see
6
+ // `src/main/services/views/host-sidebar-session-runtime.ts`). It therefore runs
7
+ // in EVERY defaultSession renderer; `activateHostSidebarRuntime`'s guard
8
+ // (`process.isMainFrame && process.argv.includes('--dimina-host-sidebar')`)
9
+ // makes it a zero-footprint no-op everywhere except the host-sidebar WCV's
10
+ // main frame, where it installs the reverse size-advertiser.
11
+ import { activateHostSidebarRuntime } from '../runtime/host-sidebar-runtime.js';
12
+ activateHostSidebarRuntime({ argv: process.argv, isMainFrame: process.isMainFrame });
13
+ //# sourceMappingURL=host-sidebar-runtime.js.map