@wrongstack/desktop 0.283.0 → 0.284.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 +93 -14
- package/dist/main/main.js.map +1 -1
- package/dist/renderer/assets/index-DNaesuTF.css +1 -0
- package/dist/renderer/assets/index-cpNF4AJ5.js +399 -0
- package/dist/renderer/assets/index-cpNF4AJ5.js.map +1 -0
- package/dist/renderer/index.html +2 -2
- package/package.json +4 -3
- package/dist/renderer/assets/index-BAP2wfHP.css +0 -1
- package/dist/renderer/assets/index-Cq-Fc_6i.js +0 -395
- package/dist/renderer/assets/index-Cq-Fc_6i.js.map +0 -1
package/dist/main/main.js
CHANGED
|
@@ -404,6 +404,7 @@ import { spawn } from "child_process";
|
|
|
404
404
|
import { randomBytes } from "crypto";
|
|
405
405
|
import { EventEmitter } from "events";
|
|
406
406
|
import * as fs2 from "fs/promises";
|
|
407
|
+
import { existsSync } from "fs";
|
|
407
408
|
import * as http from "http";
|
|
408
409
|
import { createRequire } from "module";
|
|
409
410
|
import * as net from "net";
|
|
@@ -588,6 +589,7 @@ var DesktopRuntimeManager = class extends EventEmitter {
|
|
|
588
589
|
this.emitChanged();
|
|
589
590
|
try {
|
|
590
591
|
const entry = resolveWebUiEntry();
|
|
592
|
+
const distDir = resolveWebUiDistDir();
|
|
591
593
|
const child = spawn(
|
|
592
594
|
process.execPath,
|
|
593
595
|
[
|
|
@@ -598,6 +600,8 @@ var DesktopRuntimeManager = class extends EventEmitter {
|
|
|
598
600
|
String(httpPort),
|
|
599
601
|
"--ws-port",
|
|
600
602
|
String(wsPort),
|
|
603
|
+
"--dist-dir",
|
|
604
|
+
distDir,
|
|
601
605
|
"--token",
|
|
602
606
|
token,
|
|
603
607
|
"--require-token"
|
|
@@ -628,9 +632,19 @@ var DesktopRuntimeManager = class extends EventEmitter {
|
|
|
628
632
|
this.scheduleLogChanged(runtime);
|
|
629
633
|
process.stderr.write(`[desktop:${runtime.id}] ${text}`);
|
|
630
634
|
});
|
|
635
|
+
child.once("error", (err) => {
|
|
636
|
+
runtime.status = "error";
|
|
637
|
+
runtime.error = toErrorMessage(err);
|
|
638
|
+
runtime.child = null;
|
|
639
|
+
if (this.activeRuntimeId === runtime.id) {
|
|
640
|
+
this.activeRuntimeId = firstRunningRuntimeId(this.runtimes);
|
|
641
|
+
}
|
|
642
|
+
this.emitChanged();
|
|
643
|
+
});
|
|
631
644
|
child.once("exit", (code, signal) => {
|
|
632
|
-
|
|
633
|
-
runtime.
|
|
645
|
+
if (runtime.status === "error") return;
|
|
646
|
+
runtime.status = "stopped";
|
|
647
|
+
runtime.error = code === 0 ? void 0 : `Exited with ${signal ?? `code ${code ?? "unknown"}`}`;
|
|
634
648
|
runtime.child = null;
|
|
635
649
|
if (this.activeRuntimeId === runtime.id) {
|
|
636
650
|
this.activeRuntimeId = firstRunningRuntimeId(this.runtimes);
|
|
@@ -638,15 +652,25 @@ var DesktopRuntimeManager = class extends EventEmitter {
|
|
|
638
652
|
this.emitChanged();
|
|
639
653
|
});
|
|
640
654
|
await waitForHttpReady(runtime.url, token, START_TIMEOUT_MS);
|
|
655
|
+
if (runtime.status !== "starting") {
|
|
656
|
+
throw new Error(runtime.error ?? "WebUI process exited during startup");
|
|
657
|
+
}
|
|
641
658
|
runtime.status = "running";
|
|
642
659
|
await this.persistWorkspaceState();
|
|
643
660
|
this.emitChanged();
|
|
644
661
|
return publicRuntime(runtime);
|
|
645
662
|
} catch (err) {
|
|
646
|
-
runtime.status
|
|
647
|
-
|
|
663
|
+
if (runtime.status !== "stopped" && runtime.status !== "error") {
|
|
664
|
+
runtime.status = "error";
|
|
665
|
+
}
|
|
666
|
+
if (runtime.error === void 0) {
|
|
667
|
+
runtime.error = toErrorMessage(err);
|
|
668
|
+
}
|
|
648
669
|
await terminateProcessTree(runtime.child);
|
|
649
670
|
runtime.child = null;
|
|
671
|
+
if (this.activeRuntimeId === runtime.id) {
|
|
672
|
+
this.activeRuntimeId = firstRunningRuntimeId(this.runtimes);
|
|
673
|
+
}
|
|
650
674
|
this.emitChanged();
|
|
651
675
|
throw err;
|
|
652
676
|
}
|
|
@@ -692,7 +716,6 @@ var DesktopRuntimeManager = class extends EventEmitter {
|
|
|
692
716
|
async unregisterProject(projectRoot) {
|
|
693
717
|
const resolved = path2.resolve(projectRoot);
|
|
694
718
|
this.registeredProjects = await removeGlobalProjectManifest(resolved);
|
|
695
|
-
this.recentProjects = this.recentProjects.filter((project) => !samePath(project.root, resolved));
|
|
696
719
|
await this.saveDesktopState();
|
|
697
720
|
this.emitChanged();
|
|
698
721
|
}
|
|
@@ -750,7 +773,7 @@ var DesktopRuntimeManager = class extends EventEmitter {
|
|
|
750
773
|
openProjects
|
|
751
774
|
);
|
|
752
775
|
return {
|
|
753
|
-
recentProjects:
|
|
776
|
+
recentProjects: normalizeProjectEntries(parsed.recentProjects),
|
|
754
777
|
openProjects,
|
|
755
778
|
openProjectSessions,
|
|
756
779
|
activeRuntimeId: normalizeRuntimeId(parsed.activeRuntimeId) ?? null,
|
|
@@ -1011,25 +1034,81 @@ function resolveWebUiEntry() {
|
|
|
1011
1034
|
return path2.resolve(process.env["WRONGSTACK_WEBUI_ENTRY"]);
|
|
1012
1035
|
}
|
|
1013
1036
|
const require2 = createRequire(import.meta.url);
|
|
1037
|
+
try {
|
|
1038
|
+
const serverPkgPath = require2.resolve("@wrongstack/webui-server/package.json");
|
|
1039
|
+
const candidate = path2.join(path2.dirname(serverPkgPath), "dist", "server", "entry.js");
|
|
1040
|
+
if (existsSync(candidate)) return candidate;
|
|
1041
|
+
} catch {
|
|
1042
|
+
}
|
|
1014
1043
|
const serverIndex = require2.resolve("@wrongstack/webui/server");
|
|
1015
1044
|
return path2.join(path2.dirname(serverIndex), "entry.js");
|
|
1016
1045
|
}
|
|
1046
|
+
function resolveWebUiDistDir() {
|
|
1047
|
+
if (process.env["WRONGSTACK_WEBUI_DIST"]) {
|
|
1048
|
+
return path2.resolve(process.env["WRONGSTACK_WEBUI_DIST"]);
|
|
1049
|
+
}
|
|
1050
|
+
const require2 = createRequire(import.meta.url);
|
|
1051
|
+
const serverIndex = require2.resolve("@wrongstack/webui/server");
|
|
1052
|
+
const candidate = path2.resolve(path2.dirname(serverIndex), "..");
|
|
1053
|
+
if (existsSync(candidate)) return candidate;
|
|
1054
|
+
throw new Error(
|
|
1055
|
+
`WebUI frontend assets not found at ${candidate}. Build @wrongstack/webui or set WRONGSTACK_WEBUI_DIST.`
|
|
1056
|
+
);
|
|
1057
|
+
}
|
|
1017
1058
|
async function readGlobalProjectManifest() {
|
|
1018
1059
|
const manifestFile = path2.join(wstackGlobalRoot2(), "projects.json");
|
|
1019
1060
|
try {
|
|
1020
1061
|
const raw = await fs2.readFile(manifestFile, "utf8");
|
|
1021
|
-
|
|
1022
|
-
const projects = Array.isArray(parsed.projects) ? parsed.projects : [];
|
|
1023
|
-
return projects.filter((project) => typeof project?.root === "string" && project.root.trim()).map((project) => ({
|
|
1024
|
-
...project,
|
|
1025
|
-
name: project.name || path2.basename(project.root) || project.root,
|
|
1026
|
-
root: path2.resolve(project.root),
|
|
1027
|
-
slug: project.slug || projectSlug(path2.resolve(project.root))
|
|
1028
|
-
})).sort((a, b) => (b.lastSeen ?? b.createdAt ?? "").localeCompare(a.lastSeen ?? a.createdAt ?? "")).slice(0, 80);
|
|
1062
|
+
return normalizeProjectManifest(JSON.parse(raw));
|
|
1029
1063
|
} catch {
|
|
1030
1064
|
return [];
|
|
1031
1065
|
}
|
|
1032
1066
|
}
|
|
1067
|
+
function normalizeProjectManifest(value) {
|
|
1068
|
+
if (Array.isArray(value)) return normalizeProjectEntries(value).slice(0, 80);
|
|
1069
|
+
if (!value || typeof value !== "object") return [];
|
|
1070
|
+
const manifest = value;
|
|
1071
|
+
const source = Array.isArray(manifest.projects) ? manifest.projects : Array.isArray(manifest.recentProjects) ? manifest.recentProjects : Array.isArray(manifest.recents) ? manifest.recents : [];
|
|
1072
|
+
return normalizeProjectEntries(source).slice(0, 80);
|
|
1073
|
+
}
|
|
1074
|
+
function normalizeProjectEntries(value) {
|
|
1075
|
+
if (!Array.isArray(value)) return [];
|
|
1076
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1077
|
+
const projects = [];
|
|
1078
|
+
for (const item of value) {
|
|
1079
|
+
const project = normalizeProjectEntry(item);
|
|
1080
|
+
if (!project) continue;
|
|
1081
|
+
const key = pathKey(project.root);
|
|
1082
|
+
if (seen.has(key)) continue;
|
|
1083
|
+
seen.add(key);
|
|
1084
|
+
projects.push(project);
|
|
1085
|
+
}
|
|
1086
|
+
return projects.sort(
|
|
1087
|
+
(a, b) => (b.lastSeen ?? b.createdAt ?? "").localeCompare(a.lastSeen ?? a.createdAt ?? "")
|
|
1088
|
+
);
|
|
1089
|
+
}
|
|
1090
|
+
function normalizeProjectEntry(value) {
|
|
1091
|
+
if (!value || typeof value !== "object") return null;
|
|
1092
|
+
const candidate = value;
|
|
1093
|
+
if (typeof candidate.root !== "string" || !candidate.root.trim()) return null;
|
|
1094
|
+
const root = path2.resolve(candidate.root);
|
|
1095
|
+
const name = typeof candidate.name === "string" && candidate.name.trim() ? candidate.name.trim() : path2.basename(root) || root;
|
|
1096
|
+
const entry = {
|
|
1097
|
+
name,
|
|
1098
|
+
root,
|
|
1099
|
+
slug: typeof candidate.slug === "string" && candidate.slug.trim() ? candidate.slug.trim() : projectSlug(root)
|
|
1100
|
+
};
|
|
1101
|
+
if (typeof candidate.lastSeen === "string" && candidate.lastSeen.trim()) {
|
|
1102
|
+
entry.lastSeen = candidate.lastSeen.trim();
|
|
1103
|
+
}
|
|
1104
|
+
if (typeof candidate.createdAt === "string" && candidate.createdAt.trim()) {
|
|
1105
|
+
entry.createdAt = candidate.createdAt.trim();
|
|
1106
|
+
}
|
|
1107
|
+
if (typeof candidate.lastWorkingDir === "string" && candidate.lastWorkingDir.trim()) {
|
|
1108
|
+
entry.lastWorkingDir = path2.resolve(candidate.lastWorkingDir);
|
|
1109
|
+
}
|
|
1110
|
+
return entry;
|
|
1111
|
+
}
|
|
1033
1112
|
async function touchGlobalProjectManifest(entry) {
|
|
1034
1113
|
const manifestFile = path2.join(wstackGlobalRoot2(), "projects.json");
|
|
1035
1114
|
const projects = await readGlobalProjectManifest();
|