@dimina-kit/devtools 0.4.0-dev.20260831134112 → 0.4.0-dev.20260907055341

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 (275) hide show
  1. package/README.md +52 -729
  2. package/dist/main/app/app.d.ts +27 -7
  3. package/dist/main/app/app.js +285 -681
  4. package/dist/main/app/editor-view.d.ts +21 -0
  5. package/dist/main/app/editor-view.js +71 -0
  6. package/dist/main/app/global-mirrors.d.ts +23 -0
  7. package/dist/main/app/global-mirrors.js +37 -0
  8. package/dist/main/app/host-sidebar-default.d.ts +19 -0
  9. package/dist/main/app/host-sidebar-default.js +44 -0
  10. package/dist/main/app/menu-setup.d.ts +13 -0
  11. package/dist/main/app/menu-setup.js +49 -0
  12. package/dist/main/app/open-project-ipc.d.ts +13 -0
  13. package/dist/main/app/open-project-ipc.js +21 -0
  14. package/dist/main/app/project-list-surface.d.ts +31 -0
  15. package/dist/main/app/project-list-surface.js +20 -0
  16. package/dist/main/app/project-window.d.ts +36 -0
  17. package/dist/main/app/project-window.js +93 -0
  18. package/dist/main/app/servers.d.ts +17 -0
  19. package/dist/main/app/servers.js +60 -0
  20. package/dist/main/app/ui-extension-targets.d.ts +42 -0
  21. package/dist/main/app/ui-extension-targets.js +101 -0
  22. package/dist/main/app/window-close-reveal.harness.d.ts +34 -0
  23. package/dist/main/app/window-close-reveal.harness.js +65 -0
  24. package/dist/main/app/window-events.d.ts +15 -0
  25. package/dist/main/app/window-events.js +45 -0
  26. package/dist/main/app/window-runtime-services.d.ts +41 -0
  27. package/dist/main/app/window-runtime-services.js +178 -0
  28. package/dist/main/app/workbench-modules.d.ts +24 -0
  29. package/dist/main/app/workbench-modules.js +51 -0
  30. package/dist/main/app/workbench-window.d.ts +85 -0
  31. package/dist/main/app/workbench-window.js +310 -0
  32. package/dist/main/index.bundle.js +10669 -9096
  33. package/dist/main/ipc/app.d.ts +4 -1
  34. package/dist/main/ipc/app.js +4 -3
  35. package/dist/main/ipc/device-picker.d.ts +16 -0
  36. package/dist/main/ipc/device-picker.js +27 -0
  37. package/dist/main/ipc/index.d.ts +1 -0
  38. package/dist/main/ipc/index.js +1 -0
  39. package/dist/main/ipc/internal-devtools.d.ts +2 -1
  40. package/dist/main/ipc/internal-devtools.js +4 -3
  41. package/dist/main/ipc/popover.d.ts +4 -1
  42. package/dist/main/ipc/popover.js +25 -9
  43. package/dist/main/ipc/project-create.d.ts +2 -1
  44. package/dist/main/ipc/project-create.js +6 -5
  45. package/dist/main/ipc/project-fs.d.ts +3 -1
  46. package/dist/main/ipc/project-fs.js +17 -17
  47. package/dist/main/ipc/projects.d.ts +3 -3
  48. package/dist/main/ipc/projects.js +13 -12
  49. package/dist/main/ipc/session.d.ts +4 -1
  50. package/dist/main/ipc/session.js +16 -11
  51. package/dist/main/ipc/settings.d.ts +4 -1
  52. package/dist/main/ipc/settings.js +12 -19
  53. package/dist/main/ipc/simulator-module.d.ts +5 -0
  54. package/dist/main/ipc/simulator-module.js +9 -5
  55. package/dist/main/ipc/simulator.d.ts +4 -1
  56. package/dist/main/ipc/simulator.js +12 -18
  57. package/dist/main/ipc/tooltip.d.ts +2 -1
  58. package/dist/main/ipc/tooltip.js +8 -7
  59. package/dist/main/ipc/views.d.ts +4 -1
  60. package/dist/main/ipc/views.js +20 -9
  61. package/dist/main/runtime/devtools-backend-before-quit.harness.d.ts +2 -20
  62. package/dist/main/runtime/devtools-backend-before-quit.harness.js +14 -283
  63. package/dist/main/runtime/devtools-backend.js +14 -3
  64. package/dist/main/runtime/devtools-runtime-mock.harness.d.ts +21 -0
  65. package/dist/main/runtime/devtools-runtime-mock.harness.js +313 -0
  66. package/dist/main/services/app-services.d.ts +62 -0
  67. package/dist/main/services/app-services.js +64 -0
  68. package/dist/main/services/automation/connection-target.d.ts +36 -0
  69. package/dist/main/services/automation/connection-target.js +29 -0
  70. package/dist/main/services/automation/console-bridge.d.ts +28 -0
  71. package/dist/main/services/automation/console-bridge.js +91 -0
  72. package/dist/main/services/automation/handlers/app.js +4 -4
  73. package/dist/main/services/automation/handlers/element.js +55 -21
  74. package/dist/main/services/automation/index.d.ts +12 -1
  75. package/dist/main/services/automation/index.js +54 -133
  76. package/dist/main/services/default-adapter.js +1 -1
  77. package/dist/main/services/fs-bridge-protocol.d.ts +61 -0
  78. package/dist/main/services/fs-bridge-protocol.js +34 -0
  79. package/dist/main/services/fs-watch-sse.d.ts +8 -1
  80. package/dist/main/services/fs-watch-sse.js +19 -5
  81. package/dist/main/services/mcp/connection-owner.d.ts +38 -0
  82. package/dist/main/services/mcp/connection-owner.js +79 -0
  83. package/dist/main/services/mcp/index.d.ts +3 -1
  84. package/dist/main/services/mcp/index.js +4 -3
  85. package/dist/main/services/mcp/opened-project.d.ts +88 -0
  86. package/dist/main/services/mcp/opened-project.js +60 -0
  87. package/dist/main/services/mcp/target-manager.d.ts +71 -23
  88. package/dist/main/services/mcp/target-manager.js +269 -142
  89. package/dist/main/services/mcp/target-selection.d.ts +47 -0
  90. package/dist/main/services/mcp/target-selection.js +71 -0
  91. package/dist/main/services/mcp/tools/context-tools.js +20 -5
  92. package/dist/main/services/mcp/tools/project-tools.d.ts +29 -6
  93. package/dist/main/services/mcp/tools/project-tools.js +37 -25
  94. package/dist/main/services/module.d.ts +13 -5
  95. package/dist/main/services/notifications/renderer-notifier.d.ts +28 -4
  96. package/dist/main/services/notifications/renderer-notifier.js +15 -3
  97. package/dist/main/services/projects/local-provider.js +2 -0
  98. package/dist/main/services/projects/project-repository.d.ts +31 -1
  99. package/dist/main/services/projects/project-repository.js +144 -20
  100. package/dist/main/services/projects/types.d.ts +31 -8
  101. package/dist/main/services/safe-area/index.d.ts +19 -5
  102. package/dist/main/services/safe-area/index.js +38 -13
  103. package/dist/main/services/simulator/ui-extensions.d.ts +8 -0
  104. package/dist/main/services/simulator/ui-extensions.js +16 -6
  105. package/dist/main/services/simulator-storage/index.d.ts +12 -1
  106. package/dist/main/services/simulator-storage/index.js +22 -7
  107. package/dist/main/services/simulator-storage/window-scope.d.ts +20 -0
  108. package/dist/main/services/simulator-storage/window-scope.js +20 -0
  109. package/dist/main/services/views/host-slot-port-channel.d.ts +20 -3
  110. package/dist/main/services/views/host-slot-port-channel.js +33 -5
  111. package/dist/main/services/views/managed-web-contents-view.js +21 -1
  112. package/dist/main/services/views/native-simulator-view.js +13 -16
  113. package/dist/main/services/views/overlay-panels-view.d.ts +13 -0
  114. package/dist/main/services/views/overlay-panels-view.js +31 -0
  115. package/dist/main/services/views/view-manager.d.ts +1 -1
  116. package/dist/main/services/views/view-manager.js +3 -0
  117. package/dist/main/services/window-contexts/context-router.d.ts +36 -0
  118. package/dist/main/services/window-contexts/context-router.js +55 -0
  119. package/dist/main/services/workbench-coi-host.d.ts +52 -0
  120. package/dist/main/services/workbench-coi-host.js +227 -0
  121. package/dist/main/services/workbench-coi-server.js +75 -133
  122. package/dist/main/services/workbench-coi-shutdown.d.ts +40 -0
  123. package/dist/main/services/workbench-coi-shutdown.js +69 -0
  124. package/dist/main/services/workbench-coi-static.d.ts +23 -0
  125. package/dist/main/services/workbench-coi-static.js +87 -0
  126. package/dist/main/services/workbench-context.d.ts +27 -3
  127. package/dist/main/services/workbench-context.js +10 -5
  128. package/dist/main/services/workspace/compile-mode-adapter.d.ts +18 -0
  129. package/dist/main/services/workspace/compile-mode-adapter.js +57 -0
  130. package/dist/main/services/workspace/compile-mode-store.d.ts +25 -0
  131. package/dist/main/services/workspace/compile-mode-store.js +71 -0
  132. package/dist/main/services/workspace/workspace-compile-modes.d.ts +59 -0
  133. package/dist/main/services/workspace/workspace-compile-modes.js +93 -0
  134. package/dist/main/services/workspace/workspace-referer.d.ts +17 -0
  135. package/dist/main/services/workspace/workspace-referer.js +26 -0
  136. package/dist/main/services/workspace/workspace-service.d.ts +4 -0
  137. package/dist/main/services/workspace/workspace-service.js +51 -84
  138. package/dist/main/services/workspace/workspace-thumbnails.d.ts +22 -0
  139. package/dist/main/services/workspace/workspace-thumbnails.js +67 -0
  140. package/dist/main/utils/ipc-context-source.d.ts +40 -0
  141. package/dist/main/utils/ipc-context-source.js +23 -0
  142. package/dist/main/utils/ipc-registry.d.ts +42 -36
  143. package/dist/main/utils/ipc-registry.js +117 -50
  144. package/dist/main/utils/sender-policy.d.ts +9 -0
  145. package/dist/main/utils/sender-policy.js +26 -3
  146. package/dist/main/utils/theme.d.ts +3 -2
  147. package/dist/main/utils/theme.js +3 -2
  148. package/dist/main/windows/main-window/create.d.ts +16 -0
  149. package/dist/main/windows/main-window/create.js +19 -11
  150. package/dist/main/windows/main-window/events.d.ts +1 -1
  151. package/dist/main/windows/main-window/events.js +26 -13
  152. package/dist/main/windows/main-window/index.d.ts +1 -1
  153. package/dist/main/windows/main-window/index.js +1 -1
  154. package/dist/native-host/common/common.js +94 -73
  155. package/dist/native-host/render/render.js +4079 -3171
  156. package/dist/native-host/service/service.js +2 -2
  157. package/dist/preload/runtime/native-host.d.ts +4 -0
  158. package/dist/preload/runtime/temp-files.js +9 -2
  159. package/dist/preload/runtime/wait-for-slot-root.d.ts +7 -4
  160. package/dist/preload/runtime/wait-for-slot-root.js +36 -8
  161. package/dist/preload/windows/host-dialog-runtime.cjs +10 -3
  162. package/dist/preload/windows/host-dialog-runtime.cjs.map +2 -2
  163. package/dist/preload/windows/host-sidebar-runtime.cjs +10 -3
  164. package/dist/preload/windows/host-sidebar-runtime.cjs.map +2 -2
  165. package/dist/preload/windows/host-toolbar-runtime.cjs +10 -3
  166. package/dist/preload/windows/host-toolbar-runtime.cjs.map +2 -2
  167. package/dist/preload/windows/main.cjs +181 -4
  168. package/dist/preload/windows/main.cjs.map +4 -4
  169. package/dist/preload/windows/simulator.cjs +10 -0
  170. package/dist/preload/windows/simulator.cjs.map +2 -2
  171. package/dist/preload/windows/simulator.js +10 -0
  172. package/dist/renderer/assets/button-CB2MWjHY.js +2 -0
  173. package/dist/renderer/assets/constants-CkoGPQTS.js +2 -0
  174. package/dist/renderer/assets/constants-zQZ2-y21.js +2 -0
  175. package/dist/renderer/assets/{createLucideIcon-Bqi8hpdi.js → createLucideIcon-cZ9FlZZw.js} +2 -2
  176. package/dist/renderer/assets/devicePicker-H2eIO4e1.js +2 -0
  177. package/dist/renderer/assets/dialog-pHzEA8Vx.js +46 -0
  178. package/dist/renderer/assets/dist-B5HADirS.js +2 -0
  179. package/dist/renderer/assets/{dist-DKWdE1TK.js → dist-DIFlRMKe.js} +2 -2
  180. package/dist/renderer/assets/hostSidebarDefault-DRWh6OCt.js +2 -0
  181. package/dist/renderer/assets/index-CEL_XFge.js +2 -0
  182. package/dist/renderer/assets/{input-Ct3alvkq.js → input-CAObw95L.js} +2 -2
  183. package/dist/renderer/assets/ipc-channels-overlays-gIPUFnqc.js +2 -0
  184. package/dist/renderer/assets/jsx-runtime-DICEQH_0.css +1 -0
  185. package/dist/renderer/assets/{jsx-runtime-DGLHmmOq.js → jsx-runtime-DIw5wnYl.js} +1 -1
  186. package/dist/renderer/assets/plus-BQ9u5EbL.js +2 -0
  187. package/dist/renderer/assets/popover-Cw7G2Ctp.js +2 -0
  188. package/dist/renderer/assets/presets-DMZOb9ay.js +2 -0
  189. package/dist/renderer/assets/project-api-YTOr_Yvo.js +2 -0
  190. package/dist/renderer/assets/{projectCreateDialog-Bbjz75bP.js → projectCreateDialog-BmLqiYxn.js} +2 -2
  191. package/dist/renderer/assets/search-BMvuYF48.js +2 -0
  192. package/dist/renderer/assets/select-nFP95TxM.js +2 -0
  193. package/dist/renderer/assets/settings-CnpVfSWt.js +2 -0
  194. package/dist/renderer/assets/settings-api-Ccsf-Nsj.js +2 -0
  195. package/dist/renderer/assets/settings-tab-bar-CAzrv32m.js +2 -0
  196. package/dist/renderer/assets/smartphone-Bb2GdIKy.js +2 -0
  197. package/dist/renderer/assets/tabs-CPKN3Mmq.js +2 -0
  198. package/dist/renderer/assets/{tooltip-B_-_YVbw.js → tooltip-D6AxXRk5.js} +2 -2
  199. package/dist/renderer/assets/types-Bh0hA7El.js +2 -0
  200. package/dist/renderer/assets/updateDialog-CwndJ0Bl.js +2 -0
  201. package/dist/renderer/assets/{utils-kfQov6Pa.js → utils-sEB5OZEQ.js} +2 -2
  202. package/dist/renderer/assets/view-api-B-2zPBR5.js +2 -0
  203. package/dist/renderer/assets/view-ids-BfaDVV5P.js +2 -0
  204. package/dist/renderer/assets/workbench-BLJ0wKsg.js +5 -0
  205. package/dist/renderer/assets/{workbenchSettings-CV4LVA9b.js → workbenchSettings-YD0Ctbm_.js} +3 -3
  206. package/dist/renderer/entries/device-picker/index.html +28 -0
  207. package/dist/renderer/entries/host-sidebar-default/index.html +6 -5
  208. package/dist/renderer/entries/main/index.html +16 -17
  209. package/dist/renderer/entries/popover/index.html +16 -10
  210. package/dist/renderer/entries/project-create-dialog/index.html +12 -12
  211. package/dist/renderer/entries/settings/index.html +10 -10
  212. package/dist/renderer/entries/tooltip/index.html +5 -5
  213. package/dist/renderer/entries/update-dialog/index.html +10 -10
  214. package/dist/renderer/entries/workbench/index.html +49 -0
  215. package/dist/renderer/entries/workbench-settings/index.html +12 -11
  216. package/dist/service-host/host-env-update.cjs +23 -0
  217. package/dist/service-host/preload.cjs +24 -49
  218. package/dist/service-host/service-message-queue.cjs +71 -0
  219. package/dist/service-host/sync-impls/system-info.js +31 -9
  220. package/dist/shared/compile-mode-state.d.ts +73 -0
  221. package/dist/shared/compile-mode-state.js +100 -0
  222. package/dist/shared/compile-modes.d.ts +152 -0
  223. package/dist/shared/compile-modes.js +237 -0
  224. package/dist/shared/ipc-channels-overlays.d.ts +8 -2
  225. package/dist/shared/ipc-channels-overlays.js +19 -2
  226. package/dist/shared/ipc-channels.d.ts +5 -10
  227. package/dist/shared/ipc-channels.js +17 -14
  228. package/dist/shared/ipc-schemas.d.ts +76 -24
  229. package/dist/shared/ipc-schemas.js +55 -10
  230. package/dist/shared/project-window-types.d.ts +42 -0
  231. package/dist/shared/project-window-types.js +2 -0
  232. package/dist/shared/types.d.ts +43 -17
  233. package/dist/shared/view-ids.d.ts +1 -0
  234. package/dist/shared/view-ids.js +3 -1
  235. package/dist/simulator/assets/bridge-channels-B3JAmRfl.js +2 -0
  236. package/dist/simulator/assets/device-shell-ATEhHV2_.css +1 -0
  237. package/dist/simulator/assets/device-shell-pxnZZp10.js +431 -0
  238. package/dist/simulator/assets/simulator-Dwp7lnvu.js +10 -0
  239. package/dist/simulator/assets/simulator-mini-app-DFo7fhi5.js +2 -0
  240. package/dist/simulator/assets/simulator-ui-B2ddJB1R.js +2 -0
  241. package/dist/simulator/simulator.html +3 -3
  242. package/dist/simulator/temp-files.d.ts +6 -0
  243. package/dist/simulator/temp-files.js +46 -4
  244. package/dist/simulator/types.d.ts +7 -0
  245. package/dist/vscode-workbench/assets/__vite-browser-external-JIkWewFf.js +1 -0
  246. package/dist/vscode-workbench/assets/{dist-CMfmHflW.js → dist-CXG-u1VB.js} +3 -3
  247. package/dist/vscode-workbench/assets/{iconv-lite-umd-Bx8CgaZq.js → iconv-lite-umd-Dxx9Qyb4.js} +1 -1
  248. package/dist/vscode-workbench/assets/{index-CdG6YWhW.js → index-6VJMsaWj.js} +460 -460
  249. package/dist/vscode-workbench/assets/{jschardet-M0qgd2lN.js → jschardet-Ba3D16vt.js} +1 -1
  250. package/dist/vscode-workbench/index.html +1 -1
  251. package/package.json +11 -8
  252. package/dist/renderer/assets/button-D5Q2wkXq.js +0 -2
  253. package/dist/renderer/assets/constants-D7DfVqMp.js +0 -2
  254. package/dist/renderer/assets/constants-D8zsejFq.js +0 -2
  255. package/dist/renderer/assets/dialog-e1TecTOY.js +0 -46
  256. package/dist/renderer/assets/hostSidebarDefault-B3yLfy8j.js +0 -2
  257. package/dist/renderer/assets/index-CsPD68N_.js +0 -5
  258. package/dist/renderer/assets/ipc-channels-overlays-LsDzGAtV.js +0 -2
  259. package/dist/renderer/assets/jsx-runtime-2vXHouwr.css +0 -1
  260. package/dist/renderer/assets/popover-Dix5cm_b.js +0 -2
  261. package/dist/renderer/assets/project-api-k7Oq9iaq.js +0 -2
  262. package/dist/renderer/assets/select-acGb0AmJ.js +0 -2
  263. package/dist/renderer/assets/settings-CQrTMr43.js +0 -2
  264. package/dist/renderer/assets/settings-api-CrUQ9rYV.js +0 -2
  265. package/dist/renderer/assets/settings-tab-bar-Cw1kVIf2.js +0 -2
  266. package/dist/renderer/assets/types-CsEKtFyr.js +0 -2
  267. package/dist/renderer/assets/updateDialog-NsF8223A.js +0 -2
  268. package/dist/renderer/assets/view-api-CLn3rcQE.js +0 -2
  269. package/dist/simulator/assets/bridge-channels-zhsumfky.js +0 -2
  270. package/dist/simulator/assets/device-shell-CmtM1QxP.js +0 -2
  271. package/dist/simulator/assets/device-shell-iFZo1igL.css +0 -1
  272. package/dist/simulator/assets/simulator-CIobn3Mh.js +0 -10
  273. package/dist/simulator/assets/simulator-mini-app-CRe6n9br.js +0 -2
  274. package/dist/simulator/assets/simulator-ui-C_cP602X.js +0 -2
  275. package/dist/vscode-workbench/assets/__vite-browser-external-Bc1vizTf.js +0 -1
@@ -1,4 +1,7 @@
1
1
  import type { WorkbenchContext } from '../services/workbench-context.js';
2
2
  import type { Disposable } from '@dimina-kit/electron-deck/main';
3
- export declare function registerAppIpc(ctx: Pick<WorkbenchContext, 'brandingProvider' | 'appName' | 'senderPolicy'>): Disposable;
3
+ import { type IpcInput } from '../utils/ipc-context-source.js';
4
+ type AppIpcCtx = Pick<WorkbenchContext, 'brandingProvider' | 'appName' | 'senderPolicy'>;
5
+ export declare function registerAppIpc(input: IpcInput<AppIpcCtx>): Disposable;
6
+ export {};
4
7
  //# sourceMappingURL=app.d.ts.map
@@ -1,8 +1,9 @@
1
1
  import { AppChannel } from '../../shared/ipc-channels.js';
2
2
  import { IpcRegistry } from '../utils/ipc-registry.js';
3
- export function registerAppIpc(ctx) {
4
- return new IpcRegistry(ctx.senderPolicy)
5
- .handle(AppChannel.GetBranding, async () => {
3
+ import { toIpcContextSource } from '../utils/ipc-context-source.js';
4
+ export function registerAppIpc(input) {
5
+ return new IpcRegistry(toIpcContextSource(input))
6
+ .handleRouted(AppChannel.GetBranding, async (ctx) => {
6
7
  if (ctx.brandingProvider)
7
8
  return ctx.brandingProvider();
8
9
  return { appName: ctx.appName };
@@ -0,0 +1,16 @@
1
+ import type { WorkbenchModule } from '../services/module.js';
2
+ import type { ViewManager } from '../services/views/view-manager.js';
3
+ import type { RendererNotifier } from '../services/notifications/renderer-notifier.js';
4
+ import type { Disposable } from '@dimina-kit/electron-deck/main';
5
+ import { type SenderPolicy } from '../utils/ipc-registry.js';
6
+ import { type IpcInput } from '../utils/ipc-context-source.js';
7
+ /** Module-local narrow deps — deliberately NOT `Pick<WorkbenchContext, ...>`
8
+ * (the gate in eslint.config.* is shrink-only; see its message). */
9
+ export interface DevicePickerIpcDeps {
10
+ views: Pick<ViewManager, 'showDevicePicker' | 'hideDevicePicker'>;
11
+ notify: Pick<RendererNotifier, 'devicePickerSelected'>;
12
+ senderPolicy?: SenderPolicy;
13
+ }
14
+ export declare function registerDevicePickerIpc(input: IpcInput<DevicePickerIpcDeps>): Disposable;
15
+ export declare const devicePickerModule: WorkbenchModule;
16
+ //# sourceMappingURL=device-picker.d.ts.map
@@ -0,0 +1,27 @@
1
+ import { DevicePickerChannel } from '../../shared/ipc-channels-overlays.js';
2
+ import { DevicePickerDeviceSchema } from '../../shared/ipc-schemas.js';
3
+ import { validate } from '../utils/ipc-schema.js';
4
+ import { IpcRegistry } from '../utils/ipc-registry.js';
5
+ import { toIpcContextSource } from '../utils/ipc-context-source.js';
6
+ export function registerDevicePickerIpc(input) {
7
+ return new IpcRegistry(toIpcContextSource(input))
8
+ .onRouted(DevicePickerChannel.Show, (ctx, _event, ...args) => {
9
+ const [data] = validate(DevicePickerChannel.Show, DevicePickerDeviceSchema, args);
10
+ ctx.views.showDevicePicker(data);
11
+ })
12
+ .onRouted(DevicePickerChannel.Cancel, (ctx) => {
13
+ ctx.views.hideDevicePicker();
14
+ })
15
+ .onRouted(DevicePickerChannel.Select, (ctx, _event, ...args) => {
16
+ const [data] = validate(DevicePickerChannel.Select, DevicePickerDeviceSchema, args);
17
+ ctx.views.hideDevicePicker();
18
+ ctx.notify.devicePickerSelected(data);
19
+ });
20
+ // OverlayChannel.Ready is registered once, in tooltip.ts — every overlay
21
+ // renderer (this one included) funnels readiness through that single
22
+ // listener, so a second registration here would double-fire markOverlayReady.
23
+ }
24
+ export const devicePickerModule = {
25
+ setup: (ctx) => registerDevicePickerIpc(ctx),
26
+ };
27
+ //# sourceMappingURL=device-picker.js.map
@@ -3,6 +3,7 @@ export { registerSimulatorIpc } from './simulator.js';
3
3
  export { registerPopoverIpc, popoverModule } from './popover.js';
4
4
  export { registerTooltipIpc, tooltipModule } from './tooltip.js';
5
5
  export { registerProjectCreateIpc, projectCreateModule } from './project-create.js';
6
+ export { registerDevicePickerIpc, devicePickerModule } from './device-picker.js';
6
7
  export { registerProjectsIpc, projectsModule } from './projects.js';
7
8
  export { registerSessionIpc, sessionModule } from './session.js';
8
9
  export { registerSettingsIpc, settingsModule } from './settings.js';
@@ -3,6 +3,7 @@ export { registerSimulatorIpc } from './simulator.js';
3
3
  export { registerPopoverIpc, popoverModule } from './popover.js';
4
4
  export { registerTooltipIpc, tooltipModule } from './tooltip.js';
5
5
  export { registerProjectCreateIpc, projectCreateModule } from './project-create.js';
6
+ export { registerDevicePickerIpc, devicePickerModule } from './device-picker.js';
6
7
  export { registerProjectsIpc, projectsModule } from './projects.js';
7
8
  export { registerSessionIpc, sessionModule } from './session.js';
8
9
  export { registerSettingsIpc, settingsModule } from './settings.js';
@@ -1,5 +1,6 @@
1
1
  import type { Disposable } from '@dimina-kit/electron-deck/main';
2
2
  import { type SenderPolicy } from '../utils/ipc-registry.js';
3
+ import { type IpcInput } from '../utils/ipc-context-source.js';
3
4
  import type { InternalDevtoolsWindow } from '../windows/internal-devtools-window/index.js';
4
5
  /**
5
6
  * Standalone internal (app-wide) DevTools debug window. The simulator
@@ -11,5 +12,5 @@ export interface InternalDevtoolsIpcDeps {
11
12
  internalDevtoolsWindow?: InternalDevtoolsWindow;
12
13
  senderPolicy: SenderPolicy;
13
14
  }
14
- export declare function registerInternalDevtoolsIpc(ctx: InternalDevtoolsIpcDeps): Disposable;
15
+ export declare function registerInternalDevtoolsIpc(input: IpcInput<InternalDevtoolsIpcDeps>): Disposable;
15
16
  //# sourceMappingURL=internal-devtools.d.ts.map
@@ -1,8 +1,9 @@
1
1
  import { InternalDevtoolsChannel } from '../../shared/ipc-channels.js';
2
2
  import { IpcRegistry } from '../utils/ipc-registry.js';
3
- export function registerInternalDevtoolsIpc(ctx) {
4
- return new IpcRegistry(ctx.senderPolicy)
5
- .handle(InternalDevtoolsChannel.Open, () => {
3
+ import { toIpcContextSource } from '../utils/ipc-context-source.js';
4
+ export function registerInternalDevtoolsIpc(input) {
5
+ return new IpcRegistry(toIpcContextSource(input))
6
+ .handleRouted(InternalDevtoolsChannel.Open, (ctx) => {
6
7
  ctx.internalDevtoolsWindow?.open();
7
8
  });
8
9
  }
@@ -1,6 +1,9 @@
1
1
  import type { WorkbenchContext } from '../services/workbench-context.js';
2
2
  import type { WorkbenchModule } from '../services/module.js';
3
3
  import type { Disposable } from '@dimina-kit/electron-deck/main';
4
- export declare function registerPopoverIpc(ctx: Pick<WorkbenchContext, 'views' | 'notify' | 'senderPolicy'>): Disposable;
4
+ import { type IpcInput } from '../utils/ipc-context-source.js';
5
+ type PopoverIpcCtx = Pick<WorkbenchContext, 'views' | 'notify' | 'senderPolicy' | 'workspace'>;
6
+ export declare function registerPopoverIpc(input: IpcInput<PopoverIpcCtx>): Disposable;
5
7
  export declare const popoverModule: WorkbenchModule;
8
+ export {};
6
9
  //# sourceMappingURL=popover.d.ts.map
@@ -1,20 +1,36 @@
1
1
  import { PopoverChannel } from '../../shared/ipc-channels-overlays.js';
2
- import { PopoverShowSchema, PopoverRelaunchSchema, } from '../../shared/ipc-schemas.js';
2
+ import { PopoverShowSchema, PopoverApplySchema, } from '../../shared/ipc-schemas.js';
3
3
  import { validate } from '../utils/ipc-schema.js';
4
4
  import { IpcRegistry } from '../utils/ipc-registry.js';
5
- export function registerPopoverIpc(ctx) {
6
- return new IpcRegistry(ctx.senderPolicy)
7
- .handle(PopoverChannel.Show, (_event, ...args) => {
5
+ import { toIpcContextSource } from '../utils/ipc-context-source.js';
6
+ export function registerPopoverIpc(input) {
7
+ return new IpcRegistry(toIpcContextSource(input))
8
+ .handleRouted(PopoverChannel.Show, (ctx, _event, ...args) => {
8
9
  const [data] = validate(PopoverChannel.Show, PopoverShowSchema, args);
9
- ctx.views.showPopover(data);
10
+ // A stale/misbehaving renderer may still send the old `modes` field —
11
+ // never trust it. The live state always comes from the currently open
12
+ // project's store, injected here.
13
+ const { modes: _modes, ...rest } = data;
14
+ const { state } = ctx.workspace.getCompileModeState();
15
+ ctx.views.showPopover({ ...rest, state });
10
16
  })
11
- .handle(PopoverChannel.Hide, () => {
17
+ .handleRouted(PopoverChannel.Hide, (ctx) => {
12
18
  ctx.views.hidePopover();
13
19
  })
14
- .on(PopoverChannel.Relaunch, (_event, ...args) => {
15
- const [newConfig] = validate(PopoverChannel.Relaunch, PopoverRelaunchSchema, args);
20
+ .handleRouted(PopoverChannel.Apply, async (ctx, _event, ...args) => {
21
+ const [payload] = validate(PopoverChannel.Apply, PopoverApplySchema, args);
22
+ // Hide BEFORE touching the store: a slow or failing apply must never
23
+ // leave a stale popover window on screen.
16
24
  ctx.views.hidePopover();
17
- ctx.notify.popoverRelaunch(newConfig);
25
+ try {
26
+ return await ctx.workspace.applyCompileModeCommand(payload.command);
27
+ }
28
+ catch (err) {
29
+ ctx.notify.compileModesApplyFailed({
30
+ message: err instanceof Error ? err.message : String(err),
31
+ });
32
+ throw err;
33
+ }
18
34
  });
19
35
  }
20
36
  export const popoverModule = {
@@ -3,6 +3,7 @@ import type { ViewManager } from '../services/views/view-manager.js';
3
3
  import type { RendererNotifier } from '../services/notifications/renderer-notifier.js';
4
4
  import type { Disposable } from '@dimina-kit/electron-deck/main';
5
5
  import { type SenderPolicy } from '../utils/ipc-registry.js';
6
+ import { type IpcInput } from '../utils/ipc-context-source.js';
6
7
  /** Module-local narrow deps — deliberately NOT `Pick<WorkbenchContext, ...>`
7
8
  * (the gate in eslint.config.* is shrink-only; see its message). */
8
9
  export interface ProjectCreateIpcDeps {
@@ -10,6 +11,6 @@ export interface ProjectCreateIpcDeps {
10
11
  notify: Pick<RendererNotifier, 'projectCreateSubmitted'>;
11
12
  senderPolicy?: SenderPolicy;
12
13
  }
13
- export declare function registerProjectCreateIpc(ctx: ProjectCreateIpcDeps): Disposable;
14
+ export declare function registerProjectCreateIpc(input: IpcInput<ProjectCreateIpcDeps>): Disposable;
14
15
  export declare const projectCreateModule: WorkbenchModule;
15
16
  //# sourceMappingURL=project-create.d.ts.map
@@ -2,16 +2,17 @@ import { ProjectCreateChannel } from '../../shared/ipc-channels-overlays.js';
2
2
  import { ProjectCreateShowSchema, ProjectCreateSubmitSchema } from '../../shared/ipc-schemas.js';
3
3
  import { validate } from '../utils/ipc-schema.js';
4
4
  import { IpcRegistry } from '../utils/ipc-registry.js';
5
- export function registerProjectCreateIpc(ctx) {
6
- return new IpcRegistry(ctx.senderPolicy)
7
- .on(ProjectCreateChannel.Show, (_event, ...args) => {
5
+ import { toIpcContextSource } from '../utils/ipc-context-source.js';
6
+ export function registerProjectCreateIpc(input) {
7
+ return new IpcRegistry(toIpcContextSource(input))
8
+ .onRouted(ProjectCreateChannel.Show, (ctx, _event, ...args) => {
8
9
  const [data] = validate(ProjectCreateChannel.Show, ProjectCreateShowSchema, args);
9
10
  ctx.views.showProjectCreateDialog(data);
10
11
  })
11
- .on(ProjectCreateChannel.Cancel, () => {
12
+ .onRouted(ProjectCreateChannel.Cancel, (ctx) => {
12
13
  ctx.views.hideProjectCreateDialog();
13
14
  })
14
- .on(ProjectCreateChannel.Submit, (_event, ...args) => {
15
+ .onRouted(ProjectCreateChannel.Submit, (ctx, _event, ...args) => {
15
16
  const [input] = validate(ProjectCreateChannel.Submit, ProjectCreateSubmitSchema, args);
16
17
  ctx.views.hideProjectCreateDialog();
17
18
  ctx.notify.projectCreateSubmitted(input);
@@ -1,5 +1,6 @@
1
1
  import type { WorkbenchContext } from '../services/workbench-context.js';
2
2
  import type { Disposable } from '@dimina-kit/electron-deck/main';
3
+ import { type IpcInput } from '../utils/ipc-context-source.js';
3
4
  /** Dependency/VCS/build directories invisible to every project-tree consumer:
4
5
  * IPC `listFiles`, the `/__fs/readdir` bridge (so the workbench mirror and the
5
6
  * WAL ledger seed never walk into them), and the `/__fs/watch` change stream.
@@ -148,7 +149,8 @@ declare function listFiles(root: string, rootArg: string): Promise<string[]>;
148
149
  * Register the project-fs IPC channels. Call once during workbench setup;
149
150
  * the returned Disposable removes every channel (park on `ctx.registry`).
150
151
  */
151
- export declare function registerProjectFsIpc(ctx: Pick<WorkbenchContext, 'workspace' | 'senderPolicy'>): Disposable;
152
+ type ProjectFsIpcCtx = Pick<WorkbenchContext, 'workspace' | 'senderPolicy'>;
153
+ export declare function registerProjectFsIpc(input: IpcInput<ProjectFsIpcCtx>): Disposable;
152
154
  /** Test seams — pure handlers, no Electron needed. */
153
155
  export declare const __testing: {
154
156
  readFile: typeof readFile;
@@ -45,6 +45,7 @@ import nodeFs from 'node:fs';
45
45
  import path from 'node:path';
46
46
  import { z } from 'zod';
47
47
  import { IpcRegistry } from '../utils/ipc-registry.js';
48
+ import { toIpcContextSource } from '../utils/ipc-context-source.js';
48
49
  import { validate } from '../utils/ipc-schema.js';
49
50
  import { ProjectFsChannel } from '../../shared/ipc-channels.js';
50
51
  import { WATCH_IGNORE_DIRS } from '@dimina-kit/devkit/watch-ignore';
@@ -552,44 +553,43 @@ async function listFiles(root, rootArg) {
552
553
  }
553
554
  return out;
554
555
  }
555
- /**
556
- * Register the project-fs IPC channels. Call once during workbench setup;
557
- * the returned Disposable removes every channel (park on `ctx.registry`).
558
- */
559
- export function registerProjectFsIpc(ctx) {
560
- const getRoot = () => ctx.workspace.getProjectPath();
561
- const getLastClosedRoot = () => ctx.workspace.getLastClosedProjectPath();
562
- return new IpcRegistry(ctx.senderPolicy)
563
- .handle(ProjectFsChannel.GetRoot, () => getRoot())
564
- .handle(ProjectFsChannel.ReadFile, (_event, ...args) => {
556
+ export function registerProjectFsIpc(input) {
557
+ // Roots are read per call from the CALLING window's workspace: each window
558
+ // has its own open project, so a captured root would sandbox one window's
559
+ // file access against another's project.
560
+ const getRoot = (ctx) => ctx.workspace.getProjectPath();
561
+ const getLastClosedRoot = (ctx) => ctx.workspace.getLastClosedProjectPath();
562
+ return new IpcRegistry(toIpcContextSource(input))
563
+ .handleRouted(ProjectFsChannel.GetRoot, (ctx) => getRoot(ctx))
564
+ .handleRouted(ProjectFsChannel.ReadFile, (ctx, _event, ...args) => {
565
565
  const [p] = validate(ProjectFsChannel.ReadFile, ReadFileSchema, args);
566
566
  // Reads stay scoped to the CURRENT root only — never widen the read
567
567
  // surface to the last-closed project.
568
- return readFile(getRoot(), p);
568
+ return readFile(getRoot(ctx), p);
569
569
  })
570
- .handle(ProjectFsChannel.WriteFile, (_event, ...args) => {
570
+ .handleRouted(ProjectFsChannel.WriteFile, (ctx, _event, ...args) => {
571
571
  const [p, content] = validate(ProjectFsChannel.WriteFile, WriteFileSchema, args);
572
572
  // Accept a write under the current OR the just-closed project root (the
573
573
  // latter rescues an in-flight teardown flush after `closeProject`). The
574
574
  // selected root then runs the FULL sandbox (realpath containment +
575
575
  // ancestor guard + O_NOFOLLOW) inside `writeFile`, so the boundary is
576
576
  // never relaxed — only WHICH root is considered.
577
- const root = pickWriteRoot(p, { current: getRoot(), lastClosed: getLastClosedRoot() });
577
+ const root = pickWriteRoot(p, { current: getRoot(ctx), lastClosed: getLastClosedRoot(ctx) });
578
578
  return writeFile(root, p, content);
579
579
  })
580
- .handleSync(ProjectFsChannel.WriteFileSync, (_event, ...args) => {
580
+ .handleSyncRouted(ProjectFsChannel.WriteFileSync, (ctx, _event, ...args) => {
581
581
  // Synchronous twin of WriteFile for the editor's beforeunload flush. Same
582
582
  // root selection + same sandbox (`writeFileSync` mirrors `writeFile`); the
583
583
  // only difference is the blocking transport. Returns `{ ok: true }`; any
584
584
  // throw is converted to `{ ok: false, code, message }` by `handleSync`.
585
585
  const [p, content] = validate(ProjectFsChannel.WriteFileSync, WriteFileSchema, args);
586
- const root = pickWriteRoot(p, { current: getRoot(), lastClosed: getLastClosedRoot() });
586
+ const root = pickWriteRoot(p, { current: getRoot(ctx), lastClosed: getLastClosedRoot(ctx) });
587
587
  writeFileSync(root, p, content);
588
588
  return { ok: true };
589
589
  })
590
- .handle(ProjectFsChannel.ListFiles, (_event, ...args) => {
590
+ .handleRouted(ProjectFsChannel.ListFiles, (ctx, _event, ...args) => {
591
591
  const [p] = validate(ProjectFsChannel.ListFiles, ListFilesSchema, args);
592
- return listFiles(getRoot(), p);
592
+ return listFiles(getRoot(ctx), p);
593
593
  });
594
594
  }
595
595
  /** Test seams — pure handlers, no Electron needed. */
@@ -1,8 +1,8 @@
1
1
  import type { WorkbenchContext } from '../services/workbench-context.js';
2
2
  import type { WorkbenchModule } from '../services/module.js';
3
3
  import type { Disposable } from '@dimina-kit/electron-deck/main';
4
- type ProjectsIpcCtx = Pick<WorkbenchContext, 'workspace' | 'windows' | 'senderPolicy' | 'projectsProvider' | 'projectTemplates' | 'customCreateProjectDialog' | 'customEditProjectDialog' | 'notify' | 'views'>;
5
- export declare function registerProjectsIpc(ctx: ProjectsIpcCtx): Disposable;
4
+ import { type IpcInput } from '../utils/ipc-context-source.js';
5
+ export type ProjectsIpcCtx = Pick<WorkbenchContext, 'workspace' | 'windows' | 'senderPolicy' | 'projectsProvider' | 'projectTemplates' | 'customCreateProjectDialog' | 'customEditProjectDialog' | 'notify' | 'views'>;
6
+ export declare function registerProjectsIpc(input: IpcInput<ProjectsIpcCtx>): Disposable;
6
7
  export declare const projectsModule: WorkbenchModule;
7
- export {};
8
8
  //# sourceMappingURL=projects.d.ts.map
@@ -4,22 +4,23 @@ import { ProjectsChannel, DialogChannel } from '../../shared/ipc-channels.js';
4
4
  import { ProjectsAddSchema, ProjectsOpenEditDialogSchema, ProjectsRemoveSchema, ProjectsUpdateSchema, } from '../../shared/ipc-schemas.js';
5
5
  import { validate } from '../utils/ipc-schema.js';
6
6
  import { IpcRegistry } from '../utils/ipc-registry.js';
7
+ import { toIpcContextSource } from '../utils/ipc-context-source.js';
7
8
  import { sanitizeTemplates } from '../services/projects/templates.js';
8
9
  import { createProject } from '../services/projects/create-project-service.js';
9
10
  import { loadWorkbenchSettings, saveWorkbenchSettings, } from '../services/settings/index.js';
10
- export function registerProjectsIpc(ctx) {
11
- return new IpcRegistry(ctx.senderPolicy)
12
- .handle(ProjectsChannel.List, () => {
11
+ export function registerProjectsIpc(input) {
12
+ return new IpcRegistry(toIpcContextSource(input))
13
+ .handleRouted(ProjectsChannel.List, (ctx) => {
13
14
  return ctx.workspace.listProjects();
14
15
  })
15
- .handle(DialogChannel.OpenDirectory, async () => {
16
+ .handleRouted(DialogChannel.OpenDirectory, async (ctx) => {
16
17
  const result = await dialog.showOpenDialog(ctx.windows.mainWindow, {
17
18
  properties: ['openDirectory'],
18
19
  title: '选择小程序项目目录',
19
20
  });
20
21
  return result.canceled ? null : result.filePaths[0];
21
22
  })
22
- .handle(ProjectsChannel.Add, async (_event, ...args) => {
23
+ .handleRouted(ProjectsChannel.Add, async (ctx, _event, ...args) => {
23
24
  const [dirPath] = validate(ProjectsChannel.Add, ProjectsAddSchema, args);
24
25
  const dirError = await ctx.workspace.validateProjectDir(dirPath);
25
26
  if (dirError) {
@@ -56,22 +57,22 @@ export function registerProjectsIpc(ctx) {
56
57
  ctx.views.hostSidebar.send('project-category-forced', { category: importedCategory });
57
58
  return project;
58
59
  })
59
- .handle(ProjectsChannel.Remove, (_event, ...args) => {
60
+ .handleRouted(ProjectsChannel.Remove, (ctx, _event, ...args) => {
60
61
  const [dirPath] = validate(ProjectsChannel.Remove, ProjectsRemoveSchema, args);
61
62
  return ctx.workspace.removeProject(dirPath);
62
63
  })
63
- .handle(ProjectsChannel.Update, (_event, ...args) => {
64
+ .handleRouted(ProjectsChannel.Update, (ctx, _event, ...args) => {
64
65
  const [dirPath, patch] = validate(ProjectsChannel.Update, ProjectsUpdateSchema, args);
65
66
  return ctx.workspace.updateProject(dirPath, patch);
66
67
  })
67
68
  // ── template catalog + create flow ──
68
- .handle(ProjectsChannel.ListTemplates, () => {
69
+ .handleRouted(ProjectsChannel.ListTemplates, (ctx) => {
69
70
  // Sanitize at the IPC boundary: `generate` is a function and the
70
71
  // structured-clone algorithm Electron uses for invoke would otherwise
71
72
  // throw "could not be cloned" before the renderer ever sees it.
72
73
  return sanitizeTemplates(ctx.projectTemplates ?? []);
73
74
  })
74
- .handle(ProjectsChannel.OpenCreateDialog, async () => {
75
+ .handleRouted(ProjectsChannel.OpenCreateDialog, async (ctx) => {
75
76
  if (!ctx.customCreateProjectDialog)
76
77
  return null;
77
78
  const sanitized = sanitizeTemplates(ctx.projectTemplates ?? []);
@@ -80,7 +81,7 @@ export function registerProjectsIpc(ctx) {
80
81
  templates: sanitized,
81
82
  });
82
83
  })
83
- .handle(ProjectsChannel.OpenEditDialog, async (_event, ...args) => {
84
+ .handleRouted(ProjectsChannel.OpenEditDialog, async (ctx, _event, ...args) => {
84
85
  if (!ctx.customEditProjectDialog)
85
86
  return null;
86
87
  const [dirPath] = validate(ProjectsChannel.OpenEditDialog, ProjectsOpenEditDialogSchema, args);
@@ -100,7 +101,7 @@ export function registerProjectsIpc(ctx) {
100
101
  // fall through into the built-in one right behind it.
101
102
  return { result };
102
103
  })
103
- .handle(ProjectsChannel.Create, async (_event, ...args) => {
104
+ .handleRouted(ProjectsChannel.Create, async (ctx, _event, ...args) => {
104
105
  // We deliberately don't run this through zod yet — the input shape is
105
106
  // wide (any template can stash arbitrary `extra` fields) and the
106
107
  // service does its own per-field validation. Bound size to keep this
@@ -145,7 +146,7 @@ export function registerProjectsIpc(ctx) {
145
146
  }
146
147
  return project;
147
148
  })
148
- .handle(ProjectsChannel.GetCreateDefaults, () => {
149
+ .handleRouted(ProjectsChannel.GetCreateDefaults, () => {
149
150
  // Fallback chain: persisted last parent → user's Documents → home.
150
151
  // Documents covers the common "我把项目都放在 Documents/ 下" case for
151
152
  // first-time users on macOS; home is just a safe final fallback.
@@ -1,6 +1,9 @@
1
1
  import type { WorkbenchContext } from '../services/workbench-context.js';
2
2
  import type { WorkbenchModule } from '../services/module.js';
3
3
  import type { Disposable } from '@dimina-kit/electron-deck/main';
4
- export declare function registerSessionIpc(ctx: Pick<WorkbenchContext, 'workspace' | 'senderPolicy'>): Disposable;
4
+ import { type IpcInput } from '../utils/ipc-context-source.js';
5
+ type SessionIpcCtx = Pick<WorkbenchContext, 'workspace' | 'senderPolicy'>;
6
+ export declare function registerSessionIpc(input: IpcInput<SessionIpcCtx>): Disposable;
5
7
  export declare const sessionModule: WorkbenchModule;
8
+ export {};
6
9
  //# sourceMappingURL=session.d.ts.map
@@ -1,29 +1,34 @@
1
1
  import { ProjectChannel } from '../../shared/ipc-channels.js';
2
- import { ProjectCaptureThumbnailSchema, ProjectGetCompileConfigSchema, ProjectGetPagesSchema, ProjectGetThumbnailSchema, ProjectOpenSchema, ProjectSaveCompileConfigSchema, } from '../../shared/ipc-schemas.js';
2
+ import { ProjectCaptureThumbnailSchema, ProjectGetCompileConfigSchema, ProjectGetCompileModeStateSchema, ProjectGetPagesSchema, ProjectGetThumbnailSchema, ProjectOpenSchema, ProjectSaveCompileConfigSchema, } from '../../shared/ipc-schemas.js';
3
3
  import { validate } from '../utils/ipc-schema.js';
4
4
  import { IpcRegistry } from '../utils/ipc-registry.js';
5
- export function registerSessionIpc(ctx) {
6
- return new IpcRegistry(ctx.senderPolicy)
7
- .handle(ProjectChannel.Open, (_, ...args) => {
5
+ import { toIpcContextSource } from '../utils/ipc-context-source.js';
6
+ export function registerSessionIpc(input) {
7
+ return new IpcRegistry(toIpcContextSource(input))
8
+ .handleRouted(ProjectChannel.Open, (ctx, _e, ...args) => {
8
9
  const [projectPath] = validate(ProjectChannel.Open, ProjectOpenSchema, args);
9
10
  return ctx.workspace.openProject(projectPath);
10
11
  })
11
- .handle(ProjectChannel.GetPages, (_, ...args) => {
12
+ .handleRouted(ProjectChannel.GetPages, (ctx, _e, ...args) => {
12
13
  const [projectPath] = validate(ProjectChannel.GetPages, ProjectGetPagesSchema, args);
13
14
  return ctx.workspace.getProjectPages(projectPath);
14
15
  })
15
- .handle(ProjectChannel.GetCompileConfig, (_, ...args) => {
16
+ .handleRouted(ProjectChannel.GetCompileConfig, (ctx, _e, ...args) => {
16
17
  const [projectPath] = validate(ProjectChannel.GetCompileConfig, ProjectGetCompileConfigSchema, args);
17
18
  return ctx.workspace.getCompileConfig(projectPath);
18
19
  })
19
- .handle(ProjectChannel.SaveCompileConfig, (_, ...args) => {
20
+ .handleRouted(ProjectChannel.SaveCompileConfig, (ctx, _e, ...args) => {
20
21
  const [projectPath, config] = validate(ProjectChannel.SaveCompileConfig, ProjectSaveCompileConfigSchema, args);
21
22
  return ctx.workspace.saveCompileConfig(projectPath, config);
22
23
  })
23
- .handle(ProjectChannel.Close, () => {
24
+ .handleRouted(ProjectChannel.GetCompileModeState, (ctx, _e, ...args) => {
25
+ const [projectPath] = validate(ProjectChannel.GetCompileModeState, ProjectGetCompileModeStateSchema, args);
26
+ return ctx.workspace.getCompileModeState(projectPath);
27
+ })
28
+ .handleRouted(ProjectChannel.Close, (ctx) => {
24
29
  return ctx.workspace.closeProject();
25
30
  })
26
- .handle(ProjectChannel.Rebuild, async () => {
31
+ .handleRouted(ProjectChannel.Rebuild, async (ctx) => {
27
32
  const session = ctx.workspace.getSession();
28
33
  if (!session)
29
34
  throw new Error('project:rebuild — no active project session');
@@ -34,11 +39,11 @@ export function registerSessionIpc(ctx) {
34
39
  await session.rebuild();
35
40
  return { supported: true };
36
41
  })
37
- .handle(ProjectChannel.CaptureThumbnail, (_, ...args) => {
42
+ .handleRouted(ProjectChannel.CaptureThumbnail, (ctx, _e, ...args) => {
38
43
  const [projectPath] = validate(ProjectChannel.CaptureThumbnail, ProjectCaptureThumbnailSchema, args);
39
44
  return ctx.workspace.captureThumbnail(projectPath);
40
45
  })
41
- .handle(ProjectChannel.GetThumbnail, (_, ...args) => {
46
+ .handleRouted(ProjectChannel.GetThumbnail, (ctx, _e, ...args) => {
42
47
  const [projectPath] = validate(ProjectChannel.GetThumbnail, ProjectGetThumbnailSchema, args);
43
48
  return ctx.workspace.getThumbnail(projectPath);
44
49
  });
@@ -1,6 +1,9 @@
1
1
  import type { WorkbenchContext } from '../services/workbench-context.js';
2
2
  import type { Disposable } from '@dimina-kit/electron-deck/main';
3
3
  import type { WorkbenchModule } from '../services/module.js';
4
- export declare function registerSettingsIpc(ctx: Pick<WorkbenchContext, 'views' | 'notify' | 'workspace' | 'rendererDir' | 'senderPolicy'>): Disposable;
4
+ import { type IpcInput } from '../utils/ipc-context-source.js';
5
+ type SettingsIpcCtx = Pick<WorkbenchContext, 'views' | 'notify' | 'workspace' | 'rendererDir' | 'senderPolicy'>;
6
+ export declare function registerSettingsIpc(input: IpcInput<SettingsIpcCtx>): Disposable;
5
7
  export declare const settingsModule: WorkbenchModule;
8
+ export {};
6
9
  //# sourceMappingURL=settings.d.ts.map
@@ -4,29 +4,30 @@ import { WorkbenchSettingsChannel } from '../../shared/ipc-channels.js';
4
4
  import { SettingsChannel } from '../../shared/ipc-channels-overlays.js';
5
5
  import { DEFAULT_CDP_PORT } from '../../shared/constants.js';
6
6
  import { getMcpStatus } from '../services/mcp/status.js';
7
- import { SettingsConfigChangedSchema, SettingsProjectSettingsChangedSchema, SettingsSetVisibleSchema, WorkbenchSettingsSaveSchema, WorkbenchSettingsSetThemeSchema, } from '../../shared/ipc-schemas.js';
7
+ import { SettingsProjectSettingsChangedSchema, SettingsSetVisibleSchema, WorkbenchSettingsSaveSchema, WorkbenchSettingsSetThemeSchema, } from '../../shared/ipc-schemas.js';
8
8
  import { validate } from '../utils/ipc-schema.js';
9
9
  import { IpcRegistry } from '../utils/ipc-registry.js';
10
- export function registerSettingsIpc(ctx) {
11
- return new IpcRegistry(ctx.senderPolicy)
12
- .handle(WorkbenchSettingsChannel.Get, () => {
10
+ import { toIpcContextSource } from '../utils/ipc-context-source.js';
11
+ export function registerSettingsIpc(input) {
12
+ return new IpcRegistry(toIpcContextSource(input))
13
+ .handleRouted(WorkbenchSettingsChannel.Get, () => {
13
14
  return loadWorkbenchSettings();
14
15
  })
15
- .handle(WorkbenchSettingsChannel.Save, (_, ...args) => {
16
+ .handleRouted(WorkbenchSettingsChannel.Save, (_ctx, _e, ...args) => {
16
17
  const [settings] = validate(WorkbenchSettingsChannel.Save, WorkbenchSettingsSaveSchema, args);
17
18
  saveWorkbenchSettings(settings);
18
19
  applyTheme(settings.theme ?? 'system');
19
20
  return { success: true };
20
21
  })
21
- .handle(WorkbenchSettingsChannel.SetTheme, (_, ...args) => {
22
+ .handleRouted(WorkbenchSettingsChannel.SetTheme, (_ctx, _e, ...args) => {
22
23
  const [theme] = validate(WorkbenchSettingsChannel.SetTheme, WorkbenchSettingsSetThemeSchema, args);
23
24
  applyTheme(theme);
24
25
  })
25
- .handle(WorkbenchSettingsChannel.Restart, () => {
26
+ .handleRouted(WorkbenchSettingsChannel.Restart, () => {
26
27
  app.relaunch();
27
28
  app.quit();
28
29
  })
29
- .handle(WorkbenchSettingsChannel.GetCdpStatus, () => {
30
+ .handleRouted(WorkbenchSettingsChannel.GetCdpStatus, () => {
30
31
  const settings = loadWorkbenchSettings();
31
32
  const switchValue = app.commandLine.getSwitchValue('remote-debugging-port');
32
33
  const implicitDevDefault = !app.isPackaged && !settings.cdp.enabled && switchValue === String(DEFAULT_CDP_PORT);
@@ -38,7 +39,7 @@ export function registerSettingsIpc(ctx) {
38
39
  implicitDevDefault,
39
40
  };
40
41
  })
41
- .handle(WorkbenchSettingsChannel.GetMcpStatus, () => {
42
+ .handleRouted(WorkbenchSettingsChannel.GetMcpStatus, () => {
42
43
  const settings = loadWorkbenchSettings();
43
44
  const runtime = getMcpStatus();
44
45
  return {
@@ -49,14 +50,13 @@ export function registerSettingsIpc(ctx) {
49
50
  error: runtime.error,
50
51
  };
51
52
  })
52
- .handle(SettingsChannel.SetVisible, async (_, ...args) => {
53
+ .handleRouted(SettingsChannel.SetVisible, async (ctx, _e, ...args) => {
53
54
  const [visible] = validate(SettingsChannel.SetVisible, SettingsSetVisibleSchema, args);
54
55
  if (visible) {
55
56
  await ctx.views.showSettings();
56
57
  const projectPath = ctx.workspace.getProjectPath();
57
58
  ctx.notify.settingsInit({
58
59
  projectPath,
59
- config: await ctx.workspace.getCompileConfig(projectPath),
60
60
  projectSettings: ctx.workspace.getProjectSettings(projectPath),
61
61
  });
62
62
  }
@@ -64,14 +64,7 @@ export function registerSettingsIpc(ctx) {
64
64
  ctx.views.hideSettings();
65
65
  }
66
66
  })
67
- .on(SettingsChannel.ConfigChanged, async (_, ...args) => {
68
- const [config] = validate(SettingsChannel.ConfigChanged, SettingsConfigChangedSchema, args);
69
- const projectPath = ctx.workspace.getProjectPath();
70
- if (projectPath) {
71
- await ctx.workspace.saveCompileConfig(projectPath, config);
72
- }
73
- })
74
- .on(SettingsChannel.ProjectSettingsChanged, (_, ...args) => {
67
+ .onRouted(SettingsChannel.ProjectSettingsChanged, (ctx, _e, ...args) => {
75
68
  const [patch] = validate(SettingsChannel.ProjectSettingsChanged, SettingsProjectSettingsChangedSchema, args);
76
69
  ctx.workspace.updateProjectSettings(ctx.workspace.getProjectPath(), patch);
77
70
  });
@@ -10,6 +10,11 @@ import type { WorkbenchModule } from '../services/module.js';
10
10
  * window decides whether to actually call dmb:* channels, but the main-side
11
11
  * handlers must always be ready or `ipcRenderer.invoke('dmb:spawn')` fails
12
12
  * with `No handler registered`.
13
+ *
14
+ * The router installs onto a concrete context (it assigns `ctx.bridge`,
15
+ * `ctx.consoleForwarder` and `ctx.diagnostics`, which the window assembly
16
+ * reads straight afterwards), so it is per-window wiring rather than
17
+ * app-level registration.
13
18
  */
14
19
  export declare const simulatorModule: WorkbenchModule;
15
20
  //# sourceMappingURL=simulator-module.d.ts.map
@@ -1,4 +1,4 @@
1
- import { DisposableRegistry } from '@dimina-kit/electron-deck/main';
1
+ import { toDisposable } from '@dimina-kit/electron-deck/main';
2
2
  import { registerSimulatorIpc } from './simulator.js';
3
3
  import { installBridgeRouter } from './bridge-router.js';
4
4
  /**
@@ -12,13 +12,17 @@ import { installBridgeRouter } from './bridge-router.js';
12
12
  * window decides whether to actually call dmb:* channels, but the main-side
13
13
  * handlers must always be ready or `ipcRenderer.invoke('dmb:spawn')` fails
14
14
  * with `No handler registered`.
15
+ *
16
+ * The router installs onto a concrete context (it assigns `ctx.bridge`,
17
+ * `ctx.consoleForwarder` and `ctx.diagnostics`, which the window assembly
18
+ * reads straight afterwards), so it is per-window wiring rather than
19
+ * app-level registration.
15
20
  */
16
21
  export const simulatorModule = {
17
- setup: (ctx) => {
18
- const reg = new DisposableRegistry();
19
- reg.add(registerSimulatorIpc(ctx));
22
+ setup: (source) => registerSimulatorIpc(source),
23
+ setupWindow: (ctx) => {
20
24
  installBridgeRouter(ctx);
21
- return reg;
25
+ return toDisposable(() => { });
22
26
  },
23
27
  };
24
28
  //# sourceMappingURL=simulator-module.js.map
@@ -1,4 +1,7 @@
1
1
  import type { WorkbenchContext } from '../services/workbench-context.js';
2
2
  import type { Disposable } from '@dimina-kit/electron-deck/main';
3
- export declare function registerSimulatorIpc(ctx: Pick<WorkbenchContext, 'views' | 'notify' | 'senderPolicy' | 'simulatorApis' | 'bridge'>): Disposable;
3
+ import { type IpcInput } from '../utils/ipc-context-source.js';
4
+ type SimulatorIpcCtx = Pick<WorkbenchContext, 'views' | 'notify' | 'senderPolicy' | 'simulatorApis' | 'bridge'>;
5
+ export declare function registerSimulatorIpc(input: IpcInput<SimulatorIpcCtx>): Disposable;
6
+ export {};
4
7
  //# sourceMappingURL=simulator.d.ts.map