@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
@@ -0,0 +1,21 @@
1
+ import type { CustomFileTypes, WorkbenchAppConfig } from '../../shared/types.js';
2
+ import type { ViewManager } from '../services/views/view-manager.js';
3
+ import type { WorkspaceService } from '../services/workspace/workspace-service.js';
4
+ import type { DisposableRegistry } from '@dimina-kit/electron-deck/main';
5
+ /** Narrow view of the context fields the embedded editor depends on. */
6
+ export interface EditorViewContext {
7
+ workspace: WorkspaceService;
8
+ fileTypes: CustomFileTypes;
9
+ views: ViewManager;
10
+ registry: DisposableRegistry;
11
+ }
12
+ /**
13
+ * Embedded workbench editor — the sole devtools editor. Stands up the COI http
14
+ * server that serves the workbench bundle with the SharedArrayBuffer isolation
15
+ * headers and bridges `/__fs/*` onto the active project, then hands its base URL
16
+ * to the view manager so the 'editor' dock slot mounts the workbench
17
+ * WebContentsView. Both the server and the WCV tear down with the context
18
+ * registry.
19
+ */
20
+ export declare function setupEditorView(config: WorkbenchAppConfig, context: EditorViewContext, getActiveAppId: () => string | null): Promise<void>;
21
+ //# sourceMappingURL=editor-view.d.ts.map
@@ -0,0 +1,71 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import { devtoolsPackageRoot } from '../utils/paths.js';
4
+ import { startWorkbenchCoiServer } from '../services/workbench-coi-server.js';
5
+ /**
6
+ * Embedded workbench editor — the sole devtools editor. Stands up the COI http
7
+ * server that serves the workbench bundle with the SharedArrayBuffer isolation
8
+ * headers and bridges `/__fs/*` onto the active project, then hands its base URL
9
+ * to the view manager so the 'editor' dock slot mounts the workbench
10
+ * WebContentsView. Both the server and the WCV tear down with the context
11
+ * registry.
12
+ */
13
+ export async function setupEditorView(config, context, getActiveAppId) {
14
+ // Default the bundle dir to the devtools package's OWN `dist/vscode-workbench`
15
+ // (resolved from the package root), NOT relative to the caller's rendererDir:
16
+ // a host that overrides `rendererDir` but omits `editorViewConfig.bundleDir`
17
+ // would otherwise compute a path next to ITS renderer, where no workbench
18
+ // bundle exists → 404 / blank editor.
19
+ const bundleDir = config.editorViewConfig?.bundleDir ?? path.join(devtoolsPackageRoot, 'dist/vscode-workbench');
20
+ // Skip the entire editor assembly when the bundle is missing. Starting the COI
21
+ // server and attaching the WCV against a non-existent bundle yields a silent
22
+ // blank editor (the WCV loads index.html → 404); a launchable app with no
23
+ // editor is strictly better. The view manager never gets a source, so the
24
+ // 'editor' slot's lazy attach is a no-op.
25
+ if (!fs.existsSync(path.join(bundleDir, 'index.html'))) {
26
+ console.warn(`[workbench] editor bundle not found at ${bundleDir} — skipping embedded editor assembly`);
27
+ return;
28
+ }
29
+ const coiServer = await startWorkbenchCoiServer({
30
+ rootDir: bundleDir,
31
+ getProjectRoot: () => context.workspace.getProjectPath(),
32
+ extensionsDir: config.editorViewConfig?.extensionsDir,
33
+ getFileTypes: () => context.fileTypes,
34
+ // Names the editor's VS Code workspace after the active miniapp, so each
35
+ // project gets its own open-editors/view-state bucket instead of all of
36
+ // them sharing the one derived from the constant mirror root.
37
+ getProjectIdentity: () => ({
38
+ appId: getActiveAppId(),
39
+ projectPath: context.workspace.getProjectPath(),
40
+ }),
41
+ });
42
+ try {
43
+ // Return the close promise so the registry awaits server shutdown on dispose
44
+ // instead of fire-and-forgetting it (a dangling http server would keep the
45
+ // port + event loop alive past teardown).
46
+ context.registry.add(() => coiServer.close());
47
+ // The registry disposes LIFO, so this runs BEFORE the context-level
48
+ // disposeAll: void any in-flight open's attach hold here too, or a stale
49
+ // release / cap firing could rebuild the workbench during the awaited
50
+ // coiServer.close() above, before disposeAll's own cancel runs.
51
+ context.registry.add(() => {
52
+ context.views.cancelWorkbenchAttachHold();
53
+ context.views.detachWorkbench();
54
+ });
55
+ }
56
+ catch (err) {
57
+ // The window was torn down while the bridge was still binding, so the
58
+ // registry that would have closed it is already disposed and refuses new
59
+ // entries. Close it here instead: an orphaned route keeps the shared COI
60
+ // listener (and its port) alive for the rest of the process.
61
+ await coiServer.close().catch(() => { });
62
+ throw err;
63
+ }
64
+ // Only HAND the view manager the COI URL — do NOT load yet. The heavy
65
+ // WebContentsView load (10MB bundle + ext-host) is deferred to the first time
66
+ // the 'editor' dock slot becomes visible (first non-zero bounds), so it never
67
+ // sits on the app boot critical path. Loading it eagerly here delayed
68
+ // preload/window-ready enough to trip the e2e launch health check.
69
+ context.views.setWorkbenchSource(coiServer.baseUrl);
70
+ }
71
+ //# sourceMappingURL=editor-view.js.map
@@ -0,0 +1,23 @@
1
+ import type { BrowserWindow } from 'electron';
2
+ import type { ConsoleForwarder } from '../services/console-forward/index.js';
3
+ import type { DiagnosticsBus } from '../services/diagnostics/index.js';
4
+ import type { CdpSessionBroker } from '../services/cdp-session/index.js';
5
+ import type { InternalDevtoolsWindow } from '../windows/internal-devtools-window/index.js';
6
+ import { type DisposableRegistry } from '@dimina-kit/electron-deck/main';
7
+ /** Narrow view of the context fields the two global mirrors depend on. */
8
+ export interface GlobalMirrorContext {
9
+ consoleForwarder?: ConsoleForwarder;
10
+ diagnostics?: DiagnosticsBus;
11
+ internalDevtoolsWindow?: InternalDevtoolsWindow;
12
+ cdpSessionBroker: CdpSessionBroker;
13
+ registry: DisposableRegistry;
14
+ }
15
+ /**
16
+ * Console + diagnostics mirrors into the standalone internal DevTools window.
17
+ *
18
+ * Both mirrors target the INSPECTED side — `mainWindow.webContents`, per
19
+ * internal-devtools-window.ts's setDevToolsWebContents relationship — and NOT
20
+ * the front-end host page the `onHostChanged` callback hands them.
21
+ */
22
+ export declare function installGlobalMirrors(context: GlobalMirrorContext, mainWindow: BrowserWindow): void;
23
+ //# sourceMappingURL=global-mirrors.d.ts.map
@@ -0,0 +1,37 @@
1
+ import { createGlobalConsoleMirror } from '../services/console-forward/global-console-mirror.js';
2
+ import { createGlobalDiagnosticsMirror } from '../services/console-forward/global-diagnostics-mirror.js';
3
+ import { toDisposable } from '@dimina-kit/electron-deck/main';
4
+ /**
5
+ * Console + diagnostics mirrors into the standalone internal DevTools window.
6
+ *
7
+ * Both mirrors target the INSPECTED side — `mainWindow.webContents`, per
8
+ * internal-devtools-window.ts's setDevToolsWebContents relationship — and NOT
9
+ * the front-end host page the `onHostChanged` callback hands them.
10
+ */
11
+ export function installGlobalMirrors(context, mainWindow) {
12
+ // While the standalone internal DevTools window is open, mirror every guest
13
+ // console entry (service + render, UNFILTERED — see global-console-mirror.ts)
14
+ // into it — each open replays the forwarder's current history buffer first
15
+ // (see that module's doc comment for why the subscribe lifecycle is gated on
16
+ // onHostChanged rather than subscribed once at construction time).
17
+ // `context.consoleForwarder` is assembled by the simulator module's
18
+ // installBridgeRouter; absent only when that builtin module was disabled via
19
+ // config.
20
+ if (context.consoleForwarder && context.internalDevtoolsWindow) {
21
+ const consoleMirror = createGlobalConsoleMirror(context.consoleForwarder, mainWindow.webContents, context.internalDevtoolsWindow.onHostChanged,
22
+ // CDP transport (never executeJavaScript) — see the mirror's inject()
23
+ // doc for the setDevToolsWebContents + external-CDP double-attach hang.
24
+ { broker: context.cdpSessionBroker });
25
+ context.registry.add(toDisposable(() => consoleMirror.dispose()));
26
+ }
27
+ // Same wiring for diagnostics: every diagnostic — including
28
+ // `audience:'internal'` ones console-forward's own service-host injection
29
+ // now skips (see compile-standby.ts / index.ts's handleDiagnostic gate) —
30
+ // surfaces here instead of vanishing. `context.diagnostics` is assembled
31
+ // alongside `context.consoleForwarder` by the same installBridgeRouter call.
32
+ if (context.diagnostics && context.internalDevtoolsWindow) {
33
+ const diagnosticsMirror = createGlobalDiagnosticsMirror(context.diagnostics, mainWindow.webContents, context.internalDevtoolsWindow.onHostChanged, { broker: context.cdpSessionBroker });
34
+ context.registry.add(toDisposable(() => diagnosticsMirror.dispose()));
35
+ }
36
+ }
37
+ //# sourceMappingURL=global-mirrors.js.map
@@ -0,0 +1,19 @@
1
+ import type { ViewManager } from '../services/views/view-manager.js';
2
+ import type { RendererNotifier } from '../services/notifications/renderer-notifier.js';
3
+ import type { DisposableRegistry } from '@dimina-kit/electron-deck/main';
4
+ /** Narrow view of the context fields the default sidebar content depends on. */
5
+ export interface HostSidebarContext {
6
+ views: ViewManager;
7
+ notify: RendererNotifier;
8
+ registry: DisposableRegistry;
9
+ }
10
+ /**
11
+ * devtools' own default content for the host-sidebar slot: a narrow icon rail
12
+ * (logo + 小程序/小游戏 toggle) filtering the project-list grid by
13
+ * `Project.type`. Loaded BEFORE `config.onSetup` runs, so any downstream
14
+ * `loadURL`/`loadFile` call inside onSetup necessarily happens later and
15
+ * naturally supersedes this default via plain chronological ordering — no
16
+ * override flag needed.
17
+ */
18
+ export declare function installHostSidebarDefault(context: HostSidebarContext, rendererDir: string): void;
19
+ //# sourceMappingURL=host-sidebar-default.d.ts.map
@@ -0,0 +1,44 @@
1
+ import path from 'path';
2
+ import { HOST_SIDEBAR_DEFAULT_WIDTH } from '../../shared/constants.js';
3
+ /**
4
+ * devtools' own default content for the host-sidebar slot: a narrow icon rail
5
+ * (logo + 小程序/小游戏 toggle) filtering the project-list grid by
6
+ * `Project.type`. Loaded BEFORE `config.onSetup` runs, so any downstream
7
+ * `loadURL`/`loadFile` call inside onSetup necessarily happens later and
8
+ * naturally supersedes this default via plain chronological ordering — no
9
+ * override flag needed.
10
+ */
11
+ export function installHostSidebarDefault(context, rendererDir) {
12
+ context.registry.add(context.views.hostSidebar.onMessage('project-category-selected', (payload) => {
13
+ const category = payload?.category;
14
+ if (category !== 'miniprogram' && category !== 'minigame')
15
+ return;
16
+ context.notify.hostSidebarCategorySelected(category);
17
+ }));
18
+ context.views.hostSidebar
19
+ .loadFile(path.join(rendererDir, 'entries/host-sidebar-default/index.html'))
20
+ .catch((err) => {
21
+ console.warn('[workbench] failed to load host-sidebar default content:', err);
22
+ });
23
+ // Seed the notified width with the rail's own known intrinsic width
24
+ // (`HOST_SIDEBAR_DEFAULT_WIDTH`) instead of leaving it at 0 until the
25
+ // rail's in-page advertiser reports back. That report can never arrive on
26
+ // its own: the placeholder above only becomes "desired visible" once a
27
+ // nonzero width is known (project-list-screen.tsx), attach only happens
28
+ // for a "desired visible" view (placement-reconciler.ts), and the rail's
29
+ // advertiser (view-anchor's measure-loop.ts) only ever fires via
30
+ // `requestAnimationFrame`, which Chromium never schedules for a
31
+ // WebContentsView that was never attached — a structural deadlock, not a
32
+ // slow-to-resolve race. `setWidthMode({fixed})` pushes the seed
33
+ // synchronously (no attach/rAF dependency) and, critically, retains it in
34
+ // `getHostSidebarWidth()` too, so a renderer that mounts and pulls before
35
+ // any push replays the real seed instead of a stale 0. Flipping back to
36
+ // 'auto' immediately after, before anything has attached or advertised, is
37
+ // a same-tick no-op past the seed (`setExtentMode`'s reapply branch only
38
+ // fires once something has actually been advertised) — it leaves the slot
39
+ // in 'auto' for whichever content ends up loaded (this rail's own later
40
+ // report, or a downstream replacement's), not pinned.
41
+ context.views.hostSidebar.setWidthMode({ fixed: HOST_SIDEBAR_DEFAULT_WIDTH });
42
+ context.views.hostSidebar.setWidthMode('auto');
43
+ }
44
+ //# sourceMappingURL=host-sidebar-default.js.map
@@ -0,0 +1,13 @@
1
+ import type { BrowserWindow } from 'electron';
2
+ import type { WorkbenchAppConfig } from '../../shared/types.js';
3
+ import type { WorkspaceService } from '../services/workspace/workspace-service.js';
4
+ import type { RendererNotifier } from '../services/notifications/renderer-notifier.js';
5
+ /** Narrow view of the context fields the menu surface closes over. */
6
+ export interface MenuHostContext {
7
+ appName: string;
8
+ workspace: WorkspaceService;
9
+ openSettings: () => Promise<void>;
10
+ notify: RendererNotifier;
11
+ }
12
+ export declare function installMenu(config: WorkbenchAppConfig, mainWindow: BrowserWindow, activeContext: () => MenuHostContext, revealProjectList: () => void): void;
13
+ //# sourceMappingURL=menu-setup.d.ts.map
@@ -0,0 +1,49 @@
1
+ import { installAppMenu } from '../menu/index.js';
2
+ /**
3
+ * Build the hand-written narrow `MenuContext` a host menu builder receives —
4
+ * explicit construction (not clone+delete), so the runtime object carries
5
+ * EXACTLY the contract members and nothing else. Every member is a lazy
6
+ * closure over the live context: a host monkey-patch of
7
+ * `context.workspace.openProject` (the documented permission-gate pattern)
8
+ * still intercepts calls made through this menu surface.
9
+ *
10
+ * The context is resolved per call, never captured: the menu is installed once
11
+ * before any project exists, and a project lives in its own window, so a menu
12
+ * item run later must reach the window the user is actually in.
13
+ */
14
+ function toMenuContext(activeContext, revealProjectList) {
15
+ return {
16
+ get appName() { return activeContext().appName; },
17
+ workspace: {
18
+ hasActiveSession: () => activeContext().workspace.hasActiveSession(),
19
+ getProjectPath: () => activeContext().workspace.getProjectPath(),
20
+ openProject: (projectPath) => activeContext().workspace.openProject(projectPath),
21
+ closeProject: () => activeContext().workspace.closeProject(),
22
+ getSession: () => activeContext().workspace.getSession(),
23
+ },
24
+ openSettings: () => activeContext().openSettings(),
25
+ notify: {
26
+ projectStatus: (payload) => activeContext().notify.projectStatus(payload),
27
+ // A project opens in its own window, so "back to the project list" is
28
+ // no longer a screen change inside one window — it brings the list
29
+ // window forward. That window owns its own context, which may not be
30
+ // `activeContext()` (a project window can be the active one), so this
31
+ // routes through the injected surface instead of notifying whatever is
32
+ // currently active.
33
+ windowNavigateBack: () => revealProjectList(),
34
+ },
35
+ };
36
+ }
37
+ export function installMenu(config, mainWindow, activeContext, revealProjectList) {
38
+ // Menu: use host-provided builder or fall back to default. Both consume the
39
+ // same narrow MenuContext, so the built-in menu proves the hand-written
40
+ // contract covers the real internal consumption.
41
+ const menuContext = toMenuContext(activeContext, revealProjectList);
42
+ if (config.menuBuilder) {
43
+ config.menuBuilder(mainWindow, menuContext);
44
+ }
45
+ else {
46
+ installAppMenu(menuContext);
47
+ }
48
+ }
49
+ //# sourceMappingURL=menu-setup.js.map
@@ -0,0 +1,13 @@
1
+ import type { IpcContextSource } from '../utils/ipc-context-source.js';
2
+ import { IpcRegistry } from '../utils/ipc-registry.js';
3
+ import type { ProjectRef } from './project-window.js';
4
+ /**
5
+ * Opening a project from the list — and from MCP's project_open, which the
6
+ * list renderer forwards here — always means "give it its own window", so the
7
+ * channel does nothing but hand the request to the workbench window manager.
8
+ *
9
+ * Generic over the context type: the handler never touches the context, and
10
+ * naming it would drag `WorkbenchContext` into this module.
11
+ */
12
+ export declare function registerOpenProjectWindowIpc<TCtx>(router: IpcContextSource<TCtx>, open: (project: ProjectRef) => Promise<unknown>): IpcRegistry<TCtx>;
13
+ //# sourceMappingURL=open-project-ipc.d.ts.map
@@ -0,0 +1,21 @@
1
+ import { WindowChannel } from '../../shared/ipc-channels.js';
2
+ import { IpcRegistry } from '../utils/ipc-registry.js';
3
+ /**
4
+ * Opening a project from the list — and from MCP's project_open, which the
5
+ * list renderer forwards here — always means "give it its own window", so the
6
+ * channel does nothing but hand the request to the workbench window manager.
7
+ *
8
+ * Generic over the context type: the handler never touches the context, and
9
+ * naming it would drag `WorkbenchContext` into this module.
10
+ */
11
+ export function registerOpenProjectWindowIpc(router, open) {
12
+ const windowIpc = new IpcRegistry(router);
13
+ windowIpc.handleRouted(WindowChannel.OpenProjectWindow, async (_ctx, _event, ...args) => {
14
+ const project = args[0];
15
+ if (!project?.path)
16
+ throw new Error('openProjectWindow requires a project path');
17
+ await open({ path: project.path, name: project.name });
18
+ });
19
+ return windowIpc;
20
+ }
21
+ //# sourceMappingURL=open-project-ipc.js.map
@@ -0,0 +1,31 @@
1
+ import type { BrowserWindow } from 'electron';
2
+ import type { UpdateInfo } from '../../shared/types.js';
3
+ /**
4
+ * Narrow view of the context fields the project-list surface closes over —
5
+ * structural, not `WorkbenchContext` (see eslint-workbench-context-gate) —
6
+ * so the surface carries no dependency on the whole workbench.
7
+ */
8
+ export interface ProjectListSurfaceContext {
9
+ notify: {
10
+ windowNavigateBack: () => void;
11
+ };
12
+ views: {
13
+ showUpdateDialog: (info: UpdateInfo) => void;
14
+ };
15
+ }
16
+ export interface ProjectListSurfaceDeps {
17
+ window: BrowserWindow;
18
+ context: ProjectListSurfaceContext;
19
+ }
20
+ export interface ProjectListSurface {
21
+ revealProjectList: () => void;
22
+ showUpdate: (info: UpdateInfo) => void;
23
+ }
24
+ /**
25
+ * "回到项目列表" 和更新弹窗都属于列表窗口本身,而不是当时 activeContext() 恰好
26
+ * 解析到的窗口——那个窗口可能是某个项目工作台。这里是两条路径共同的入口:
27
+ * revealProjectList 把列表窗口带到前台并通知它自己的 context 刷新;showUpdate
28
+ * 先做同一件事,再弹更新对话框,避免窗口还处于 hide() 状态时用户看不到弹窗。
29
+ */
30
+ export declare function createProjectListSurface(deps: ProjectListSurfaceDeps): ProjectListSurface;
31
+ //# sourceMappingURL=project-list-surface.d.ts.map
@@ -0,0 +1,20 @@
1
+ import { revealWindow } from './window-events.js';
2
+ /**
3
+ * "回到项目列表" 和更新弹窗都属于列表窗口本身,而不是当时 activeContext() 恰好
4
+ * 解析到的窗口——那个窗口可能是某个项目工作台。这里是两条路径共同的入口:
5
+ * revealProjectList 把列表窗口带到前台并通知它自己的 context 刷新;showUpdate
6
+ * 先做同一件事,再弹更新对话框,避免窗口还处于 hide() 状态时用户看不到弹窗。
7
+ */
8
+ export function createProjectListSurface(deps) {
9
+ const { window, context } = deps;
10
+ const revealProjectList = () => {
11
+ revealWindow(window);
12
+ context.notify.windowNavigateBack();
13
+ };
14
+ const showUpdate = (info) => {
15
+ revealProjectList();
16
+ context.views.showUpdateDialog(info);
17
+ };
18
+ return { revealProjectList, showUpdate };
19
+ }
20
+ //# sourceMappingURL=project-list-surface.js.map
@@ -0,0 +1,36 @@
1
+ import { BrowserWindow } from 'electron';
2
+ import type { WorkbenchAppConfig } from '../../shared/types.js';
3
+ import { type WorkbenchContext } from '../services/workbench-context.js';
4
+ import type { AppServices } from '../services/app-services.js';
5
+ import type { WindowContextRouter } from '../services/window-contexts/context-router.js';
6
+ /** The project a workbench window is opened for. */
7
+ export interface ProjectRef {
8
+ path: string;
9
+ name?: string;
10
+ }
11
+ /** A window and the context that answers IPC coming from it. */
12
+ export interface ProjectWindow {
13
+ window: BrowserWindow;
14
+ context: WorkbenchContext;
15
+ dispose: () => Promise<void>;
16
+ }
17
+ export interface CreateProjectWindowOptions {
18
+ config: WorkbenchAppConfig;
19
+ rendererDir: string;
20
+ appServices: AppServices;
21
+ router: WindowContextRouter<WorkbenchContext>;
22
+ }
23
+ export declare function disposeContext(ctx: WorkbenchContext): Promise<void>;
24
+ /**
25
+ * The project-list window. It is the application's root window: the app-level
26
+ * IPC surface is registered while it exists, and it stays open for the whole
27
+ * session so workbench windows can come and go around it.
28
+ */
29
+ export declare function createLauncherWindow(opts: CreateProjectWindowOptions): ProjectWindow;
30
+ /**
31
+ * A workbench window: one open mini-program project, with its own simulator,
32
+ * panels and editor. The project identity travels in the URL query so the
33
+ * renderer entry can mount straight into the project without asking main.
34
+ */
35
+ export declare function createWorkbenchWindow(opts: CreateProjectWindowOptions, project: ProjectRef): ProjectWindow;
36
+ //# sourceMappingURL=project-window.d.ts.map
@@ -0,0 +1,93 @@
1
+ import { nativeImage } from 'electron';
2
+ import path from 'path';
3
+ import { defaultPreloadPath } from '../utils/paths.js';
4
+ import { createMainWindow } from '../windows/main-window/index.js';
5
+ // eslint-disable-next-line no-restricted-syntax -- grandfathered(workbench-context): shrink-only
6
+ import { createWorkbenchContext } from '../services/workbench-context.js';
7
+ function createConfiguredMainWindow(config, rendererDir, entry, title, autoShow, query) {
8
+ const mainWindow = createMainWindow({
9
+ title,
10
+ indexHtml: path.join(rendererDir, entry),
11
+ query,
12
+ width: config.window?.width,
13
+ height: config.window?.height,
14
+ minWidth: config.window?.minWidth,
15
+ minHeight: config.window?.minHeight,
16
+ autoShow,
17
+ });
18
+ // Set window/taskbar icon if provided (Linux/Windows; macOS uses app bundle icon)
19
+ if (config.icon) {
20
+ const icon = nativeImage.createFromPath(config.icon);
21
+ if (!icon.isEmpty())
22
+ mainWindow.setIcon(icon);
23
+ }
24
+ return mainWindow;
25
+ }
26
+ function createContext(config, mainWindow, rendererDir, appServices) {
27
+ return createWorkbenchContext({
28
+ mainWindow,
29
+ appServices,
30
+ adapter: config.adapter,
31
+ preloadPath: config.preloadPath ?? defaultPreloadPath,
32
+ rendererDir,
33
+ appName: config.appName,
34
+ apiNamespaces: config.apiNamespaces,
35
+ fileTypes: config.fileTypes,
36
+ brandingProvider: config.brandingProvider,
37
+ customCreateProjectDialog: config.customCreateProjectDialog,
38
+ // No cast needed here: the hook receives the project record, so the
39
+ // main-process `Project` the context hands it satisfies the structural
40
+ // `EditableProject` the config declares.
41
+ customEditProjectDialog: config.customEditProjectDialog,
42
+ onBeforeOpenProject: config.onBeforeOpenProject,
43
+ });
44
+ }
45
+ export async function disposeContext(ctx) {
46
+ await ctx.workspace.closeProject();
47
+ await ctx.registry.dispose().catch((err) => {
48
+ console.warn('[workbench] dispose registry encountered errors:', err);
49
+ });
50
+ }
51
+ /**
52
+ * Build a window together with the context that owns it, and publish that
53
+ * context to the router so IPC arriving from this window is answered by it.
54
+ *
55
+ * The router registration is parked on the context's own registry: a window
56
+ * that is torn down must stop claiming senders in the same breath, or a
57
+ * recycled `webContents.id` would resolve to a dead context.
58
+ */
59
+ function createWindowWithContext(opts, entry, title, autoShow, query) {
60
+ const { config, rendererDir, appServices, router } = opts;
61
+ const window = createConfiguredMainWindow(config, rendererDir, entry, title, autoShow, query);
62
+ const context = createContext(config, window, rendererDir, appServices);
63
+ // Anchor the window's renderer as the first Connection. Resources scoped to
64
+ // that webContents (acquired by later wiring) tear down with it; see
65
+ // packages/electron-deck/docs/foundation.md (teardown paths).
66
+ context.connections.acquire(window.webContents);
67
+ context.registry.add(router.register(context));
68
+ return { window, context, dispose: () => disposeContext(context) };
69
+ }
70
+ /**
71
+ * The project-list window. It is the application's root window: the app-level
72
+ * IPC surface is registered while it exists, and it stays open for the whole
73
+ * session so workbench windows can come and go around it.
74
+ */
75
+ export function createLauncherWindow(opts) {
76
+ return createWindowWithContext(opts, 'entries/main/index.html', opts.config.appName ?? 'Dimina DevTools', opts.config.window?.autoShow);
77
+ }
78
+ /**
79
+ * A workbench window: one open mini-program project, with its own simulator,
80
+ * panels and editor. The project identity travels in the URL query so the
81
+ * renderer entry can mount straight into the project without asking main.
82
+ */
83
+ export function createWorkbenchWindow(opts, project) {
84
+ return createWindowWithContext(opts, 'entries/workbench/index.html', project.name || opts.config.appName || 'Dimina DevTools',
85
+ // Always hidden: `workbench-window.ts`'s reveal gate is the sole place
86
+ // that ever shows a project window, once BOTH `setupProjectWindow` has
87
+ // resolved and the renderer's own `ready-to-show` has fired. Passing
88
+ // anything but `false` here would let `createMainWindow`'s own
89
+ // `ready-to-show` handler show the window itself and race that gate.
90
+ // `config.projectWindow?.autoShow` is read by the gate instead, not here.
91
+ false, { path: project.path, name: project.name ?? '' });
92
+ }
93
+ //# sourceMappingURL=project-window.js.map
@@ -0,0 +1,17 @@
1
+ import type { WorkbenchAppInstance } from './app.js';
2
+ import { startAutomationServer } from '../services/automation/index.js';
3
+ import { type McpOpenedProject, type McpProjectTarget } from '../services/mcp/index.js';
4
+ import type { Disposable } from '@dimina-kit/electron-deck/main';
5
+ /**
6
+ * The automation server outlives every window: it binds its port at boot,
7
+ * before any project is open, so it cannot capture a context at start and
8
+ * takes `getContext` instead. What that resolver hands back is only the
9
+ * starting point — each connection pins the first project window it reaches
10
+ * and stays there, so window focus cannot redirect a live client.
11
+ */
12
+ export declare function setupAutomation(instance: WorkbenchAppInstance, getContext: Parameters<typeof startAutomationServer>[0], senders: Parameters<typeof startAutomationServer>[1]): Promise<Disposable | null>;
13
+ export declare function setupMcp(currentProject: () => McpProjectTarget, openProjectWindow: (project: {
14
+ path: string;
15
+ name: string;
16
+ }) => Promise<McpOpenedProject>): Disposable | null;
17
+ //# sourceMappingURL=servers.d.ts.map
@@ -0,0 +1,60 @@
1
+ import { app } from 'electron';
2
+ import { startAutomationServer } from '../services/automation/index.js';
3
+ import { startMcpServer, } from '../services/mcp/index.js';
4
+ import { loadWorkbenchSettings } from '../services/settings/index.js';
5
+ /** Parse --auto, --auto-port, --project from process.argv. */
6
+ function parseAutoArgs() {
7
+ const argv = process.argv;
8
+ let auto = false;
9
+ let autoPort = 9420;
10
+ let projectPath = '';
11
+ for (let i = 0; i < argv.length; i++) {
12
+ if (argv[i] === 'auto' || argv[i] === '--auto')
13
+ auto = true;
14
+ if ((argv[i] === '--auto-port' || argv[i] === '--auto_port') && argv[i + 1]) {
15
+ const parsed = parseInt(argv[i + 1], 10);
16
+ // 0 → OS-assigned free port (used by parallel e2e workers)
17
+ if (Number.isFinite(parsed) && parsed >= 0)
18
+ autoPort = parsed;
19
+ }
20
+ if (argv[i] === '--project' && argv[i + 1]) {
21
+ projectPath = argv[i + 1];
22
+ }
23
+ }
24
+ return { auto, autoPort, projectPath };
25
+ }
26
+ /**
27
+ * The automation server outlives every window: it binds its port at boot,
28
+ * before any project is open, so it cannot capture a context at start and
29
+ * takes `getContext` instead. What that resolver hands back is only the
30
+ * starting point — each connection pins the first project window it reaches
31
+ * and stays there, so window focus cannot redirect a live client.
32
+ */
33
+ export async function setupAutomation(instance, getContext, senders) {
34
+ // Start automation server if --auto flag is present
35
+ const autoArgs = parseAutoArgs();
36
+ if (!autoArgs.auto)
37
+ return null;
38
+ const server = await startAutomationServer(getContext, senders, autoArgs.autoPort);
39
+ instance.automationServer = server;
40
+ // Stable, parseable line for e2e harnesses that scrape stdout.
41
+ console.log(`[automation] listening on ws://127.0.0.1:${server.port}`);
42
+ return { dispose: () => server.close() };
43
+ }
44
+ export function setupMcp(currentProject, openProjectWindow) {
45
+ const settings = loadWorkbenchSettings();
46
+ if (!settings.mcp.enabled)
47
+ return null;
48
+ const cdpPortSwitch = app.commandLine.getSwitchValue('remote-debugging-port');
49
+ const cdpPort = cdpPortSwitch ? parseInt(cdpPortSwitch, 10) : settings.cdp.port;
50
+ // Resolved per tool call, not once at boot: the project MCP drives lives in
51
+ // whichever workbench window is active, and that changes as windows open and
52
+ // close. Each call then holds the target it got.
53
+ return startMcpServer(cdpPort, settings.mcp.port, {
54
+ currentProject,
55
+ // A project opens into its own window; the renderer entry mounted there
56
+ // compiles it and attaches the simulator.
57
+ requestOpenInUi: (p) => openProjectWindow(p),
58
+ });
59
+ }
60
+ //# sourceMappingURL=servers.js.map
@@ -0,0 +1,42 @@
1
+ /**
2
+ * The ledger of host-registered simulator UI extensions.
3
+ *
4
+ * A registration is app-level — the host makes it once — but an extension can
5
+ * only exist inside a PROJECT window: it mounts into that window's device
6
+ * frame and talks to its simulator renderer. So one registration becomes one
7
+ * live extension per project window, and the ledger is what keeps those copies
8
+ * in step with the windows: every project window that opens gets its own copy,
9
+ * and a copy exists exactly as long as the window that owns it.
10
+ *
11
+ * The project list is deliberately not a target. It runs no bridge router and
12
+ * no simulator, so an extension registered into it could never mount, and
13
+ * `invoke` — which follows the window the user works in — would be answered by
14
+ * that dead copy every time the list window has focus.
15
+ */
16
+ import { type Disposable } from '@dimina-kit/electron-deck/main';
17
+ import type { SimulatorUiExtensionHandle, SimulatorUiExtensionRegistration } from '../../shared/simulator-ui.js';
18
+ /**
19
+ * The window surface the ledger needs, described structurally so this module
20
+ * does not import WorkbenchContext (see eslint-workbench-context-gate).
21
+ */
22
+ export interface UiExtensionWindow {
23
+ simulatorUiExtensions: {
24
+ register: (registration: SimulatorUiExtensionRegistration) => SimulatorUiExtensionHandle;
25
+ };
26
+ registry: {
27
+ add: (d: Disposable) => Disposable;
28
+ };
29
+ }
30
+ export interface UiExtensionTargetsDeps<W extends UiExtensionWindow> {
31
+ /** Every open project window, in open order. */
32
+ projectWindows: () => W[];
33
+ /** The project window the user is working in, or null when none is open. */
34
+ activeWindow: () => W | null;
35
+ }
36
+ export interface UiExtensionTargets<W extends UiExtensionWindow> {
37
+ /** Give a freshly opened project window its copy of every registration. */
38
+ attachTo: (window: W) => void;
39
+ register: (registration: SimulatorUiExtensionRegistration) => SimulatorUiExtensionHandle;
40
+ }
41
+ export declare function createUiExtensionTargets<W extends UiExtensionWindow>(deps: UiExtensionTargetsDeps<W>): UiExtensionTargets<W>;
42
+ //# sourceMappingURL=ui-extension-targets.d.ts.map