codexdesktop-rebuild-electron
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseCodex Desktop Rebuild Skill
Codex Desktop Rebuild Skill
Overview
概述
CodexDesktop-Rebuild is a cross-platform Electron application that rebuilds the OpenAI Codex Desktop App for macOS, Windows, and Linux. It uses Electron Forge for building and packaging across multiple architectures (x64, arm64).
CodexDesktop-Rebuild是一款跨平台Electron应用,可为macOS、Windows和Linux系统重构OpenAI Codex桌面应用。它使用Electron Forge在多种架构(x64、arm64)上进行构建和打包。
Installation
安装
bash
undefinedbash
undefinedClone the repository
Clone the repository
git clone https://github.com/Haleclipse/CodexDesktop-Rebuild.git
cd CodexDesktop-Rebuild
git clone https://github.com/Haleclipse/CodexDesktop-Rebuild.git
cd CodexDesktop-Rebuild
Install dependencies
Install dependencies
npm install
undefinednpm install
undefinedDevelopment
开发
Running in Development Mode
运行开发模式
bash
npm run devThis starts the Electron app with hot-reloading enabled via Vite.
bash
npm run dev此命令将启动带有Vite热重载功能的Electron应用。
Project Structure
项目结构
├── src/
│ ├── .vite/build/ # Main process (Electron backend)
│ └── webview/ # Renderer process (Frontend UI)
├── resources/
│ ├── electron.icns # macOS app icon
│ └── notification.wav # Notification sound
├── scripts/
│ └── patch-copyright.js
├── forge.config.js # Electron Forge configuration
└── package.json├── src/
│ ├── .vite/build/ # Main process (Electron backend)
│ └── webview/ # Renderer process (Frontend UI)
├── resources/
│ ├── electron.icns # macOS app icon
│ └── notification.wav # Notification sound
├── scripts/
│ └── patch-copyright.js
├── forge.config.js # Electron Forge configuration
└── package.jsonBuilding
构建
Build for Current Platform
为当前平台构建
bash
npm run buildbash
npm run buildBuild for Specific Platforms
为特定平台构建
bash
undefinedbash
undefinedmacOS
macOS
npm run build:mac-x64
npm run build:mac-arm64
npm run build:mac-x64
npm run build:mac-arm64
Windows
Windows
npm run build:win-x64
npm run build:win-x64
Linux
Linux
npm run build:linux-x64
npm run build:linux-arm64
undefinednpm run build:linux-x64
npm run build:linux-arm64
undefinedBuild All Platforms
为所有平台构建
bash
npm run build:allThis creates distributables in the directory.
out/bash
npm run build:all构建产物将生成在目录中。
out/Configuration
配置
Electron Forge Configuration
Electron Forge配置
The file controls build settings:
forge.config.jsjavascript
module.exports = {
packagerConfig: {
name: 'Codex Desktop',
icon: './resources/electron',
asar: true,
executableName: 'codex-desktop',
appBundleId: 'com.cometix.codex',
},
makers: [
{
name: '@electron-forge/maker-zip',
platforms: ['darwin', 'linux', 'win32']
},
{
name: '@electron-forge/maker-dmg',
config: {
name: 'Codex Desktop',
icon: './resources/electron.icns'
}
},
{
name: '@electron-forge/maker-deb',
config: {
options: {
maintainer: 'Cometix Space',
homepage: 'https://github.com/Haleclipse/CodexDesktop-Rebuild'
}
}
}
],
plugins: [
{
name: '@electron-forge/plugin-vite',
config: {
build: [
{
entry: 'src/.vite/build/main.js',
config: 'vite.main.config.js'
}
],
renderer: [
{
name: 'main_window',
config: 'vite.renderer.config.js'
}
]
}
}
]
};forge.config.jsjavascript
module.exports = {
packagerConfig: {
name: 'Codex Desktop',
icon: './resources/electron',
asar: true,
executableName: 'codex-desktop',
appBundleId: 'com.cometix.codex',
},
makers: [
{
name: '@electron-forge/maker-zip',
platforms: ['darwin', 'linux', 'win32']
},
{
name: '@electron-forge/maker-dmg',
config: {
name: 'Codex Desktop',
icon: './resources/electron.icns'
}
},
{
name: '@electron-forge/maker-deb',
config: {
options: {
maintainer: 'Cometix Space',
homepage: 'https://github.com/Haleclipse/CodexDesktop-Rebuild'
}
}
}
],
plugins: [
{
name: '@electron-forge/plugin-vite',
config: {
build: [
{
entry: 'src/.vite/build/main.js',
config: 'vite.main.config.js'
}
],
renderer: [
{
name: 'main_window',
config: 'vite.renderer.config.js'
}
]
}
}
]
};Package.json Scripts
Package.json脚本
javascript
{
"scripts": {
"dev": "electron-forge start",
"build": "electron-forge make",
"build:mac-x64": "electron-forge make --platform=darwin --arch=x64",
"build:mac-arm64": "electron-forge make --platform=darwin --arch=arm64",
"build:win-x64": "electron-forge make --platform=win32 --arch=x64",
"build:linux-x64": "electron-forge make --platform=linux --arch=x64",
"build:linux-arm64": "electron-forge make --platform=linux --arch=arm64",
"build:all": "npm run build:mac-x64 && npm run build:mac-arm64 && npm run build:win-x64 && npm run build:linux-x64 && npm run build:linux-arm64"
}
}javascript
{
"scripts": {
"dev": "electron-forge start",
"build": "electron-forge make",
"build:mac-x64": "electron-forge make --platform=darwin --arch=x64",
"build:mac-arm64": "electron-forge make --platform=darwin --arch=arm64",
"build:win-x64": "electron-forge make --platform=win32 --arch=x64",
"build:linux-x64": "electron-forge make --platform=linux --arch=x64",
"build:linux-arm64": "electron-forge make --platform=linux --arch=arm64",
"build:all": "npm run build:mac-x64 && npm run build:mac-arm64 && npm run build:win-x64 && npm run build:linux-x64 && npm run build:linux-arm64"
}
}Main Process Development
主进程开发
Basic Electron Main Process Structure
基础Electron主进程结构
javascript
// src/.vite/build/main.js
const { app, BrowserWindow } = require('electron');
const path = require('path');
let mainWindow;
function createWindow() {
mainWindow = new BrowserWindow({
width: 1200,
height: 800,
webPreferences: {
nodeIntegration: false,
contextIsolation: true,
preload: path.join(__dirname, 'preload.js')
},
icon: path.join(__dirname, '../../resources/electron.icns')
});
// Load the renderer
if (process.env.VITE_DEV_SERVER_URL) {
mainWindow.loadURL(process.env.VITE_DEV_SERVER_URL);
} else {
mainWindow.loadFile(path.join(__dirname, '../renderer/index.html'));
}
}
app.whenReady().then(createWindow);
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit();
}
});
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow();
}
});javascript
// src/.vite/build/main.js
const { app, BrowserWindow } = require('electron');
const path = require('path');
let mainWindow;
function createWindow() {
mainWindow = new BrowserWindow({
width: 1200,
height: 800,
webPreferences: {
nodeIntegration: false,
contextIsolation: true,
preload: path.join(__dirname, 'preload.js')
},
icon: path.join(__dirname, '../../resources/electron.icns')
});
// Load the renderer
if (process.env.VITE_DEV_SERVER_URL) {
mainWindow.loadURL(process.env.VITE_DEV_SERVER_URL);
} else {
mainWindow.loadFile(path.join(__dirname, '../renderer/index.html'));
}
}
app.whenReady().then(createWindow);
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit();
}
});
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow();
}
});IPC Communication
IPC通信
javascript
// Main process
const { ipcMain } = require('electron');
ipcMain.handle('execute-codex-command', async (event, command) => {
// Execute codex CLI command
const result = await executeCommand(command);
return result;
});
// Renderer process
const { ipcRenderer } = require('electron');
async function runCodex(command) {
const result = await ipcRenderer.invoke('execute-codex-command', command);
return result;
}javascript
// Main process
const { ipcMain } = require('electron');
ipcMain.handle('execute-codex-command', async (event, command) => {
// Execute codex CLI command
const result = await executeCommand(command);
return result;
});
// Renderer process
const { ipcRenderer } = require('electron');
async function runCodex(command) {
const result = await ipcRenderer.invoke('execute-codex-command', command);
return result;
}Renderer Development
渲染进程开发
Vite Configuration for Renderer
渲染进程Vite配置
javascript
// vite.renderer.config.js
import { defineConfig } from 'vite';
import path from 'path';
export default defineConfig({
root: path.join(__dirname, 'src/webview'),
build: {
outDir: path.join(__dirname, '.vite/renderer'),
emptyOutDir: true
}
});javascript
// vite.renderer.config.js
import { defineConfig } from 'vite';
import path from 'path';
export default defineConfig({
root: path.join(__dirname, 'src/webview'),
build: {
outDir: path.join(__dirname, '.vite/renderer'),
emptyOutDir: true
}
});Frontend Integration
前端集成
javascript
// src/webview/main.js
import './style.css';
// Initialize the app
document.addEventListener('DOMContentLoaded', () => {
const app = document.getElementById('app');
app.innerHTML = `
<div class="codex-interface">
<h1>Codex Desktop</h1>
<textarea id="prompt" placeholder="Enter your prompt..."></textarea>
<button id="execute">Execute</button>
<pre id="output"></pre>
</div>
`;
document.getElementById('execute').addEventListener('click', async () => {
const prompt = document.getElementById('prompt').value;
const output = await window.codex.execute(prompt);
document.getElementById('output').textContent = output;
});
});javascript
// src/webview/main.js
import './style.css';
// Initialize the app
document.addEventListener('DOMContentLoaded', () => {
const app = document.getElementById('app');
app.innerHTML = `
<div class="codex-interface">
<h1>Codex Desktop</h1>
<textarea id="prompt" placeholder="Enter your prompt..."></textarea>
<button id="execute">Execute</button>
<pre id="output"></pre>
</div>
`;
document.getElementById('execute').addEventListener('click', async () => {
const prompt = document.getElementById('prompt').value;
const output = await window.codex.execute(prompt);
document.getElementById('output').textContent = output;
});
});CI/CD with GitHub Actions
GitHub Actions持续集成/持续部署
The project automatically builds on push to or tag creation:
masteryaml
undefined项目在推送至分支或创建标签时自动构建:
masteryaml
undefined.github/workflows/build.yml
.github/workflows/build.yml
name: Build
on:
push:
branches: [master]
tags: ['v*']
jobs:
build:
strategy:
matrix:
os: [macos-latest, windows-latest, ubuntu-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 18
- run: npm install
- run: npm run build
- uses: actions/upload-artifact@v3
with:
name: dist-${{ matrix.os }}
path: out/
undefinedname: Build
on:
push:
branches: [master]
tags: ['v*']
jobs:
build:
strategy:
matrix:
os: [macos-latest, windows-latest, ubuntu-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 18
- run: npm install
- run: npm run build
- uses: actions/upload-artifact@v3
with:
name: dist-${{ matrix.os }}
path: out/
undefinedTroubleshooting
故障排查
Build Fails on Native Dependencies
原生依赖构建失败
bash
undefinedbash
undefinedRebuild native modules for Electron
为Electron重新构建原生模块
npm install --save-dev @electron/rebuild
npx electron-rebuild
undefinednpm install --save-dev @electron/rebuild
npx electron-rebuild
undefinedIcon Not Showing
图标不显示
Ensure icon files exist:
- macOS:
resources/electron.icns - Windows:
resources/electron.ico - Linux:
resources/electron.png
确保图标文件存在:
- macOS:
resources/electron.icns - Windows:
resources/electron.ico - Linux:
resources/electron.png
Code Signing Issues on macOS
macOS代码签名问题
javascript
// forge.config.js
module.exports = {
packagerConfig: {
osxSign: {
identity: process.env.APPLE_IDENTITY,
'hardened-runtime': true,
entitlements: 'entitlements.plist',
'entitlements-inherit': 'entitlements.plist',
'signature-flags': 'library'
},
osxNotarize: {
appleId: process.env.APPLE_ID,
appleIdPassword: process.env.APPLE_PASSWORD,
teamId: process.env.APPLE_TEAM_ID
}
}
};javascript
// forge.config.js
module.exports = {
packagerConfig: {
osxSign: {
identity: process.env.APPLE_IDENTITY,
'hardened-runtime': true,
entitlements: 'entitlements.plist',
'entitlements-inherit': 'entitlements.plist',
'signature-flags': 'library'
},
osxNotarize: {
appleId: process.env.APPLE_ID,
appleIdPassword: process.env.APPLE_PASSWORD,
teamId: process.env.APPLE_TEAM_ID
}
}
};Development Server Not Starting
开发服务器无法启动
bash
undefinedbash
undefinedClear Vite cache
清除Vite缓存
rm -rf .vite
rm -rf .vite
Reinstall dependencies
重新安装依赖
rm -rf node_modules package-lock.json
npm install
undefinedrm -rf node_modules package-lock.json
npm install
undefinedCross-Platform Build Issues
跨平台构建问题
Use Docker for consistent builds:
bash
docker run --rm -v $(pwd):/project electronuserland/builder:wine \
/bin/bash -c "cd /project && npm install && npm run build:win-x64"使用Docker实现一致构建:
bash
docker run --rm -v $(pwd):/project electronuserland/builder:wine \
/bin/bash -c "cd /project && npm install && npm run build:win-x64"Common Patterns
常见模式
Adding Custom Menu
添加自定义菜单
javascript
const { Menu } = require('electron');
const template = [
{
label: 'File',
submenu: [
{ role: 'quit' }
]
},
{
label: 'Edit',
submenu: [
{ role: 'undo' },
{ role: 'redo' },
{ type: 'separator' },
{ role: 'cut' },
{ role: 'copy' },
{ role: 'paste' }
]
}
];
const menu = Menu.buildFromTemplate(template);
Menu.setApplicationMenu(menu);javascript
const { Menu } = require('electron');
const template = [
{
label: 'File',
submenu: [
{ role: 'quit' }
]
},
{
label: 'Edit',
submenu: [
{ role: 'undo' },
{ role: 'redo' },
{ type: 'separator' },
{ role: 'cut' },
{ role: 'copy' },
{ role: 'paste' }
]
}
];
const menu = Menu.buildFromTemplate(template);
Menu.setApplicationMenu(menu);Auto-Update Configuration
自动更新配置
javascript
const { autoUpdater } = require('electron-updater');
autoUpdater.checkForUpdatesAndNotify();
autoUpdater.on('update-available', () => {
// Notify user
});
autoUpdater.on('update-downloaded', () => {
// Prompt to restart
autoUpdater.quitAndInstall();
});javascript
const { autoUpdater } = require('electron-updater');
autoUpdater.checkForUpdatesAndNotify();
autoUpdater.on('update-available', () => {
// Notify user
});
autoUpdater.on('update-downloaded', () => {
// Prompt to restart
autoUpdater.quitAndInstall();
});Environment-Specific Configuration
环境特定配置
javascript
// Check environment
const isDev = process.env.NODE_ENV === 'development';
if (isDev) {
// Enable DevTools
mainWindow.webContents.openDevTools();
}javascript
// Check environment
const isDev = process.env.NODE_ENV === 'development';
if (isDev) {
// Enable DevTools
mainWindow.webContents.openDevTools();
}