@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.
- package/README.md +8 -6
- package/dist/main/api.d.ts +1 -1
- package/dist/main/app/app.js +22 -12
- package/dist/main/app/launch.d.ts +4 -4
- package/dist/main/app/launch.js +5 -17
- package/dist/main/index.bundle.js +309 -213
- package/dist/main/menu/index.d.ts +2 -2
- package/dist/main/menu/index.js +4 -2
- package/dist/main/runtime/miniapp-runtime.d.ts +79 -11
- package/dist/main/services/views/host-toolbar-port-channel.d.ts +10 -0
- package/dist/main/services/views/host-toolbar-port-channel.js +89 -10
- package/dist/main/services/views/view-manager.d.ts +12 -0
- package/dist/main/services/views/view-manager.js +10 -0
- package/dist/main/services/workbench-context.d.ts +7 -0
- package/dist/main/services/workbench-context.js +5 -0
- package/dist/main/services/workspace/workspace-service.d.ts +3 -7
- package/dist/main/services/workspace/workspace-service.js +27 -0
- package/dist/main/windows/settings-window/index.d.ts +33 -0
- package/dist/main/windows/settings-window/index.js +59 -0
- package/dist/preload/runtime/host-toolbar-port.d.ts +10 -5
- package/dist/preload/runtime/host-toolbar-port.js +24 -0
- package/dist/preload/windows/host-toolbar-runtime.cjs +9 -0
- package/dist/preload/windows/host-toolbar-runtime.cjs.map +2 -2
- package/dist/shared/types.d.ts +48 -11
- package/package.json +4 -4
|
@@ -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
|
|
743
|
+
import { app as app14, BrowserWindow as BrowserWindow8, nativeImage, session as session4 } from "electron";
|
|
744
744
|
import fs10 from "fs";
|
|
745
|
-
import
|
|
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
|
|
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
|
-
|
|
1737
|
-
|
|
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
|
|
2655
|
+
import path9 from "path";
|
|
2538
2656
|
import fs4 from "fs";
|
|
2539
2657
|
var log2 = createLogger("projects");
|
|
2540
2658
|
function getProjectsFile() {
|
|
2541
|
-
return
|
|
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(
|
|
2564
|
-
const configPath =
|
|
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 =
|
|
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 =
|
|
2700
|
+
let name = path9.basename(dirPath);
|
|
2583
2701
|
try {
|
|
2584
|
-
const configPath =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
|
2974
|
+
import path10 from "path";
|
|
2843
2975
|
import { app as app6 } from "electron";
|
|
2844
2976
|
function getThumbnailDir() {
|
|
2845
|
-
return
|
|
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
|
|
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
|
|
2913
|
-
var TEMPLATES_DIR =
|
|
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:
|
|
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:
|
|
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
|
|
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
|
|
3045
|
-
var AbsolutePath =
|
|
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 =
|
|
3050
|
-
var ProjectOpenSchema =
|
|
3051
|
-
var CompileConfigShape =
|
|
3052
|
-
startPage:
|
|
3053
|
-
scene:
|
|
3054
|
-
queryParams:
|
|
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 =
|
|
3189
|
+
var ProjectSaveCompileConfigSchema = z3.tuple([
|
|
3057
3190
|
AbsolutePath,
|
|
3058
3191
|
CompileConfigShape
|
|
3059
3192
|
]);
|
|
3060
|
-
var PopoverShowSchema =
|
|
3061
|
-
var SimWidth =
|
|
3062
|
-
var SimulatorAttachNativeSchema =
|
|
3063
|
-
|
|
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 =
|
|
3069
|
-
|
|
3070
|
-
x:
|
|
3071
|
-
y:
|
|
3072
|
-
width:
|
|
3073
|
-
height:
|
|
3074
|
-
zoom:
|
|
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 =
|
|
3078
|
-
|
|
3079
|
-
brand:
|
|
3080
|
-
model:
|
|
3081
|
-
system:
|
|
3082
|
-
platform:
|
|
3083
|
-
pixelRatio:
|
|
3084
|
-
screenWidth:
|
|
3085
|
-
screenHeight:
|
|
3086
|
-
statusBarHeight:
|
|
3087
|
-
safeAreaBottom:
|
|
3088
|
-
notchType:
|
|
3089
|
-
safeAreaInsets:
|
|
3090
|
-
top:
|
|
3091
|
-
right:
|
|
3092
|
-
bottom:
|
|
3093
|
-
left:
|
|
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 =
|
|
3098
|
-
var ViewBoundsSchema =
|
|
3099
|
-
|
|
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 =
|
|
3107
|
-
|
|
3108
|
-
axis:
|
|
3239
|
+
var HostToolbarAdvertiseHeightSchema = z3.tuple([
|
|
3240
|
+
z3.object({
|
|
3241
|
+
axis: z3.literal("block"),
|
|
3109
3242
|
extent: NonNegInt
|
|
3110
3243
|
})
|
|
3111
3244
|
]);
|
|
3112
|
-
var SimulatorCustomApiInvokeSchema =
|
|
3113
|
-
|
|
3114
|
-
|
|
3245
|
+
var SimulatorCustomApiInvokeSchema = z3.tuple([
|
|
3246
|
+
z3.string().min(1).max(256),
|
|
3247
|
+
z3.unknown()
|
|
3115
3248
|
]);
|
|
3116
|
-
var ProjectGetPagesSchema =
|
|
3117
|
-
var ProjectGetCompileConfigSchema =
|
|
3118
|
-
var ProjectsRemoveSchema =
|
|
3119
|
-
var WorkbenchSettingsSaveSchema =
|
|
3120
|
-
|
|
3121
|
-
cdp:
|
|
3122
|
-
enabled:
|
|
3123
|
-
port:
|
|
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:
|
|
3126
|
-
enabled:
|
|
3127
|
-
port:
|
|
3258
|
+
mcp: z3.looseObject({
|
|
3259
|
+
enabled: z3.boolean(),
|
|
3260
|
+
port: z3.number().int().min(0).max(65535)
|
|
3128
3261
|
}),
|
|
3129
|
-
compile:
|
|
3130
|
-
watch:
|
|
3262
|
+
compile: z3.looseObject({
|
|
3263
|
+
watch: z3.boolean()
|
|
3131
3264
|
}),
|
|
3132
|
-
theme:
|
|
3133
|
-
lastCreateBaseDir:
|
|
3265
|
+
theme: z3.enum(["system", "light", "dark"]),
|
|
3266
|
+
lastCreateBaseDir: z3.union([z3.string(), z3.null()])
|
|
3134
3267
|
})
|
|
3135
3268
|
]);
|
|
3136
|
-
var WorkbenchSettingsSetThemeSchema =
|
|
3137
|
-
|
|
3269
|
+
var WorkbenchSettingsSetThemeSchema = z3.tuple([
|
|
3270
|
+
z3.enum(["system", "light", "dark"])
|
|
3138
3271
|
]);
|
|
3139
|
-
var SettingsSetVisibleSchema =
|
|
3140
|
-
var SettingsConfigChangedSchema =
|
|
3141
|
-
var PopoverRelaunchSchema =
|
|
3142
|
-
var SettingsProjectSettingsChangedSchema =
|
|
3143
|
-
|
|
3144
|
-
uploadWithSourceMap:
|
|
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 =
|
|
3148
|
-
var ProjectGetThumbnailSchema =
|
|
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
|
|
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
|
|
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 =
|
|
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 =
|
|
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
|
|
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
|
|
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 =
|
|
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[
|
|
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 =
|
|
3666
|
-
if (resolved !== root && !resolved.startsWith(root +
|
|
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
|
|
3678
|
-
import
|
|
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 =
|
|
3682
|
-
var serviceHostHtmlPath =
|
|
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
|
|
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
|
|
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
|
|
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(
|
|
4668
|
-
renderPreloadUrl: pathToFileURL3(
|
|
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 =
|
|
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(
|
|
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
|
|
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:
|
|
6567
|
-
level:
|
|
6568
|
-
sinceTimestamp:
|
|
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:
|
|
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:
|
|
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:
|
|
6604
|
-
minStatus:
|
|
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
|
|
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:
|
|
6863
|
-
reload:
|
|
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:
|
|
6879
|
-
x:
|
|
6880
|
-
y:
|
|
6881
|
-
selector:
|
|
6882
|
-
nth:
|
|
6883
|
-
text:
|
|
6884
|
-
key:
|
|
6885
|
-
deltaX:
|
|
6886
|
-
deltaY:
|
|
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
|
|
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(
|
|
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
|
|
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
|
|
8024
|
+
return path18.join(env, "files");
|
|
7892
8025
|
}
|
|
7893
|
-
return
|
|
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 =
|
|
7928
|
-
const normalized =
|
|
7929
|
-
if (normalized !== base && !normalized.startsWith(base +
|
|
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
|
|
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 =
|
|
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(
|
|
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
|
|
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 =
|
|
8220
|
-
if (normalized !== base && !normalized.startsWith(base +
|
|
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 !==
|
|
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 +
|
|
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 =
|
|
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:
|
|
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
|
-
|
|
8656
|
-
|
|
8657
|
-
|
|
8658
|
-
|
|
8659
|
-
|
|
8660
|
-
|
|
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
|
|
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) => {
|