@dimina-kit/devtools 0.3.2-dev.20260524104239 → 0.3.2-dev.20260601115343

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 (174) hide show
  1. package/README.md +20 -7
  2. package/dist/main/api.d.ts +1 -1
  3. package/dist/main/app/app.js +30 -2
  4. package/dist/main/app/bootstrap.d.ts +9 -0
  5. package/dist/main/app/bootstrap.js +28 -1
  6. package/dist/main/index.bundle.js +1468 -496
  7. package/dist/main/ipc/project-fs.d.ts +57 -0
  8. package/dist/main/ipc/project-fs.js +448 -0
  9. package/dist/main/ipc/simulator-module.js +2 -0
  10. package/dist/main/ipc/views.d.ts +19 -0
  11. package/dist/main/ipc/views.js +27 -0
  12. package/dist/main/services/layout/index.d.ts +1 -1
  13. package/dist/main/services/layout/index.js +3 -3
  14. package/dist/main/services/simulator-temp-files/disk.d.ts +55 -0
  15. package/dist/main/services/simulator-temp-files/disk.js +215 -0
  16. package/dist/main/services/simulator-temp-files/fs-channels.d.ts +69 -0
  17. package/dist/main/services/simulator-temp-files/fs-channels.js +108 -0
  18. package/dist/main/services/simulator-temp-files/index.d.ts +33 -0
  19. package/dist/main/services/simulator-temp-files/index.js +160 -0
  20. package/dist/main/services/simulator-temp-files/request-handler.d.ts +30 -0
  21. package/dist/main/services/simulator-temp-files/request-handler.js +178 -0
  22. package/dist/main/services/simulator-temp-files/resolver.d.ts +22 -0
  23. package/dist/main/services/simulator-temp-files/resolver.js +22 -0
  24. package/dist/main/services/simulator-temp-files/store.d.ts +14 -0
  25. package/dist/main/services/simulator-temp-files/store.js +24 -0
  26. package/dist/main/services/toolbar/toolbar-store.d.ts +3 -3
  27. package/dist/main/services/toolbar/toolbar-store.js +18 -1
  28. package/dist/main/services/update/update-manager.d.ts +10 -0
  29. package/dist/main/services/update/update-manager.js +16 -3
  30. package/dist/main/services/views/view-manager.d.ts +17 -4
  31. package/dist/main/services/views/view-manager.js +71 -14
  32. package/dist/main/services/workbench-context.d.ts +6 -1
  33. package/dist/main/services/workspace/workspace-service.d.ts +8 -0
  34. package/dist/main/services/workspace/workspace-service.js +22 -4
  35. package/dist/main/utils/ipc-registry.d.ts +10 -1
  36. package/dist/main/utils/ipc-registry.js +43 -0
  37. package/dist/preload/runtime/temp-files.d.ts +8 -0
  38. package/dist/preload/runtime/temp-files.js +34 -0
  39. package/dist/preload/shared/expose.js +2 -2
  40. package/dist/preload/windows/main.cjs +4 -0
  41. package/dist/preload/windows/main.cjs.map +2 -2
  42. package/dist/preload/windows/simulator.js +40 -8
  43. package/dist/renderer/assets/abap-DiwvWnMr.js +2 -0
  44. package/dist/renderer/assets/apex-CmtZjKlf.js +2 -0
  45. package/dist/renderer/assets/azcli-DL2My_i-.js +2 -0
  46. package/dist/renderer/assets/bat-B-nC98wG.js +2 -0
  47. package/dist/renderer/assets/bicep-Ju5MwOgh.js +3 -0
  48. package/dist/renderer/assets/cameligo-8Eu1TyBr.js +2 -0
  49. package/dist/renderer/assets/chunk-DPI0Y_ll.js +1 -0
  50. package/dist/renderer/assets/clojure-u-RpMkH3.js +2 -0
  51. package/dist/renderer/assets/codicon-ngg6Pgfi.ttf +0 -0
  52. package/dist/renderer/assets/coffee-CdA7bbTe.js +2 -0
  53. package/dist/renderer/assets/constants-CLAQX6VZ.js +2 -0
  54. package/dist/renderer/assets/cpp-CzNFP8ks.js +2 -0
  55. package/dist/renderer/assets/csharp-j1LThmcE.js +2 -0
  56. package/dist/renderer/assets/csp-CLRC61y6.js +2 -0
  57. package/dist/renderer/assets/css-r6rC_7P2.js +4 -0
  58. package/dist/renderer/assets/css.worker-DyDu5ynT.js +90 -0
  59. package/dist/renderer/assets/cssMode-BCBgxrnA.js +2 -0
  60. package/dist/renderer/assets/cypher-CW08XVUh.js +2 -0
  61. package/dist/renderer/assets/dart-Cs9aL5T_.js +2 -0
  62. package/dist/renderer/assets/dockerfile-BWM0M184.js +2 -0
  63. package/dist/renderer/assets/ecl-MJJuer5P.js +2 -0
  64. package/dist/renderer/assets/editor-CWI9TnMM.css +1 -0
  65. package/dist/renderer/assets/editor.api2-BTaYmRq7.js +873 -0
  66. package/dist/renderer/assets/editor.worker-Dpt_xPrs.js +27 -0
  67. package/dist/renderer/assets/elixir-D2AIuXqn.js +2 -0
  68. package/dist/renderer/assets/flow9-B2H24giC.js +2 -0
  69. package/dist/renderer/assets/freemarker2-DGDGzimW.js +4 -0
  70. package/dist/renderer/assets/fsharp-CMk2OIJN.js +2 -0
  71. package/dist/renderer/assets/go-BrMkuJg0.js +2 -0
  72. package/dist/renderer/assets/graphql-PSR1UKGv.js +2 -0
  73. package/dist/renderer/assets/handlebars-bOHhw3EG.js +2 -0
  74. package/dist/renderer/assets/hcl-DAQrbDOW.js +2 -0
  75. package/dist/renderer/assets/html-BMyuX0_c.js +2 -0
  76. package/dist/renderer/assets/html.worker-IWNXhnIC.js +503 -0
  77. package/dist/renderer/assets/htmlMode-DR4kXJ7l.js +2 -0
  78. package/dist/renderer/assets/index-BDMxXUfn.js +50 -0
  79. package/dist/renderer/assets/ini-0TG5BxW0.js +2 -0
  80. package/dist/renderer/assets/input-CCYS8Ave.js +2 -0
  81. package/dist/renderer/assets/{ipc-transport-BzPzxPwf.js → ipc-transport-Bn4KXvhu.js} +5 -5
  82. package/dist/renderer/assets/ipc-transport-Cu7tubyg.css +1 -0
  83. package/dist/renderer/assets/java-rgorz17v.js +2 -0
  84. package/dist/renderer/assets/javascript-Bu-tl1P7.js +2 -0
  85. package/dist/renderer/assets/json.worker-c4h5s80L.js +59 -0
  86. package/dist/renderer/assets/jsonMode-MQV_ffLR.js +8 -0
  87. package/dist/renderer/assets/julia-C8VMdHm8.js +2 -0
  88. package/dist/renderer/assets/kotlin-AhhC4Qhm.js +2 -0
  89. package/dist/renderer/assets/less-Cgca25AP.js +3 -0
  90. package/dist/renderer/assets/lexon-D0GHdBaw.js +2 -0
  91. package/dist/renderer/assets/liquid-ClkfOvhB.js +2 -0
  92. package/dist/renderer/assets/lspLanguageFeatures-Bke_4Ie9.js +5 -0
  93. package/dist/renderer/assets/lua-DmRsNG-P.js +2 -0
  94. package/dist/renderer/assets/m3-BgL5dNKT.js +2 -0
  95. package/dist/renderer/assets/markdown-BuJfycGS.js +2 -0
  96. package/dist/renderer/assets/mdx-RZdUskPu.js +2 -0
  97. package/dist/renderer/assets/mips-C9m_93PR.js +2 -0
  98. package/dist/renderer/assets/monaco.contribution-B7rUMaEv.js +3 -0
  99. package/dist/renderer/assets/msdax-CpFHC9OI.js +2 -0
  100. package/dist/renderer/assets/mysql-qFvltsqN.js +2 -0
  101. package/dist/renderer/assets/objective-c-Bnmr858J.js +2 -0
  102. package/dist/renderer/assets/pascal-WP0_D5AO.js +2 -0
  103. package/dist/renderer/assets/pascaligo-Blom4Rij.js +2 -0
  104. package/dist/renderer/assets/perl-B-vk8g64.js +2 -0
  105. package/dist/renderer/assets/pgsql-Cgvz6v67.js +2 -0
  106. package/dist/renderer/assets/php-8a3Lrw9m.js +2 -0
  107. package/dist/renderer/assets/pla-DuFqEZ8V.js +2 -0
  108. package/dist/renderer/assets/popover-CH4rwpdt.js +2 -0
  109. package/dist/renderer/assets/postiats-DkLtSgkp.js +2 -0
  110. package/dist/renderer/assets/powerquery-BJ1aNepW.js +2 -0
  111. package/dist/renderer/assets/powershell-rE98k687.js +2 -0
  112. package/dist/renderer/assets/protobuf-CUheFacr.js +3 -0
  113. package/dist/renderer/assets/pug-LDcAMD8w.js +2 -0
  114. package/dist/renderer/assets/python-Cobrm_-8.js +2 -0
  115. package/dist/renderer/assets/qsharp-DUKSQoR1.js +2 -0
  116. package/dist/renderer/assets/r-D-QApv87.js +2 -0
  117. package/dist/renderer/assets/razor-BEUIQFNJ.js +2 -0
  118. package/dist/renderer/assets/redis-SXdDyWR9.js +2 -0
  119. package/dist/renderer/assets/redshift-Y6lsCryn.js +2 -0
  120. package/dist/renderer/assets/restructuredtext-edObr9a8.js +2 -0
  121. package/dist/renderer/assets/ruby-CNnUfF-8.js +2 -0
  122. package/dist/renderer/assets/rust-IHUZWzBr.js +2 -0
  123. package/dist/renderer/assets/sb-DrUvY44N.js +2 -0
  124. package/dist/renderer/assets/scala-B4hbXGLM.js +2 -0
  125. package/dist/renderer/assets/scheme-BGrd12j3.js +2 -0
  126. package/dist/renderer/assets/scss-x5G1ES4U.js +4 -0
  127. package/dist/renderer/assets/select-Ct4-sijm.js +2 -0
  128. package/dist/renderer/assets/settings-CMTB-t0x.js +2 -0
  129. package/dist/renderer/assets/{settings-api-BXCw9vOZ.js → settings-api-Csdngf9Z.js} +2 -2
  130. package/dist/renderer/assets/shell-DOehe2Y8.js +2 -0
  131. package/dist/renderer/assets/solidity-BeRvcwWV.js +2 -0
  132. package/dist/renderer/assets/sophia-DZbkUNjy.js +2 -0
  133. package/dist/renderer/assets/sparql-B7_oi5-h.js +2 -0
  134. package/dist/renderer/assets/sql-CTlsFWVE.js +2 -0
  135. package/dist/renderer/assets/st-DJVEJdPE.js +2 -0
  136. package/dist/renderer/assets/swift-CwhT3fYa.js +2 -0
  137. package/dist/renderer/assets/systemverilog-BQN63pkN.js +2 -0
  138. package/dist/renderer/assets/tcl-DqwfpskA.js +2 -0
  139. package/dist/renderer/assets/ts.worker-BwM5Ha3L.js +67720 -0
  140. package/dist/renderer/assets/tsMode-BHa7dl9v.js +12 -0
  141. package/dist/renderer/assets/twig-BiyenUgc.js +2 -0
  142. package/dist/renderer/assets/typescript-15aT0Yj8.js +2 -0
  143. package/dist/renderer/assets/typespec-CWOJribt.js +2 -0
  144. package/dist/renderer/assets/vb-Cq5F87m3.js +2 -0
  145. package/dist/renderer/assets/wgsl-BAvW2lVr.js +299 -0
  146. package/dist/renderer/assets/workbenchSettings-CODFCzOg.js +8 -0
  147. package/dist/renderer/assets/workers-CRBS0W-v.js +2 -0
  148. package/dist/renderer/assets/xml-bR2Zh-HV.js +2 -0
  149. package/dist/renderer/assets/yaml-Bdk54Qrb.js +2 -0
  150. package/dist/renderer/entries/main/index.html +29 -6
  151. package/dist/renderer/entries/popover/index.html +7 -6
  152. package/dist/renderer/entries/settings/index.html +6 -5
  153. package/dist/renderer/entries/workbench-settings/index.html +6 -5
  154. package/dist/shared/constants.d.ts +0 -4
  155. package/dist/shared/constants.js +0 -4
  156. package/dist/shared/ipc-channels.d.ts +24 -0
  157. package/dist/shared/ipc-channels.js +37 -0
  158. package/dist/shared/ipc-schemas.d.ts +6 -0
  159. package/dist/shared/ipc-schemas.js +15 -0
  160. package/dist/shared/types.d.ts +37 -0
  161. package/dist/shared/vpath.d.ts +42 -0
  162. package/dist/shared/vpath.js +105 -0
  163. package/dist/simulator/assets/simulator-B4e3c6_O.js +9 -0
  164. package/dist/simulator/simulator.html +1 -1
  165. package/package.json +5 -4
  166. package/dist/renderer/assets/constants-DI382mTP.js +0 -2
  167. package/dist/renderer/assets/index-4lkyF644.js +0 -46
  168. package/dist/renderer/assets/input-D4byFOLS.js +0 -2
  169. package/dist/renderer/assets/ipc-transport-DqbRdZNO.css +0 -1
  170. package/dist/renderer/assets/popover-cxKrg_os.js +0 -2
  171. package/dist/renderer/assets/select-BgSkkdHW.js +0 -2
  172. package/dist/renderer/assets/settings-oD2K1jdT.js +0 -2
  173. package/dist/renderer/assets/workbenchSettings-CTNBpTft.js +0 -8
  174. package/dist/simulator/assets/simulator-DDRBJ6Wa.js +0 -9
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  基于 Electron 的小程序开发者工具。提供模拟器、Chrome DevTools 面板、WXML/AppData/Storage 面板、编译配置等功能。
4
4
 
5
- 下游 host 通过 `createWorkbenchApp()` 集成并定制 devtools。扩展模型设计见 [`docs/extension-model.md`](docs/extension-model.md)。
5
+ 下游 host 通过 [`@dimina-kit/workbench`](../workbench)`workbench(config)` fluent API 集成并定制 devtools。扩展模型设计见 [`docs/workbench-model.md`](docs/workbench-model.md)。
6
6
 
7
7
  ---
8
8
 
@@ -53,10 +53,14 @@ createWorkbenchApp({
53
53
  instance.registerSimulatorApi('login', (params) => myLogin(params))
54
54
 
55
55
  // 工具栏:整表替换,随 host 状态(如登录态)重算时再 set 一次
56
- const refreshToolbar = () => instance.toolbar.set([
57
- { id: 'deploy', label: '发布', handler: () => deploy() },
58
- { id: 'preview', label: '预览', handler: () => preview() },
59
- ])
56
+ const refreshToolbar = () => {
57
+ const currentUser = getCurrentUser()
58
+ instance.toolbar.set([
59
+ { id: 'account', label: '当前用户', kind: 'avatar', placement: 'leading', displayInitial: currentUser?.name, avatarUrl: currentUser?.avatar, handler: () => showAccount() },
60
+ { id: 'preview', label: '预览', placement: 'primary', handler: () => preview() },
61
+ { id: 'deploy', label: '发布', placement: 'trailing', handler: () => deploy() },
62
+ ])
63
+ }
60
64
  refreshToolbar()
61
65
 
62
66
  // 自定义 IPC:经 gated 的 IpcRegistry,不再裸 ipcMain.handle
@@ -66,6 +70,12 @@ createWorkbenchApp({
66
70
  // const win = createDialogWindow(/* ... */)
67
71
  // instance.registerTrustedWindow(win)
68
72
  },
73
+ onBeforeOpenProject: async ({ projectPath, instance }) => {
74
+ const ok = await canOpenProject(projectPath)
75
+ return ok
76
+ ? { allow: true }
77
+ : { allow: false, reason: '当前账号没有项目权限' }
78
+ },
69
79
  onBeforeClose: ({ context }) => {
70
80
  // 窗口关闭前的自定义清理;session 关闭和 view 销毁由框架自动处理
71
81
  },
@@ -203,8 +213,9 @@ src/
203
213
  | `rendererDir` | `string` | 内置 | 自定义 renderer HTML 目录 |
204
214
  | `icon` | `string` | — | 窗口/任务栏图标路径(macOS 使用 app bundle 图标) |
205
215
  | `menuBuilder` | `(mainWindow, menuContext: MenuContext) => void` | 内置菜单 | 自定义菜单构建器;`menuContext` 为收窄后的 `MenuContext`,不含 `registry`/`senderPolicy` 等内部管线 |
206
- | `onSetup` | `(instance) => void` | — | 窗口和 context 创建后的回调,用于注册 Contribution(见下文)|
207
- | `onBeforeClose` | `(instance) => void` | — | 窗口关闭前的回调,session 关闭由框架自动处理 |
216
+ | `onSetup` | `(instance) => void \| Promise<void>` | — | 窗口和 context 创建后的回调,用于注册 Contribution(见下文)|
217
+ | `onBeforeOpenProject` | `({ projectPath, instance }) => BeforeOpenProjectResult \| Promise<BeforeOpenProjectResult>` | — | 项目目录校验通过后、关闭当前 session 和编译新项目之前的宿主准入钩子 |
218
+ | `onBeforeClose` | `(instance) => void \| Promise<void>` | — | 窗口关闭前的回调,session 关闭由框架自动处理 |
208
219
  | `window` | `WorkbenchWindowConfig` | — | 窗口尺寸覆盖 |
209
220
  | `updateChecker` | `UpdateChecker` | — | 自定义更新检查器;提供后启用"检查更新"功能 |
210
221
  | `updateOptions` | `{ checkInterval?, initialDelay?, getCurrentVersion? }` | — | 仅当 `updateChecker` 提供时生效,默认 1h / 5s |
@@ -220,6 +231,8 @@ src/
220
231
  | `instance.ipc` | `IpcRegistry` 实例,`instance.ipc.handle(channel, fn)` 注册自定义 IPC;已绑定 `senderPolicy` 网关 |
221
232
  | `instance.registerTrustedWindow(win)` | 把 host 自有弹窗 `BrowserWindow` 加入受信 sender 集,否则其发起的 `instance.ipc` 调用会被网关拒绝。窗口关闭即移除 |
222
233
 
234
+ `onSetup` 可以返回 Promise;`createWorkbenchApp().start()` 会等待 `onSetup` 解析完成后才继续后续启动流程,因此宿主在 `onSetup` 内注册的 simulator API 会早于 simulator `<webview>` 首次枚举自定义 API。
235
+
223
236
  ### 内置面板 ID
224
237
 
225
238
  `'wxml'` \| `'console'` \| `'appdata'` \| `'storage'`
@@ -15,5 +15,5 @@ export { IpcRegistry } from './utils/ipc-registry.js';
15
15
  export type { SenderPolicy } from './utils/ipc-registry.js';
16
16
  export { UpdateManager, createGitHubReleaseChecker } from './services/update/index.js';
17
17
  export type { UpdateManagerOptions, GitHubReleaseCheckerOptions, PickAssetContext, VersionScheme, } from './services/update/index.js';
18
- export type { WorkbenchConfig, WorkbenchAppConfig, CompilationAdapter, ProjectSession, ToolbarAction, BuiltinPanelId, BuiltinModuleId, UpdateChecker, UpdateInfo, } from '../shared/types.js';
18
+ export type { BeforeOpenProjectHook, BeforeOpenProjectResult, WorkbenchConfig, WorkbenchAppConfig, CompilationAdapter, ProjectSession, ToolbarAction, ToolbarActionInput, ToolbarActionKind, ToolbarActionPlacement, BuiltinPanelId, BuiltinModuleId, UpdateChecker, UpdateInfo, } from '../shared/types.js';
19
19
  //# sourceMappingURL=api.d.ts.map
@@ -1,5 +1,6 @@
1
- import { setupCdpPort } from './bootstrap.js';
2
- import { app, BrowserWindow, nativeImage } from 'electron';
1
+ import { setupCdpPort, registerDifileScheme } from './bootstrap.js';
2
+ import { registerProjectFsIpc } from '../ipc/project-fs.js';
3
+ import { app, BrowserWindow, nativeImage, session } from 'electron';
3
4
  import fs from 'fs';
4
5
  import path from 'path';
5
6
  import { rendererDir as defaultRendererDir, defaultPreloadPath } from '../utils/paths.js';
@@ -13,6 +14,7 @@ import { registerAppIpc, popoverModule, projectsModule, sessionModule, settingsM
13
14
  import { startAutomationServer } from '../services/automation/index.js';
14
15
  import { startMcpServer } from '../services/mcp/index.js';
15
16
  import { setupSimulatorStorage } from '../services/simulator-storage/index.js';
17
+ import { setupSimulatorTempFiles } from '../services/simulator-temp-files/index.js';
16
18
  import { UpdateManager } from '../services/update/index.js';
17
19
  import { toDisposable } from '../utils/disposable.js';
18
20
  import { IpcRegistry } from '../utils/ipc-registry.js';
@@ -258,7 +260,21 @@ function enableDevRendererAutoReload(rendererDir) {
258
260
  export function createWorkbenchApp(config = {}) {
259
261
  let setupPromise = null;
260
262
  let appEventsRegistered = false;
263
+ // Lock the visible app name BEFORE app.whenReady so the dock label,
264
+ // ⌘-Tab card and macOS app-menu first item all read "Dimina DevTools"
265
+ // in both dev (unpackaged Electron) and packaged builds. `app.setName`
266
+ // overrides the unpackaged process name ("Electron") and is harmless
267
+ // when the packaged Info.plist already says the same thing.
268
+ // Host integrators that brand the app differently can still override
269
+ // `config.appName`; we keep our default consistent with `electron-builder.yml#productName`.
270
+ try {
271
+ app.setName(config.appName ?? 'Dimina DevTools');
272
+ }
273
+ catch { /* electron stub in tests */ }
261
274
  setupCdpPort();
275
+ // Privileged scheme registration must run before `app.whenReady` —
276
+ // registering it later throws.
277
+ registerDifileScheme();
262
278
  async function setup() {
263
279
  if (setupPromise)
264
280
  return setupPromise;
@@ -268,11 +284,20 @@ export function createWorkbenchApp(config = {}) {
268
284
  const mainWindow = createConfiguredMainWindow(config, rendererDir);
269
285
  const context = createContext(config, mainWindow, rendererDir);
270
286
  context.registry.add(registerAppIpc(context));
287
+ // Sandboxed project file-system IPC for the in-renderer Monaco editor.
288
+ context.registry.add(registerProjectFsIpc(context));
271
289
  // One process-wide listener that re-syncs every window's native
272
290
  // backgroundColor on theme change — windows otherwise keep the stale
273
291
  // creation-time color (see installThemeBackgroundSync).
274
292
  context.registry.add(installThemeBackgroundSync());
275
293
  registerBuiltinModules(config, context);
294
+ // Wire the simulator-side difile:// protocol handler + temp-file IPC
295
+ // before host onSetup so any host-driven simulator boot sees the
296
+ // protocol live. The module installs its own narrow sender-policy
297
+ // (simulator-session-only) — see file header — because the default
298
+ // workbench policy intentionally rejects the simulator <webview>.
299
+ const simSession = session.fromPartition('persist:simulator');
300
+ context.registry.add(setupSimulatorTempFiles(simSession));
276
301
  installMenu(config, mainWindow, context);
277
302
  // Gated custom-IPC surface for the host. Bound to ctx.senderPolicy so
278
303
  // host channels go through the same gateway as built-in IPC, and
@@ -300,6 +325,9 @@ export function createWorkbenchApp(config = {}) {
300
325
  },
301
326
  dispose: () => disposeContext(context),
302
327
  };
328
+ if (config.onBeforeOpenProject) {
329
+ context.beforeOpenProject = (projectPath) => config.onBeforeOpenProject({ projectPath, instance });
330
+ }
303
331
  if (config.onSetup) {
304
332
  await config.onSetup(instance);
305
333
  }
@@ -1,3 +1,12 @@
1
+ /**
2
+ * Register `difile://` as a privileged scheme so `simSession.protocol.handle`
3
+ * can serve `difile://devtools/{uuid}` URLs from the simulator webview without
4
+ * tripping CSP / fetch-API restrictions. Must be called before `app.whenReady`.
5
+ *
6
+ * Idempotent — subsequent calls are no-ops because Electron throws if the same
7
+ * scheme is registered twice.
8
+ */
9
+ export declare function registerDifileScheme(): void;
1
10
  /**
2
11
  * Suppress EPIPE errors on stdout/stderr.
3
12
  * Call at the very top of your entry file, before any imports that may write.
@@ -1,6 +1,33 @@
1
- import { app } from 'electron';
1
+ import { app, protocol } from 'electron';
2
2
  import { DEFAULT_CDP_PORT } from '../../shared/constants.js';
3
3
  import { loadWorkbenchSettings } from '../services/settings/index.js';
4
+ let difileSchemeRegistered = false;
5
+ /**
6
+ * Register `difile://` as a privileged scheme so `simSession.protocol.handle`
7
+ * can serve `difile://devtools/{uuid}` URLs from the simulator webview without
8
+ * tripping CSP / fetch-API restrictions. Must be called before `app.whenReady`.
9
+ *
10
+ * Idempotent — subsequent calls are no-ops because Electron throws if the same
11
+ * scheme is registered twice.
12
+ */
13
+ export function registerDifileScheme() {
14
+ if (difileSchemeRegistered)
15
+ return;
16
+ difileSchemeRegistered = true;
17
+ protocol.registerSchemesAsPrivileged([
18
+ {
19
+ scheme: 'difile',
20
+ privileges: {
21
+ standard: true,
22
+ secure: true,
23
+ supportFetchAPI: true,
24
+ stream: true,
25
+ bypassCSP: true,
26
+ corsEnabled: true,
27
+ },
28
+ },
29
+ ]);
30
+ }
4
31
  /**
5
32
  * Suppress EPIPE errors on stdout/stderr.
6
33
  * Call at the very top of your entry file, before any imports that may write.