@dimina-kit/devtools 0.3.2-dev.20260525152421 → 0.3.2-dev.20260610082053

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 (295) hide show
  1. package/README.md +43 -40
  2. package/dist/main/api.d.ts +0 -1
  3. package/dist/main/api.js +5 -1
  4. package/dist/main/app/app.d.ts +15 -5
  5. package/dist/main/app/app.js +247 -110
  6. package/dist/main/app/bootstrap.d.ts +16 -0
  7. package/dist/main/app/bootstrap.js +20 -0
  8. package/dist/main/app/launch.d.ts +8 -4
  9. package/dist/main/app/launch.js +9 -4
  10. package/dist/main/index.bundle.js +6607 -2102
  11. package/dist/main/index.js +9 -1
  12. package/dist/main/ipc/app.d.ts +1 -1
  13. package/dist/main/ipc/bridge-router.d.ts +61 -0
  14. package/dist/main/ipc/bridge-router.js +1300 -0
  15. package/dist/main/ipc/panels.d.ts +1 -1
  16. package/dist/main/ipc/panels.js +6 -2
  17. package/dist/main/ipc/popover.d.ts +1 -1
  18. package/dist/main/ipc/project-fs.d.ts +57 -0
  19. package/dist/main/ipc/project-fs.js +448 -0
  20. package/dist/main/ipc/projects.d.ts +1 -1
  21. package/dist/main/ipc/session.d.ts +1 -1
  22. package/dist/main/ipc/settings.d.ts +1 -1
  23. package/dist/main/ipc/simulator-module.d.ts +6 -0
  24. package/dist/main/ipc/simulator-module.js +11 -1
  25. package/dist/main/ipc/simulator.d.ts +2 -2
  26. package/dist/main/ipc/simulator.js +49 -5
  27. package/dist/main/ipc/toolbar.d.ts +1 -1
  28. package/dist/main/ipc/views.d.ts +19 -0
  29. package/dist/main/ipc/views.js +65 -0
  30. package/dist/main/runtime/devtools-backend.d.ts +17 -0
  31. package/dist/main/runtime/devtools-backend.js +49 -0
  32. package/dist/main/runtime/miniapp-runtime.d.ts +39 -0
  33. package/dist/main/runtime/miniapp-runtime.js +17 -0
  34. package/dist/main/services/automation/exec.d.ts +27 -2
  35. package/dist/main/services/automation/exec.js +37 -3
  36. package/dist/main/services/automation/handlers/app.js +127 -11
  37. package/dist/main/services/automation/handlers/page.js +36 -19
  38. package/dist/main/services/automation/index.js +40 -13
  39. package/dist/main/services/automation/wait-active-page.d.ts +56 -0
  40. package/dist/main/services/automation/wait-active-page.js +71 -0
  41. package/dist/main/services/console-forward/index.d.ts +36 -0
  42. package/dist/main/services/console-forward/index.js +81 -0
  43. package/dist/main/services/dimina-resource-server.d.ts +7 -0
  44. package/dist/main/services/dimina-resource-server.js +99 -0
  45. package/dist/main/services/elements-forward/index.d.ts +66 -0
  46. package/dist/main/services/elements-forward/index.js +583 -0
  47. package/dist/main/services/layout/index.d.ts +23 -1
  48. package/dist/main/services/layout/index.js +28 -3
  49. package/dist/main/services/mcp/index.d.ts +1 -0
  50. package/dist/main/services/mcp/index.js +3 -0
  51. package/dist/main/services/mcp/server.d.ts +1 -1
  52. package/dist/main/services/mcp/server.js +1 -1
  53. package/dist/main/services/mcp/target-manager.d.ts +35 -0
  54. package/dist/main/services/mcp/target-manager.js +63 -1
  55. package/dist/main/services/mcp/tools/context-tools.js +15 -1
  56. package/dist/main/services/module.d.ts +1 -1
  57. package/dist/main/services/network-forward/index.d.ts +190 -0
  58. package/dist/main/services/network-forward/index.js +765 -0
  59. package/dist/main/services/notifications/renderer-notifier.d.ts +11 -0
  60. package/dist/main/services/notifications/renderer-notifier.js +7 -1
  61. package/dist/main/services/render-inspect/index.d.ts +41 -0
  62. package/dist/main/services/render-inspect/index.js +88 -0
  63. package/dist/main/services/safe-area/index.d.ts +17 -0
  64. package/dist/main/services/safe-area/index.js +59 -0
  65. package/dist/main/services/service-host-pool/pool.d.ts +197 -0
  66. package/dist/main/services/service-host-pool/pool.js +364 -0
  67. package/dist/main/services/simulator/custom-apis.d.ts +34 -0
  68. package/dist/main/services/simulator/custom-apis.js +22 -0
  69. package/dist/main/services/simulator-appdata/index.d.ts +35 -0
  70. package/dist/main/services/simulator-appdata/index.js +71 -0
  71. package/dist/main/services/simulator-current-page/index.d.ts +24 -0
  72. package/dist/main/services/simulator-current-page/index.js +19 -0
  73. package/dist/main/services/simulator-storage/index.d.ts +37 -2
  74. package/dist/main/services/simulator-storage/index.js +209 -32
  75. package/dist/main/services/simulator-storage/service-storage-ops.d.ts +40 -0
  76. package/dist/main/services/simulator-storage/service-storage-ops.js +67 -0
  77. package/dist/main/services/simulator-temp-files/fs-channels.js +1 -1
  78. package/dist/main/services/simulator-temp-files/index.d.ts +1 -1
  79. package/dist/main/services/simulator-temp-files/index.js +1 -1
  80. package/dist/main/services/simulator-temp-files/request-handler.js +1 -1
  81. package/dist/main/services/simulator-wxml/index.d.ts +29 -0
  82. package/dist/main/services/simulator-wxml/index.js +28 -0
  83. package/dist/main/services/update/update-manager.d.ts +10 -0
  84. package/dist/main/services/update/update-manager.js +16 -3
  85. package/dist/main/services/views/devtools-tabs.d.ts +47 -0
  86. package/dist/main/services/views/devtools-tabs.js +95 -0
  87. package/dist/main/services/views/view-manager.d.ts +142 -4
  88. package/dist/main/services/views/view-manager.js +909 -17
  89. package/dist/main/services/workbench-context.d.ts +66 -1
  90. package/dist/main/services/workbench-context.js +6 -1
  91. package/dist/main/services/workspace/workspace-service.d.ts +8 -0
  92. package/dist/main/services/workspace/workspace-service.js +12 -0
  93. package/dist/main/utils/ipc-registry.d.ts +11 -2
  94. package/dist/main/utils/ipc-registry.js +63 -3
  95. package/dist/main/utils/paths.d.ts +15 -0
  96. package/dist/main/utils/paths.js +19 -0
  97. package/dist/main/utils/sender-policy.d.ts +9 -3
  98. package/dist/main/utils/sender-policy.js +18 -4
  99. package/dist/main/utils/theme.d.ts +1 -1
  100. package/dist/main/utils/theme.js +1 -1
  101. package/dist/main/windows/main-window/create.d.ts +0 -6
  102. package/dist/main/windows/main-window/create.js +11 -59
  103. package/dist/main/windows/main-window/events.d.ts +1 -1
  104. package/dist/main/windows/main-window/events.js +1 -1
  105. package/dist/main/windows/service-host-window/create.d.ts +52 -0
  106. package/dist/main/windows/service-host-window/create.js +112 -0
  107. package/dist/native-host/common/common.js +368 -0
  108. package/dist/native-host/container/pageFrame.css +1 -0
  109. package/dist/native-host/render/render.js +9334 -0
  110. package/dist/native-host/service/service.js +6 -0
  111. package/dist/preload/index.d.ts +2 -0
  112. package/dist/preload/index.js +6 -0
  113. package/dist/preload/instrumentation/app-data.d.ts +18 -20
  114. package/dist/preload/instrumentation/app-data.js +23 -160
  115. package/dist/preload/instrumentation/wxml-extract.d.ts +1 -1
  116. package/dist/preload/instrumentation/wxml-extract.js +1 -1
  117. package/dist/preload/runtime/bridge.d.ts +3 -8
  118. package/dist/preload/runtime/bridge.js +2 -32
  119. package/dist/preload/runtime/custom-apis.js +20 -17
  120. package/dist/preload/runtime/host-toolbar-advertiser.d.ts +27 -0
  121. package/dist/preload/runtime/host-toolbar-advertiser.js +55 -0
  122. package/dist/preload/runtime/main-api-runner.d.ts +9 -0
  123. package/dist/preload/runtime/main-api-runner.js +85 -0
  124. package/dist/preload/runtime/native-host.d.ts +43 -0
  125. package/dist/preload/runtime/native-host.js +83 -0
  126. package/dist/preload/shared/expose.d.ts +10 -5
  127. package/dist/preload/shared/expose.js +29 -11
  128. package/dist/preload/shared/sid-registry.d.ts +11 -0
  129. package/dist/preload/shared/sid-registry.js +38 -0
  130. package/dist/preload/windows/host-toolbar.cjs +161 -0
  131. package/dist/preload/windows/host-toolbar.cjs.map +7 -0
  132. package/dist/preload/windows/host-toolbar.d.ts +2 -0
  133. package/dist/preload/windows/host-toolbar.js +12 -0
  134. package/dist/preload/windows/main.cjs +1939 -0
  135. package/dist/preload/windows/main.cjs.map +4 -4
  136. package/dist/preload/windows/simulator.cjs +925 -0
  137. package/dist/preload/windows/simulator.cjs.map +7 -0
  138. package/dist/preload/windows/simulator.js +243 -573
  139. package/dist/render-host/pageFrame.html +29 -0
  140. package/dist/render-host/preload.cjs +154 -0
  141. package/dist/render-host/render-inspect.js +295 -0
  142. package/dist/renderer/assets/abap-DiwvWnMr.js +2 -0
  143. package/dist/renderer/assets/apex-CmtZjKlf.js +2 -0
  144. package/dist/renderer/assets/azcli-DL2My_i-.js +2 -0
  145. package/dist/renderer/assets/bat-B-nC98wG.js +2 -0
  146. package/dist/renderer/assets/bicep-Ju5MwOgh.js +3 -0
  147. package/dist/renderer/assets/cameligo-8Eu1TyBr.js +2 -0
  148. package/dist/renderer/assets/chunk-DPI0Y_ll.js +1 -0
  149. package/dist/renderer/assets/clojure-u-RpMkH3.js +2 -0
  150. package/dist/renderer/assets/codicon-ngg6Pgfi.ttf +0 -0
  151. package/dist/renderer/assets/coffee-CdA7bbTe.js +2 -0
  152. package/dist/renderer/assets/constants-CLAQX6VZ.js +2 -0
  153. package/dist/renderer/assets/cpp-CzNFP8ks.js +2 -0
  154. package/dist/renderer/assets/csharp-j1LThmcE.js +2 -0
  155. package/dist/renderer/assets/csp-CLRC61y6.js +2 -0
  156. package/dist/renderer/assets/css-r6rC_7P2.js +4 -0
  157. package/dist/renderer/assets/css.worker-DyDu5ynT.js +90 -0
  158. package/dist/renderer/assets/cssMode-BCBgxrnA.js +2 -0
  159. package/dist/renderer/assets/cypher-CW08XVUh.js +2 -0
  160. package/dist/renderer/assets/dart-Cs9aL5T_.js +2 -0
  161. package/dist/renderer/assets/dockerfile-BWM0M184.js +2 -0
  162. package/dist/renderer/assets/ecl-MJJuer5P.js +2 -0
  163. package/dist/renderer/assets/editor-CWI9TnMM.css +1 -0
  164. package/dist/renderer/assets/editor.api2-BTaYmRq7.js +873 -0
  165. package/dist/renderer/assets/editor.worker-Dpt_xPrs.js +27 -0
  166. package/dist/renderer/assets/elixir-D2AIuXqn.js +2 -0
  167. package/dist/renderer/assets/flow9-B2H24giC.js +2 -0
  168. package/dist/renderer/assets/freemarker2-DGDGzimW.js +4 -0
  169. package/dist/renderer/assets/fsharp-CMk2OIJN.js +2 -0
  170. package/dist/renderer/assets/go-BrMkuJg0.js +2 -0
  171. package/dist/renderer/assets/graphql-PSR1UKGv.js +2 -0
  172. package/dist/renderer/assets/handlebars-bOHhw3EG.js +2 -0
  173. package/dist/renderer/assets/hcl-DAQrbDOW.js +2 -0
  174. package/dist/renderer/assets/html-BMyuX0_c.js +2 -0
  175. package/dist/renderer/assets/html.worker-IWNXhnIC.js +503 -0
  176. package/dist/renderer/assets/htmlMode-DR4kXJ7l.js +2 -0
  177. package/dist/renderer/assets/index-CcJKzatF.js +50 -0
  178. package/dist/renderer/assets/ini-0TG5BxW0.js +2 -0
  179. package/dist/renderer/assets/input-QGx6FFX1.js +2 -0
  180. package/dist/renderer/assets/ipc-transport-BT4QYQqu.css +1 -0
  181. package/dist/renderer/assets/{ipc-transport-BzPzxPwf.js → ipc-transport-DvZvwK-Z.js} +5 -5
  182. package/dist/renderer/assets/java-rgorz17v.js +2 -0
  183. package/dist/renderer/assets/javascript-Bu-tl1P7.js +2 -0
  184. package/dist/renderer/assets/json.worker-c4h5s80L.js +59 -0
  185. package/dist/renderer/assets/jsonMode-MQV_ffLR.js +8 -0
  186. package/dist/renderer/assets/julia-C8VMdHm8.js +2 -0
  187. package/dist/renderer/assets/kotlin-AhhC4Qhm.js +2 -0
  188. package/dist/renderer/assets/less-Cgca25AP.js +3 -0
  189. package/dist/renderer/assets/lexon-D0GHdBaw.js +2 -0
  190. package/dist/renderer/assets/liquid-ClkfOvhB.js +2 -0
  191. package/dist/renderer/assets/lspLanguageFeatures-Bke_4Ie9.js +5 -0
  192. package/dist/renderer/assets/lua-DmRsNG-P.js +2 -0
  193. package/dist/renderer/assets/m3-BgL5dNKT.js +2 -0
  194. package/dist/renderer/assets/markdown-BuJfycGS.js +2 -0
  195. package/dist/renderer/assets/mdx-RZdUskPu.js +2 -0
  196. package/dist/renderer/assets/mips-C9m_93PR.js +2 -0
  197. package/dist/renderer/assets/monaco.contribution-B7rUMaEv.js +3 -0
  198. package/dist/renderer/assets/msdax-CpFHC9OI.js +2 -0
  199. package/dist/renderer/assets/mysql-qFvltsqN.js +2 -0
  200. package/dist/renderer/assets/objective-c-Bnmr858J.js +2 -0
  201. package/dist/renderer/assets/pascal-WP0_D5AO.js +2 -0
  202. package/dist/renderer/assets/pascaligo-Blom4Rij.js +2 -0
  203. package/dist/renderer/assets/perl-B-vk8g64.js +2 -0
  204. package/dist/renderer/assets/pgsql-Cgvz6v67.js +2 -0
  205. package/dist/renderer/assets/php-8a3Lrw9m.js +2 -0
  206. package/dist/renderer/assets/pla-DuFqEZ8V.js +2 -0
  207. package/dist/renderer/assets/popover-BOH1If1J.js +2 -0
  208. package/dist/renderer/assets/postiats-DkLtSgkp.js +2 -0
  209. package/dist/renderer/assets/powerquery-BJ1aNepW.js +2 -0
  210. package/dist/renderer/assets/powershell-rE98k687.js +2 -0
  211. package/dist/renderer/assets/protobuf-CUheFacr.js +3 -0
  212. package/dist/renderer/assets/pug-LDcAMD8w.js +2 -0
  213. package/dist/renderer/assets/python-Cobrm_-8.js +2 -0
  214. package/dist/renderer/assets/qsharp-DUKSQoR1.js +2 -0
  215. package/dist/renderer/assets/r-D-QApv87.js +2 -0
  216. package/dist/renderer/assets/razor-BEUIQFNJ.js +2 -0
  217. package/dist/renderer/assets/redis-SXdDyWR9.js +2 -0
  218. package/dist/renderer/assets/redshift-Y6lsCryn.js +2 -0
  219. package/dist/renderer/assets/restructuredtext-edObr9a8.js +2 -0
  220. package/dist/renderer/assets/ruby-CNnUfF-8.js +2 -0
  221. package/dist/renderer/assets/rust-IHUZWzBr.js +2 -0
  222. package/dist/renderer/assets/sb-DrUvY44N.js +2 -0
  223. package/dist/renderer/assets/scala-B4hbXGLM.js +2 -0
  224. package/dist/renderer/assets/scheme-BGrd12j3.js +2 -0
  225. package/dist/renderer/assets/scss-x5G1ES4U.js +4 -0
  226. package/dist/renderer/assets/select-C7JQ8G5N.js +2 -0
  227. package/dist/renderer/assets/settings-DpAbTJyF.js +2 -0
  228. package/dist/renderer/assets/{settings-api-BXCw9vOZ.js → settings-api-RD2IZF53.js} +2 -2
  229. package/dist/renderer/assets/shell-DOehe2Y8.js +2 -0
  230. package/dist/renderer/assets/solidity-BeRvcwWV.js +2 -0
  231. package/dist/renderer/assets/sophia-DZbkUNjy.js +2 -0
  232. package/dist/renderer/assets/sparql-B7_oi5-h.js +2 -0
  233. package/dist/renderer/assets/sql-CTlsFWVE.js +2 -0
  234. package/dist/renderer/assets/st-DJVEJdPE.js +2 -0
  235. package/dist/renderer/assets/swift-CwhT3fYa.js +2 -0
  236. package/dist/renderer/assets/systemverilog-BQN63pkN.js +2 -0
  237. package/dist/renderer/assets/tcl-DqwfpskA.js +2 -0
  238. package/dist/renderer/assets/ts.worker-BwM5Ha3L.js +67720 -0
  239. package/dist/renderer/assets/tsMode-BHa7dl9v.js +12 -0
  240. package/dist/renderer/assets/twig-BiyenUgc.js +2 -0
  241. package/dist/renderer/assets/typescript-15aT0Yj8.js +2 -0
  242. package/dist/renderer/assets/typespec-CWOJribt.js +2 -0
  243. package/dist/renderer/assets/vb-Cq5F87m3.js +2 -0
  244. package/dist/renderer/assets/wgsl-BAvW2lVr.js +299 -0
  245. package/dist/renderer/assets/workbenchSettings-CNJX4Qna.js +8 -0
  246. package/dist/renderer/assets/workers-CRBS0W-v.js +2 -0
  247. package/dist/renderer/assets/xml-bR2Zh-HV.js +2 -0
  248. package/dist/renderer/assets/yaml-Bdk54Qrb.js +2 -0
  249. package/dist/renderer/entries/main/index.html +29 -6
  250. package/dist/renderer/entries/popover/index.html +7 -6
  251. package/dist/renderer/entries/settings/index.html +6 -5
  252. package/dist/renderer/entries/workbench-settings/index.html +6 -5
  253. package/dist/service-host/preload.cjs +254 -0
  254. package/dist/service-host/service.html +10 -0
  255. package/dist/service-host/sourcemap-rewrite.cjs +58 -0
  256. package/dist/service-host/sync-api-patch.js +20 -0
  257. package/dist/service-host/sync-impls/menu-button.js +16 -0
  258. package/dist/service-host/sync-impls/storage.js +50 -0
  259. package/dist/service-host/sync-impls/system-info.js +54 -0
  260. package/dist/shared/appdata-accumulator.d.ts +95 -0
  261. package/dist/shared/appdata-accumulator.js +213 -0
  262. package/dist/shared/bridge-channels.d.ts +364 -0
  263. package/dist/shared/bridge-channels.js +54 -0
  264. package/dist/shared/constants.d.ts +0 -4
  265. package/dist/shared/constants.js +0 -4
  266. package/dist/shared/ipc-channels.d.ts +108 -1
  267. package/dist/shared/ipc-channels.js +127 -10
  268. package/dist/shared/ipc-schemas.d.ts +65 -2
  269. package/dist/shared/ipc-schemas.js +79 -3
  270. package/dist/shared/open-in-editor.d.ts +71 -0
  271. package/dist/shared/open-in-editor.js +138 -0
  272. package/dist/shared/simulator-api-metadata.d.ts +21 -0
  273. package/dist/shared/simulator-api-metadata.js +23 -0
  274. package/dist/shared/types.d.ts +2 -2
  275. package/dist/shared/vpath.d.ts +42 -0
  276. package/dist/shared/vpath.js +105 -0
  277. package/dist/simulator/assets/device-shell-DsdcNEkt.css +1 -0
  278. package/dist/simulator/assets/device-shell-vwYSOVrh.js +2 -0
  279. package/dist/simulator/assets/jsx-runtime-P6ZegaOf.js +2 -0
  280. package/dist/simulator/assets/simulator-DddliUL5.js +10 -0
  281. package/dist/simulator/assets/simulator-mini-app-BDNu5n26.js +2 -0
  282. package/dist/simulator/device-shell/menu-button-geometry.js +8 -0
  283. package/dist/simulator/simulator.html +2 -112
  284. package/package.json +9 -9
  285. package/dist/main/utils/disposable.d.ts +0 -18
  286. package/dist/main/utils/disposable.js +0 -67
  287. package/dist/renderer/assets/constants-DI382mTP.js +0 -2
  288. package/dist/renderer/assets/index-4lkyF644.js +0 -46
  289. package/dist/renderer/assets/input-D4byFOLS.js +0 -2
  290. package/dist/renderer/assets/ipc-transport-DqbRdZNO.css +0 -1
  291. package/dist/renderer/assets/popover-cxKrg_os.js +0 -2
  292. package/dist/renderer/assets/select-BgSkkdHW.js +0 -2
  293. package/dist/renderer/assets/settings-oD2K1jdT.js +0 -2
  294. package/dist/renderer/assets/workbenchSettings-CTNBpTft.js +0 -8
  295. package/dist/simulator/assets/simulator-CVOFTpSj.js +0 -9
@@ -16,9 +16,18 @@
16
16
  * events stop flowing until they close it.
17
17
  */
18
18
  import { app, webContents as wcStatic } from 'electron';
19
+ import { DisposableRegistry } from '@dimina-kit/electron-deck/main';
19
20
  import { SimulatorElementChannel, SimulatorStorageChannel, } from '../../../shared/ipc-channels.js';
20
- import { DisposableRegistry } from '../../utils/disposable.js';
21
21
  import { IpcRegistry } from '../../utils/ipc-registry.js';
22
+ import { decodeStorageValue, encodeStorageValue, serviceStorage } from './service-storage-ops.js';
23
+ /** Async wx storage API names routed through the unified service-window store. */
24
+ export const STORAGE_API_NAMES = new Set([
25
+ 'setStorage',
26
+ 'getStorage',
27
+ 'removeStorage',
28
+ 'clearStorage',
29
+ 'getStorageInfo',
30
+ ]);
22
31
  function isSimulatorWebview(wc) {
23
32
  if (wc.isDestroyed())
24
33
  return false;
@@ -39,6 +48,15 @@ function safeOff(target, event, fn) {
39
48
  export function setupSimulatorStorage(host, options) {
40
49
  const registry = new DisposableRegistry();
41
50
  const getActiveAppId = options.getActiveAppId;
51
+ // Native-host: the mini-app's storage lives on the service-host window's
52
+ // file:// origin (sync-impls + the unified async path both write there), not
53
+ // the simulator <webview>'s http:// origin the CDP path attaches to. Resolve
54
+ // the service window fresh each call (the pre-warm pool can swap it on respawn).
55
+ function nativeServiceWc() {
56
+ if (!options.bridge?.isNativeHost())
57
+ return null;
58
+ return options.bridge.getServiceWc(getActiveAppId() ?? undefined);
59
+ }
42
60
  let attachedWc = null;
43
61
  let attachDisposables = null;
44
62
  /**
@@ -107,8 +125,23 @@ export function setupSimulatorStorage(host, options) {
107
125
  void ad.disposeAll().catch(() => { });
108
126
  }
109
127
  };
110
- wc.once('destroyed', onDestroyed);
111
- attach.add(() => safeOff(wc, 'destroyed', onDestroyed));
128
+ if (options.connections) {
129
+ // Route through the connection layer: own() disposes onDestroyed
130
+ // deterministically on wc destroy / connection reset, and the returned
131
+ // Disposable lets us release it early when this attach segment tears
132
+ // down (detach / re-attach).
133
+ const owned = options.connections.acquire(wc).own(onDestroyed);
134
+ attach.add(() => owned.dispose());
135
+ }
136
+ else {
137
+ try {
138
+ wc.once('destroyed', onDestroyed);
139
+ }
140
+ catch {
141
+ // fake-wc safety (unit tests pass a wc without a real emitter)
142
+ }
143
+ attach.add(() => safeOff(wc, 'destroyed', onDestroyed));
144
+ }
112
145
  attachedWc = wc;
113
146
  }
114
147
  catch (e) {
@@ -257,6 +290,17 @@ export function setupSimulatorStorage(host, options) {
257
290
  host.send(SimulatorStorageChannel.Event, evt);
258
291
  }
259
292
  async function setItem(key, value) {
293
+ const nativeWc = nativeServiceWc();
294
+ if (nativeWc) {
295
+ try {
296
+ await serviceStorage(nativeWc).writeOne(key, value);
297
+ pushSyntheticEvent({ type: 'added', key, newValue: value });
298
+ return { ok: true };
299
+ }
300
+ catch (e) {
301
+ return { ok: false, error: e.message };
302
+ }
303
+ }
260
304
  return withStorageWrite(async ({ wc, storageId }) => {
261
305
  await wc.debugger.sendCommand('DOMStorage.setDOMStorageItem', { storageId, key, value });
262
306
  pushSyntheticEvent({ type: 'added', key, newValue: value });
@@ -264,6 +308,17 @@ export function setupSimulatorStorage(host, options) {
264
308
  });
265
309
  }
266
310
  async function removeItem(key) {
311
+ const nativeWc = nativeServiceWc();
312
+ if (nativeWc) {
313
+ try {
314
+ await serviceStorage(nativeWc).removeOne(key);
315
+ pushSyntheticEvent({ type: 'removed', key });
316
+ return { ok: true };
317
+ }
318
+ catch (e) {
319
+ return { ok: false, error: e.message };
320
+ }
321
+ }
267
322
  return withStorageWrite(async ({ wc, storageId }) => {
268
323
  await wc.debugger.sendCommand('DOMStorage.removeDOMStorageItem', { storageId, key });
269
324
  pushSyntheticEvent({ type: 'removed', key });
@@ -275,6 +330,23 @@ export function setupSimulatorStorage(host, options) {
275
330
  // Falls back to origin-wide `DOMStorage.clear` only when no active appId is
276
331
  // set (matches the snapshot filter's documented null-fallback).
277
332
  async function clearScoped() {
333
+ const nativeWc = nativeServiceWc();
334
+ if (nativeWc) {
335
+ try {
336
+ const prefix = activePrefix();
337
+ const ss = serviceStorage(nativeWc);
338
+ if (prefix)
339
+ await ss.clearPrefix(prefix);
340
+ else
341
+ await ss.clearAll();
342
+ if (!host.isDestroyed())
343
+ host.send(SimulatorStorageChannel.Event, { type: 'cleared' });
344
+ return { ok: true };
345
+ }
346
+ catch (e) {
347
+ return { ok: false, error: e.message };
348
+ }
349
+ }
278
350
  return withStorageWrite(async ({ wc, storageId }) => {
279
351
  const prefix = activePrefix();
280
352
  if (!prefix) {
@@ -296,12 +368,33 @@ export function setupSimulatorStorage(host, options) {
296
368
  // state in the shared simulator partition. The renderer guards this with a
297
369
  // confirm dialog; we don't second-guess here.
298
370
  async function clearAll() {
371
+ const nativeWc = nativeServiceWc();
372
+ if (nativeWc) {
373
+ try {
374
+ await serviceStorage(nativeWc).clearAll();
375
+ if (!host.isDestroyed())
376
+ host.send(SimulatorStorageChannel.Event, { type: 'cleared' });
377
+ return { ok: true };
378
+ }
379
+ catch (e) {
380
+ return { ok: false, error: e.message };
381
+ }
382
+ }
299
383
  return withStorageWrite(async ({ wc, storageId }) => {
300
384
  await wc.debugger.sendCommand('DOMStorage.clear', { storageId });
301
385
  return { ok: true };
302
386
  });
303
387
  }
304
388
  async function getSnapshot() {
389
+ const nativeWc = nativeServiceWc();
390
+ if (nativeWc) {
391
+ const prefix = activePrefix();
392
+ if (!prefix)
393
+ return [];
394
+ const entries = await serviceStorage(nativeWc).readAll(prefix);
395
+ // Keys returned with the `${appId}_` prefix intact (same as the CDP path).
396
+ return entries.map(([key, value]) => ({ key, value }));
397
+ }
305
398
  return withStorageRead([], async ({ wc, storageId }) => {
306
399
  const result = (await wc.debugger.sendCommand('DOMStorage.getDOMStorageItems', {
307
400
  storageId,
@@ -337,10 +430,24 @@ export function setupSimulatorStorage(host, options) {
337
430
  };
338
431
  wc.on('did-finish-load', onFinishLoad);
339
432
  sub.add(() => safeOff(wc, 'did-finish-load', onFinishLoad));
340
- wc.once('destroyed', () => {
433
+ const onWcDestroyed = () => {
341
434
  void sub.disposeAll().catch(() => { });
342
435
  wcSubs.delete(wc);
343
- });
436
+ };
437
+ if (options.connections) {
438
+ // Per-wc cleanup (this wc's did-finish-load sub + wcSubs entry). Route
439
+ // through the connection layer so it fires deterministically on wc
440
+ // destroy / reset rather than the bespoke 'destroyed' hook.
441
+ options.connections.acquire(wc).own(onWcDestroyed);
442
+ }
443
+ else {
444
+ try {
445
+ wc.once('destroyed', onWcDestroyed);
446
+ }
447
+ catch {
448
+ // fake-wc safety (unit tests pass a wc without a real emitter)
449
+ }
450
+ }
344
451
  };
345
452
  app.on('web-contents-created', onWcCreated);
346
453
  registry.add(() => {
@@ -353,6 +460,49 @@ export function setupSimulatorStorage(host, options) {
353
460
  await sub.disposeAll().catch(() => { });
354
461
  }
355
462
  });
463
+ // Element inspection. Default path delegates to the simulator iframe's
464
+ // `__simulatorData`. Native-host path targets the active render-host
465
+ // <webview> guest via the render inspector (the page DOM lives there, not in
466
+ // the simulator iframe). Looked up fresh each call so a DevTools-induced CDP
467
+ // detach (default path) or a render-guest swap (native path) is tolerated.
468
+ async function inspectElement(sid) {
469
+ if (!sid)
470
+ return null;
471
+ if (options.bridge?.isNativeHost() && options.renderInspector) {
472
+ const wc = options.bridge.getActiveRenderWc(getActiveAppId() ?? undefined);
473
+ if (!wc)
474
+ return null;
475
+ return options.renderInspector.highlight(wc, sid);
476
+ }
477
+ const sim = findSimulatorWebContents();
478
+ if (!sim)
479
+ return null;
480
+ try {
481
+ const result = (await sim.executeJavaScript(`window.__simulatorData && window.__simulatorData.highlightElement ? window.__simulatorData.highlightElement(${JSON.stringify(sid)}) : null`));
482
+ return result ?? null;
483
+ }
484
+ catch (e) {
485
+ console.warn('[simulator-element] inspect failed:', e.message);
486
+ return null;
487
+ }
488
+ }
489
+ async function clearElementInspection() {
490
+ if (options.bridge?.isNativeHost() && options.renderInspector) {
491
+ const wc = options.bridge.getActiveRenderWc(getActiveAppId() ?? undefined);
492
+ if (wc)
493
+ await options.renderInspector.unhighlight(wc);
494
+ return;
495
+ }
496
+ const sim = findSimulatorWebContents();
497
+ if (!sim)
498
+ return;
499
+ try {
500
+ await sim.executeJavaScript('window.__simulatorData && window.__simulatorData.unhighlightElement && window.__simulatorData.unhighlightElement()');
501
+ }
502
+ catch {
503
+ // best-effort
504
+ }
505
+ }
356
506
  // IPC handlers — gated by the workbench SenderPolicy when provided so this
357
507
  // module routes through the same C-stage sender white-list as every other
358
508
  // workbench-built-in (main-window renderer + overlay views only). Without
@@ -370,7 +520,60 @@ export function setupSimulatorStorage(host, options) {
370
520
  registry.add(ipc);
371
521
  // Detach active CDP session last
372
522
  registry.add(() => detachFromSim());
373
- return registry;
523
+ // ── Runtime async-storage unification (native-host) ───────────────────────
524
+ // bridge-router routes async wx.setStorage/etc. here so they hit the SAME
525
+ // service-host file:// store as the sync APIs (no more split origin). After a
526
+ // write we push a synthetic panel event so the Storage panel stays live on
527
+ // in-app writes (executeJavaScript writes don't emit CDP DOMStorage events).
528
+ async function runtimeInvoke(appId, name, params) {
529
+ const wc = options.bridge?.getServiceWc(appId);
530
+ if (!wc)
531
+ throw new Error('service-host window unavailable');
532
+ const ss = serviceStorage(wc);
533
+ const prefix = `${appId}_`;
534
+ const key = typeof params.key === 'string' ? params.key : '';
535
+ const fullKey = prefix + key;
536
+ switch (name) {
537
+ case 'setStorage': {
538
+ const value = encodeStorageValue(params.data);
539
+ await ss.writeOne(fullKey, value);
540
+ pushSyntheticEvent({ type: 'added', key: fullKey, newValue: value });
541
+ return { errMsg: 'setStorage:ok' };
542
+ }
543
+ case 'getStorage': {
544
+ const raw = await ss.readOne(fullKey);
545
+ if (raw === null)
546
+ throw new Error('getStorage:fail data not found');
547
+ return { data: decodeStorageValue(raw), errMsg: 'getStorage:ok' };
548
+ }
549
+ case 'removeStorage': {
550
+ await ss.removeOne(fullKey);
551
+ pushSyntheticEvent({ type: 'removed', key: fullKey });
552
+ return { errMsg: 'removeStorage:ok' };
553
+ }
554
+ case 'clearStorage': {
555
+ await ss.clearPrefix(prefix);
556
+ if (appId === getActiveAppId() && !host.isDestroyed()) {
557
+ host.send(SimulatorStorageChannel.Event, { type: 'cleared' });
558
+ }
559
+ return { errMsg: 'clearStorage:ok' };
560
+ }
561
+ case 'getStorageInfo': {
562
+ const entries = await ss.readAll(prefix);
563
+ const keys = entries.map(([k]) => k.slice(prefix.length));
564
+ let currentSize = 0;
565
+ for (const [, v] of entries)
566
+ currentSize += v ? v.length * 2 : 0;
567
+ return { keys, currentSize, limitSize: 10 * 1024 * 1024, errMsg: 'getStorageInfo:ok' };
568
+ }
569
+ default:
570
+ throw new Error(`unsupported storage api ${name}`);
571
+ }
572
+ }
573
+ const storageApi = options.bridge?.isNativeHost()
574
+ ? { invoke: runtimeInvoke }
575
+ : null;
576
+ return { dispose: () => registry.dispose(), storageApi };
374
577
  }
375
578
  // Element inspection delegates to the simulator preload's __simulatorData
376
579
  // bridge via executeJavaScript. Looked up independently from `attachedWc` so
@@ -383,30 +586,4 @@ function findSimulatorWebContents() {
383
586
  }
384
587
  return null;
385
588
  }
386
- async function inspectElement(sid) {
387
- if (!sid)
388
- return null;
389
- const sim = findSimulatorWebContents();
390
- if (!sim)
391
- return null;
392
- try {
393
- const result = (await sim.executeJavaScript(`window.__simulatorData && window.__simulatorData.highlightElement ? window.__simulatorData.highlightElement(${JSON.stringify(sid)}) : null`));
394
- return result ?? null;
395
- }
396
- catch (e) {
397
- console.warn('[simulator-element] inspect failed:', e.message);
398
- return null;
399
- }
400
- }
401
- async function clearElementInspection() {
402
- const sim = findSimulatorWebContents();
403
- if (!sim)
404
- return;
405
- try {
406
- await sim.executeJavaScript('window.__simulatorData && window.__simulatorData.unhighlightElement && window.__simulatorData.unhighlightElement()');
407
- }
408
- catch {
409
- // best-effort
410
- }
411
- }
412
589
  //# sourceMappingURL=index.js.map
@@ -0,0 +1,40 @@
1
+ /**
2
+ * service-storage-ops — localStorage primitives executed INSIDE the service-host
3
+ * window (`wc`) via `executeJavaScript`, plus the wx-storage value encode/decode
4
+ * pair.
5
+ *
6
+ * Under native-host the mini-app's storage lives on the service-host window's
7
+ * `file://` origin (sync APIs write there via sync-impls/storage.ts, and the
8
+ * unified async path routes there too). The Storage panel + the async-storage
9
+ * runtime both read/write through here so there is exactly ONE store.
10
+ *
11
+ * The key/value scheme stays byte-compatible with
12
+ * `src/service-host/sync-impls/storage.ts` (the authoritative wx storage impl):
13
+ * - key = `${appId}_${key}`
14
+ * - value = `typeof data === 'object' ? JSON.stringify(data) : String(data)`
15
+ * - scoped clear removes every key whose name startsWith `${appId}_`
16
+ *
17
+ * Args are embedded via JSON.stringify so special characters can't break out of
18
+ * the injected code. Reads tolerate failure (→ []/null); writes propagate so the
19
+ * caller can fail the wx callback / surface the panel error.
20
+ */
21
+ import type { WebContents } from 'electron';
22
+ /** Encode a wx storage value to its localStorage string form. Matches sync-impls/storage.ts. */
23
+ export declare function encodeStorageValue(data: unknown): string;
24
+ /** Decode a localStorage string back to a value (JSON.parse, falling back to the raw string). */
25
+ export declare function decodeStorageValue(raw: string): unknown;
26
+ export interface ServiceStorage {
27
+ /** All [fullKey, value] entries whose key startsWith `prefix`. */
28
+ readAll(prefix: string): Promise<Array<[string, string]>>;
29
+ /** Raw value for a full (already-prefixed) key, or null if absent. */
30
+ readOne(fullKey: string): Promise<string | null>;
31
+ writeOne(fullKey: string, value: string): Promise<void>;
32
+ removeOne(fullKey: string): Promise<void>;
33
+ /** Remove every key whose name startsWith `prefix`. */
34
+ clearPrefix(prefix: string): Promise<void>;
35
+ /** Origin-wide localStorage.clear(). */
36
+ clearAll(): Promise<void>;
37
+ }
38
+ /** localStorage ops executed inside `wc` (the service-host window) via executeJavaScript. */
39
+ export declare function serviceStorage(wc: WebContents): ServiceStorage;
40
+ //# sourceMappingURL=service-storage-ops.d.ts.map
@@ -0,0 +1,67 @@
1
+ /** Encode a wx storage value to its localStorage string form. Matches sync-impls/storage.ts. */
2
+ export function encodeStorageValue(data) {
3
+ return typeof data === 'object' ? JSON.stringify(data) : String(data);
4
+ }
5
+ /** Decode a localStorage string back to a value (JSON.parse, falling back to the raw string). */
6
+ export function decodeStorageValue(raw) {
7
+ try {
8
+ return JSON.parse(raw);
9
+ }
10
+ catch {
11
+ return raw;
12
+ }
13
+ }
14
+ /** localStorage ops executed inside `wc` (the service-host window) via executeJavaScript. */
15
+ export function serviceStorage(wc) {
16
+ return {
17
+ async readAll(prefix) {
18
+ const code = `(() => {
19
+ const out = []
20
+ const p = ${JSON.stringify(prefix)}
21
+ for (let i = 0; i < localStorage.length; i++) {
22
+ const k = localStorage.key(i)
23
+ if (k && k.startsWith(p)) out.push([k, localStorage.getItem(k)])
24
+ }
25
+ return out
26
+ })()`;
27
+ try {
28
+ const result = await wc.executeJavaScript(code);
29
+ return Array.isArray(result) ? result : [];
30
+ }
31
+ catch {
32
+ return [];
33
+ }
34
+ },
35
+ async readOne(fullKey) {
36
+ try {
37
+ const result = await wc.executeJavaScript(`localStorage.getItem(${JSON.stringify(fullKey)})`);
38
+ return result === null || result === undefined ? null : String(result);
39
+ }
40
+ catch {
41
+ return null;
42
+ }
43
+ },
44
+ async writeOne(fullKey, value) {
45
+ await wc.executeJavaScript(`localStorage.setItem(${JSON.stringify(fullKey)}, ${JSON.stringify(value)})`);
46
+ },
47
+ async removeOne(fullKey) {
48
+ await wc.executeJavaScript(`localStorage.removeItem(${JSON.stringify(fullKey)})`);
49
+ },
50
+ async clearPrefix(prefix) {
51
+ const code = `(() => {
52
+ const p = ${JSON.stringify(prefix)}
53
+ const doomed = []
54
+ for (let i = 0; i < localStorage.length; i++) {
55
+ const k = localStorage.key(i)
56
+ if (k && k.startsWith(p)) doomed.push(k)
57
+ }
58
+ doomed.forEach((k) => localStorage.removeItem(k))
59
+ })()`;
60
+ await wc.executeJavaScript(code);
61
+ },
62
+ async clearAll() {
63
+ await wc.executeJavaScript('localStorage.clear()');
64
+ },
65
+ };
66
+ }
67
+ //# sourceMappingURL=service-storage-ops.js.map
@@ -23,7 +23,7 @@
23
23
  */
24
24
  import fs from 'node:fs/promises';
25
25
  import path from 'node:path';
26
- import { sandboxBase } from '../../../simulator/vpath.js';
26
+ import { sandboxBase } from '../../../shared/vpath.js';
27
27
  import { readDiskDir, readDiskFile, statDiskFile, writeDiskFile, } from './disk.js';
28
28
  /**
29
29
  * Defense-in-depth: a hostile preload could synthesize a `realPath` that
@@ -28,6 +28,6 @@
28
28
  * size cap), simplified for a dev-tools session scope.
29
29
  */
30
30
  import type { Session } from 'electron';
31
- import { type Disposable } from '../../utils/disposable.js';
31
+ import { type Disposable } from '@dimina-kit/electron-deck/main';
32
32
  export declare function setupSimulatorTempFiles(simSession: Session): Disposable;
33
33
  //# sourceMappingURL=index.d.ts.map
@@ -28,7 +28,7 @@
28
28
  * size cap), simplified for a dev-tools session scope.
29
29
  */
30
30
  import { IpcRegistry } from '../../utils/ipc-registry.js';
31
- import { toDisposable } from '../../utils/disposable.js';
31
+ import { toDisposable } from '@dimina-kit/electron-deck/main';
32
32
  import { registerTempFile, revokeTempFile, revokeAllTempFiles } from './store.js';
33
33
  import { handleDifileRequest } from './request-handler.js';
34
34
  import { handleFsMkdir, handleFsRead, handleFsReaddir, handleFsStat, handleFsUnlink, handleFsWrite, } from './fs-channels.js';
@@ -18,7 +18,7 @@
18
18
  * into the renderer's network failure surface; we deliberately do not
19
19
  * leak errno strings.
20
20
  */
21
- import { resolveVPath } from '../../../simulator/vpath.js';
21
+ import { resolveVPath } from '../../../shared/vpath.js';
22
22
  import { readDiskFile } from './disk.js';
23
23
  const CACHE_CONTROL = 'public, max-age=31536000, immutable';
24
24
  function getHeader(headers, name) {
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Native-host WXML panel service.
3
+ *
4
+ * Mirrors simulator-storage's main→renderer contract so the renderer WXML panel
5
+ * needs no per-mode branching of its own data shape:
6
+ * - PULL: answers `SimulatorWxmlChannel.GetSnapshot` by reading the active
7
+ * render-host guest's WXML tree via the injected RenderInspector.
8
+ * - PUSH: on bridge render-side activity (domReady / active-page change),
9
+ * re-reads the tree and pushes `SimulatorWxmlChannel.Event` to the renderer
10
+ * host — keeping the panel reactive without polling.
11
+ *
12
+ * Only meaningful under native-host (the default dimina-fe path sources WXML
13
+ * from the simulator guest's miniappSnapshot transport); app.ts gates the call
14
+ * on `ctx.bridge.isNativeHost()`.
15
+ */
16
+ import type { WebContents } from 'electron';
17
+ import type { BridgeRouterHandle } from '../../ipc/bridge-router.js';
18
+ import { type Disposable } from '@dimina-kit/electron-deck/main';
19
+ import { type SenderPolicy } from '../../utils/ipc-registry.js';
20
+ import type { RenderInspector } from '../render-inspect/index.js';
21
+ export interface SimulatorWxmlOptions {
22
+ bridge: BridgeRouterHandle;
23
+ inspector: RenderInspector;
24
+ getActiveAppId: () => string | null;
25
+ /** Sender gate applied to the WXML IPC handler; omitted in unit tests. */
26
+ senderPolicy?: SenderPolicy;
27
+ }
28
+ export declare function setupSimulatorWxml(host: WebContents, options: SimulatorWxmlOptions): Disposable;
29
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,28 @@
1
+ import { SimulatorWxmlChannel } from '../../../shared/ipc-channels.js';
2
+ import { DisposableRegistry } from '@dimina-kit/electron-deck/main';
3
+ import { IpcRegistry } from '../../utils/ipc-registry.js';
4
+ export function setupSimulatorWxml(host, options) {
5
+ const { bridge, inspector, getActiveAppId } = options;
6
+ const registry = new DisposableRegistry();
7
+ /** Read the WXML tree of the visible page of the active app, or null. */
8
+ async function pull() {
9
+ const wc = bridge.getActiveRenderWc(getActiveAppId() ?? undefined);
10
+ if (!wc)
11
+ return null;
12
+ return inspector.getWxml(wc);
13
+ }
14
+ const ipc = new IpcRegistry(options.senderPolicy);
15
+ ipc.handle(SimulatorWxmlChannel.GetSnapshot, () => pull());
16
+ registry.add(ipc);
17
+ // Re-read + push when a page's DOM mounts or the visible page changes.
18
+ const unsubscribe = bridge.onRenderEvent(() => {
19
+ void pull().then((tree) => {
20
+ if (host.isDestroyed())
21
+ return;
22
+ host.send(SimulatorWxmlChannel.Event, tree);
23
+ });
24
+ });
25
+ registry.add(unsubscribe);
26
+ return registry;
27
+ }
28
+ //# sourceMappingURL=index.js.map
@@ -24,6 +24,16 @@ export declare class UpdateManager {
24
24
  private getCurrentVersion;
25
25
  private latestUpdate;
26
26
  private downloadedPath;
27
+ /**
28
+ * Whether this instance has already emitted `Available` once. The periodic
29
+ * check fires forever (interval default 1h), and downstream UI (qdmp shell
30
+ * renders a native toast / Notification) is not idempotent — every event
31
+ * stacks. We dedupe at the source: at most one Available per instance
32
+ * lifetime, regardless of how the upstream `info.version` shifts. The user
33
+ * already knows "an update exists"; tracking minor version bumps mid-
34
+ * session is not worth duplicating the toast.
35
+ */
36
+ private hasNotified;
27
37
  private timer;
28
38
  private initialTimer;
29
39
  private ipc;
@@ -7,6 +7,16 @@ export class UpdateManager {
7
7
  getCurrentVersion;
8
8
  latestUpdate = null;
9
9
  downloadedPath = null;
10
+ /**
11
+ * Whether this instance has already emitted `Available` once. The periodic
12
+ * check fires forever (interval default 1h), and downstream UI (qdmp shell
13
+ * renders a native toast / Notification) is not idempotent — every event
14
+ * stacks. We dedupe at the source: at most one Available per instance
15
+ * lifetime, regardless of how the upstream `info.version` shifts. The user
16
+ * already knows "an update exists"; tracking minor version bumps mid-
17
+ * session is not worth duplicating the toast.
18
+ */
19
+ hasNotified = false;
10
20
  timer = null;
11
21
  initialTimer = null;
12
22
  ipc;
@@ -85,9 +95,12 @@ export class UpdateManager {
85
95
  }
86
96
  async checkAndNotify() {
87
97
  const result = await this.check();
88
- if (result.hasUpdate && result.info) {
89
- this.mainWindow.webContents.send(UpdateChannel.Available, result.info);
90
- }
98
+ if (!result.hasUpdate || !result.info)
99
+ return;
100
+ if (this.hasNotified)
101
+ return;
102
+ this.hasNotified = true;
103
+ this.mainWindow.webContents.send(UpdateChannel.Available, result.info);
91
104
  }
92
105
  }
93
106
  //# sourceMappingURL=update-manager.js.map
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Customize the embedded Chrome DevTools front-end's panel tab bar.
3
+ *
4
+ * The right-panel DevTools (a WebContents rendering `devtools://`, attached to the
5
+ * service-host via `setDevToolsWebContents` + `openDevTools`) shows ALL its panels
6
+ * by default. For the mini-app workflow only Elements / Console / Network are
7
+ * meaningful in the default tab bar — but we do NOT want to delete the rest: they
8
+ * stay reachable on demand via the command menu (Cmd+Shift+P → "Show Sources" …).
9
+ *
10
+ * ── How (registry, not DOM) ─────────────────────────────────────────────────
11
+ * The modern ESM DevTools front-end does NOT expose `UI.ViewManager` on
12
+ * `globalThis`, so the tab bar can't be driven through the view manager. Panels
13
+ * register themselves via `registerViewExtension({id, location:'panel', persistence})`
14
+ * into a module-level registry; the official mutators are `registerViewExtension`,
15
+ * `getRegisteredViewExtensions` and `maybeRemoveViewExtension`. We:
16
+ * 1. `import('./ui/legacy/legacy.js')` to reach those functions (the real export
17
+ * path on Electron 41 / Chromium ~138, verified at runtime);
18
+ * 2. whitelist-patch `registerViewExtension` so any future non-kept panel comes
19
+ * in with `persistence:'transient'` (hidden from the default bar);
20
+ * 3. for the already-registered non-kept panels, `maybeRemoveViewExtension(id)`
21
+ * then re-register a copy with `persistence:'transient'`.
22
+ * Transient views are not shown in the default tab bar but stay in the command
23
+ * menu — and because this is DevTools' own panel path, there is NO `>>` overflow
24
+ * or `×` close-button residue (which a DOM `display:none` hack leaves behind).
25
+ *
26
+ * ── Locale infobar ──────────────────────────────────────────────────────────
27
+ * The "DevTools is now available in 中文" banner is suppressed via the official
28
+ * host preference `disable-locale-info-bar` (a GLOBAL setting that lives in host
29
+ * preferences, NOT page localStorage), set through `InspectorFrontendHost.setPreference`.
30
+ *
31
+ * ── Degradation ─────────────────────────────────────────────────────────────
32
+ * If the ESM module can't be resolved, a bounded DOM `display:none` fallback hides
33
+ * the non-kept tabs (by visible name) so the bar still looks right. Everything is
34
+ * wrapped in try/catch in the injected realm and silently no-ops on any failure.
35
+ */
36
+ /**
37
+ * Canonical DevTools panel view ids kept in the DEFAULT tab bar (stable front-end
38
+ * ids, unchanged for many Chromium releases): `elements`, `console`, `network`.
39
+ */
40
+ export declare const DEVTOOLS_KEPT_VIEW_IDS: readonly string[];
41
+ /**
42
+ * Build the `executeJavaScript` source injected into the DevTools front-end
43
+ * WebContents. The kept ids + display names are carried as JSON data literals
44
+ * (never interpolated as bare code), same discipline as the other injectors.
45
+ */
46
+ export declare function buildCustomizeTabsScript(keptIds?: readonly string[]): string;
47
+ //# sourceMappingURL=devtools-tabs.d.ts.map