@wrongstack/desktop 0.287.0 → 0.289.0
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/dist/main/main.js
CHANGED
|
@@ -3,7 +3,7 @@ import * as path4 from "node:path";
|
|
|
3
3
|
import * as fs3 from "node:fs/promises";
|
|
4
4
|
import { wstackGlobalRoot as wstackGlobalRoot3 } from "@wrongstack/core/utils";
|
|
5
5
|
import {
|
|
6
|
-
app,
|
|
6
|
+
app as app2,
|
|
7
7
|
BaseWindow,
|
|
8
8
|
dialog,
|
|
9
9
|
ipcMain as ipcMain2,
|
|
@@ -13,6 +13,52 @@ import {
|
|
|
13
13
|
WebContentsView
|
|
14
14
|
} from "electron";
|
|
15
15
|
|
|
16
|
+
// src/main/macos-platform.ts
|
|
17
|
+
import { app, Menu } from "electron";
|
|
18
|
+
function initMacOS() {
|
|
19
|
+
if (process.platform !== "darwin") return;
|
|
20
|
+
app.setActivationPolicy("regular");
|
|
21
|
+
app.on("open-file", (_event, filePath) => {
|
|
22
|
+
if (app.isReady()) {
|
|
23
|
+
handleFileOpen(filePath);
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
app.dock?.setMenu(
|
|
27
|
+
Menu.buildFromTemplate([
|
|
28
|
+
{
|
|
29
|
+
label: "New Window",
|
|
30
|
+
click: () => {
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
])
|
|
34
|
+
);
|
|
35
|
+
app.setAboutPanelOptions({
|
|
36
|
+
applicationName: "WrongStack Desktop",
|
|
37
|
+
applicationVersion: app.getVersion(),
|
|
38
|
+
version: process.versions.electron ? `Electron ${process.versions.electron}` : ""
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
function handleFileOpen(filePath) {
|
|
42
|
+
pendingOpenFilePath = filePath;
|
|
43
|
+
}
|
|
44
|
+
var pendingOpenFilePath = null;
|
|
45
|
+
function drainPendingOpenFilePath() {
|
|
46
|
+
const path5 = pendingOpenFilePath;
|
|
47
|
+
pendingOpenFilePath = null;
|
|
48
|
+
return path5;
|
|
49
|
+
}
|
|
50
|
+
function firstOpenFileArg(argv) {
|
|
51
|
+
if (process.platform !== "darwin") return null;
|
|
52
|
+
for (let index = 1; index < argv.length; index++) {
|
|
53
|
+
const arg = argv[index];
|
|
54
|
+
if (arg == null) continue;
|
|
55
|
+
if (arg.startsWith("-")) continue;
|
|
56
|
+
if (arg === "." || arg === "--") continue;
|
|
57
|
+
return arg;
|
|
58
|
+
}
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
|
|
16
62
|
// src/main/agent-bridge.ts
|
|
17
63
|
import { randomUUID } from "node:crypto";
|
|
18
64
|
import { EventEmitter } from "node:events";
|
|
@@ -398,7 +444,11 @@ var IPC = {
|
|
|
398
444
|
// Embedded WebUI view side — the desktop shell pushes locale changes here
|
|
399
445
|
// so the React WebUI inside Electron can swap i18n instantly, without waiting
|
|
400
446
|
// for the config-file watcher → WS prefs.updated round-trip.
|
|
401
|
-
webuiLocaleChanged: "desktop:webui-locale-changed"
|
|
447
|
+
webuiLocaleChanged: "desktop:webui-locale-changed",
|
|
448
|
+
// macOS open-file event forwarded from main process to shell renderer.
|
|
449
|
+
// The shell uses this to decide whether to open a dragged/double-clicked
|
|
450
|
+
// path as a project directory.
|
|
451
|
+
openFile: "desktop:open-file"
|
|
402
452
|
};
|
|
403
453
|
|
|
404
454
|
// src/main/i18n-main.ts
|
|
@@ -1187,6 +1237,26 @@ async function terminateProcessTree(child) {
|
|
|
1187
1237
|
if (!child || child.killed || !child.pid) return;
|
|
1188
1238
|
if (process.platform !== "win32") {
|
|
1189
1239
|
child.kill("SIGTERM");
|
|
1240
|
+
const deadline = Date.now() + 5e3;
|
|
1241
|
+
await new Promise((resolve2) => {
|
|
1242
|
+
const check = () => {
|
|
1243
|
+
if (child.killed || !child.pid) {
|
|
1244
|
+
resolve2();
|
|
1245
|
+
return;
|
|
1246
|
+
}
|
|
1247
|
+
if (Date.now() >= deadline) {
|
|
1248
|
+
try {
|
|
1249
|
+
process.kill(-child.pid, "SIGKILL");
|
|
1250
|
+
} catch {
|
|
1251
|
+
child.kill("SIGKILL");
|
|
1252
|
+
}
|
|
1253
|
+
resolve2();
|
|
1254
|
+
return;
|
|
1255
|
+
}
|
|
1256
|
+
setTimeout(check, 100);
|
|
1257
|
+
};
|
|
1258
|
+
check();
|
|
1259
|
+
});
|
|
1190
1260
|
return;
|
|
1191
1261
|
}
|
|
1192
1262
|
await new Promise((resolve2) => {
|
|
@@ -1526,7 +1596,7 @@ var DESKTOP_WEBUI_ACTIONS = /* @__PURE__ */ new Set([
|
|
|
1526
1596
|
var DESKTOP_WEBUI_VIEWS = /* @__PURE__ */ new Set([
|
|
1527
1597
|
"chat",
|
|
1528
1598
|
"settings",
|
|
1529
|
-
"
|
|
1599
|
+
"goal",
|
|
1530
1600
|
"specs",
|
|
1531
1601
|
"sddboard",
|
|
1532
1602
|
"sddwizard",
|
|
@@ -1561,7 +1631,6 @@ var DESKTOP_WEBUI_OVERLAYS = /* @__PURE__ */ new Set([
|
|
|
1561
1631
|
"queue"
|
|
1562
1632
|
]);
|
|
1563
1633
|
var DESKTOP_WEBUI_DOCKS = /* @__PURE__ */ new Set([
|
|
1564
|
-
"autophase",
|
|
1565
1634
|
"goal",
|
|
1566
1635
|
"fleet",
|
|
1567
1636
|
"work",
|
|
@@ -1685,7 +1754,7 @@ function getSidebarWidth(windowWidth, collapsed) {
|
|
|
1685
1754
|
}
|
|
1686
1755
|
|
|
1687
1756
|
// src/main/menu/index.ts
|
|
1688
|
-
import { Menu } from "electron";
|
|
1757
|
+
import { Menu as Menu2 } from "electron";
|
|
1689
1758
|
|
|
1690
1759
|
// src/main/menu/projects-menu.ts
|
|
1691
1760
|
import path3 from "node:path";
|
|
@@ -2018,7 +2087,7 @@ function configureApplicationMenu(ctx) {
|
|
|
2018
2087
|
buildWorkspaceMenu(ctx, actions, hasActiveWebui, activeWebuiPrefs, navigate),
|
|
2019
2088
|
buildViewMenu(ctx)
|
|
2020
2089
|
];
|
|
2021
|
-
|
|
2090
|
+
Menu2.setApplicationMenu(Menu2.buildFromTemplate(template));
|
|
2022
2091
|
}
|
|
2023
2092
|
|
|
2024
2093
|
// src/main/ipc-handlers/index.ts
|
|
@@ -2308,8 +2377,11 @@ function isRecord2(value) {
|
|
|
2308
2377
|
}
|
|
2309
2378
|
|
|
2310
2379
|
// src/main/main.ts
|
|
2311
|
-
|
|
2312
|
-
|
|
2380
|
+
initMacOS();
|
|
2381
|
+
if (process.platform === "win32") {
|
|
2382
|
+
app2.setAppUserModelId("com.wrongstack.desktop");
|
|
2383
|
+
}
|
|
2384
|
+
app2.setPath("userData", path4.join(wstackGlobalRoot3(), "desktop", "electron-profile"));
|
|
2313
2385
|
var manager = new DesktopRuntimeManager();
|
|
2314
2386
|
var bridge = new DesktopAgentBridge();
|
|
2315
2387
|
var mainWindow = null;
|
|
@@ -2341,6 +2413,22 @@ function sameOrigin(candidate, base) {
|
|
|
2341
2413
|
return false;
|
|
2342
2414
|
}
|
|
2343
2415
|
}
|
|
2416
|
+
function revealInExplorer(root) {
|
|
2417
|
+
shell.openPath(root).catch((err) => {
|
|
2418
|
+
if (process.platform === "darwin") {
|
|
2419
|
+
void shell.openPath(path4.dirname(root)).catch(() => void 0);
|
|
2420
|
+
}
|
|
2421
|
+
console.error(
|
|
2422
|
+
JSON.stringify({
|
|
2423
|
+
level: "warn",
|
|
2424
|
+
event: "desktop.reveal_in_explorer_failed",
|
|
2425
|
+
root,
|
|
2426
|
+
message: err instanceof Error ? err.message : String(err),
|
|
2427
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
2428
|
+
})
|
|
2429
|
+
);
|
|
2430
|
+
});
|
|
2431
|
+
}
|
|
2344
2432
|
function setShellSidebarCollapsed(collapsed) {
|
|
2345
2433
|
shellSidebarCollapsed = collapsed;
|
|
2346
2434
|
layoutWebuiViews();
|
|
@@ -2885,7 +2973,7 @@ function createMenuContext() {
|
|
|
2885
2973
|
shell.openExternal(url);
|
|
2886
2974
|
},
|
|
2887
2975
|
revealInExplorer: (root) => {
|
|
2888
|
-
|
|
2976
|
+
revealInExplorer(root);
|
|
2889
2977
|
}
|
|
2890
2978
|
};
|
|
2891
2979
|
}
|
|
@@ -2922,7 +3010,7 @@ function buildIpcHandlerContext() {
|
|
|
2922
3010
|
abortRuntime: (id, wsUrl) => bridge.abort(id, wsUrl),
|
|
2923
3011
|
openExternal: (url) => safeOpenExternal(url),
|
|
2924
3012
|
revealInExplorer: (root) => {
|
|
2925
|
-
|
|
3013
|
+
revealInExplorer(root);
|
|
2926
3014
|
},
|
|
2927
3015
|
findWebuiEntryBySenderId: (senderId) => findWebuiEntryBySenderId(senderId),
|
|
2928
3016
|
getPendingWebuiCommandAcks: () => pendingWebuiCommandAcks,
|
|
@@ -2953,12 +3041,29 @@ async function boot() {
|
|
|
2953
3041
|
const defaultWidth = 1180;
|
|
2954
3042
|
const defaultHeight = 720;
|
|
2955
3043
|
let appIcon;
|
|
2956
|
-
|
|
2957
|
-
|
|
2958
|
-
|
|
2959
|
-
|
|
2960
|
-
|
|
2961
|
-
|
|
3044
|
+
if (process.platform !== "darwin") {
|
|
3045
|
+
try {
|
|
3046
|
+
const iconPath = new URL("../../assets/icon.svg", import.meta.url).pathname;
|
|
3047
|
+
await fs3.stat(iconPath);
|
|
3048
|
+
appIcon = nativeImage.createFromPath(iconPath);
|
|
3049
|
+
if (appIcon.isEmpty()) appIcon = void 0;
|
|
3050
|
+
} catch {
|
|
3051
|
+
}
|
|
3052
|
+
} else {
|
|
3053
|
+
try {
|
|
3054
|
+
const pngPath = new URL("../../assets/icon.png", import.meta.url).pathname;
|
|
3055
|
+
await fs3.stat(pngPath);
|
|
3056
|
+
appIcon = nativeImage.createFromPath(pngPath);
|
|
3057
|
+
if (appIcon.isEmpty()) appIcon = void 0;
|
|
3058
|
+
} catch {
|
|
3059
|
+
try {
|
|
3060
|
+
const icnsPath = new URL("../../assets/icon.icns", import.meta.url).pathname;
|
|
3061
|
+
await fs3.stat(icnsPath);
|
|
3062
|
+
appIcon = nativeImage.createFromPath(icnsPath);
|
|
3063
|
+
if (appIcon.isEmpty()) appIcon = void 0;
|
|
3064
|
+
} catch {
|
|
3065
|
+
}
|
|
3066
|
+
}
|
|
2962
3067
|
}
|
|
2963
3068
|
const winOptions = {
|
|
2964
3069
|
width: prevState?.width ?? defaultWidth,
|
|
@@ -2994,6 +3099,11 @@ async function boot() {
|
|
|
2994
3099
|
configureApplicationMenu2();
|
|
2995
3100
|
broadcastState();
|
|
2996
3101
|
});
|
|
3102
|
+
app2.on("open-file", (_event, filePath) => {
|
|
3103
|
+
if (shellView && !shellView.webContents.isDestroyed()) {
|
|
3104
|
+
shellView.webContents.send(IPC.openFile, filePath);
|
|
3105
|
+
}
|
|
3106
|
+
});
|
|
2997
3107
|
let lastWatchedLocale;
|
|
2998
3108
|
watchProviderConfig(
|
|
2999
3109
|
desktopConfigPaths.globalConfigPath,
|
|
@@ -3017,17 +3127,25 @@ async function boot() {
|
|
|
3017
3127
|
disposeAllWebuiEntries();
|
|
3018
3128
|
void saveWindowState();
|
|
3019
3129
|
quittingAfterCleanup = true;
|
|
3020
|
-
|
|
3130
|
+
app2.exit(0);
|
|
3021
3131
|
});
|
|
3022
3132
|
await restoreLastWorkspace();
|
|
3133
|
+
const argvOpenPath = firstOpenFileArg(process.argv);
|
|
3134
|
+
const queuedOpenPath = drainPendingOpenFilePath();
|
|
3135
|
+
const openPath = argvOpenPath ?? queuedOpenPath;
|
|
3136
|
+
if (openPath && shellView && !shellView.webContents.isDestroyed()) {
|
|
3137
|
+
shellView.webContents.send(IPC.openFile, openPath);
|
|
3138
|
+
}
|
|
3023
3139
|
mainWindow.show();
|
|
3024
3140
|
shellView.webContents.focus();
|
|
3025
3141
|
}
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
3142
|
+
app2.whenReady().then(boot);
|
|
3143
|
+
app2.on("window-all-closed", () => {
|
|
3144
|
+
if (process.platform !== "darwin") {
|
|
3145
|
+
app2.quit();
|
|
3146
|
+
}
|
|
3029
3147
|
});
|
|
3030
|
-
|
|
3148
|
+
app2.on("before-quit", () => {
|
|
3031
3149
|
if (mainWindow) {
|
|
3032
3150
|
mainWindow.removeAllListeners("close");
|
|
3033
3151
|
void saveWindowState();
|
|
@@ -3035,7 +3153,7 @@ app.on("before-quit", () => {
|
|
|
3035
3153
|
bridge.closeAll();
|
|
3036
3154
|
disposeAllWebuiEntries();
|
|
3037
3155
|
});
|
|
3038
|
-
|
|
3156
|
+
app2.on("activate", () => {
|
|
3039
3157
|
if (!mainWindow) return;
|
|
3040
3158
|
mainWindow.show();
|
|
3041
3159
|
shellView?.webContents.focus();
|