codexdesktop-rebuild-electron

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Codex Desktop Rebuild Skill

Codex Desktop Rebuild Skill

Skill by ara.so — Codex Skills collection.
ara.so提供的Skill — Codex Skills合集。

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
undefined
bash
undefined

Clone the repository

Clone the repository

Install dependencies

Install dependencies

npm install
undefined
npm install
undefined

Development

开发

Running in Development Mode

运行开发模式

bash
npm run dev
This 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.json

Building

构建

Build for Current Platform

为当前平台构建

bash
npm run build
bash
npm run build

Build for Specific Platforms

为特定平台构建

bash
undefined
bash
undefined

macOS

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
undefined
npm run build:linux-x64 npm run build:linux-arm64
undefined

Build All Platforms

为所有平台构建

bash
npm run build:all
This creates distributables in the
out/
directory.
bash
npm run build:all
构建产物将生成在
out/
目录中。

Configuration

配置

Electron Forge Configuration

Electron Forge配置

The
forge.config.js
file controls build settings:
javascript
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.js
文件控制构建设置:
javascript
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
master
or tag creation:
yaml
undefined
项目在推送至
master
分支或创建标签时自动构建:
yaml
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/
undefined
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/
undefined

Troubleshooting

故障排查

Build Fails on Native Dependencies

原生依赖构建失败

bash
undefined
bash
undefined

Rebuild native modules for Electron

为Electron重新构建原生模块

npm install --save-dev @electron/rebuild npx electron-rebuild
undefined
npm install --save-dev @electron/rebuild npx electron-rebuild
undefined

Icon 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
undefined
bash
undefined

Clear Vite cache

清除Vite缓存

rm -rf .vite
rm -rf .vite

Reinstall dependencies

重新安装依赖

rm -rf node_modules package-lock.json npm install
undefined
rm -rf node_modules package-lock.json npm install
undefined

Cross-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();
}