@dimina-kit/devtools 0.3.2-dev.20260611135124 → 0.4.0-dev.20260612025610

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.
@@ -740,9 +740,9 @@ function registerProjectFsIpc(ctx) {
740
740
  }
741
741
 
742
742
  // src/main/app/app.ts
743
- import { app as app14, BrowserWindow as BrowserWindow7, nativeImage, session as session4 } from "electron";
743
+ import { app as app14, BrowserWindow as BrowserWindow8, nativeImage, session as session4 } from "electron";
744
744
  import fs10 from "fs";
745
- import path20 from "path";
745
+ import path21 from "path";
746
746
 
747
747
  // src/main/utils/paths.ts
748
748
  import fs3 from "fs";
@@ -1655,8 +1655,10 @@ import { MessageChannelMain } from "electron";
1655
1655
  function createHostToolbarPortChannel(opts) {
1656
1656
  let activePort = null;
1657
1657
  let activeWc = null;
1658
- let disposed = false;
1658
+ let state = "absent";
1659
+ let generation = 0;
1659
1660
  const handlers2 = [];
1661
+ const readyHandlers = [];
1660
1662
  function dispatch(data) {
1661
1663
  if (typeof data !== "object" || data === null) return;
1662
1664
  const { channel, payload } = data;
@@ -1665,10 +1667,11 @@ function createHostToolbarPortChannel(opts) {
1665
1667
  if (entry.channel === channel) entry.handler(payload);
1666
1668
  }
1667
1669
  }
1668
- function dropActivePort(close) {
1670
+ function dropActivePort(close, next) {
1669
1671
  const port = activePort;
1670
1672
  activePort = null;
1671
1673
  activeWc = null;
1674
+ if (state !== "disposed") state = next;
1672
1675
  if (close && port) {
1673
1676
  try {
1674
1677
  port.close();
@@ -1676,21 +1679,36 @@ function createHostToolbarPortChannel(opts) {
1676
1679
  }
1677
1680
  }
1678
1681
  }
1682
+ function invokeReadyHandler(handler) {
1683
+ try {
1684
+ handler();
1685
+ } catch (err) {
1686
+ console.error("[host-toolbar] onReady handler threw:", err);
1687
+ }
1688
+ }
1689
+ function fireReadyHandlers() {
1690
+ for (const entry of [...readyHandlers]) {
1691
+ if (readyHandlers.includes(entry)) invokeReadyHandler(entry.handler);
1692
+ }
1693
+ }
1679
1694
  function handshake(wc) {
1680
- if (disposed) return;
1695
+ if (state === "disposed") return;
1681
1696
  if (!opts.isCurrent(wc)) return;
1682
- dropActivePort(true);
1697
+ dropActivePort(true, "awaitingHandshake");
1683
1698
  const { port1, port2 } = new MessageChannelMain();
1684
1699
  port1.on("message", (event) => {
1685
1700
  dispatch(event.data);
1686
1701
  });
1687
1702
  port1.on("close", () => {
1688
- if (activePort === port1) dropActivePort(false);
1703
+ if (activePort === port1) dropActivePort(false, "absent");
1689
1704
  });
1690
1705
  wc.postMessage(ViewChannel.HostToolbarPort, null, [port2]);
1691
1706
  port1.start();
1692
1707
  activePort = port1;
1693
1708
  activeWc = wc;
1709
+ state = "ready";
1710
+ generation++;
1711
+ fireReadyHandlers();
1694
1712
  }
1695
1713
  return {
1696
1714
  attach(wc) {
@@ -1702,15 +1720,15 @@ function createHostToolbarPortChannel(opts) {
1702
1720
  const isSameDocument = typeof details?.isSameDocument === "boolean" ? details.isSameDocument : isInPlace;
1703
1721
  const isMainFrame = typeof details?.isMainFrame === "boolean" ? details.isMainFrame : isMainFramePositional;
1704
1722
  if (isSameDocument || !isMainFrame) return;
1705
- dropActivePort(true);
1723
+ dropActivePort(true, "awaitingHandshake");
1706
1724
  }
1707
1725
  );
1708
1726
  wc.on("destroyed", () => {
1709
- if (activeWc === wc) dropActivePort(true);
1727
+ if (activeWc === wc) dropActivePort(true, "absent");
1710
1728
  });
1711
1729
  },
1712
1730
  invalidate() {
1713
- dropActivePort(true);
1731
+ dropActivePort(true, "awaitingHandshake");
1714
1732
  },
1715
1733
  onMessage(channel, handler) {
1716
1734
  if (typeof channel !== "string" || channel === "") {
@@ -1727,15 +1745,38 @@ function createHostToolbarPortChannel(opts) {
1727
1745
  }
1728
1746
  };
1729
1747
  },
1748
+ onReady(handler) {
1749
+ if (state === "disposed") {
1750
+ return { dispose() {
1751
+ } };
1752
+ }
1753
+ const entry = { handler };
1754
+ readyHandlers.push(entry);
1755
+ if (state === "ready") {
1756
+ const scheduledGeneration = generation;
1757
+ queueMicrotask(() => {
1758
+ if (state !== "ready" || generation !== scheduledGeneration || !activePort) return;
1759
+ if (!readyHandlers.includes(entry)) return;
1760
+ invokeReadyHandler(entry.handler);
1761
+ });
1762
+ }
1763
+ return {
1764
+ dispose() {
1765
+ const i = readyHandlers.indexOf(entry);
1766
+ if (i >= 0) readyHandlers.splice(i, 1);
1767
+ }
1768
+ };
1769
+ },
1730
1770
  send(channel, payload) {
1731
1771
  if (!activePort) return false;
1732
1772
  activePort.postMessage({ channel, payload });
1733
1773
  return true;
1734
1774
  },
1735
1775
  dispose() {
1736
- disposed = true;
1737
- dropActivePort(true);
1776
+ dropActivePort(true, "absent");
1777
+ state = "disposed";
1738
1778
  handlers2.length = 0;
1779
+ readyHandlers.length = 0;
1739
1780
  }
1740
1781
  };
1741
1782
  }
@@ -1937,6 +1978,11 @@ function createViewManager(ctx) {
1937
1978
  hostToolbarPreloadOverride = path22;
1938
1979
  },
1939
1980
  setHeightMode(mode) {
1981
+ if (mode !== "auto" && !(Number.isFinite(mode.fixed) && mode.fixed >= 0)) {
1982
+ throw new TypeError(
1983
+ `hostToolbar.setHeightMode: fixed height must be a finite, non-negative number (got ${mode.fixed})`
1984
+ );
1985
+ }
1940
1986
  hostToolbarHeightMode = mode;
1941
1987
  if (mode !== "auto") {
1942
1988
  ctx.notify.hostToolbarHeightChanged(mode.fixed);
@@ -1945,6 +1991,9 @@ function createViewManager(ctx) {
1945
1991
  onMessage(channel, handler) {
1946
1992
  return hostToolbarPort.onMessage(channel, handler);
1947
1993
  },
1994
+ onReady(handler) {
1995
+ return hostToolbarPort.onReady(handler);
1996
+ },
1948
1997
  send(channel, payload) {
1949
1998
  return hostToolbarPort.send(channel, payload);
1950
1999
  }
@@ -2532,13 +2581,82 @@ function createWindowService(mainWindow) {
2532
2581
  };
2533
2582
  }
2534
2583
 
2584
+ // src/main/windows/settings-window/create.ts
2585
+ import { BrowserWindow as BrowserWindow3 } from "electron";
2586
+ import path8 from "path";
2587
+ async function createSettingsWindow(parent, rendererDir2) {
2588
+ const win = new BrowserWindow3({
2589
+ width: 420,
2590
+ height: 560,
2591
+ minWidth: 380,
2592
+ minHeight: 480,
2593
+ parent: parent ?? void 0,
2594
+ title: "\u5F00\u53D1\u5DE5\u5177\u8BBE\u7F6E",
2595
+ backgroundColor: themeBg(),
2596
+ webPreferences: {
2597
+ nodeIntegration: false,
2598
+ contextIsolation: true,
2599
+ sandbox: false,
2600
+ preload: mainPreloadPath
2601
+ }
2602
+ });
2603
+ applyNavigationHardening(win.webContents, rendererDir2);
2604
+ await win.loadFile(path8.join(rendererDir2, "entries/workbench-settings/index.html"));
2605
+ return win;
2606
+ }
2607
+
2608
+ // src/main/windows/settings-window/events.ts
2609
+ function wireSettingsWindowEvents(win, onClosed) {
2610
+ win.on("closed", () => {
2611
+ onClosed();
2612
+ });
2613
+ }
2614
+
2615
+ // src/main/windows/settings-window/index.ts
2616
+ var inFlightCreations = /* @__PURE__ */ new WeakMap();
2617
+ async function getOrCreateSettingsWindow(deps) {
2618
+ const existing = deps.windows.settingsWindow;
2619
+ if (existing && !existing.isDestroyed()) return existing;
2620
+ const inFlight = inFlightCreations.get(deps.windows);
2621
+ if (inFlight) return inFlight;
2622
+ const creation = (async () => {
2623
+ const win = await createSettingsWindow(deps.windows.mainWindow, deps.rendererDir);
2624
+ deps.windows.setSettingsWindow(win);
2625
+ wireSettingsWindowEvents(win, () => {
2626
+ if (deps.windows.settingsWindow === win) {
2627
+ deps.windows.setSettingsWindow(null);
2628
+ }
2629
+ });
2630
+ return win;
2631
+ })();
2632
+ inFlightCreations.set(deps.windows, creation);
2633
+ try {
2634
+ return await creation;
2635
+ } finally {
2636
+ if (inFlightCreations.get(deps.windows) === creation) {
2637
+ inFlightCreations.delete(deps.windows);
2638
+ }
2639
+ }
2640
+ }
2641
+ async function openSettingsWindow(deps) {
2642
+ const win = await getOrCreateSettingsWindow(deps);
2643
+ win.show();
2644
+ win.focus();
2645
+ deps.notify.workbenchSettingsInit(win, {
2646
+ settings: loadWorkbenchSettings()
2647
+ });
2648
+ }
2649
+
2650
+ // src/main/services/workspace/workspace-service.ts
2651
+ import { z as z2 } from "zod";
2652
+
2535
2653
  // src/main/services/projects/project-repository.ts
2536
2654
  import { app as app5 } from "electron";
2537
- import path8 from "path";
2655
+ import path9 from "path";
2538
2656
  import fs4 from "fs";
2539
2657
  var log2 = createLogger("projects");
2540
2658
  function getProjectsFile() {
2541
- return path8.join(app5.getPath("userData"), "dimina-projects.json");
2659
+ return path9.join(app5.getPath("userData"), "dimina-projects.json");
2542
2660
  }
2543
2661
  function load() {
2544
2662
  try {
@@ -2560,13 +2678,13 @@ function validateProjectDir(dirPath) {
2560
2678
  if (!fs4.existsSync(dirPath)) {
2561
2679
  return `\u5C0F\u7A0B\u5E8F\u76EE\u5F55\u4E0D\u5B58\u5728\uFF1A${dirPath}`;
2562
2680
  }
2563
- if (!fs4.existsSync(path8.join(dirPath, "app.json"))) {
2564
- const configPath = path8.join(dirPath, "project.config.json");
2681
+ if (!fs4.existsSync(path9.join(dirPath, "app.json"))) {
2682
+ const configPath = path9.join(dirPath, "project.config.json");
2565
2683
  if (fs4.existsSync(configPath)) {
2566
2684
  try {
2567
2685
  const cfg = JSON.parse(fs4.readFileSync(configPath, "utf-8"));
2568
2686
  if (cfg.miniprogramRoot) {
2569
- const resolvedRoot = path8.resolve(dirPath, cfg.miniprogramRoot);
2687
+ const resolvedRoot = path9.resolve(dirPath, cfg.miniprogramRoot);
2570
2688
  return `\u8BE5\u76EE\u5F55\u7F3A\u5C11 app.json\uFF0Cproject.config.json \u4E2D\u6307\u5B9A\u4E86 miniprogramRoot: "${cfg.miniprogramRoot}"\uFF0C\u8BF7\u5BFC\u5165 ${resolvedRoot}`;
2571
2689
  }
2572
2690
  } catch (err) {
@@ -2579,9 +2697,9 @@ function validateProjectDir(dirPath) {
2579
2697
  }
2580
2698
  function addProject(dirPath) {
2581
2699
  const projects = load();
2582
- let name = path8.basename(dirPath);
2700
+ let name = path9.basename(dirPath);
2583
2701
  try {
2584
- const configPath = path8.join(dirPath, "project.config.json");
2702
+ const configPath = path9.join(dirPath, "project.config.json");
2585
2703
  if (fs4.existsSync(configPath)) {
2586
2704
  const cfg = JSON.parse(fs4.readFileSync(configPath, "utf-8"));
2587
2705
  if (cfg.projectname) name = cfg.projectname;
@@ -2620,7 +2738,7 @@ function getCompileConfig(dirPath) {
2620
2738
  };
2621
2739
  }
2622
2740
  function getProjectPages(dirPath) {
2623
- const appJsonPath = path8.join(dirPath, "app.json");
2741
+ const appJsonPath = path9.join(dirPath, "app.json");
2624
2742
  try {
2625
2743
  const appJson = JSON.parse(
2626
2744
  fs4.readFileSync(appJsonPath, "utf-8")
@@ -2646,7 +2764,7 @@ function getProjectSettings(projectPath) {
2646
2764
  return { uploadWithSourceMap: false };
2647
2765
  }
2648
2766
  try {
2649
- const configPath = path8.join(projectPath, "project.config.json");
2767
+ const configPath = path9.join(projectPath, "project.config.json");
2650
2768
  const config = JSON.parse(fs4.readFileSync(configPath, "utf-8"));
2651
2769
  return {
2652
2770
  uploadWithSourceMap: !!config.setting?.uploadWithSourceMap
@@ -2657,7 +2775,7 @@ function getProjectSettings(projectPath) {
2657
2775
  }
2658
2776
  function updateProjectSettings(projectPath, patch) {
2659
2777
  if (!projectPath) return;
2660
- const configPath = path8.join(projectPath, "project.config.json");
2778
+ const configPath = path9.join(projectPath, "project.config.json");
2661
2779
  let config = {};
2662
2780
  try {
2663
2781
  config = JSON.parse(fs4.readFileSync(configPath, "utf-8"));
@@ -2700,6 +2818,7 @@ function getSimulatorServicewechatReferer() {
2700
2818
  }
2701
2819
 
2702
2820
  // src/main/services/workspace/workspace-service.ts
2821
+ var SessionAppInfoSchema = z2.looseObject({ appId: z2.string() });
2703
2822
  function createWorkspaceService(ctx) {
2704
2823
  let currentSession = null;
2705
2824
  let currentProjectPath = "";
@@ -2776,6 +2895,19 @@ function createWorkspaceService(ctx) {
2776
2895
  sendStatus("error", String(err));
2777
2896
  return { success: false, error: String(err) };
2778
2897
  }
2898
+ if (!SessionAppInfoSchema.safeParse(session5.appInfo).success) {
2899
+ try {
2900
+ await session5.close();
2901
+ } catch (closeErr) {
2902
+ console.warn(
2903
+ "[workspace] closing appId-less adapter session failed (non-fatal):",
2904
+ closeErr
2905
+ );
2906
+ }
2907
+ const error = "adapter returned session.appInfo without a string appId \u2014 the CompilationAdapter must supply appInfo.appId";
2908
+ sendStatus("error", error);
2909
+ return { success: false, error };
2910
+ }
2779
2911
  currentSession = session5;
2780
2912
  currentProjectPath = projectPath;
2781
2913
  bestEffort("updateLastOpened", () => {
@@ -2839,16 +2971,16 @@ function createWorkspaceService(ctx) {
2839
2971
  // src/main/services/projects/thumbnail.ts
2840
2972
  import { createHash } from "crypto";
2841
2973
  import fs5 from "fs";
2842
- import path9 from "path";
2974
+ import path10 from "path";
2843
2975
  import { app as app6 } from "electron";
2844
2976
  function getThumbnailDir() {
2845
- return path9.join(app6.getPath("userData"), "thumbnails");
2977
+ return path10.join(app6.getPath("userData"), "thumbnails");
2846
2978
  }
2847
2979
  function hashProjectPath(projectPath) {
2848
2980
  return createHash("sha256").update(projectPath).digest("hex").slice(0, 16);
2849
2981
  }
2850
2982
  function getThumbnailPath(projectPath) {
2851
- return path9.join(getThumbnailDir(), `${hashProjectPath(projectPath)}.png`);
2983
+ return path10.join(getThumbnailDir(), `${hashProjectPath(projectPath)}.png`);
2852
2984
  }
2853
2985
  var DATA_URL_PNG_PREFIX = "data:image/png;base64,";
2854
2986
  function saveThumbnailFromDataUrl(projectPath, imageDataUrl) {
@@ -2909,20 +3041,20 @@ function sanitizeTemplates(templates) {
2909
3041
  }
2910
3042
 
2911
3043
  // src/main/services/projects/builtin-templates.ts
2912
- import path10 from "node:path";
2913
- var TEMPLATES_DIR = path10.join(devtoolsPackageRoot, "templates");
3044
+ import path11 from "node:path";
3045
+ var TEMPLATES_DIR = path11.join(devtoolsPackageRoot, "templates");
2914
3046
  var BUILTIN_TEMPLATES = [
2915
3047
  {
2916
3048
  id: "blank",
2917
3049
  name: "Blank",
2918
3050
  description: "\u6700\u5C0F\u9AA8\u67B6\uFF1Aapp.* + \u4E00\u4E2A index \u9875\u9762",
2919
- source: { type: "directory", path: path10.join(TEMPLATES_DIR, "blank") }
3051
+ source: { type: "directory", path: path11.join(TEMPLATES_DIR, "blank") }
2920
3052
  },
2921
3053
  {
2922
3054
  id: "taro-todo",
2923
3055
  name: "Taro Todo",
2924
3056
  description: "Taro \u7F16\u8BD1\u4EA7\u7269\u7684 Todo \u793A\u4F8B",
2925
- source: { type: "directory", path: path10.join(TEMPLATES_DIR, "taro-todo") }
3057
+ source: { type: "directory", path: path11.join(TEMPLATES_DIR, "taro-todo") }
2926
3058
  }
2927
3059
  ];
2928
3060
 
@@ -2943,6 +3075,7 @@ function createWorkbenchContext(opts) {
2943
3075
  ctx.windows = createWindowService(opts.mainWindow);
2944
3076
  ctx.views = createViewManager(ctx);
2945
3077
  ctx.notify = createRendererNotifier(ctx);
3078
+ ctx.openSettings = () => openSettingsWindow(ctx);
2946
3079
  ctx.projectsProvider = opts.projectsProvider ?? createLocalProjectsProvider();
2947
3080
  ctx.projectTemplates = resolveTemplates(
2948
3081
  BUILTIN_TEMPLATES,
@@ -2965,7 +3098,7 @@ function installAppMenu(ctx) {
2965
3098
  {
2966
3099
  label: "\u5F00\u53D1\u5DE5\u5177\u8BBE\u7F6E",
2967
3100
  click: () => {
2968
- void openSettingsWindow(ctx).catch(() => {
3101
+ void ctx.openSettings().catch(() => {
2969
3102
  });
2970
3103
  }
2971
3104
  },
@@ -3041,111 +3174,111 @@ function registerAppIpc(ctx) {
3041
3174
  }
3042
3175
 
3043
3176
  // src/shared/ipc-schemas.ts
3044
- import { z as z2 } from "zod";
3045
- var AbsolutePath = z2.string().min(1).refine(
3177
+ import { z as z3 } from "zod";
3178
+ var AbsolutePath = z3.string().min(1).refine(
3046
3179
  (p) => p.startsWith("/") || /^[a-zA-Z]:\\/.test(p) || /^[a-zA-Z]:\//.test(p),
3047
3180
  "must be an absolute path"
3048
3181
  );
3049
- var ProjectsAddSchema = z2.tuple([AbsolutePath]);
3050
- var ProjectOpenSchema = z2.tuple([AbsolutePath]);
3051
- var CompileConfigShape = z2.looseObject({
3052
- startPage: z2.string().optional(),
3053
- scene: z2.number().optional(),
3054
- queryParams: z2.array(z2.looseObject({ key: z2.string(), value: z2.string() })).optional()
3182
+ var ProjectsAddSchema = z3.tuple([AbsolutePath]);
3183
+ var ProjectOpenSchema = z3.tuple([AbsolutePath]);
3184
+ var CompileConfigShape = z3.looseObject({
3185
+ startPage: z3.string().optional(),
3186
+ scene: z3.number().optional(),
3187
+ queryParams: z3.array(z3.looseObject({ key: z3.string(), value: z3.string() })).optional()
3055
3188
  });
3056
- var ProjectSaveCompileConfigSchema = z2.tuple([
3189
+ var ProjectSaveCompileConfigSchema = z3.tuple([
3057
3190
  AbsolutePath,
3058
3191
  CompileConfigShape
3059
3192
  ]);
3060
- var PopoverShowSchema = z2.tuple([z2.looseObject({})]);
3061
- var SimWidth = z2.number().int().min(100).max(2e3);
3062
- var SimulatorAttachNativeSchema = z2.tuple([
3063
- z2.string().url().refine((u) => u.startsWith("http://") || u.startsWith("https://"), {
3193
+ var PopoverShowSchema = z3.tuple([z3.looseObject({})]);
3194
+ var SimWidth = z3.number().int().min(100).max(2e3);
3195
+ var SimulatorAttachNativeSchema = z3.tuple([
3196
+ z3.string().url().refine((u) => u.startsWith("http://") || u.startsWith("https://"), {
3064
3197
  message: "simulator URL must be http(s)"
3065
3198
  }),
3066
3199
  SimWidth
3067
3200
  ]);
3068
- var SimulatorSetNativeBoundsSchema = z2.tuple([
3069
- z2.object({
3070
- x: z2.number().finite(),
3071
- y: z2.number().finite(),
3072
- width: z2.number().finite(),
3073
- height: z2.number().finite(),
3074
- zoom: z2.number().finite().positive()
3201
+ var SimulatorSetNativeBoundsSchema = z3.tuple([
3202
+ z3.object({
3203
+ x: z3.number().finite(),
3204
+ y: z3.number().finite(),
3205
+ width: z3.number().finite(),
3206
+ height: z3.number().finite(),
3207
+ zoom: z3.number().finite().positive()
3075
3208
  })
3076
3209
  ]);
3077
- var SimulatorSetDeviceInfoSchema = z2.tuple([
3078
- z2.object({
3079
- brand: z2.string().max(64),
3080
- model: z2.string().max(64),
3081
- system: z2.string().max(64),
3082
- platform: z2.string().max(32),
3083
- pixelRatio: z2.number().finite().positive(),
3084
- screenWidth: z2.number().int().min(100).max(4e3),
3085
- screenHeight: z2.number().int().min(100).max(4e3),
3086
- statusBarHeight: z2.number().finite().min(0).max(400),
3087
- safeAreaBottom: z2.number().finite().min(0).max(400),
3088
- notchType: z2.enum(["none", "notch", "dynamic-island"]),
3089
- safeAreaInsets: z2.object({
3090
- top: z2.number().finite().min(0).max(400),
3091
- right: z2.number().finite().min(0).max(400),
3092
- bottom: z2.number().finite().min(0).max(400),
3093
- left: z2.number().finite().min(0).max(400)
3210
+ var SimulatorSetDeviceInfoSchema = z3.tuple([
3211
+ z3.object({
3212
+ brand: z3.string().max(64),
3213
+ model: z3.string().max(64),
3214
+ system: z3.string().max(64),
3215
+ platform: z3.string().max(32),
3216
+ pixelRatio: z3.number().finite().positive(),
3217
+ screenWidth: z3.number().int().min(100).max(4e3),
3218
+ screenHeight: z3.number().int().min(100).max(4e3),
3219
+ statusBarHeight: z3.number().finite().min(0).max(400),
3220
+ safeAreaBottom: z3.number().finite().min(0).max(400),
3221
+ notchType: z3.enum(["none", "notch", "dynamic-island"]),
3222
+ safeAreaInsets: z3.object({
3223
+ top: z3.number().finite().min(0).max(400),
3224
+ right: z3.number().finite().min(0).max(400),
3225
+ bottom: z3.number().finite().min(0).max(400),
3226
+ left: z3.number().finite().min(0).max(400)
3094
3227
  })
3095
3228
  })
3096
3229
  ]);
3097
- var NonNegInt = z2.number().int().min(0).max(1e5);
3098
- var ViewBoundsSchema = z2.tuple([
3099
- z2.object({
3230
+ var NonNegInt = z3.number().int().min(0).max(1e5);
3231
+ var ViewBoundsSchema = z3.tuple([
3232
+ z3.object({
3100
3233
  x: NonNegInt,
3101
3234
  y: NonNegInt,
3102
3235
  width: NonNegInt,
3103
3236
  height: NonNegInt
3104
3237
  })
3105
3238
  ]);
3106
- var HostToolbarAdvertiseHeightSchema = z2.tuple([
3107
- z2.object({
3108
- axis: z2.literal("block"),
3239
+ var HostToolbarAdvertiseHeightSchema = z3.tuple([
3240
+ z3.object({
3241
+ axis: z3.literal("block"),
3109
3242
  extent: NonNegInt
3110
3243
  })
3111
3244
  ]);
3112
- var SimulatorCustomApiInvokeSchema = z2.tuple([
3113
- z2.string().min(1).max(256),
3114
- z2.unknown()
3245
+ var SimulatorCustomApiInvokeSchema = z3.tuple([
3246
+ z3.string().min(1).max(256),
3247
+ z3.unknown()
3115
3248
  ]);
3116
- var ProjectGetPagesSchema = z2.tuple([AbsolutePath]);
3117
- var ProjectGetCompileConfigSchema = z2.tuple([AbsolutePath]);
3118
- var ProjectsRemoveSchema = z2.tuple([AbsolutePath]);
3119
- var WorkbenchSettingsSaveSchema = z2.tuple([
3120
- z2.looseObject({
3121
- cdp: z2.looseObject({
3122
- enabled: z2.boolean(),
3123
- port: z2.number().int().min(0).max(65535)
3249
+ var ProjectGetPagesSchema = z3.tuple([AbsolutePath]);
3250
+ var ProjectGetCompileConfigSchema = z3.tuple([AbsolutePath]);
3251
+ var ProjectsRemoveSchema = z3.tuple([AbsolutePath]);
3252
+ var WorkbenchSettingsSaveSchema = z3.tuple([
3253
+ z3.looseObject({
3254
+ cdp: z3.looseObject({
3255
+ enabled: z3.boolean(),
3256
+ port: z3.number().int().min(0).max(65535)
3124
3257
  }),
3125
- mcp: z2.looseObject({
3126
- enabled: z2.boolean(),
3127
- port: z2.number().int().min(0).max(65535)
3258
+ mcp: z3.looseObject({
3259
+ enabled: z3.boolean(),
3260
+ port: z3.number().int().min(0).max(65535)
3128
3261
  }),
3129
- compile: z2.looseObject({
3130
- watch: z2.boolean()
3262
+ compile: z3.looseObject({
3263
+ watch: z3.boolean()
3131
3264
  }),
3132
- theme: z2.enum(["system", "light", "dark"]),
3133
- lastCreateBaseDir: z2.union([z2.string(), z2.null()])
3265
+ theme: z3.enum(["system", "light", "dark"]),
3266
+ lastCreateBaseDir: z3.union([z3.string(), z3.null()])
3134
3267
  })
3135
3268
  ]);
3136
- var WorkbenchSettingsSetThemeSchema = z2.tuple([
3137
- z2.enum(["system", "light", "dark"])
3269
+ var WorkbenchSettingsSetThemeSchema = z3.tuple([
3270
+ z3.enum(["system", "light", "dark"])
3138
3271
  ]);
3139
- var SettingsSetVisibleSchema = z2.tuple([z2.boolean()]);
3140
- var SettingsConfigChangedSchema = z2.tuple([CompileConfigShape]);
3141
- var PopoverRelaunchSchema = z2.tuple([CompileConfigShape]);
3142
- var SettingsProjectSettingsChangedSchema = z2.tuple([
3143
- z2.looseObject({
3144
- uploadWithSourceMap: z2.boolean().optional()
3272
+ var SettingsSetVisibleSchema = z3.tuple([z3.boolean()]);
3273
+ var SettingsConfigChangedSchema = z3.tuple([CompileConfigShape]);
3274
+ var PopoverRelaunchSchema = z3.tuple([CompileConfigShape]);
3275
+ var SettingsProjectSettingsChangedSchema = z3.tuple([
3276
+ z3.looseObject({
3277
+ uploadWithSourceMap: z3.boolean().optional()
3145
3278
  })
3146
3279
  ]);
3147
- var ProjectCaptureThumbnailSchema = z2.tuple([AbsolutePath]);
3148
- var ProjectGetThumbnailSchema = z2.tuple([AbsolutePath]);
3280
+ var ProjectCaptureThumbnailSchema = z3.tuple([AbsolutePath]);
3281
+ var ProjectGetThumbnailSchema = z3.tuple([AbsolutePath]);
3149
3282
 
3150
3283
  // src/shared/bridge-channels.ts
3151
3284
  var BRIDGE_CHANNELS = {
@@ -3258,11 +3391,11 @@ var popoverModule = {
3258
3391
 
3259
3392
  // src/main/ipc/projects.ts
3260
3393
  import { app as app7, dialog } from "electron";
3261
- import path12 from "path";
3394
+ import path13 from "path";
3262
3395
 
3263
3396
  // src/main/services/projects/create-project-service.ts
3264
3397
  import fs6 from "node:fs";
3265
- import path11 from "node:path";
3398
+ import path12 from "node:path";
3266
3399
  var DEFAULT_TEMPLATE_ID = "blank";
3267
3400
  async function createProject(input, ctx) {
3268
3401
  const name = (input.name ?? "").trim();
@@ -3309,7 +3442,7 @@ async function createProject(input, ctx) {
3309
3442
  force: true
3310
3443
  });
3311
3444
  }
3312
- const cfgPath = path11.join(target, "project.config.json");
3445
+ const cfgPath = path12.join(target, "project.config.json");
3313
3446
  let cfg = {};
3314
3447
  if (fs6.existsSync(cfgPath)) {
3315
3448
  try {
@@ -3395,7 +3528,7 @@ function registerProjectsIpc(ctx) {
3395
3528
  }
3396
3529
  try {
3397
3530
  const settings = loadWorkbenchSettings();
3398
- const newBase = path12.dirname(input.path);
3531
+ const newBase = path13.dirname(input.path);
3399
3532
  if (newBase && settings.lastCreateBaseDir !== newBase) {
3400
3533
  saveWorkbenchSettings({ ...settings, lastCreateBaseDir: newBase });
3401
3534
  }
@@ -3567,7 +3700,7 @@ import { DisposableRegistry as DisposableRegistry6 } from "@dimina-kit/electron-
3567
3700
 
3568
3701
  // src/main/ipc/bridge-router.ts
3569
3702
  import { app as app11, ipcMain as ipcMain3, protocol as protocol2, session as electronSession, webContents as webContents2 } from "electron";
3570
- import path15 from "node:path";
3703
+ import path16 from "node:path";
3571
3704
  import { pathToFileURL as pathToFileURL3 } from "node:url";
3572
3705
 
3573
3706
  // src/shared/simulator-api-metadata.ts
@@ -3582,7 +3715,7 @@ import { createDebugTap } from "@dimina-kit/electron-deck/main";
3582
3715
  // src/main/services/dimina-resource-server.ts
3583
3716
  import http from "node:http";
3584
3717
  import fs7 from "node:fs";
3585
- import path13 from "node:path";
3718
+ import path14 from "node:path";
3586
3719
  var MIME_TYPES = {
3587
3720
  ".css": "text/css; charset=utf-8",
3588
3721
  ".html": "text/html; charset=utf-8",
@@ -3598,7 +3731,7 @@ var MIME_TYPES = {
3598
3731
  ".wasm": "application/wasm"
3599
3732
  };
3600
3733
  async function startDiminaResourceServer(rootDir) {
3601
- const root = path13.resolve(rootDir);
3734
+ const root = path14.resolve(rootDir);
3602
3735
  const server = http.createServer((req, res) => {
3603
3736
  void handleRequest(root, req, res);
3604
3737
  });
@@ -3646,7 +3779,7 @@ async function handleRequest(root, req, res) {
3646
3779
  return;
3647
3780
  }
3648
3781
  res.writeHead(200, {
3649
- "content-type": MIME_TYPES[path13.extname(filePath)] ?? "application/octet-stream",
3782
+ "content-type": MIME_TYPES[path14.extname(filePath)] ?? "application/octet-stream",
3650
3783
  "content-length": stat.size,
3651
3784
  "cache-control": "no-store"
3652
3785
  });
@@ -3662,8 +3795,8 @@ async function handleRequest(root, req, res) {
3662
3795
  }
3663
3796
  function resolveContainedPath(root, pathname) {
3664
3797
  const relative = pathname.replace(/^\/+/, "") || "index.html";
3665
- const resolved = path13.resolve(root, relative);
3666
- if (resolved !== root && !resolved.startsWith(root + path13.sep)) return null;
3798
+ const resolved = path14.resolve(root, relative);
3799
+ if (resolved !== root && !resolved.startsWith(root + path14.sep)) return null;
3667
3800
  return resolved;
3668
3801
  }
3669
3802
  function setCorsHeaders(res) {
@@ -3674,16 +3807,16 @@ function setCorsHeaders(res) {
3674
3807
  }
3675
3808
 
3676
3809
  // src/main/windows/service-host-window/create.ts
3677
- import { app as app9, BrowserWindow as BrowserWindow3 } from "electron";
3678
- import path14 from "node:path";
3810
+ import { app as app9, BrowserWindow as BrowserWindow4 } from "electron";
3811
+ import path15 from "node:path";
3679
3812
  import { pathToFileURL as pathToFileURL2 } from "node:url";
3680
3813
  var SERVICE_HOST_PARTITION = SHARED_MINIAPP_PARTITION;
3681
- var serviceHostPreloadPath = path14.join(devtoolsPackageRoot, "dist/service-host/preload.cjs");
3682
- var serviceHostHtmlPath = path14.join(devtoolsPackageRoot, "dist/service-host/service.html");
3814
+ var serviceHostPreloadPath = path15.join(devtoolsPackageRoot, "dist/service-host/preload.cjs");
3815
+ var serviceHostHtmlPath = path15.join(devtoolsPackageRoot, "dist/service-host/service.html");
3683
3816
  function constructServiceHostWindow(opts = {}) {
3684
3817
  const partition = opts.partition ?? SERVICE_HOST_PARTITION;
3685
3818
  configureMiniappSession(partition);
3686
- return new BrowserWindow3({
3819
+ return new BrowserWindow4({
3687
3820
  width: 980,
3688
3821
  height: 720,
3689
3822
  show: false,
@@ -3754,7 +3887,7 @@ function createServiceHostWindow(opts) {
3754
3887
  }
3755
3888
 
3756
3889
  // src/main/services/service-host-pool/pool.ts
3757
- import { BrowserWindow as BrowserWindow4 } from "electron";
3890
+ import { BrowserWindow as BrowserWindow5 } from "electron";
3758
3891
  var BLANK_URL = "about:blank";
3759
3892
  var HARD_MAX_POOL_SIZE = 4;
3760
3893
  var RESET_STORAGES = [
@@ -3951,7 +4084,7 @@ var ServiceHostPool = class {
3951
4084
  }
3952
4085
  }
3953
4086
  createWindow(spec) {
3954
- return new BrowserWindow4({
4087
+ return new BrowserWindow5({
3955
4088
  show: false,
3956
4089
  width: spec.size?.width,
3957
4090
  height: spec.size?.height,
@@ -4664,8 +4797,8 @@ function installBridgeRouter(ctx) {
4664
4797
  const onNativeHostQuery = (event) => {
4665
4798
  const reply = {
4666
4799
  enabled: true,
4667
- renderHostHtmlUrl: pathToFileURL3(path15.join(devtoolsPackageRoot, "dist/render-host/pageFrame.html")).toString(),
4668
- renderPreloadUrl: pathToFileURL3(path15.join(devtoolsPackageRoot, "dist/render-host/preload.cjs")).toString(),
4800
+ renderHostHtmlUrl: pathToFileURL3(path16.join(devtoolsPackageRoot, "dist/render-host/pageFrame.html")).toString(),
4801
+ renderPreloadUrl: pathToFileURL3(path16.join(devtoolsPackageRoot, "dist/render-host/preload.cjs")).toString(),
4669
4802
  device: currentDevice ?? void 0
4670
4803
  };
4671
4804
  event.returnValue = reply;
@@ -4915,14 +5048,14 @@ async function handleSpawn(state, ctx, event, opts) {
4915
5048
  const appSessionId = bridgeId;
4916
5049
  const simulatorWc = resolveSimulatorWebContents(ctx, opts.simulatorWcId, event.sender);
4917
5050
  const pagePath = normalizePagePath(opts.pagePath || "pages/index/index");
4918
- const pkgRoot = path15.resolve(opts.pkgRoot || process.cwd());
5051
+ const pkgRoot = path16.resolve(opts.pkgRoot || process.cwd());
4919
5052
  const root = opts.root || "main";
4920
5053
  let resourceServer = null;
4921
5054
  let resourceBaseUrl;
4922
5055
  if (opts.resourceBaseUrl) {
4923
5056
  resourceBaseUrl = opts.resourceBaseUrl.endsWith("/") ? opts.resourceBaseUrl : `${opts.resourceBaseUrl}/`;
4924
5057
  } else {
4925
- resourceServer = await startDiminaResourceServer(path15.resolve(pkgRoot, root));
5058
+ resourceServer = await startDiminaResourceServer(path16.resolve(pkgRoot, root));
4926
5059
  resourceBaseUrl = resourceServer.baseUrl;
4927
5060
  }
4928
5061
  const selectedDevice = ctx.bridge?.getDevice?.() ?? null;
@@ -6542,7 +6675,7 @@ function getClient(kind) {
6542
6675
  }
6543
6676
 
6544
6677
  // src/main/services/mcp/tool-registry.ts
6545
- import { z as z3 } from "zod";
6678
+ import { z as z4 } from "zod";
6546
6679
  function registerCommonTargetTools(server, kind) {
6547
6680
  const descriptions = kind === "simulator" ? {
6548
6681
  screenshot: "Take a screenshot of the simulator webview",
@@ -6563,9 +6696,9 @@ function registerCommonTargetTools(server, kind) {
6563
6696
  return { content: [{ type: "image", data, mimeType: "image/png" }] };
6564
6697
  });
6565
6698
  server.tool(`${kind}_console_logs`, descriptions.consoleLogs, {
6566
- limit: z3.number().optional().default(50).describe("Maximum number of log entries"),
6567
- level: z3.enum(["error", "warning", "warn", "info", "log", "debug"]).optional().describe("Only return entries with this level"),
6568
- sinceTimestamp: z3.string().optional().describe("ISO timestamp; only return entries at or after this time")
6699
+ limit: z4.number().optional().default(50).describe("Maximum number of log entries"),
6700
+ level: z4.enum(["error", "warning", "warn", "info", "log", "debug"]).optional().describe("Only return entries with this level"),
6701
+ sinceTimestamp: z4.string().optional().describe("ISO timestamp; only return entries at or after this time")
6569
6702
  }, async ({ limit, level, sinceTimestamp }) => {
6570
6703
  getClient(kind);
6571
6704
  let entries = getTargetState(kind).consoleLogs;
@@ -6580,7 +6713,7 @@ function registerCommonTargetTools(server, kind) {
6580
6713
  });
6581
6714
  if (kind !== "workbench") {
6582
6715
  server.tool(`${kind}_evaluate`, descriptions.evaluate, {
6583
- expression: z3.string().describe("JavaScript expression to evaluate")
6716
+ expression: z4.string().describe("JavaScript expression to evaluate")
6584
6717
  }, async ({ expression }) => {
6585
6718
  const c = getClient(kind);
6586
6719
  const result = await c.Runtime.evaluate({ expression, returnByValue: true, awaitPromise: true });
@@ -6593,15 +6726,15 @@ ${JSON.stringify(result.exceptionDetails, null, 2)}` }], isError: true };
6593
6726
  });
6594
6727
  }
6595
6728
  server.tool(`${kind}_get_dom`, descriptions.getDom, {
6596
- depth: z3.number().optional().default(3).describe("Maximum depth")
6729
+ depth: z4.number().optional().default(3).describe("Maximum depth")
6597
6730
  }, async ({ depth }) => {
6598
6731
  const c = getClient(kind);
6599
6732
  const { root } = await c.DOM.getDocument({ depth });
6600
6733
  return { content: [{ type: "text", text: JSON.stringify(root, null, 2) }] };
6601
6734
  });
6602
6735
  server.tool(`${kind}_network_log`, descriptions.networkLog, {
6603
- limit: z3.number().optional().default(20).describe("Maximum number of entries"),
6604
- minStatus: z3.number().optional().describe("Only return entries with status >= minStatus (status 0 = failed before response is included when minStatus >= 400)")
6736
+ limit: z4.number().optional().default(20).describe("Maximum number of entries"),
6737
+ minStatus: z4.number().optional().describe("Only return entries with status >= minStatus (status 0 = failed before response is included when minStatus >= 400)")
6605
6738
  }, async ({ limit, minStatus }) => {
6606
6739
  getClient(kind);
6607
6740
  let entries = getTargetState(kind).networkRequests;
@@ -6856,11 +6989,11 @@ function registerContextTools(server) {
6856
6989
  }
6857
6990
 
6858
6991
  // src/main/services/mcp/tools/simulator-tools.ts
6859
- import { z as z4 } from "zod";
6992
+ import { z as z5 } from "zod";
6860
6993
  function registerSimulatorTools(server) {
6861
6994
  server.tool("simulator_navigate", "Navigate the simulator to a URL, or reload the current page", {
6862
- url: z4.string().optional().describe("URL to navigate to"),
6863
- reload: z4.boolean().optional().describe("If true, reload current page instead of navigating")
6995
+ url: z5.string().optional().describe("URL to navigate to"),
6996
+ reload: z5.boolean().optional().describe("If true, reload current page instead of navigating")
6864
6997
  }, async ({ url, reload }) => {
6865
6998
  const c = getClient("simulator");
6866
6999
  if (reload) {
@@ -6875,15 +7008,15 @@ function registerSimulatorTools(server) {
6875
7008
  return { content: [{ type: "text", text: "Error: either url or reload is required" }], isError: true };
6876
7009
  });
6877
7010
  server.tool("simulator_input", "Dispatch input to the simulator. `tap_coord` requires x and y. `tap_selector` requires selector and optional nth. `type` requires selector and text. `scroll` requires x, y, deltaX, and deltaY. `key` is best-effort for common keys such as Enter, Escape, Tab, Arrow* and Space.", {
6878
- action: z4.enum(["tap_coord", "tap_selector", "type", "scroll", "key"]).describe("Input action to dispatch"),
6879
- x: z4.number().optional().describe("Viewport x coordinate for `tap_coord` or `scroll`"),
6880
- y: z4.number().optional().describe("Viewport y coordinate for `tap_coord` or `scroll`"),
6881
- selector: z4.string().optional().describe("CSS selector for `tap_selector` or `type`"),
6882
- nth: z4.number().int().optional().describe("Zero-based index when selector matches multiple elements; defaults to 0"),
6883
- text: z4.string().optional().describe("Text to insert for `type`"),
6884
- key: z4.string().optional().describe("Best-effort keyboard key name for `key`; common keys such as Enter, Escape, Tab, Arrow* and Space work best"),
6885
- deltaX: z4.number().optional().describe("Horizontal wheel delta for `scroll`"),
6886
- deltaY: z4.number().optional().describe("Vertical wheel delta for `scroll`")
7011
+ action: z5.enum(["tap_coord", "tap_selector", "type", "scroll", "key"]).describe("Input action to dispatch"),
7012
+ x: z5.number().optional().describe("Viewport x coordinate for `tap_coord` or `scroll`"),
7013
+ y: z5.number().optional().describe("Viewport y coordinate for `tap_coord` or `scroll`"),
7014
+ selector: z5.string().optional().describe("CSS selector for `tap_selector` or `type`"),
7015
+ nth: z5.number().int().optional().describe("Zero-based index when selector matches multiple elements; defaults to 0"),
7016
+ text: z5.string().optional().describe("Text to insert for `type`"),
7017
+ key: z5.string().optional().describe("Best-effort keyboard key name for `key`; common keys such as Enter, Escape, Tab, Arrow* and Space work best"),
7018
+ deltaX: z5.number().optional().describe("Horizontal wheel delta for `scroll`"),
7019
+ deltaY: z5.number().optional().describe("Vertical wheel delta for `scroll`")
6887
7020
  }, async ({ action, x, y, selector, nth, text, key, deltaX, deltaY }) => {
6888
7021
  const c = getClient("simulator");
6889
7022
  const err = (msg) => ({ content: [{ type: "text", text: `Error: ${msg}` }], isError: true });
@@ -7794,10 +7927,10 @@ function setupSimulatorCurrentPage(host, options) {
7794
7927
 
7795
7928
  // src/main/services/render-inspect/index.ts
7796
7929
  import { readFileSync } from "node:fs";
7797
- import path16 from "node:path";
7930
+ import path17 from "node:path";
7798
7931
  var DEFAULT_SOURCE_PATH = "dist/render-host/render-inspect.js";
7799
7932
  function createRenderInspector(options = {}) {
7800
- const loadSource = options.loadSource ?? (() => readFileSync(path16.join(devtoolsPackageRoot, DEFAULT_SOURCE_PATH), "utf8"));
7933
+ const loadSource = options.loadSource ?? (() => readFileSync(path17.join(devtoolsPackageRoot, DEFAULT_SOURCE_PATH), "utf8"));
7801
7934
  let cachedSource = null;
7802
7935
  const injected = /* @__PURE__ */ new Set();
7803
7936
  function source() {
@@ -7883,14 +8016,14 @@ function revokeAllTempFiles(store) {
7883
8016
 
7884
8017
  // src/shared/vpath.ts
7885
8018
  import os from "node:os";
7886
- import path17 from "node:path";
8019
+ import path18 from "node:path";
7887
8020
  var DIFILE_PREFIX = "difile://";
7888
8021
  function sandboxBase() {
7889
8022
  const env = typeof process !== "undefined" && process.env && process.env.DIMINA_HOME || "";
7890
8023
  if (env) {
7891
- return path17.join(env, "files");
8024
+ return path18.join(env, "files");
7892
8025
  }
7893
- return path17.join(os.homedir(), ".dimina", "files");
8026
+ return path18.join(os.homedir(), ".dimina", "files");
7894
8027
  }
7895
8028
  function resolveVPath(url) {
7896
8029
  if (typeof url !== "string") return null;
@@ -7924,15 +8057,15 @@ function resolveVPath(url) {
7924
8057
  return { kind, writable };
7925
8058
  }
7926
8059
  const base = sandboxBase();
7927
- const joined = path17.join(base, decoded);
7928
- const normalized = path17.normalize(joined);
7929
- if (normalized !== base && !normalized.startsWith(base + path17.sep)) return null;
8060
+ const joined = path18.join(base, decoded);
8061
+ const normalized = path18.normalize(joined);
8062
+ if (normalized !== base && !normalized.startsWith(base + path18.sep)) return null;
7930
8063
  return { kind, writable, realPath: normalized };
7931
8064
  }
7932
8065
 
7933
8066
  // src/main/services/simulator-temp-files/disk.ts
7934
8067
  import fs8 from "node:fs/promises";
7935
- import path18 from "node:path";
8068
+ import path19 from "node:path";
7936
8069
  var EXT_MIME = {
7937
8070
  ".txt": "text/plain",
7938
8071
  ".log": "text/plain",
@@ -7997,7 +8130,7 @@ function sniffMime(head) {
7997
8130
  return null;
7998
8131
  }
7999
8132
  function extMime(realPath) {
8000
- const ext = path18.extname(realPath).toLowerCase();
8133
+ const ext = path19.extname(realPath).toLowerCase();
8001
8134
  if (!ext) return null;
8002
8135
  return EXT_MIME[ext] ?? null;
8003
8136
  }
@@ -8067,7 +8200,7 @@ async function readDiskFile(realPath, opts) {
8067
8200
  }
8068
8201
  async function writeDiskFile(realPath, bytes) {
8069
8202
  const buf = Buffer.isBuffer(bytes) ? bytes : Buffer.from(new Uint8Array(bytes));
8070
- await fs8.mkdir(path18.dirname(realPath), { recursive: true });
8203
+ await fs8.mkdir(path19.dirname(realPath), { recursive: true });
8071
8204
  await fs8.writeFile(realPath, buf);
8072
8205
  }
8073
8206
  async function readDiskDir(realPath) {
@@ -8209,28 +8342,28 @@ async function handleDifileRequest(ctx, req) {
8209
8342
 
8210
8343
  // src/main/services/simulator-temp-files/fs-channels.ts
8211
8344
  import fs9 from "node:fs/promises";
8212
- import path19 from "node:path";
8345
+ import path20 from "node:path";
8213
8346
  async function enforceSandbox(realPath) {
8214
8347
  if (typeof realPath !== "string" || realPath.length === 0) {
8215
8348
  throw new Error("sandbox: realPath must be a non-empty string");
8216
8349
  }
8217
8350
  const base = sandboxBase();
8218
8351
  const baseReal = await fs9.realpath(base).catch(() => base);
8219
- const normalized = path19.normalize(realPath);
8220
- if (normalized !== base && !normalized.startsWith(base + path19.sep)) {
8352
+ const normalized = path20.normalize(realPath);
8353
+ if (normalized !== base && !normalized.startsWith(base + path20.sep)) {
8221
8354
  throw new Error("sandbox: realPath escapes the user-data base");
8222
8355
  }
8223
8356
  let probe = normalized;
8224
- while (probe !== path19.parse(probe).root) {
8357
+ while (probe !== path20.parse(probe).root) {
8225
8358
  try {
8226
8359
  const resolved = await fs9.realpath(probe);
8227
- if (resolved !== baseReal && !resolved.startsWith(baseReal + path19.sep)) {
8360
+ if (resolved !== baseReal && !resolved.startsWith(baseReal + path20.sep)) {
8228
8361
  throw new Error("sandbox: realPath escapes the user-data base via symlink");
8229
8362
  }
8230
8363
  break;
8231
8364
  } catch (err) {
8232
8365
  if (err.code === "ENOENT") {
8233
- probe = path19.dirname(probe);
8366
+ probe = path20.dirname(probe);
8234
8367
  continue;
8235
8368
  }
8236
8369
  throw err;
@@ -8614,7 +8747,7 @@ async function disposeContext(ctx) {
8614
8747
  function createConfiguredMainWindow(config, rendererDir2) {
8615
8748
  const mainWindow = createMainWindow({
8616
8749
  title: config.appName ?? "Dimina DevTools",
8617
- indexHtml: path20.join(rendererDir2, "entries/main/index.html"),
8750
+ indexHtml: path21.join(rendererDir2, "entries/main/index.html"),
8618
8751
  width: config.window?.width,
8619
8752
  height: config.window?.height,
8620
8753
  minWidth: config.window?.minWidth,
@@ -8652,12 +8785,21 @@ function registerBuiltinModules(config, context) {
8652
8785
  });
8653
8786
  }
8654
8787
  function toMenuContext(context) {
8655
- const menuContext = { ...context };
8656
- delete menuContext.registry;
8657
- delete menuContext.senderPolicy;
8658
- delete menuContext.trustedWindowSenderIds;
8659
- delete menuContext.simulatorApis;
8660
- return menuContext;
8788
+ return {
8789
+ appName: context.appName,
8790
+ workspace: {
8791
+ hasActiveSession: () => context.workspace.hasActiveSession(),
8792
+ getProjectPath: () => context.workspace.getProjectPath(),
8793
+ openProject: (projectPath) => context.workspace.openProject(projectPath),
8794
+ closeProject: () => context.workspace.closeProject(),
8795
+ getSession: () => context.workspace.getSession()
8796
+ },
8797
+ openSettings: () => context.openSettings(),
8798
+ notify: {
8799
+ projectStatus: (payload) => context.notify.projectStatus(payload),
8800
+ windowNavigateBack: () => context.notify.windowNavigateBack()
8801
+ }
8802
+ };
8661
8803
  }
8662
8804
  function installMenu(config, mainWindow, context) {
8663
8805
  if (config.menuBuilder) {
@@ -8714,7 +8856,7 @@ function enableDevRendererAutoReload(rendererDir2) {
8714
8856
  const watcher = fs10.watch(rendererDir2, { recursive: true }, () => {
8715
8857
  if (reloadTimer) clearTimeout(reloadTimer);
8716
8858
  reloadTimer = setTimeout(() => {
8717
- for (const win of BrowserWindow7.getAllWindows()) {
8859
+ for (const win of BrowserWindow8.getAllWindows()) {
8718
8860
  win.webContents.reload();
8719
8861
  }
8720
8862
  }, 300);
@@ -8932,56 +9074,10 @@ function createDevtoolsBackend(config = {}) {
8932
9074
  };
8933
9075
  }
8934
9076
 
8935
- // src/main/windows/settings-window/create.ts
8936
- import { BrowserWindow as BrowserWindow8 } from "electron";
8937
- import path21 from "path";
8938
- async function createSettingsWindow(parent, rendererDir2) {
8939
- const win = new BrowserWindow8({
8940
- width: 420,
8941
- height: 560,
8942
- minWidth: 380,
8943
- minHeight: 480,
8944
- parent: parent ?? void 0,
8945
- title: "\u5F00\u53D1\u5DE5\u5177\u8BBE\u7F6E",
8946
- backgroundColor: themeBg(),
8947
- webPreferences: {
8948
- nodeIntegration: false,
8949
- contextIsolation: true,
8950
- sandbox: false,
8951
- preload: mainPreloadPath
8952
- }
8953
- });
8954
- applyNavigationHardening(win.webContents, rendererDir2);
8955
- await win.loadFile(path21.join(rendererDir2, "entries/workbench-settings/index.html"));
8956
- return win;
8957
- }
8958
-
8959
- // src/main/windows/settings-window/events.ts
8960
- function wireSettingsWindowEvents(win, onClosed) {
8961
- win.on("closed", () => {
8962
- onClosed();
8963
- });
8964
- }
8965
-
8966
9077
  // src/main/app/launch.ts
8967
9078
  function launch(config = {}) {
8968
9079
  return frameworkElectronDeck({ backend: createDevtoolsBackend(config) });
8969
9080
  }
8970
- async function openSettingsWindow(ctx) {
8971
- let win = ctx.windows.settingsWindow;
8972
- if (!win || win.isDestroyed()) {
8973
- win = await createSettingsWindow(ctx.windows.mainWindow, ctx.rendererDir);
8974
- ctx.windows.setSettingsWindow(win);
8975
- wireSettingsWindowEvents(win, () => {
8976
- ctx.windows.setSettingsWindow(null);
8977
- });
8978
- }
8979
- win.show();
8980
- win.focus();
8981
- ctx.notify.workbenchSettingsInit(win, {
8982
- settings: loadWorkbenchSettings()
8983
- });
8984
- }
8985
9081
 
8986
9082
  // src/main/index.ts
8987
9083
  launch().catch((err) => {