Monorepo for Aesthetic.Computer
aesthetic.computer
1/**
2 * Aesthetic Computer - Preload Script
3 * Exposes safe APIs to renderer process
4 *
5 * Note: This script is used for production/development windows (contextIsolation=true)
6 * Shell windows use nodeIntegration=true and don't need this bridge.
7 */
8
9const { contextBridge, ipcRenderer } = require('electron');
10
11// Only use contextBridge when contextIsolation is enabled
12// (Shell windows have nodeIntegration=true and contextIsolation=false)
13try {
14 contextBridge.exposeInMainWorld('ac', {
15 // Mode management
16 getMode: () => ipcRenderer.invoke('get-mode'),
17 getUrls: () => ipcRenderer.invoke('get-urls'),
18 switchMode: (mode) => ipcRenderer.invoke('switch-mode', mode),
19
20 // Docker/Container management
21 checkDocker: () => ipcRenderer.invoke('check-docker'),
22 checkContainer: () => ipcRenderer.invoke('check-container'),
23 startContainer: () => ipcRenderer.invoke('start-container'),
24 openShell: () => ipcRenderer.invoke('open-shell'),
25
26 // Navigation from main process
27 onNavigate: (callback) => {
28 ipcRenderer.on('navigate', (event, url) => callback(url));
29 },
30
31 // Menu commands
32 onGoBack: (callback) => {
33 ipcRenderer.on('go-back', () => callback());
34 },
35 onGoForward: (callback) => {
36 ipcRenderer.on('go-forward', () => callback());
37 },
38 onFocusLocation: (callback) => {
39 ipcRenderer.on('focus-location', () => callback());
40 },
41 onToggleDevtools: (callback) => {
42 ipcRenderer.on('toggle-devtools', () => callback());
43 },
44
45 // Status updates
46 onStatus: (callback) => {
47 ipcRenderer.on('status', (event, message) => callback(message));
48 },
49
50 // Window controls
51 moveWindow: (x, y) => ipcRenderer.send('move-window', { x, y }),
52 openWindow: (url) => ipcRenderer.invoke('ac-open-window', { url }),
53 closeWindow: () => ipcRenderer.invoke('ac-close-window'),
54 openExternalUrl: (url) => ipcRenderer.invoke('open-external-url', url),
55
56 // Open DevTools docked at bottom (toggled via ~ command in prompt)
57 openDevTools: () => ipcRenderer.send('open-devtools'),
58
59 // App info (for desktop.mjs)
60 getAppInfo: () => ipcRenderer.invoke('get-app-info'),
61
62 // Platform info
63 platform: process.platform,
64 });
65
66 contextBridge.exposeInMainWorld('electronAPI', {
67 // Docker checks
68 checkDocker: () => ipcRenderer.invoke('check-docker'),
69 checkContainer: () => ipcRenderer.invoke('check-container'),
70 startContainer: () => ipcRenderer.invoke('start-container'),
71
72 // PTY management
73 connectPty: () => ipcRenderer.invoke('connect-pty'),
74 sendToPty: (data) => ipcRenderer.send('pty-input', data),
75 resizePty: (cols, rows) => ipcRenderer.send('pty-resize', cols, rows),
76
77 // PTY events
78 onPtyData: (callback) => {
79 ipcRenderer.on('pty-data', (event, data) => callback(data));
80 },
81 onPtyExit: (callback) => {
82 ipcRenderer.on('pty-exit', (event, code) => callback(code));
83 },
84 });
85} catch (e) {
86 // contextBridge not available (shell window with nodeIntegration)
87 // That's fine - shell.html uses require() directly
88 console.log('[preload] contextBridge not available, using nodeIntegration mode');
89}