@dimina-kit/devtools 0.4.0 → 0.5.0-dev.20260908120530

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 (507) hide show
  1. package/README.md +51 -660
  2. package/dist/main/api.d.ts +2 -1
  3. package/dist/main/app/app.d.ts +41 -12
  4. package/dist/main/app/app.js +299 -514
  5. package/dist/main/app/bootstrap.d.ts +8 -5
  6. package/dist/main/app/bootstrap.js +15 -15
  7. package/dist/main/app/editor-view.d.ts +21 -0
  8. package/dist/main/app/editor-view.js +71 -0
  9. package/dist/main/app/global-mirrors.d.ts +23 -0
  10. package/dist/main/app/global-mirrors.js +37 -0
  11. package/dist/main/app/host-sidebar-default.d.ts +19 -0
  12. package/dist/main/app/host-sidebar-default.js +44 -0
  13. package/dist/main/app/lifecycle.d.ts +12 -1
  14. package/dist/main/app/lifecycle.js +27 -1
  15. package/dist/main/app/menu-setup.d.ts +13 -0
  16. package/dist/main/app/menu-setup.js +49 -0
  17. package/dist/main/app/native-overview.d.ts +1 -1
  18. package/dist/main/app/open-project-ipc.d.ts +13 -0
  19. package/dist/main/app/open-project-ipc.js +21 -0
  20. package/dist/main/app/project-list-surface.d.ts +31 -0
  21. package/dist/main/app/project-list-surface.js +20 -0
  22. package/dist/main/app/project-window.d.ts +36 -0
  23. package/dist/main/app/project-window.js +93 -0
  24. package/dist/main/app/servers.d.ts +17 -0
  25. package/dist/main/app/servers.js +60 -0
  26. package/dist/main/app/ui-extension-targets.d.ts +42 -0
  27. package/dist/main/app/ui-extension-targets.js +101 -0
  28. package/dist/main/app/window-close-reveal.harness.d.ts +34 -0
  29. package/dist/main/app/window-close-reveal.harness.js +65 -0
  30. package/dist/main/app/window-events.d.ts +15 -0
  31. package/dist/main/app/window-events.js +45 -0
  32. package/dist/main/app/window-runtime-services.d.ts +41 -0
  33. package/dist/main/app/window-runtime-services.js +197 -0
  34. package/dist/main/app/workbench-modules.d.ts +24 -0
  35. package/dist/main/app/workbench-modules.js +51 -0
  36. package/dist/main/app/workbench-window.d.ts +85 -0
  37. package/dist/main/app/workbench-window.js +310 -0
  38. package/dist/main/index.bundle.js +11712 -9986
  39. package/dist/main/index.js +49 -1
  40. package/dist/main/ipc/app-lifecycle.d.ts +1 -31
  41. package/dist/main/ipc/app-lifecycle.js +1 -53
  42. package/dist/main/ipc/app.d.ts +4 -1
  43. package/dist/main/ipc/app.js +4 -3
  44. package/dist/main/ipc/bridge-router.d.ts +19 -116
  45. package/dist/main/ipc/bridge-router.js +28 -2128
  46. package/dist/main/ipc/device-picker.d.ts +16 -0
  47. package/dist/main/ipc/device-picker.js +27 -0
  48. package/dist/main/ipc/index.d.ts +5 -0
  49. package/dist/main/ipc/index.js +5 -0
  50. package/dist/main/ipc/internal-devtools.d.ts +16 -0
  51. package/dist/main/ipc/internal-devtools.js +10 -0
  52. package/dist/main/ipc/page-scroll.d.ts +1 -13
  53. package/dist/main/ipc/page-scroll.js +1 -16
  54. package/dist/main/ipc/popover.d.ts +4 -1
  55. package/dist/main/ipc/popover.js +26 -19
  56. package/dist/main/ipc/project-create.d.ts +16 -0
  57. package/dist/main/ipc/project-create.js +27 -0
  58. package/dist/main/ipc/project-fs.d.ts +38 -3
  59. package/dist/main/ipc/project-fs.js +53 -22
  60. package/dist/main/ipc/projects.d.ts +3 -3
  61. package/dist/main/ipc/projects.js +47 -11
  62. package/dist/main/ipc/session-listener-bag.d.ts +1 -40
  63. package/dist/main/ipc/session-listener-bag.js +1 -39
  64. package/dist/main/ipc/session.d.ts +4 -1
  65. package/dist/main/ipc/session.js +26 -26
  66. package/dist/main/ipc/settings.d.ts +4 -1
  67. package/dist/main/ipc/settings.js +17 -19
  68. package/dist/main/ipc/simulator-module.d.ts +9 -3
  69. package/dist/main/ipc/simulator-module.js +13 -10
  70. package/dist/main/ipc/simulator.d.ts +4 -1
  71. package/dist/main/ipc/simulator.js +12 -18
  72. package/dist/main/ipc/tooltip.d.ts +14 -0
  73. package/dist/main/ipc/tooltip.js +29 -0
  74. package/dist/main/ipc/views.d.ts +19 -2
  75. package/dist/main/ipc/views.js +76 -8
  76. package/dist/main/runtime/devtools-backend-before-quit.harness.d.ts +43 -0
  77. package/dist/main/runtime/devtools-backend-before-quit.harness.js +87 -0
  78. package/dist/main/runtime/devtools-backend.js +60 -4
  79. package/dist/main/runtime/devtools-runtime-mock.harness.d.ts +21 -0
  80. package/dist/main/runtime/devtools-runtime-mock.harness.js +313 -0
  81. package/dist/main/runtime/miniapp-runtime.d.ts +91 -22
  82. package/dist/main/services/app-services.d.ts +62 -0
  83. package/dist/main/services/app-services.js +64 -0
  84. package/dist/main/services/automation/connection-target.d.ts +36 -0
  85. package/dist/main/services/automation/connection-target.js +29 -0
  86. package/dist/main/services/automation/console-bridge.d.ts +28 -0
  87. package/dist/main/services/automation/console-bridge.js +91 -0
  88. package/dist/main/services/automation/handlers/app.js +4 -4
  89. package/dist/main/services/automation/handlers/element.js +55 -21
  90. package/dist/main/services/automation/index.d.ts +12 -1
  91. package/dist/main/services/automation/index.js +54 -133
  92. package/dist/main/services/cdp-session/index.d.ts +87 -0
  93. package/dist/main/services/cdp-session/index.js +173 -0
  94. package/dist/main/services/compile-standby.js +4 -0
  95. package/dist/main/services/console-forward/cdp-inject.d.ts +18 -0
  96. package/dist/main/services/console-forward/cdp-inject.js +30 -0
  97. package/dist/main/services/console-forward/global-console-mirror.d.ts +33 -0
  98. package/dist/main/services/console-forward/global-console-mirror.js +71 -0
  99. package/dist/main/services/console-forward/global-diagnostics-mirror.d.ts +33 -0
  100. package/dist/main/services/console-forward/global-diagnostics-mirror.js +73 -0
  101. package/dist/main/services/console-forward/index.d.ts +1 -46
  102. package/dist/main/services/console-forward/index.js +1 -185
  103. package/dist/main/services/console-forward/internal-log.d.ts +2 -0
  104. package/dist/main/services/console-forward/internal-log.js +2 -0
  105. package/dist/main/services/console-forward/open-gated-relay.d.ts +67 -0
  106. package/dist/main/services/console-forward/open-gated-relay.js +55 -0
  107. package/dist/main/services/default-adapter.js +1 -1
  108. package/dist/main/services/diagnostics/index.d.ts +1 -48
  109. package/dist/main/services/diagnostics/index.js +1 -60
  110. package/dist/main/services/dimina-resource-server.d.ts +1 -6
  111. package/dist/main/services/dimina-resource-server.js +1 -98
  112. package/dist/main/services/elements-forward/index.d.ts +132 -15
  113. package/dist/main/services/elements-forward/index.js +155 -304
  114. package/dist/main/services/fs-bridge-protocol.d.ts +61 -0
  115. package/dist/main/services/fs-bridge-protocol.js +34 -0
  116. package/dist/main/services/fs-watch-sse.d.ts +40 -0
  117. package/dist/main/services/fs-watch-sse.js +113 -0
  118. package/dist/main/services/http-json.d.ts +9 -0
  119. package/dist/main/services/http-json.js +6 -0
  120. package/dist/main/services/layout/index.d.ts +11 -0
  121. package/dist/main/services/layout/index.js +23 -0
  122. package/dist/main/services/mcp/connection-owner.d.ts +38 -0
  123. package/dist/main/services/mcp/connection-owner.js +79 -0
  124. package/dist/main/services/mcp/index.d.ts +3 -1
  125. package/dist/main/services/mcp/index.js +4 -3
  126. package/dist/main/services/mcp/opened-project.d.ts +88 -0
  127. package/dist/main/services/mcp/opened-project.js +60 -0
  128. package/dist/main/services/mcp/server.d.ts +2 -1
  129. package/dist/main/services/mcp/server.js +29 -4
  130. package/dist/main/services/mcp/target-manager.d.ts +71 -23
  131. package/dist/main/services/mcp/target-manager.js +269 -138
  132. package/dist/main/services/mcp/target-selection.d.ts +47 -0
  133. package/dist/main/services/mcp/target-selection.js +71 -0
  134. package/dist/main/services/mcp/tools/context-tools.js +20 -5
  135. package/dist/main/services/mcp/tools/project-tools.d.ts +72 -0
  136. package/dist/main/services/mcp/tools/project-tools.js +133 -0
  137. package/dist/main/services/module.d.ts +13 -5
  138. package/dist/main/services/network-forward/body-cache.d.ts +72 -0
  139. package/dist/main/services/network-forward/body-cache.js +179 -0
  140. package/dist/main/services/network-forward/frontend-dispatch.d.ts +91 -0
  141. package/dist/main/services/network-forward/frontend-dispatch.js +148 -0
  142. package/dist/main/services/network-forward/global-body-gate.d.ts +46 -0
  143. package/dist/main/services/network-forward/global-body-gate.js +93 -0
  144. package/dist/main/services/network-forward/global-mirror-test-fixtures.d.ts +48 -0
  145. package/dist/main/services/network-forward/global-mirror-test-fixtures.js +96 -0
  146. package/dist/main/services/network-forward/http.d.ts +47 -0
  147. package/dist/main/services/network-forward/http.js +162 -0
  148. package/dist/main/services/network-forward/index.d.ts +135 -15
  149. package/dist/main/services/network-forward/index.js +854 -224
  150. package/dist/main/services/network-forward/request-ids.d.ts +5 -0
  151. package/dist/main/services/network-forward/request-ids.js +5 -0
  152. package/dist/main/services/network-forward/user-facing.d.ts +21 -0
  153. package/dist/main/services/network-forward/user-facing.js +50 -0
  154. package/dist/main/services/network-forward/websocket.d.ts +36 -0
  155. package/dist/main/services/network-forward/websocket.js +120 -0
  156. package/dist/main/services/notifications/renderer-notifier.d.ts +71 -9
  157. package/dist/main/services/notifications/renderer-notifier.js +45 -8
  158. package/dist/main/services/projects/create-project-service.js +19 -5
  159. package/dist/main/services/projects/local-provider.js +8 -4
  160. package/dist/main/services/projects/project-repository.d.ts +59 -7
  161. package/dist/main/services/projects/project-repository.js +285 -51
  162. package/dist/main/services/projects/types.d.ts +44 -34
  163. package/dist/main/services/render-inspect/index.d.ts +12 -2
  164. package/dist/main/services/render-inspect/index.js +21 -102
  165. package/dist/main/services/safe-area/index.d.ts +21 -6
  166. package/dist/main/services/safe-area/index.js +92 -46
  167. package/dist/main/services/service-host-pool/pool.d.ts +1 -196
  168. package/dist/main/services/service-host-pool/pool.js +1 -363
  169. package/dist/main/services/settings/index.d.ts +7 -1
  170. package/dist/main/services/settings/index.js +22 -2
  171. package/dist/main/services/simulator/custom-apis.d.ts +1 -42
  172. package/dist/main/services/simulator/custom-apis.js +1 -46
  173. package/dist/main/services/simulator/referer.d.ts +1 -9
  174. package/dist/main/services/simulator/referer.js +1 -19
  175. package/dist/main/services/simulator/ui-extensions.d.ts +21 -0
  176. package/dist/main/services/simulator/ui-extensions.js +176 -0
  177. package/dist/main/services/simulator-appdata/index.d.ts +6 -0
  178. package/dist/main/services/simulator-appdata/index.js +21 -2
  179. package/dist/main/services/simulator-current-page/index.d.ts +5 -3
  180. package/dist/main/services/simulator-current-page/index.js +8 -1
  181. package/dist/main/services/simulator-storage/index.d.ts +34 -5
  182. package/dist/main/services/simulator-storage/index.js +73 -71
  183. package/dist/main/services/simulator-storage/service-storage-ops.d.ts +1 -39
  184. package/dist/main/services/simulator-storage/service-storage-ops.js +1 -66
  185. package/dist/main/services/simulator-storage/window-scope.d.ts +20 -0
  186. package/dist/main/services/simulator-storage/window-scope.js +20 -0
  187. package/dist/main/services/simulator-temp-files/disk.d.ts +1 -54
  188. package/dist/main/services/simulator-temp-files/disk.js +1 -237
  189. package/dist/main/services/simulator-temp-files/fs-channels.d.ts +1 -68
  190. package/dist/main/services/simulator-temp-files/fs-channels.js +1 -107
  191. package/dist/main/services/simulator-temp-files/index.d.ts +1 -32
  192. package/dist/main/services/simulator-temp-files/index.js +1 -181
  193. package/dist/main/services/simulator-temp-files/request-handler.d.ts +1 -29
  194. package/dist/main/services/simulator-temp-files/request-handler.js +1 -177
  195. package/dist/main/services/simulator-temp-files/resolver.d.ts +1 -21
  196. package/dist/main/services/simulator-temp-files/resolver.js +1 -21
  197. package/dist/main/services/simulator-temp-files/store.d.ts +1 -13
  198. package/dist/main/services/simulator-temp-files/store.js +1 -23
  199. package/dist/main/services/update/github-release-checker.js +22 -3
  200. package/dist/main/services/update/update-manager.d.ts +21 -4
  201. package/dist/main/services/update/update-manager.js +55 -11
  202. package/dist/main/services/views/clear-console-filter.d.ts +44 -0
  203. package/dist/main/services/views/clear-console-filter.js +86 -0
  204. package/dist/main/services/views/console-filter-test-fixtures.d.ts +94 -0
  205. package/dist/main/services/views/console-filter-test-fixtures.js +82 -0
  206. package/dist/main/services/views/console-filter.d.ts +94 -0
  207. package/dist/main/services/views/console-filter.js +190 -0
  208. package/dist/main/services/views/devtools-tabs.d.ts +24 -4
  209. package/dist/main/services/views/devtools-tabs.js +40 -21
  210. package/dist/main/services/views/frontend-bootstrap-gate.d.ts +59 -0
  211. package/dist/main/services/views/frontend-bootstrap-gate.js +117 -0
  212. package/dist/main/services/views/host-dialog-port-channel.d.ts +18 -0
  213. package/dist/main/services/views/host-dialog-port-channel.js +15 -0
  214. package/dist/main/services/views/host-dialog-session-runtime.d.ts +10 -0
  215. package/dist/main/services/views/host-dialog-session-runtime.js +17 -0
  216. package/dist/main/services/views/host-dialog-view.d.ts +95 -0
  217. package/dist/main/services/views/host-dialog-view.js +147 -0
  218. package/dist/main/services/views/host-sidebar-port-channel.d.ts +18 -0
  219. package/dist/main/services/views/host-sidebar-port-channel.js +15 -0
  220. package/dist/main/services/views/host-sidebar-session-runtime.d.ts +10 -0
  221. package/dist/main/services/views/host-sidebar-session-runtime.js +17 -0
  222. package/dist/main/services/views/host-sidebar-view.d.ts +59 -0
  223. package/dist/main/services/views/host-sidebar-view.js +44 -0
  224. package/dist/main/services/views/host-slot-port-channel.d.ts +124 -0
  225. package/dist/main/services/views/host-slot-port-channel.js +289 -0
  226. package/dist/main/services/views/host-slot-session-runtime.d.ts +40 -0
  227. package/dist/main/services/views/host-slot-session-runtime.js +50 -0
  228. package/dist/main/services/views/host-slot-view.d.ts +109 -0
  229. package/dist/main/services/views/host-slot-view.js +147 -0
  230. package/dist/main/services/views/host-toolbar-port-channel.d.ts +6 -91
  231. package/dist/main/services/views/host-toolbar-port-channel.js +10 -243
  232. package/dist/main/services/views/host-toolbar-session-runtime.d.ts +5 -30
  233. package/dist/main/services/views/host-toolbar-session-runtime.js +9 -47
  234. package/dist/main/services/views/host-toolbar-view.d.ts +34 -7
  235. package/dist/main/services/views/host-toolbar-view.js +30 -237
  236. package/dist/main/services/views/managed-web-contents-view.d.ts +48 -0
  237. package/dist/main/services/views/managed-web-contents-view.js +143 -0
  238. package/dist/main/services/views/miniapp-partition.d.ts +1 -89
  239. package/dist/main/services/views/miniapp-partition.js +1 -158
  240. package/dist/main/services/views/native-simulator-devtools-host.js +206 -68
  241. package/dist/main/services/views/native-simulator-view.d.ts +6 -0
  242. package/dist/main/services/views/native-simulator-view.js +47 -40
  243. package/dist/main/services/views/native-view-tree.d.ts +25 -0
  244. package/dist/main/services/views/native-view-tree.js +69 -0
  245. package/dist/main/services/views/overlay-panels-view.d.ts +63 -4
  246. package/dist/main/services/views/overlay-panels-view.js +257 -108
  247. package/dist/main/services/views/placement-reconciler.d.ts +18 -18
  248. package/dist/main/services/views/placement-reconciler.js +91 -29
  249. package/dist/main/services/views/placement-test-driver.d.ts +27 -0
  250. package/dist/main/services/views/placement-test-driver.js +29 -0
  251. package/dist/main/services/views/refresh-styles.d.ts +10 -0
  252. package/dist/main/services/views/refresh-styles.js +57 -0
  253. package/dist/main/services/views/simulator-session-policy.d.ts +1 -27
  254. package/dist/main/services/views/simulator-session-policy.js +1 -98
  255. package/dist/main/services/views/view-manager-devtools-host-test-fixtures.d.ts +76 -0
  256. package/dist/main/services/views/view-manager-devtools-host-test-fixtures.js +184 -0
  257. package/dist/main/services/views/view-manager.d.ts +69 -88
  258. package/dist/main/services/views/view-manager.js +62 -7
  259. package/dist/main/services/views/workbench-view.d.ts +2 -0
  260. package/dist/main/services/views/workbench-view.js +104 -17
  261. package/dist/main/services/window-contexts/context-router.d.ts +36 -0
  262. package/dist/main/services/window-contexts/context-router.js +55 -0
  263. package/dist/main/services/workbench-coi-host.d.ts +52 -0
  264. package/dist/main/services/workbench-coi-host.js +227 -0
  265. package/dist/main/services/workbench-coi-server.d.ts +11 -0
  266. package/dist/main/services/workbench-coi-server.js +126 -126
  267. package/dist/main/services/workbench-coi-shutdown.d.ts +40 -0
  268. package/dist/main/services/workbench-coi-shutdown.js +69 -0
  269. package/dist/main/services/workbench-coi-static.d.ts +23 -0
  270. package/dist/main/services/workbench-coi-static.js +87 -0
  271. package/dist/main/services/workbench-context.d.ts +88 -8
  272. package/dist/main/services/workbench-context.js +54 -6
  273. package/dist/main/services/workspace/compile-log-buffer.d.ts +40 -0
  274. package/dist/main/services/workspace/compile-log-buffer.js +41 -0
  275. package/dist/main/services/workspace/compile-mode-adapter.d.ts +18 -0
  276. package/dist/main/services/workspace/compile-mode-adapter.js +57 -0
  277. package/dist/main/services/workspace/compile-mode-store.d.ts +25 -0
  278. package/dist/main/services/workspace/compile-mode-store.js +71 -0
  279. package/dist/main/services/workspace/open-project-guards.d.ts +16 -0
  280. package/dist/main/services/workspace/open-project-guards.js +42 -0
  281. package/dist/main/services/workspace/rebuild-status.d.ts +37 -0
  282. package/dist/main/services/workspace/rebuild-status.js +36 -0
  283. package/dist/main/services/workspace/session-status-store.d.ts +47 -0
  284. package/dist/main/services/workspace/session-status-store.js +73 -0
  285. package/dist/main/services/workspace/status-tap.d.ts +20 -0
  286. package/dist/main/services/workspace/status-tap.js +32 -0
  287. package/dist/main/services/workspace/workspace-compile-modes.d.ts +59 -0
  288. package/dist/main/services/workspace/workspace-compile-modes.js +93 -0
  289. package/dist/main/services/workspace/workspace-lifecycle-race.testutil.d.ts +22 -0
  290. package/dist/main/services/workspace/workspace-lifecycle-race.testutil.js +62 -0
  291. package/dist/main/services/workspace/workspace-referer.d.ts +17 -0
  292. package/dist/main/services/workspace/workspace-referer.js +26 -0
  293. package/dist/main/services/workspace/workspace-service.d.ts +7 -5
  294. package/dist/main/services/workspace/workspace-service.js +96 -135
  295. package/dist/main/services/workspace/workspace-thumbnails.d.ts +22 -0
  296. package/dist/main/services/workspace/workspace-thumbnails.js +67 -0
  297. package/dist/main/utils/ipc-context-source.d.ts +40 -0
  298. package/dist/main/utils/ipc-context-source.js +23 -0
  299. package/dist/main/utils/ipc-registry.d.ts +46 -21
  300. package/dist/main/utils/ipc-registry.js +166 -76
  301. package/dist/main/utils/paths.d.ts +18 -0
  302. package/dist/main/utils/paths.js +18 -0
  303. package/dist/main/utils/sender-policy.d.ts +10 -1
  304. package/dist/main/utils/sender-policy.js +42 -4
  305. package/dist/main/utils/theme.d.ts +18 -8
  306. package/dist/main/utils/theme.js +19 -9
  307. package/dist/main/windows/internal-devtools-window/index.d.ts +66 -0
  308. package/dist/main/windows/internal-devtools-window/index.js +160 -0
  309. package/dist/main/windows/main-window/create.d.ts +16 -0
  310. package/dist/main/windows/main-window/create.js +19 -11
  311. package/dist/main/windows/main-window/events.d.ts +1 -1
  312. package/dist/main/windows/main-window/events.js +26 -13
  313. package/dist/main/windows/main-window/index.d.ts +1 -1
  314. package/dist/main/windows/main-window/index.js +1 -1
  315. package/dist/main/windows/service-host-window/create.d.ts +1 -92
  316. package/dist/main/windows/service-host-window/create.js +1 -154
  317. package/dist/native-host/common/common.js +173 -53
  318. package/dist/native-host/container/pageFrame.css +1 -1
  319. package/dist/native-host/render/render.js +8278 -3659
  320. package/dist/native-host/service/service.js +2 -2
  321. package/dist/preload/index.d.ts +2 -0
  322. package/dist/preload/index.js +1 -0
  323. package/dist/preload/instrumentation/app-data.d.ts +2 -2
  324. package/dist/preload/instrumentation/app-data.js +1 -1
  325. package/dist/preload/instrumentation/wxml.js +1 -1
  326. package/dist/preload/runtime/bridge.d.ts +3 -3
  327. package/dist/preload/runtime/bridge.js +2 -2
  328. package/dist/preload/runtime/clipboard.d.ts +6 -0
  329. package/dist/preload/runtime/clipboard.js +12 -0
  330. package/dist/preload/runtime/host-dialog-advertiser.d.ts +22 -0
  331. package/dist/preload/runtime/host-dialog-advertiser.js +37 -0
  332. package/dist/preload/runtime/host-dialog-port.d.ts +44 -0
  333. package/dist/preload/runtime/host-dialog-port.js +53 -0
  334. package/dist/preload/runtime/host-dialog-runtime.d.ts +28 -0
  335. package/dist/preload/runtime/host-dialog-runtime.js +36 -0
  336. package/dist/preload/runtime/host-sidebar-advertiser.d.ts +19 -0
  337. package/dist/preload/runtime/host-sidebar-advertiser.js +35 -0
  338. package/dist/preload/runtime/host-sidebar-port.d.ts +44 -0
  339. package/dist/preload/runtime/host-sidebar-port.js +53 -0
  340. package/dist/preload/runtime/host-sidebar-runtime.d.ts +28 -0
  341. package/dist/preload/runtime/host-sidebar-runtime.js +36 -0
  342. package/dist/preload/runtime/host-slot-port-bridge.d.ts +18 -0
  343. package/dist/preload/runtime/host-slot-port-bridge.js +112 -0
  344. package/dist/preload/runtime/host-toolbar-advertiser.d.ts +5 -13
  345. package/dist/preload/runtime/host-toolbar-advertiser.js +18 -38
  346. package/dist/preload/runtime/host-toolbar-port.d.ts +9 -0
  347. package/dist/preload/runtime/host-toolbar-port.js +11 -95
  348. package/dist/preload/runtime/native-host.d.ts +14 -0
  349. package/dist/preload/runtime/native-host.js +5 -8
  350. package/dist/preload/runtime/node-bindings.d.ts +18 -0
  351. package/dist/preload/runtime/node-bindings.js +44 -0
  352. package/dist/preload/runtime/temp-files.js +9 -2
  353. package/dist/preload/runtime/wait-for-slot-root.d.ts +23 -0
  354. package/dist/preload/runtime/wait-for-slot-root.js +80 -0
  355. package/dist/preload/shared/api-compat.js +63 -41
  356. package/dist/preload/windows/host-dialog-runtime.cjs +360 -0
  357. package/dist/preload/windows/host-dialog-runtime.cjs.map +7 -0
  358. package/dist/preload/windows/host-dialog-runtime.d.ts +2 -0
  359. package/dist/preload/windows/host-dialog-runtime.js +13 -0
  360. package/dist/preload/windows/host-sidebar-runtime.cjs +361 -0
  361. package/dist/preload/windows/host-sidebar-runtime.cjs.map +7 -0
  362. package/dist/preload/windows/host-sidebar-runtime.d.ts +2 -0
  363. package/dist/preload/windows/host-sidebar-runtime.js +13 -0
  364. package/dist/preload/windows/host-toolbar-runtime.cjs +142 -52
  365. package/dist/preload/windows/host-toolbar-runtime.cjs.map +3 -3
  366. package/dist/preload/windows/main.cjs +4922 -1246
  367. package/dist/preload/windows/main.cjs.map +4 -4
  368. package/dist/preload/windows/main.css +428 -0
  369. package/dist/preload/windows/main.css.map +7 -0
  370. package/dist/preload/windows/simulator.cjs +376 -322
  371. package/dist/preload/windows/simulator.cjs.map +4 -4
  372. package/dist/preload/windows/simulator.js +376 -322
  373. package/dist/render-host/pageFrame.html +4 -4
  374. package/dist/render-host/preload.cjs +30 -0
  375. package/dist/render-host/render-inspect.js +184 -115
  376. package/dist/renderer/assets/button-CB2MWjHY.js +2 -0
  377. package/dist/renderer/assets/constants-CkoGPQTS.js +2 -0
  378. package/dist/renderer/assets/constants-zQZ2-y21.js +2 -0
  379. package/dist/renderer/assets/createLucideIcon-cZ9FlZZw.js +2 -0
  380. package/dist/renderer/assets/devicePicker-H2eIO4e1.js +2 -0
  381. package/dist/renderer/assets/dialog-pHzEA8Vx.js +46 -0
  382. package/dist/renderer/assets/dist-B5HADirS.js +2 -0
  383. package/dist/renderer/assets/dist-DIFlRMKe.js +2 -0
  384. package/dist/renderer/assets/hostSidebarDefault-DRWh6OCt.js +2 -0
  385. package/dist/renderer/assets/index-CEL_XFge.js +2 -0
  386. package/dist/renderer/assets/input-CAObw95L.js +2 -0
  387. package/dist/renderer/assets/ipc-channels-overlays-gIPUFnqc.js +2 -0
  388. package/dist/renderer/assets/jsx-runtime-DICEQH_0.css +1 -0
  389. package/dist/renderer/assets/jsx-runtime-DIw5wnYl.js +9 -0
  390. package/dist/renderer/assets/plus-BQ9u5EbL.js +2 -0
  391. package/dist/renderer/assets/popover-Cw7G2Ctp.js +2 -0
  392. package/dist/renderer/assets/presets-DMZOb9ay.js +2 -0
  393. package/dist/renderer/assets/project-api-YTOr_Yvo.js +2 -0
  394. package/dist/renderer/assets/projectCreateDialog-BmLqiYxn.js +2 -0
  395. package/dist/renderer/assets/search-BMvuYF48.js +2 -0
  396. package/dist/renderer/assets/select-nFP95TxM.js +2 -0
  397. package/dist/renderer/assets/settings-CnpVfSWt.js +2 -0
  398. package/dist/renderer/assets/settings-api-Ccsf-Nsj.js +2 -0
  399. package/dist/renderer/assets/settings-tab-bar-CAzrv32m.js +2 -0
  400. package/dist/renderer/assets/smartphone-Bb2GdIKy.js +2 -0
  401. package/dist/renderer/assets/tabs-CPKN3Mmq.js +2 -0
  402. package/dist/renderer/assets/tooltip-D6AxXRk5.js +2 -0
  403. package/dist/renderer/assets/types-Bh0hA7El.js +2 -0
  404. package/dist/renderer/assets/updateDialog-CwndJ0Bl.js +2 -0
  405. package/dist/renderer/assets/utils-sEB5OZEQ.js +2 -0
  406. package/dist/renderer/assets/view-api-B-2zPBR5.js +2 -0
  407. package/dist/renderer/assets/view-ids-BfaDVV5P.js +2 -0
  408. package/dist/renderer/assets/workbench-C0Jkdlps.js +5 -0
  409. package/dist/renderer/assets/workbenchSettings-YD0Ctbm_.js +8 -0
  410. package/dist/renderer/entries/device-picker/index.html +28 -0
  411. package/dist/renderer/entries/host-sidebar-default/index.html +22 -0
  412. package/dist/renderer/entries/main/index.html +16 -7
  413. package/dist/renderer/entries/popover/index.html +16 -6
  414. package/dist/renderer/entries/project-create-dialog/index.html +27 -0
  415. package/dist/renderer/entries/settings/index.html +10 -5
  416. package/dist/renderer/entries/tooltip/index.html +21 -0
  417. package/dist/renderer/entries/update-dialog/index.html +25 -0
  418. package/dist/renderer/entries/workbench/index.html +49 -0
  419. package/dist/renderer/entries/workbench-settings/index.html +12 -5
  420. package/dist/service-host/appdata-set-data.cjs +39 -0
  421. package/dist/service-host/host-env-update.cjs +23 -0
  422. package/dist/service-host/preload.cjs +54 -48
  423. package/dist/service-host/service-message-queue.cjs +71 -0
  424. package/dist/service-host/sync-impls/menu-button-geometry.js +16 -5
  425. package/dist/service-host/sync-impls/menu-button.js +5 -3
  426. package/dist/service-host/sync-impls/system-info.js +31 -9
  427. package/dist/shared/bridge-channels.d.ts +1 -416
  428. package/dist/shared/bridge-channels.js +1 -89
  429. package/dist/shared/compile-mode-state.d.ts +73 -0
  430. package/dist/shared/compile-mode-state.js +100 -0
  431. package/dist/shared/compile-modes.d.ts +152 -0
  432. package/dist/shared/compile-modes.js +237 -0
  433. package/dist/shared/constants.d.ts +22 -0
  434. package/dist/shared/constants.js +22 -0
  435. package/dist/shared/dmb-resource-url.d.ts +2 -0
  436. package/dist/shared/dmb-resource-url.js +2 -0
  437. package/dist/shared/ipc-channels-overlays.d.ts +162 -0
  438. package/dist/shared/ipc-channels-overlays.js +203 -0
  439. package/dist/shared/ipc-channels.d.ts +24 -154
  440. package/dist/shared/ipc-channels.js +48 -96
  441. package/dist/shared/ipc-schemas.d.ts +143 -54
  442. package/dist/shared/ipc-schemas.js +137 -45
  443. package/dist/shared/node-bindings.d.ts +2 -0
  444. package/dist/shared/node-bindings.js +2 -0
  445. package/dist/shared/project-window-types.d.ts +42 -0
  446. package/dist/shared/project-window-types.js +2 -0
  447. package/dist/shared/simulator-route.d.ts +8 -0
  448. package/dist/shared/simulator-route.js +15 -0
  449. package/dist/shared/simulator-ui.d.ts +61 -0
  450. package/dist/shared/simulator-ui.js +12 -0
  451. package/dist/shared/types.d.ts +126 -41
  452. package/dist/shared/view-ids.d.ts +10 -0
  453. package/dist/shared/view-ids.js +23 -0
  454. package/dist/simulator/assets/bridge-channels-B3JAmRfl.js +2 -0
  455. package/dist/simulator/assets/device-shell-ATEhHV2_.css +1 -0
  456. package/dist/simulator/assets/device-shell-DucLepkm.js +431 -0
  457. package/dist/simulator/assets/simulator-B4rbcOVt.js +10 -0
  458. package/dist/simulator/assets/simulator-mini-app-DFo7fhi5.js +2 -0
  459. package/dist/simulator/assets/simulator-ui-BupATgKo.css +1 -0
  460. package/dist/simulator/assets/simulator-ui-i3GCc7YJ.js +2 -0
  461. package/dist/simulator/simulator.html +4 -3
  462. package/dist/simulator/temp-files.d.ts +35 -0
  463. package/dist/simulator/temp-files.js +121 -0
  464. package/dist/simulator/types.d.ts +50 -0
  465. package/dist/simulator/types.js +2 -0
  466. package/dist/vscode-workbench/assets/__vite-browser-external-JIkWewFf.js +1 -0
  467. package/dist/vscode-workbench/assets/{dist-TpGpmMGi.js → dist-CXG-u1VB.js} +3 -3
  468. package/dist/vscode-workbench/assets/fs-core-worker-urls-DZ1nod84.js +1 -0
  469. package/dist/vscode-workbench/assets/fs-core.worker-Bnmpp6fo.js +1 -0
  470. package/dist/vscode-workbench/assets/fs-query.worker-cZ-7Fjch.js +2 -0
  471. package/dist/vscode-workbench/assets/{iconv-lite-umd-C9tiCAJa.js → iconv-lite-umd-Dxx9Qyb4.js} +1 -1
  472. package/dist/vscode-workbench/assets/{index-DJ1HyMZ7.js → index-6VJMsaWj.js} +475 -475
  473. package/dist/vscode-workbench/assets/{jschardet-DE1jV513.js → jschardet-Ba3D16vt.js} +1 -1
  474. package/dist/vscode-workbench/index.html +21 -1
  475. package/package.json +23 -13
  476. package/dist/main/services/views/destroy-child-view.d.ts +0 -9
  477. package/dist/main/services/views/destroy-child-view.js +0 -23
  478. package/dist/preload/instrumentation/wxml-extract.d.ts +0 -11
  479. package/dist/preload/instrumentation/wxml-extract.js +0 -382
  480. package/dist/preload/shared/sid-registry.d.ts +0 -11
  481. package/dist/preload/shared/sid-registry.js +0 -38
  482. package/dist/renderer/assets/constants-EAMiwL9_.js +0 -2
  483. package/dist/renderer/assets/index-BMqyDx71.js +0 -49
  484. package/dist/renderer/assets/input-CDAEwpBO.js +0 -2
  485. package/dist/renderer/assets/ipc-transport-B7eFOR68.css +0 -1
  486. package/dist/renderer/assets/ipc-transport-_G1k5V1p.js +0 -9
  487. package/dist/renderer/assets/popover-DEdjK14m.js +0 -2
  488. package/dist/renderer/assets/select-DpKPCh3y.js +0 -2
  489. package/dist/renderer/assets/settings-M5q2elUr.js +0 -2
  490. package/dist/renderer/assets/settings-api-CDlZoHiO.js +0 -2
  491. package/dist/renderer/assets/workbenchSettings-CT_H1WhV.js +0 -8
  492. package/dist/shared/appdata-accumulator.d.ts +0 -95
  493. package/dist/shared/appdata-accumulator.js +0 -218
  494. package/dist/shared/request-core.d.ts +0 -84
  495. package/dist/shared/request-core.js +0 -168
  496. package/dist/shared/simulator-api-metadata.d.ts +0 -26
  497. package/dist/shared/simulator-api-metadata.js +0 -59
  498. package/dist/shared/vpath.d.ts +0 -42
  499. package/dist/shared/vpath.js +0 -105
  500. package/dist/simulator/assets/bridge-channels-zhsumfky.js +0 -2
  501. package/dist/simulator/assets/device-shell-C-wcFq3Z.js +0 -2
  502. package/dist/simulator/assets/device-shell-CS1rqAQz.css +0 -1
  503. package/dist/simulator/assets/jsx-runtime-BDTY6fEq.js +0 -2
  504. package/dist/simulator/assets/simulator-DU3-fS3v.js +0 -10
  505. package/dist/simulator/assets/simulator-mini-app-DzfMfnVM.js +0 -2
  506. package/dist/simulator/device-shell/menu-button-geometry.js +0 -8
  507. package/dist/vscode-workbench/assets/__vite-browser-external-CXi6Kz9W.js +0 -1
@@ -1,309 +1,97 @@
1
1
  import { setupCdpPort, registerDifileScheme, suppressInsecureCspWarnings } from './bootstrap.js';
2
2
  import { installMaxListenersWarningDiagnostic } from './max-listeners-diagnostic.js';
3
+ import { app, session } from 'electron';
4
+ import { rendererDir as defaultRendererDir } from '../utils/paths.js';
5
+ import { createAppServices, registerTrustedWindow } from '../services/app-services.js';
6
+ import { createWindowContextRouter } from '../services/window-contexts/context-router.js';
7
+ import { createInternalDevtoolsWindow } from '../windows/internal-devtools-window/index.js';
8
+ import { registerAppIpc, registerInternalDevtoolsIpc, registerTooltipIpc, registerProjectCreateIpc, registerDevicePickerIpc, registerViewsIpc, } from '../ipc/index.js';
3
9
  import { registerProjectFsIpc } from '../ipc/project-fs.js';
4
- import { app, BrowserWindow, nativeImage, session } from 'electron';
5
- import fs from 'fs';
6
- import path from 'path';
7
- import { rendererDir as defaultRendererDir, defaultPreloadPath, devtoolsPackageRoot } from '../utils/paths.js';
10
+ import { setupSimulatorSessionPolicy } from '../services/views/simulator-session-policy.js';
11
+ import { setupCompileWorkerStandby } from '../services/compile-standby.js';
8
12
  import { installThemeBackgroundSync } from '../utils/theme.js';
9
- import { createMainWindow, wireMainWindowEvents } from '../windows/main-window/index.js';
10
13
  import { isAppQuitting } from './lifecycle.js';
11
- import { resolveNativeAppDataKeys, resolveNativeStorageOverview } from './native-overview.js';
12
- // eslint-disable-next-line no-restricted-syntax -- grandfathered(workbench-context): shrink-only
13
- import { createWorkbenchContext } from '../services/workbench-context.js';
14
- import { setupCompileWorkerStandby } from '../services/compile-standby.js';
15
14
  import { loadWorkbenchSettings, applyTheme } from '../services/settings/index.js';
16
- import { installAppMenu } from '../menu/index.js';
17
- import { registerAppIpc, popoverModule, projectsModule, sessionModule, settingsModule, simulatorModule, } from '../ipc/index.js';
18
- import { startAutomationServer } from '../services/automation/index.js';
19
- import { startMcpServer, setNativeHost, setActiveBridgeId, setNativeOverviewProvider, } from '../services/mcp/index.js';
20
- import { setupSimulatorStorage } from '../services/simulator-storage/index.js';
21
- import { createNetworkForwarder } from '../services/network-forward/index.js';
22
- import { setupSimulatorWxml } from '../services/simulator-wxml/index.js';
23
- import { setupSimulatorAppData } from '../services/simulator-appdata/index.js';
24
- import { setupSimulatorCurrentPage } from '../services/simulator-current-page/index.js';
25
- import { createRenderInspector } from '../services/render-inspect/index.js';
26
- import { setupSimulatorTempFiles } from '../services/simulator-temp-files/index.js';
27
15
  import { SHARED_MINIAPP_PARTITION } from '../services/views/miniapp-partition.js';
28
- import { setupSimulatorSessionPolicy } from '../services/views/simulator-session-policy.js';
29
- import { startWorkbenchCoiServer } from '../services/workbench-coi-server.js';
16
+ import { setupSimulatorTempFiles } from '../services/simulator-temp-files/index.js';
30
17
  import { UpdateManager } from '../services/update/index.js';
31
- import { toDisposable } from '@dimina-kit/electron-deck/main';
18
+ import { toDisposable, DisposableRegistry } from '@dimina-kit/electron-deck/main';
32
19
  import { IpcRegistry } from '../utils/ipc-registry.js';
33
- const DEFAULT_MODULES = {
34
- projects: true,
35
- session: true,
36
- simulator: true,
37
- popover: true,
38
- settings: true,
39
- };
40
- const BUILTIN_MODULES = {
41
- projects: projectsModule,
42
- session: sessionModule,
43
- simulator: simulatorModule,
44
- popover: popoverModule,
45
- settings: settingsModule,
46
- };
47
- /**
48
- * Adds `win.webContents` to the context's trusted-sender set and returns a
49
- * Disposable that removes it again.
50
- *
51
- * Trust is reference-counted: registering the SAME window N times keeps it
52
- * trusted until every one of the N returned Disposables has been disposed.
53
- * `trustedWindowSenderIds` is a `Map<webContents.id, refCount>`; each register
54
- * bumps the count, each dispose decrements it, and the window is un-trusted
55
- * only when the count reaches zero.
56
- *
57
- * The window's `closed` event short-circuits the ref-count: it deletes the
58
- * map entry outright (the window is dead, so it must be un-trusted
59
- * immediately regardless of how many Disposables are still outstanding).
60
- * After `closed`, disposing any leftover Disposable is a safe no-op — the
61
- * map entry is already gone, so the decrement finds `undefined` and bails
62
- * without driving the count negative or resurrecting trust.
63
- *
64
- * Each returned Disposable is itself idempotent (`removed` flag), and its
65
- * `closed` listener removes itself once fired so a long-lived context
66
- * doesn't accumulate dead listeners on closed windows.
67
- */
68
- function registerTrustedWindow(context, win) {
69
- const senderId = win.webContents.id;
70
- const counts = context.trustedWindowSenderIds;
71
- counts.set(senderId, (counts.get(senderId) ?? 0) + 1);
72
- let removed = false;
73
- const onClosed = () => {
74
- // The window is gone: zero the ref-count for this sender id outright,
75
- // regardless of any other outstanding registrations for the same window.
76
- counts.delete(senderId);
77
- win.removeListener('closed', onClosed);
78
- };
79
- function remove() {
80
- if (removed)
81
- return;
82
- removed = true;
83
- win.removeListener('closed', onClosed);
84
- const count = counts.get(senderId);
85
- // `undefined` → the entry was already cleared (e.g. by `closed` or by a
86
- // prior sibling's decrement that hit zero). Nothing to do — never go
87
- // negative, never resurrect trust.
88
- if (count === undefined)
89
- return;
90
- if (count <= 1)
91
- counts.delete(senderId);
92
- else
93
- counts.set(senderId, count - 1);
94
- }
95
- win.once('closed', onClosed);
96
- return toDisposable(remove);
97
- }
98
- /** Parse --auto, --auto-port, --project from process.argv. */
99
- function parseAutoArgs() {
100
- const argv = process.argv;
101
- let auto = false;
102
- let autoPort = 9420;
103
- let projectPath = '';
104
- for (let i = 0; i < argv.length; i++) {
105
- if (argv[i] === 'auto' || argv[i] === '--auto')
106
- auto = true;
107
- if ((argv[i] === '--auto-port' || argv[i] === '--auto_port') && argv[i + 1]) {
108
- const parsed = parseInt(argv[i + 1], 10);
109
- // 0 → OS-assigned free port (used by parallel e2e workers)
110
- if (Number.isFinite(parsed) && parsed >= 0)
111
- autoPort = parsed;
112
- }
113
- if (argv[i] === '--project' && argv[i + 1]) {
114
- projectPath = argv[i + 1];
115
- }
116
- }
117
- return { auto, autoPort, projectPath };
118
- }
119
- function resolveModules(config) {
120
- return {
121
- ...DEFAULT_MODULES,
122
- ...config.modules,
123
- };
124
- }
125
- async function disposeContext(ctx) {
126
- await ctx.workspace.closeProject();
127
- await ctx.registry.dispose().catch((err) => {
128
- console.warn('[workbench] dispose registry encountered errors:', err);
129
- });
130
- }
131
- function createConfiguredMainWindow(config, rendererDir) {
132
- const mainWindow = createMainWindow({
133
- title: config.appName ?? 'Dimina DevTools',
134
- indexHtml: path.join(rendererDir, 'entries/main/index.html'),
135
- width: config.window?.width,
136
- height: config.window?.height,
137
- minWidth: config.window?.minWidth,
138
- minHeight: config.window?.minHeight,
139
- autoShow: config.window?.autoShow,
140
- });
141
- // Set window/taskbar icon if provided (Linux/Windows; macOS uses app bundle icon)
142
- if (config.icon) {
143
- const icon = nativeImage.createFromPath(config.icon);
144
- if (!icon.isEmpty())
145
- mainWindow.setIcon(icon);
146
- }
147
- return mainWindow;
148
- }
149
- function createContext(config, mainWindow, rendererDir) {
150
- return createWorkbenchContext({
151
- mainWindow,
152
- adapter: config.adapter,
153
- preloadPath: config.preloadPath ?? defaultPreloadPath,
154
- rendererDir,
155
- appName: config.appName,
156
- apiNamespaces: config.apiNamespaces,
157
- fileTypes: config.fileTypes,
158
- brandingProvider: config.brandingProvider,
159
- // The host-supplied ProjectsProvider / template types in `shared/types`
160
- // are structurally compatible with the main-process equivalents —
161
- // these casts are safe; we re-narrow at the workspace-service /
162
- // create-project-service boundary.
163
- projectsProvider: config.projectsProvider,
164
- projectTemplates: config.projectTemplates,
165
- builtinTemplates: config.builtinTemplates,
166
- customCreateProjectDialog: config.customCreateProjectDialog,
167
- onBeforeOpenProject: config.onBeforeOpenProject,
168
- });
169
- }
170
- function registerBuiltinModules(config, context) {
171
- const modules = resolveModules(config);
172
- Object.keys(modules).forEach((moduleId) => {
173
- if (modules[moduleId])
174
- context.registry.add(BUILTIN_MODULES[moduleId].setup(context));
175
- });
176
- }
20
+ import { createLauncherWindow } from './project-window.js';
21
+ import { createProjectListSurface } from './project-list-surface.js';
22
+ import { createWorkbenchWindowManager } from './workbench-window.js';
23
+ import { registerModuleIpc, setupWindowModules } from './workbench-modules.js';
24
+ import { registerOpenProjectWindowIpc } from './open-project-ipc.js';
25
+ import { createUiExtensionTargets } from './ui-extension-targets.js';
26
+ import { installGlobalMirrors } from './global-mirrors.js';
27
+ import { installHostSidebarDefault } from './host-sidebar-default.js';
28
+ import { installMenu } from './menu-setup.js';
29
+ import { createOpenForMcp, createTargetForMcp, noteActiveMcpWindowChanged, setActiveMcpWindowResolver, } from '../services/mcp/index.js';
30
+ import { setupAutomation, setupMcp } from './servers.js';
31
+ import { enableDevRendererAutoReload } from './window-events.js';
32
+ import { wireMainWindowEvents } from '../windows/main-window/index.js';
33
+ export { setupWindowModules } from './workbench-modules.js';
177
34
  /**
178
- * Build the hand-written narrow `MenuContext` a host menu builder receives
179
- * explicit construction (not clone+delete), so the runtime object carries
180
- * EXACTLY the contract members and nothing else. Every member is a lazy
181
- * closure over the live context: a host monkey-patch of
182
- * `context.workspace.openProject` (the documented permission-gate pattern)
183
- * still intercepts calls made through this menu surface.
35
+ * Registers the workbench's IPC surface against the router, so each message is
36
+ * answered with the context of the window it came from.
184
37
  */
185
- function toMenuContext(context) {
186
- return {
187
- appName: context.appName,
188
- workspace: {
189
- hasActiveSession: () => context.workspace.hasActiveSession(),
190
- getProjectPath: () => context.workspace.getProjectPath(),
191
- openProject: (projectPath) => context.workspace.openProject(projectPath),
192
- closeProject: () => context.workspace.closeProject(),
193
- getSession: () => context.workspace.getSession(),
194
- },
195
- openSettings: () => context.openSettings(),
196
- notify: {
197
- projectStatus: (payload) => context.notify.projectStatus(payload),
198
- windowNavigateBack: () => context.notify.windowNavigateBack(),
199
- },
200
- };
201
- }
202
- function installMenu(config, mainWindow, context) {
203
- // Menu: use host-provided builder or fall back to default
204
- if (config.menuBuilder) {
205
- config.menuBuilder(mainWindow, toMenuContext(context));
206
- }
207
- else {
208
- installAppMenu(context);
209
- }
210
- }
211
- async function setupAutomation(instance) {
212
- // Start automation server if --auto flag is present
213
- const autoArgs = parseAutoArgs();
214
- if (autoArgs.auto) {
215
- const server = await startAutomationServer(instance.context, autoArgs.autoPort);
216
- instance.automationServer = server;
217
- instance.context.registry.add(() => server.close());
218
- // Stable, parseable line for e2e harnesses that scrape stdout.
219
- console.log(`[automation] listening on ws://127.0.0.1:${server.port}`);
220
- }
221
- }
222
- function setupMcp() {
223
- const settings = loadWorkbenchSettings();
224
- if (!settings.mcp.enabled)
225
- return null;
226
- const cdpPortSwitch = app.commandLine.getSwitchValue('remote-debugging-port');
227
- const cdpPort = cdpPortSwitch ? parseInt(cdpPortSwitch, 10) : settings.cdp.port;
228
- return startMcpServer(cdpPort, settings.mcp.port);
229
- }
230
- function wireAppWindowEvents(config, instance) {
231
- const { mainWindow, context } = instance;
232
- // In-flight guard: `closeProject()` is async, and the window stays open
233
- // (preventDefault'd) while it runsa second close click during that window
234
- // would re-enter and tear the same session down twice. Swallow re-entrancy.
235
- let closing = false;
236
- return wireMainWindowEvents(mainWindow, {
237
- context,
238
- onResize: () => context.views.repositionAll(),
239
- onClose: async (e) => {
240
- // A real application quit (⌘Q / menu "Quit" / app.quit()) fires
241
- // `before-quit` first, then this window's `close`. Let it through so the
242
- // app actually exits — do NOT convert it into "close the project".
243
- // Without this, `hasActiveSession()` would be true and the quit gets
244
- // swallowed into closeProject(), so the app can never be quit while a
245
- // project is open.
246
- if (isAppQuitting())
247
- return;
248
- // A close arriving while a project teardown is already in flight (the
249
- // user rapid-double-clicked the close button) MUST keep the window open.
250
- // This guard runs BEFORE hasActiveSession() on purpose: `closeProject()`
251
- // → `disposeSession()` synchronously nulls the active session before it
252
- // finishes awaiting `session.close()`, so by the time the second close
253
- // arrives `hasActiveSession()` is already false. With the old guard order
254
- // that second close fell straight through the hasActiveSession() check
255
- // WITHOUT `preventDefault()`, so Electron destroyed the last window →
256
- // `window-all-closed` → `app.quit()`, quitting the whole app on a
257
- // double-click. Swallow the re-entrant close and keep the window.
258
- if (closing) {
259
- e.preventDefault();
260
- return;
261
- }
262
- if (!context.workspace.hasActiveSession())
263
- return;
264
- // Close button while a project session is open: stay in the workbench
265
- // and surface the project list. Tear down only the session — do NOT
266
- // dispose `context.registry`, which owns every IPC handler (projects,
267
- // dialog, settings…). Disposing it would leave the renderer alive but
268
- // unable to invoke anything, so subsequent clicks on Import/etc. would
269
- // raise `No handler registered for ...`.
270
- e.preventDefault();
271
- closing = true;
272
- try {
273
- if (config.onBeforeClose) {
274
- await config.onBeforeClose(instance);
275
- }
276
- await context.workspace.closeProject();
277
- context.notify.windowNavigateBack();
278
- }
279
- finally {
280
- closing = false;
281
- }
282
- },
283
- });
284
- }
285
- function enableDevRendererAutoReload(rendererDir) {
286
- // Auto-reload renderer windows when dist files change during development
287
- if (app.isPackaged) {
288
- return toDisposable(() => { });
289
- }
290
- let reloadTimer = null;
291
- const watcher = fs.watch(rendererDir, { recursive: true }, () => {
292
- if (reloadTimer)
293
- clearTimeout(reloadTimer);
294
- reloadTimer = setTimeout(() => {
295
- for (const win of BrowserWindow.getAllWindows()) {
296
- win.webContents.reload();
297
- }
298
- }, 300);
299
- });
300
- return toDisposable(() => {
301
- if (reloadTimer) {
302
- clearTimeout(reloadTimer);
303
- reloadTimer = null;
304
- }
305
- watcher.close();
306
- });
38
+ function registerWorkbenchIpc(config, router, context, mainWindow, appRegistry) {
39
+ appRegistry.add(registerAppIpc(router));
40
+ // Sandboxed project file-system IPC (the renderer-side project:fs:* surface).
41
+ appRegistry.add(registerProjectFsIpc(router));
42
+ // Standalone internal (app-wide) DevTools debug window controller — the
43
+ // independent floating CDP panel that debugs the whole Electron app (as
44
+ // opposed to the right-panel CDP, which inspects only the user's
45
+ // mini-program). Assembled before the IPC handler below so a request
46
+ // arriving right after boot always finds it.
47
+ // `isAppQuitting` lets the controller stop intercepting 'close' during a
48
+ // real quit — its habitual preventDefault()+hide() would otherwise cancel
49
+ // the quit itself and strand the process with a hidden window.
50
+ // One per window (each debugs its own renderer), so it is parked on the
51
+ // window's context registry, not the app's.
52
+ context.internalDevtoolsWindow = createInternalDevtoolsWindow(mainWindow, { isAppQuitting });
53
+ context.registry.add(toDisposable(() => context.internalDevtoolsWindow?.dispose()));
54
+ // Unconditional (not a toggleable BUILTIN_MODULES entry): it's core dev
55
+ // tooling, not a host-configurable feature.
56
+ appRegistry.add(registerInternalDevtoolsIpc(router));
57
+ // Unconditional (not a toggleable BUILTIN_MODULES entry): the tooltip
58
+ // overlay is core UI chrome (every toolbar in this app relies on it), not a
59
+ // host-configurable feature.
60
+ appRegistry.add(registerTooltipIpc(router));
61
+ // Unconditional: the project-create dialog is core UI chrome (the built-in
62
+ // "新建项目" flow every host falls back to), not a host-configurable feature.
63
+ appRegistry.add(registerProjectCreateIpc(router));
64
+ // Unconditional for the same reason as the tooltip above: the device picker
65
+ // is an overlay WebContentsView the simulator toolbar opens, and `ctx.views`
66
+ // exists regardless of the `simulator` module toggle. A host that turns the
67
+ // simulator off simply never renders the trigger.
68
+ appRegistry.add(registerDevicePickerIpc(router));
69
+ // Unconditional (not a toggleable BUILTIN_MODULES entry): placement/host-
70
+ // slot IPC has no real dependency on the simulator module — `ctx.views`
71
+ // (ViewManager) is constructed unconditionally regardless of
72
+ // `modules.simulator`, and host-sidebar in particular lives on the
73
+ // project-list page, unrelated to the simulator webview. Every renderer
74
+ // entry point also blocks its first render on `AllocatePlacementGeneration`
75
+ // (see renderer-placement-generation.ts) — gating any of this behind the
76
+ // simulator toggle would strand a host that disables it on the fatal
77
+ // boot-failure page, or leave placement silently non-functional.
78
+ appRegistry.add(registerViewsIpc(router));
79
+ // Referer/CORS webRequest policy for the simulator runtime's sessions (shared
80
+ // fallback + every per-project partition). Registered into the app registry so
81
+ // its configurator + per-session listeners are torn down with the app —
82
+ // re-creating the app never leaks a duplicate configurator, and a window
83
+ // closing must not strip the policy off the sessions other windows still use.
84
+ appRegistry.add(setupSimulatorSessionPolicy());
85
+ // One process-wide listener that re-syncs every window's native
86
+ // backgroundColor on theme changewindows otherwise keep the stale
87
+ // creation-time color (see installThemeBackgroundSync).
88
+ appRegistry.add(installThemeBackgroundSync());
89
+ // Warm-standby compile worker: only meaningful for the devkit-backed
90
+ // default adapter (a host-injected adapter has no devkit fork to adopt the
91
+ // spare). Registered into the registry so the spare dies with the app.
92
+ if (!config.adapter)
93
+ appRegistry.add(setupCompileWorkerStandby(context));
94
+ registerModuleIpc(config, router, appRegistry);
307
95
  }
308
96
  /**
309
97
  * Pre-ready bootstrap side effects (app name, CDP port, CSP suppression,
@@ -338,13 +126,23 @@ export function runDevtoolsBootstrap(config = {}) {
338
126
  catch { /* electron stub in tests */ }
339
127
  }
340
128
  /**
341
- * Domain runtime assembly — the post-whenReady body. Builds the main window +
342
- * context, registers IPC modules, stands up simulator/storage/CDP/native-host
343
- * services, and returns the fat {@link WorkbenchAppInstance}. Extracted so the
344
- * v2 `RuntimeBackend.assemble` reuses the exact same body (parity by shared
129
+ * Domain runtime assembly — the post-whenReady body. Builds the app-wide
130
+ * services and the context router, opens the project window, registers IPC
131
+ * against the router, stands up simulator/storage/CDP/native-host services, and
132
+ * returns the fat {@link WorkbenchAppInstance}. Extracted so the v2
133
+ * `RuntimeBackend.assemble` reuses the exact same body (parity by shared
345
134
  * implementation, not behavioural re-creation).
346
135
  */
347
- export async function createDevtoolsRuntime(config = {}) {
136
+ export async function createDevtoolsRuntime(config = {},
137
+ /**
138
+ * Fired the instant the `WorkbenchAppInstance` exists — BEFORE `config.onSetup`
139
+ * is awaited below, which may run arbitrarily long host code (including
140
+ * loading the host-toolbar, which opens a live MessagePort). A caller that
141
+ * only learns `instance` from this function's return value would not see it
142
+ * until `onSetup` resolves, leaving a window where an app-quit teardown hook
143
+ * has nothing to dispose yet a live toolbar port already exists.
144
+ */
145
+ onInstanceCreated) {
348
146
  // Self-gate on Electron readiness: this builds a BrowserWindow immediately, so
349
147
  // it must run after `app.whenReady()`. The framework backend path already
350
148
  // awaited it (idempotent no-op here); this guards any direct caller against
@@ -352,252 +150,239 @@ export async function createDevtoolsRuntime(config = {}) {
352
150
  await app.whenReady();
353
151
  applyTheme(loadWorkbenchSettings().theme);
354
152
  const rendererDir = config.rendererDir ?? defaultRendererDir;
355
- const mainWindow = createConfiguredMainWindow(config, rendererDir);
356
- const context = createContext(config, mainWindow, rendererDir);
357
- // Anchor the main window's renderer as the first Connection. Resources
358
- // scoped to the main webContents (acquired by later wiring) tear down with
359
- // it; see packages/electron-deck/docs/foundation.md §4.
360
- context.connections.acquire(mainWindow.webContents);
361
- context.registry.add(registerAppIpc(context));
362
- // Sandboxed project file-system IPC (the renderer-side project:fs:* surface).
363
- context.registry.add(registerProjectFsIpc(context));
364
- // Referer/CORS webRequest policy for the simulator runtime's sessions (shared
365
- // fallback + every per-project partition). Registered into the context
366
- // registry so its configurator + per-session listeners are torn down with the
367
- // context re-creating the app never leaks a duplicate configurator.
368
- context.registry.add(setupSimulatorSessionPolicy());
369
- // One process-wide listener that re-syncs every window's native
370
- // backgroundColor on theme change windows otherwise keep the stale
371
- // creation-time color (see installThemeBackgroundSync).
372
- context.registry.add(installThemeBackgroundSync());
373
- // Warm-standby compile worker: only meaningful for the devkit-backed
374
- // default adapter (a host-injected adapter has no devkit fork to adopt the
375
- // spare). Registered into the registry so the spare dies with the context.
376
- if (!config.adapter)
377
- context.registry.add(setupCompileWorkerStandby(context));
378
- registerBuiltinModules(config, context);
153
+ // App-wide, built once: the project list, the templates, the trusted-sender
154
+ // ledger and the host's simulator APIs are properties of the application, not
155
+ // of any single window.
156
+ const appServices = createAppServices({
157
+ // The host-supplied ProjectsProvider / template types in `shared/types`
158
+ // are structurally compatible with the main-process equivalents —
159
+ // these casts are safe; we re-narrow at the workspace-service /
160
+ // create-project-service boundary.
161
+ projectsProvider: config.projectsProvider,
162
+ projectTemplates: config.projectTemplates,
163
+ builtinTemplates: config.builtinTemplates,
164
+ });
165
+ const router = createWindowContextRouter();
166
+ // App-lifetime registry. `ipcMain.handle` is a process-wide singleton per
167
+ // channel, so the IPC surface is registered exactly once and answers
168
+ // whichever window a message came from. Keeping it OFF the launcher
169
+ // context's registry is what lets the user close the project list without
170
+ // stripping every handler out from under the workbench windows still open.
171
+ const appRegistry = new DisposableRegistry();
172
+ const launcher = createLauncherWindow({ config, rendererDir, appServices, router });
173
+ const { window: mainWindow, context } = launcher;
174
+ const projectList = createProjectListSurface({ window: mainWindow, context });
175
+ registerWorkbenchIpc(config, router, context, mainWindow, appRegistry);
176
+ // No `setupWindowModules` here: the only per-window module is the simulator's
177
+ // bridge router, and the project list runs no mini-app — it has no simulator,
178
+ // no service host and no page stack. Installing one here would also claim the
179
+ // process-global `dmb:*` invoke channels before the first workbench window
180
+ // could. `installGlobalMirrors` skips the console/diagnostics mirrors when the
181
+ // router never ran, so the list window keeps its own internal DevTools.
182
+ installGlobalMirrors(context, mainWindow);
379
183
  // Wire the simulator-side difile:// protocol handler + temp-file IPC
380
184
  // before host onSetup so any host-driven simulator boot sees the
381
185
  // protocol live. The module installs its own narrow sender-policy
382
186
  // (simulator-session-only) — see file header — because the default
383
187
  // workbench policy intentionally rejects the simulator <webview>.
384
188
  const simSession = session.fromPartition(SHARED_MINIAPP_PARTITION);
385
- context.registry.add(setupSimulatorTempFiles(simSession));
386
- installMenu(config, mainWindow, context);
387
- // Gated custom-IPC surface for the host. Bound to ctx.senderPolicy so
388
- // host channels go through the same gateway as built-in IPC, and
389
- // registered into ctx.registry so its handlers are torn down with the
390
- // context.
391
- const hostIpc = new IpcRegistry(context.senderPolicy);
392
- context.registry.add(hostIpc);
189
+ appRegistry.add(setupSimulatorTempFiles(simSession));
190
+ // Gated custom-IPC surface for the host. Admits any sender the router places
191
+ // in a live window, so a host channel invoked from a workbench window is
192
+ // answered the same as one invoked from the list binding it to the
193
+ // launcher's own policy would reject every workbench renderer.
194
+ const hostIpc = new IpcRegistry((sender) => router.resolve(sender) !== null);
195
+ appRegistry.add(hostIpc);
196
+ // Host-registered simulator UI extensions are app-level, but an extension can
197
+ // only live in a project window, so the ledger keeps one copy per window.
198
+ const uiExtensions = createUiExtensionTargets({
199
+ projectWindows: () => workbenchWindows.list().map((pw) => pw.context),
200
+ activeWindow: () => workbenchWindows.activeContext(),
201
+ });
202
+ // The open-project IPC is registered below, well before `config.onSetup` is
203
+ // awaited, so a renderer that races ahead can ask for a project window while
204
+ // the host is still wiring its extensions up. Those opens park on `ready`
205
+ // instead of producing a window the host never got to extend.
206
+ let markReady;
207
+ const ready = new Promise((resolve) => { markReady = resolve; });
208
+ // The parked open reports an onSetup failure to whoever asked for the
209
+ // window; this keeps the rejection handled when nobody ever asks.
210
+ void ready.catch(() => { });
211
+ const workbenchWindows = createWorkbenchWindowManager({
212
+ config,
213
+ rendererDir,
214
+ appServices,
215
+ router,
216
+ ready,
217
+ // Not wrapped in try/catch the way `onBeforeClose` is: this hook runs on
218
+ // the way IN, so a host that could not configure the window has no window
219
+ // worth keeping — the manager tears it down and the error reaches the
220
+ // caller.
221
+ setupProjectWindow: async (opened, project) => {
222
+ await config.setupProjectWindow?.(instance, {
223
+ path: project.path,
224
+ name: project.name,
225
+ window: opened.window,
226
+ context: opened.context,
227
+ });
228
+ },
229
+ setupWindowModules: (ctx) => {
230
+ setupWindowModules(config, ctx);
231
+ uiExtensions.attachTo(ctx);
232
+ },
233
+ // MCP's CDP connections are aimed at the active project window and have to
234
+ // follow it when the user moves.
235
+ onActiveContextChanged: noteActiveMcpWindowChanged,
236
+ onBeforeClose: async (closing, project) => {
237
+ try {
238
+ await config.onBeforeClose?.(instance, {
239
+ path: project.path,
240
+ name: project.name,
241
+ window: closing.window,
242
+ context: closing.context,
243
+ });
244
+ }
245
+ catch (err) {
246
+ // The host gets to react to the close, not to cancel it: revealing the
247
+ // list window below is what keeps something on screen, and it must not
248
+ // be skipped because host code threw.
249
+ console.error('[workbench] host onBeforeClose hook failed:', err);
250
+ }
251
+ // The closing window keeps its place in the manager's list until its
252
+ // teardown finishes, so "the last project" means no OTHER window is
253
+ // open. The list window may be hidden behind it (see the close handler
254
+ // below) — leaving it hidden strands the user with a running app and
255
+ // nothing on screen.
256
+ if (workbenchWindows.list().every((pw) => pw === closing))
257
+ projectList.revealProjectList();
258
+ },
259
+ });
260
+ // Menu, automation and MCP drive whatever project the user is working in, so
261
+ // they read the active WORKBENCH context, resolved per call — never the list
262
+ // window, which owns no session. With no project open they fall back to the
263
+ // launcher context, whose `hasActiveSession()` is false, while MCP's CDP
264
+ // targets and native-host state live in the window itself: null instead.
265
+ const activeProjectContext = () => workbenchWindows.activeContext() ?? context;
266
+ setActiveMcpWindowResolver(() => workbenchWindows.activeContext());
267
+ appRegistry.add(toDisposable(() => setActiveMcpWindowResolver(() => null)));
268
+ installMenu(config, mainWindow, activeProjectContext, projectList.revealProjectList);
269
+ appRegistry.add(registerOpenProjectWindowIpc(router, (project) => workbenchWindows.open(project)));
393
270
  const instance = {
394
271
  mainWindow,
395
272
  context,
396
273
  ipc: hostIpc,
274
+ // `awaitReady: false`: `ready` only resolves once `config.onSetup` itself
275
+ // settles (`markReady(setup)` below), so a host that calls
276
+ // `instance.openProjectWindow` FROM WITHIN its own `onSetup` would
277
+ // otherwise deadlock — `open()` awaiting `ready` while `ready` awaits the
278
+ // very `onSetup` call that is awaiting `open()`. The renderer-facing IPC
279
+ // path (`registerOpenProjectWindowIpc` above) keeps the default: a
280
+ // renderer racing ahead of `onSetup` still has to park.
281
+ openProjectWindow: (project) => workbenchWindows.open(project, { awaitReady: false }),
282
+ projectWindows: () => workbenchWindows.list(),
283
+ disposeViews: () => {
284
+ for (const ctx of router.list())
285
+ ctx.views.disposeAll();
286
+ },
397
287
  // Return the registry wrapper, not the raw disposable: disposing the
398
288
  // wrapper splices the registry entry out AND drives the underlying
399
289
  // teardown, so a single dispose leaves no dead entry behind.
400
- registerTrustedWindow: (win) => context.registry.add(registerTrustedWindow(context, win)),
401
- registerSimulatorApi: (name, handler) => context.registry.add(toDisposable(context.simulatorApis.register(name, handler))),
402
- dispose: () => disposeContext(context),
403
- async getLaunchConfigs() {
404
- const projectPath = context.workspace.getProjectPath();
405
- if (!projectPath)
406
- return [];
407
- return context.workspace.getLaunchConfigs(projectPath);
408
- },
409
- async setLaunchConfigs(configs) {
410
- const projectPath = context.workspace.getProjectPath();
411
- if (!projectPath)
412
- return;
413
- await context.workspace.saveLaunchConfigs(projectPath, configs);
414
- context.notify.popoverUpdateLaunchConfigs(configs);
415
- },
416
- async setActiveLaunchConfig(id) {
417
- const projectPath = context.workspace.getProjectPath();
418
- if (!projectPath)
419
- return;
420
- await context.workspace.saveActiveLaunchConfigId(projectPath, id);
421
- context.notify.popoverSwitchLaunchConfig(id);
290
+ // App-level: the trusted-sender ledger and the simulator API map are
291
+ // shared by every window, so they outlive any one of them.
292
+ registerTrustedWindow: (win) => appRegistry.add(registerTrustedWindow(appServices, win)),
293
+ // Simulator APIs live in the ONE registry AppServices owns, which every
294
+ // window's context points at, so a single registration serves every
295
+ // window — including windows opened later, since the service host reads
296
+ // the registered names off it when it spawns. The disposer therefore
297
+ // belongs to the app: parking it on a window would let that window's close
298
+ // delete the handler out from under every other open window.
299
+ registerSimulatorApi: (name, handler) => appRegistry.add(toDisposable(appServices.simulatorApis.register(name, handler))),
300
+ registerSimulatorUiExtension: (registration) => uiExtensions.register(registration),
301
+ dispose: async () => {
302
+ await workbenchWindows.disposeAll();
303
+ await launcher.dispose();
304
+ await appRegistry.dispose();
422
305
  },
423
306
  };
307
+ onInstanceCreated?.(instance);
424
308
  // Built-in simulator APIs: devtools-supplied wx.* implementations that run
425
309
  // in the main process. Hosts can override any of these in their onSetup by
426
310
  // re-registering the same name (last-write-wins on the Map).
427
311
  instance.registerSimulatorApi('login', async () => {
428
312
  return 'hello';
429
313
  });
430
- if (config.onSetup) {
431
- await config.onSetup(instance);
432
- }
314
+ installHostSidebarDefault(context, rendererDir);
315
+ // Run inside an async IIFE so a hook that throws SYNCHRONOUSLY still settles
316
+ // `ready` — leaving it pending would park every queued open forever, and
317
+ // `disposeAll()` waits on those queues.
318
+ const setup = (async () => { await config.onSetup?.(instance); })();
319
+ markReady(setup);
320
+ await setup;
433
321
  if (config.updateChecker) {
434
322
  instance.updateManager = new UpdateManager({
435
323
  checker: config.updateChecker,
436
- mainWindow,
324
+ showUpdatePanel: (info) => projectList.showUpdate(info),
325
+ notifyDownloadProgress: (percent) => context.views.notifyUpdateDownloadProgress(percent),
326
+ hideUpdatePanel: () => context.views.hideUpdateDialog(),
437
327
  senderPolicy: context.senderPolicy,
438
328
  checkInterval: config.updateOptions?.checkInterval,
439
329
  initialDelay: config.updateOptions?.initialDelay,
440
330
  getCurrentVersion: config.updateOptions?.getCurrentVersion,
441
331
  });
442
- context.registry.add(() => instance.updateManager.dispose());
332
+ appRegistry.add(() => instance.updateManager.dispose());
443
333
  }
444
- await setupAutomation(instance);
445
- const mcp = setupMcp();
334
+ const automation = await setupAutomation(instance, activeProjectContext, router);
335
+ if (automation)
336
+ appRegistry.add(automation);
337
+ const mcp = setupMcp(createTargetForMcp({
338
+ list: () => workbenchWindows.list(),
339
+ activeContext: activeProjectContext,
340
+ // `close()` (not `destroy()`) so the window's own close handling runs the
341
+ // same teardown a user-driven close does.
342
+ close: (window) => { if (!window.isDestroyed())
343
+ window.close(); },
344
+ }), createOpenForMcp(workbenchWindows));
446
345
  if (mcp)
447
- context.registry.add(mcp);
448
- // Resolve the active project's appId. Shared by the storage panel filter
449
- // and the native-host WXML/element-inspect services (which scope the
450
- // active render guest by appId).
451
- const getActiveAppId = () => {
452
- const session = context.workspace.getSession();
453
- const appInfo = session?.appInfo;
454
- return appInfo?.appId ?? null;
455
- };
456
- // Native-host: the real mini-app page runs in a nested render-host
457
- // <webview> guest, not the localhost:7788 shell. Point the MCP
458
- // `simulator` CDP target at the active render guest and keep it following
459
- // the visible page across navigation/tab switches. Only wired under
460
- // native-host so the default path stays byte-identical.
461
- if (context.bridge?.isNativeHost()) {
462
- setNativeHost(true);
463
- setNativeOverviewProvider(async () => {
464
- const appId = getActiveAppId();
465
- const stack = context.bridge?.getPageStack?.(appId ?? undefined) ?? [];
466
- const top = stack[stack.length - 1];
467
- const overview = {
468
- currentRoute: top?.pagePath ?? null,
469
- pageStackDepth: stack.length,
470
- storageKeys: [],
471
- storageCount: 0,
472
- appDataKeys: [],
473
- };
474
- if (appId) {
475
- const storage = await resolveNativeStorageOverview(context, appId);
476
- overview.storageKeys = storage.storageKeys;
477
- overview.storageCount = storage.storageCount;
478
- overview.appDataKeys = resolveNativeAppDataKeys(context, appId);
346
+ appRegistry.add(mcp);
347
+ // The list window opens no project, so its close needs none of the workbench
348
+ // teardown: just unregister its context, or a recycled `webContents.id`
349
+ // could later resolve to a destroyed window.
350
+ context.registry.add(wireMainWindowEvents(mainWindow, {
351
+ context,
352
+ onResize: () => context.views.repositionAll(),
353
+ onClose: (e) => {
354
+ if (isAppQuitting())
355
+ return;
356
+ // With projects still open, this window must survive its own close
357
+ // button: it is the only way back to the project list, and the
358
+ // app-level IPC it registered cannot be registered again on a
359
+ // replacement window. Hide it — every path back calls
360
+ // `projectList.revealProjectList()`, including the last project window
361
+ // closing.
362
+ if (workbenchWindows.list().length > 0) {
363
+ e.preventDefault();
364
+ mainWindow.hide();
365
+ return;
479
366
  }
480
- return overview;
481
- });
482
- const off = context.bridge.onRenderEvent((ev) => setActiveBridgeId(ev.bridgeId));
483
- context.registry.add(off);
484
- context.registry.add(() => setNativeHost(false));
485
- context.registry.add(() => setNativeOverviewProvider(null));
486
- }
487
- // Native-host inspector: injects the render-guest IIFE and drives WXML /
488
- // element-highlight against the active render-host <webview>. Reused by
489
- // the storage panel (element inspect) and the WXML panel service.
490
- const renderInspector = createRenderInspector({ connections: context.connections });
491
- const storage = setupSimulatorStorage(mainWindow.webContents, {
492
- senderPolicy: context.senderPolicy,
493
- connections: context.connections,
494
- // Per-project filter for the simulator-storage panel: the simulator
495
- // uses a fixed `persist:simulator` partition + a fixed simulator.html
496
- // origin, so localStorage is shared across every project that has
497
- // ever opened. The dimina runtime isolates writes with `${appId}_`
498
- // prefixes; this callback lets the storage panel filter the CDP
499
- // snapshot/event stream to the active appId.
500
- getActiveAppId,
501
- // Native-host: route element inspection to the active render guest, and
502
- // read/write storage from the service-host window's file:// store.
503
- bridge: context.bridge,
504
- renderInspector,
505
- });
506
- context.registry.add(storage);
507
- // Native-host: expose the async-storage runtime hook so bridge-router
508
- // routes async wx.setStorage/etc. to the unified service-host store.
509
- if (storage.storageApi) {
510
- context.storageApi = storage.storageApi;
511
- context.registry.add(() => { context.storageApi = undefined; });
512
- // SYNC wx storage writes bypass main (they hit the service-host localStorage
513
- // directly); the service-host posts `storageChanged` and bridge-router routes
514
- // it here so the Storage panel stays live without a manual reload.
515
- context.onServiceStorageChanged = storage.onSyncStorageChange;
516
- context.registry.add(() => { context.onServiceStorageChanged = undefined; });
517
- }
518
- // Native-host WXML + AppData panels: main sources the data (WXML pulled
519
- // from the active render guest; AppData tapped from the service→render
520
- // setData stream in bridge-router) and pushes it to the renderer. Inert on
521
- // the default dimina-fe path (which sources both from the simulator
522
- // miniappSnapshot transport), so only wire them when native-host is on.
523
- if (context.bridge?.isNativeHost()) {
524
- // Native-host: surface the simulator WCV's network (wx.request/download/
525
- // upload run there, not in the service host) in the embedded DevTools by
526
- // injecting its raw Network.* CDP events into the DevTools front-end so the
527
- // native Network tab renders them (service-host console line is the
528
- // fallback). The ViewManager calls the forwarder's attachSimulator +
529
- // setDevtoolsHost from attachNativeSimulator once the simulator WCV +
530
- // DevTools host exist; getServiceWc here is the fallback sink target.
531
- const networkForward = createNetworkForwarder({
532
- getServiceWc: (appId) => context.bridge?.getServiceWc(appId) ?? null,
533
- connections: context.connections,
534
- });
535
- context.networkForward = networkForward;
536
- context.registry.add(networkForward);
537
- context.registry.add(() => { context.networkForward = undefined; });
538
- context.registry.add(setupSimulatorWxml(mainWindow.webContents, {
539
- senderPolicy: context.senderPolicy,
540
- bridge: context.bridge,
541
- inspector: renderInspector,
542
- getActiveAppId,
543
- }));
544
- const appDataService = setupSimulatorAppData(mainWindow.webContents, {
545
- senderPolicy: context.senderPolicy,
546
- getActiveAppId,
547
- });
548
- // bridge-router feeds this via ctx.appData (service→render tap + evict).
549
- context.appData = appDataService;
550
- context.registry.add(appDataService);
551
- context.registry.add(() => { context.appData = undefined; });
552
- // Push the visible page route to the toolbar on every navigation (the
553
- // page stack lives in the DeviceShell WCV, invisible to renderer
554
- // <webview> nav events).
555
- context.registry.add(setupSimulatorCurrentPage(mainWindow.webContents, {
556
- bridge: context.bridge,
557
- }));
558
- }
559
- // Embedded workbench editor — the sole devtools editor. Stand up the COI
560
- // http server that serves the workbench bundle with the SharedArrayBuffer
561
- // isolation headers and bridges `/__fs/*` onto the active project, then hand its
562
- // base URL to the view manager so the 'editor' dock slot mounts the workbench
563
- // WebContentsView. Both the server and the WCV tear down with the context
564
- // registry.
565
- //
566
- // Default the bundle dir to the devtools package's OWN `dist/vscode-workbench`
567
- // (resolved from the package root), NOT relative to the caller's rendererDir:
568
- // a host that overrides `rendererDir` but omits `editorViewConfig.bundleDir`
569
- // would otherwise compute a path next to ITS renderer, where no workbench
570
- // bundle exists → 404 / blank editor.
571
- const bundleDir = config.editorViewConfig?.bundleDir ?? path.join(devtoolsPackageRoot, 'dist/vscode-workbench');
572
- // Skip the entire editor assembly when the bundle is missing. Starting the COI
573
- // server and attaching the WCV against a non-existent bundle yields a silent
574
- // blank editor (the WCV loads index.html → 404); a launchable app with no
575
- // editor is strictly better. The view manager never gets a source, so the
576
- // 'editor' slot's lazy attach is a no-op.
577
- if (!fs.existsSync(path.join(bundleDir, 'index.html'))) {
578
- console.warn(`[workbench] editor bundle not found at ${bundleDir} — skipping embedded editor assembly`);
579
- }
580
- else {
581
- const coiServer = await startWorkbenchCoiServer({
582
- rootDir: bundleDir,
583
- getProjectRoot: () => context.workspace.getProjectPath(),
584
- extensionsDir: config.editorViewConfig?.extensionsDir,
585
- getFileTypes: () => context.fileTypes,
586
- });
587
- // Return the close promise so the registry awaits server shutdown on dispose
588
- // instead of fire-and-forgetting it (a dangling http server would keep the
589
- // port + event loop alive past teardown).
590
- context.registry.add(() => coiServer.close());
591
- context.registry.add(() => context.views.detachWorkbench());
592
- // Only HAND the view manager the COI URL — do NOT load yet. The heavy
593
- // WebContentsView load (10MB bundle + ext-host) is deferred to the first time
594
- // the 'editor' dock slot becomes visible (first non-zero bounds), so it never
595
- // sits on the app boot critical path. Loading it eagerly here delayed
596
- // preload/window-ready enough to trip the e2e launch health check.
597
- context.views.setWorkbenchSource(coiServer.baseUrl);
598
- }
599
- context.registry.add(wireAppWindowEvents(config, instance));
600
- context.registry.add(enableDevRendererAutoReload(rendererDir));
367
+ void launcher.dispose();
368
+ },
369
+ }));
370
+ // macOS keeps the app running with no window on screen. Clicking the dock
371
+ // icon then has to bring something back, and the project list is the app's
372
+ // home — a workbench window only exists for a project the user already
373
+ // chose.
374
+ const onActivate = () => {
375
+ if (mainWindow.isDestroyed())
376
+ return;
377
+ if (mainWindow.isVisible())
378
+ return;
379
+ if (workbenchWindows.list().some((pw) => !pw.window.isDestroyed() && pw.window.isVisible()))
380
+ return;
381
+ projectList.revealProjectList();
382
+ };
383
+ app.on('activate', onActivate);
384
+ appRegistry.add(toDisposable(() => { app.removeListener('activate', onActivate); }));
385
+ appRegistry.add(enableDevRendererAutoReload(rendererDir));
601
386
  return instance;
602
387
  }
603
388
  //# sourceMappingURL=app.js.map