gaslighting-engine 0.4.2 → 0.4.4

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.
@@ -1,6 +1,6 @@
1
1
  import { app, BrowserWindow, dialog, ipcMain } from "electron";
2
2
  import { spawn } from "node:child_process";
3
- import { existsSync } from "node:fs";
3
+ import { existsSync, mkdirSync, writeFileSync } from "node:fs";
4
4
  import { dirname, join, resolve } from "node:path";
5
5
  import { fileURLToPath } from "node:url";
6
6
  import { platform } from "node:os";
@@ -21,26 +21,80 @@ const packageRoot = resolve(desktopMainDir, "..", "..");
21
21
  let currentRoot = initialRoot;
22
22
  let currentRequest = initialRequest || "Build a practical MVP without shrinking scope.";
23
23
  let mainWindow;
24
+ const desktopUserDataKey = Buffer.from(initialRoot).toString("hex").slice(0, 24);
25
+ const desktopUserDataDir = join(app.getPath("appData"), "Gaslighting Mission Control", desktopUserDataKey);
26
+ app.setName("Gaslighting Mission Control");
27
+ mkdirSync(desktopUserDataDir, { recursive: true });
28
+ app.setPath("userData", desktopUserDataDir);
29
+ app.commandLine.appendSwitch("disable-gpu-shader-disk-cache");
30
+ if (process.env.GASLIGHTING_DESKTOP_DISABLE_GPU !== "0") {
31
+ app.disableHardwareAcceleration();
32
+ }
24
33
  async function createWindow() {
25
34
  mainWindow = new BrowserWindow({
26
35
  width: 1440,
27
36
  height: 940,
28
37
  minWidth: 1120,
29
38
  minHeight: 760,
39
+ show: false,
30
40
  title: "Gaslighting Mission Control",
31
41
  backgroundColor: "#f5f5f3",
32
42
  webPreferences: {
33
- preload: join(desktopMainDir, "preload.js"),
43
+ preload: join(desktopMainDir, "preload.cjs"),
34
44
  contextIsolation: true,
35
45
  nodeIntegration: false,
36
46
  },
37
47
  });
48
+ let hasShown = false;
49
+ const showWindow = () => {
50
+ if (!hasShown && mainWindow && !mainWindow.isDestroyed()) {
51
+ hasShown = true;
52
+ mainWindow.show();
53
+ mainWindow.focus();
54
+ }
55
+ };
56
+ mainWindow.once("ready-to-show", showWindow);
57
+ if (process.env.GASLIGHTING_DESKTOP_DEBUG) {
58
+ mainWindow.webContents.on("console-message", (_event, level, message, line, sourceId) => {
59
+ console.log(`[renderer:${level}] ${message} (${sourceId}:${line})`);
60
+ });
61
+ mainWindow.webContents.on("did-fail-load", (_event, errorCode, errorDescription, validatedUrl) => {
62
+ console.error(`[renderer:load-failed] ${errorCode} ${errorDescription} ${validatedUrl}`);
63
+ });
64
+ mainWindow.webContents.on("render-process-gone", (_event, details) => {
65
+ console.error(`[renderer:gone] ${details.reason}`);
66
+ });
67
+ }
38
68
  if (process.env.GASLIGHTING_DESKTOP_DEV) {
39
69
  await mainWindow.loadURL("http://127.0.0.1:5173");
40
70
  }
41
71
  else {
42
72
  await mainWindow.loadFile(join(packageRoot, "desktop-dist", "index.html"));
43
73
  }
74
+ showWindow();
75
+ if (process.env.GASLIGHTING_DESKTOP_DEBUG) {
76
+ const snapshot = await mainWindow.webContents.executeJavaScript(`
77
+ ({
78
+ href: location.href,
79
+ title: document.title,
80
+ rootExists: Boolean(document.getElementById("root")),
81
+ rootHtml: document.getElementById("root")?.innerHTML.slice(0, 300) ?? null,
82
+ scriptSrc: Array.from(document.scripts).map((script) => script.src),
83
+ gaslightingType: typeof window.gaslighting
84
+ })
85
+ `);
86
+ console.log(`[renderer:snapshot] ${JSON.stringify(snapshot)}`);
87
+ if (process.env.GASLIGHTING_DESKTOP_DEBUG_CAPTURE) {
88
+ try {
89
+ const image = await mainWindow.webContents.capturePage();
90
+ writeFileSync(process.env.GASLIGHTING_DESKTOP_DEBUG_CAPTURE, image.toPNG());
91
+ console.log(`[renderer:capture] ${process.env.GASLIGHTING_DESKTOP_DEBUG_CAPTURE}`);
92
+ }
93
+ catch (error) {
94
+ console.error(`[renderer:capture-failed] ${String(error)}`);
95
+ }
96
+ }
97
+ }
44
98
  }
45
99
  app.whenReady().then(createWindow);
46
100
  app.on("window-all-closed", () => {
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const electron_1 = require("electron");
4
+ electron_1.contextBridge.exposeInMainWorld("gaslighting", {
5
+ selectProject: () => electron_1.ipcRenderer.invoke("project:select"),
6
+ getState: () => electron_1.ipcRenderer.invoke("mission:state"),
7
+ generate: (input) => electron_1.ipcRenderer.invoke("mission:generate", input),
8
+ startAgent: (input) => electron_1.ipcRenderer.invoke("agent:start", input),
9
+ loopStart: (input) => electron_1.ipcRenderer.invoke("loop:start", input),
10
+ loopResume: (input) => electron_1.ipcRenderer.invoke("loop:resume", input),
11
+ loopStop: () => electron_1.ipcRenderer.invoke("loop:stop"),
12
+ mcpSearch: (query) => electron_1.ipcRenderer.invoke("mcp:search", query),
13
+ mcpInstall: (input) => electron_1.ipcRenderer.invoke("mcp:install", input),
14
+ mcpList: () => electron_1.ipcRenderer.invoke("mcp:list"),
15
+ mcpDoctor: () => electron_1.ipcRenderer.invoke("mcp:doctor"),
16
+ skillCreate: (input) => electron_1.ipcRenderer.invoke("skill:create", input),
17
+ skillInstall: (input) => electron_1.ipcRenderer.invoke("skill:install", input),
18
+ skillDoctor: () => electron_1.ipcRenderer.invoke("skill:doctor"),
19
+ onTerminalData: (callback) => {
20
+ const listener = (_event, data) => callback(data);
21
+ electron_1.ipcRenderer.on("terminal:data", listener);
22
+ return () => electron_1.ipcRenderer.removeListener("terminal:data", listener);
23
+ },
24
+ });
package/dist/version.js CHANGED
@@ -1,2 +1,2 @@
1
1
  export const packageName = "gaslighting-engine";
2
- export const packageVersion = "0.4.2";
2
+ export const packageVersion = "0.4.4";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gaslighting-engine",
3
- "version": "0.4.2",
3
+ "version": "0.4.4",
4
4
  "description": "LUDGI Gaslighting-engine: a hardcore project-discipline generator for AI coding agents.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -20,6 +20,7 @@
20
20
  ],
21
21
  "scripts": {
22
22
  "build": "npm run build:cli && npm run build:desktop",
23
+ "prebuild:cli": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\"",
23
24
  "build:cli": "tsc",
24
25
  "build:desktop": "vite build --config desktop/vite.config.ts",
25
26
  "prepack": "npm run build",
@@ -1,22 +0,0 @@
1
- import { contextBridge, ipcRenderer } from "electron";
2
- contextBridge.exposeInMainWorld("gaslighting", {
3
- selectProject: () => ipcRenderer.invoke("project:select"),
4
- getState: () => ipcRenderer.invoke("mission:state"),
5
- generate: (input) => ipcRenderer.invoke("mission:generate", input),
6
- startAgent: (input) => ipcRenderer.invoke("agent:start", input),
7
- loopStart: (input) => ipcRenderer.invoke("loop:start", input),
8
- loopResume: (input) => ipcRenderer.invoke("loop:resume", input),
9
- loopStop: () => ipcRenderer.invoke("loop:stop"),
10
- mcpSearch: (query) => ipcRenderer.invoke("mcp:search", query),
11
- mcpInstall: (input) => ipcRenderer.invoke("mcp:install", input),
12
- mcpList: () => ipcRenderer.invoke("mcp:list"),
13
- mcpDoctor: () => ipcRenderer.invoke("mcp:doctor"),
14
- skillCreate: (input) => ipcRenderer.invoke("skill:create", input),
15
- skillInstall: (input) => ipcRenderer.invoke("skill:install", input),
16
- skillDoctor: () => ipcRenderer.invoke("skill:doctor"),
17
- onTerminalData: (callback) => {
18
- const listener = (_event, data) => callback(data);
19
- ipcRenderer.on("terminal:data", listener);
20
- return () => ipcRenderer.removeListener("terminal:data", listener);
21
- },
22
- });