diff --git a/.github/workflows/desktop-build.yml b/.github/workflows/desktop-build.yml new file mode 100644 index 00000000..7a1044ca --- /dev/null +++ b/.github/workflows/desktop-build.yml @@ -0,0 +1,122 @@ +name: Build Desktop App + +on: + push: + tags: + - 'v*' + workflow_dispatch: + inputs: + version: + description: 'Version tag (e.g., v1.0.0)' + required: false + default: 'dev' + +jobs: + build-windows: + runs-on: windows-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + cache: 'npm' + + - name: Install dependencies + run: npm ci + + - name: Build desktop app + run: npm run desktop:build + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Upload Windows artifact + uses: actions/upload-artifact@v4 + with: + name: AeThex-Windows + path: dist/*.exe + if-no-files-found: error + + build-macos: + runs-on: macos-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + cache: 'npm' + + - name: Install dependencies + run: npm ci + + - name: Build desktop app + run: npm run desktop:build + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Upload macOS artifact + uses: actions/upload-artifact@v4 + with: + name: AeThex-macOS + path: dist/*.dmg + if-no-files-found: error + + build-linux: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + cache: 'npm' + + - name: Install dependencies + run: npm ci + + - name: Build desktop app + run: npm run desktop:build + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Upload Linux artifact + uses: actions/upload-artifact@v4 + with: + name: AeThex-Linux + path: | + dist/*.AppImage + dist/*.deb + if-no-files-found: warn + + create-release: + needs: [build-windows, build-macos, build-linux] + runs-on: ubuntu-latest + if: startsWith(github.ref, 'refs/tags/v') + permissions: + contents: write + steps: + - name: Download all artifacts + uses: actions/download-artifact@v4 + with: + path: artifacts + + - name: Create Release + uses: softprops/action-gh-release@v1 + with: + files: | + artifacts/AeThex-Windows/*.exe + artifacts/AeThex-macOS/*.dmg + artifacts/AeThex-Linux/*.AppImage + artifacts/AeThex-Linux/*.deb + draft: false + prerelease: false + generate_release_notes: true + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..b738b7df --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 AeThex + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/build/entitlements.mac.plist b/build/entitlements.mac.plist new file mode 100644 index 00000000..e4204297 --- /dev/null +++ b/build/entitlements.mac.plist @@ -0,0 +1,12 @@ + + + + + com.apple.security.cs.allow-jit + + com.apple.security.network.client + + com.apple.security.files.user-selected.read-write + + + diff --git a/build/icons/README.md b/build/icons/README.md new file mode 100644 index 00000000..ac1909c4 --- /dev/null +++ b/build/icons/README.md @@ -0,0 +1,64 @@ +# App Icons + +This directory contains the application icons for the AeThex Desktop app. + +## Required Files + +| File | Platform | Size | Format | +|------|----------|------|--------| +| `icon.ico` | Windows | 256x256 (multi-size) | ICO | +| `icon.icns` | macOS | 512x512 (multi-size) | ICNS | +| `icon.png` | Linux | 512x512 | PNG | + +## Converting from SVG + +The `icon.svg` file is the source icon. Use one of these methods to generate platform-specific icons: + +### Option 1: Online Converters +1. **ICO**: https://convertio.co/svg-ico/ or https://cloudconvert.com/svg-to-ico +2. **ICNS**: https://cloudconvert.com/svg-to-icns +3. **PNG**: Any image editor or https://svgtopng.com/ + +### Option 2: Command Line (requires ImageMagick) + +```bash +# Install ImageMagick +# macOS: brew install imagemagick +# Ubuntu: sudo apt install imagemagick +# Windows: choco install imagemagick + +# Generate PNG +convert -background none -resize 512x512 icon.svg icon.png + +# Generate ICO (Windows) +convert -background none icon.svg -define icon:auto-resize=256,128,64,48,32,16 icon.ico + +# For ICNS (macOS), use iconutil: +mkdir icon.iconset +sips -z 16 16 icon.png --out icon.iconset/icon_16x16.png +sips -z 32 32 icon.png --out icon.iconset/icon_16x16@2x.png +sips -z 32 32 icon.png --out icon.iconset/icon_32x32.png +sips -z 64 64 icon.png --out icon.iconset/icon_32x32@2x.png +sips -z 128 128 icon.png --out icon.iconset/icon_128x128.png +sips -z 256 256 icon.png --out icon.iconset/icon_128x128@2x.png +sips -z 256 256 icon.png --out icon.iconset/icon_256x256.png +sips -z 512 512 icon.png --out icon.iconset/icon_256x256@2x.png +sips -z 512 512 icon.png --out icon.iconset/icon_512x512.png +sips -z 1024 1024 icon.png --out icon.iconset/icon_512x512@2x.png +iconutil -c icns icon.iconset +rm -rf icon.iconset +``` + +### Option 3: electron-icon-builder (Recommended) + +```bash +npm install -g electron-icon-builder +electron-icon-builder --input=icon.svg --output=./ +``` + +## Replacing the Default Icon + +1. Create your custom icon as a 512x512 or larger PNG/SVG +2. Convert to all three formats using the methods above +3. Replace the files in this directory +4. Rebuild the desktop app: `npm run desktop:build` diff --git a/build/icons/icon.svg b/build/icons/icon.svg new file mode 100644 index 00000000..8683e834 --- /dev/null +++ b/build/icons/icon.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/client/desktop/components/Overlay.tsx b/client/desktop/components/Overlay.tsx index 502241d7..1c65aa31 100644 --- a/client/desktop/components/Overlay.tsx +++ b/client/desktop/components/Overlay.tsx @@ -1,5 +1,4 @@ import { useState } from "react"; -import "../types/preload"; interface OverlayProps { defaultPath?: string; diff --git a/docs/DESKTOP-RELEASE.md b/docs/DESKTOP-RELEASE.md new file mode 100644 index 00000000..60b4fd56 --- /dev/null +++ b/docs/DESKTOP-RELEASE.md @@ -0,0 +1,191 @@ +# AeThex Desktop App - Release Guide + +This guide covers building, signing, and distributing the AeThex Desktop application. + +## Quick Start + +### Prerequisites +- Node.js 20+ +- npm or yarn +- For Windows builds: Windows 10/11 +- For macOS builds: macOS 11+ with Xcode Command Line Tools +- For Linux builds: Ubuntu 20.04+ or equivalent + +### Building Locally + +```bash +# Install dependencies +npm install + +# Build the desktop app (creates installers in ./dist) +npm run desktop:build +``` + +## Automated Builds (GitHub Actions) + +The repository includes a GitHub Actions workflow that automatically builds for all platforms. + +### Triggering a Release + +1. **Tag a release:** + ```bash + git tag v1.0.0 + git push origin v1.0.0 + ``` + +2. **Manual trigger:** + Go to Actions > Build Desktop App > Run workflow + +### Build Artifacts + +After a successful build, artifacts are available: +- **Windows:** `AeThex Desktop Terminal-{version}-win-x64.exe` +- **macOS:** `AeThex Desktop Terminal-{version}-mac-{arch}.dmg` +- **Linux:** `AeThex Desktop Terminal-{version}-x64.AppImage`, `.deb` + +## Code Signing + +### Windows Code Signing + +To sign Windows builds, you need a code signing certificate. + +1. **Get a certificate:** + - Purchase from DigiCert, Sectigo, or other CA + - Or use Azure SignTool with Azure Key Vault + +2. **Add GitHub Secrets:** + ``` + WIN_CSC_LINK: Base64-encoded .pfx certificate + WIN_CSC_KEY_PASSWORD: Certificate password + ``` + +3. **Update electron-builder.yml:** + ```yaml + win: + certificateFile: ${env.WIN_CSC_LINK} + certificatePassword: ${env.WIN_CSC_KEY_PASSWORD} + ``` + +### macOS Code Signing & Notarization + +Apple requires apps to be signed and notarized for distribution. + +1. **Prerequisites:** + - Apple Developer Program membership ($99/year) + - Developer ID Application certificate + - App-specific password for notarization + +2. **Add GitHub Secrets:** + ``` + APPLE_ID: Your Apple ID email + APPLE_APP_SPECIFIC_PASSWORD: Generated from appleid.apple.com + APPLE_TEAM_ID: Your Team ID (from Developer Portal) + CSC_LINK: Base64-encoded .p12 certificate + CSC_KEY_PASSWORD: Certificate password + ``` + +3. **Update GitHub workflow to include notarization:** + ```yaml + - name: Build and notarize + run: npm run desktop:build + env: + APPLE_ID: ${{ secrets.APPLE_ID }} + APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_APP_SPECIFIC_PASSWORD }} + APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }} + CSC_LINK: ${{ secrets.CSC_LINK }} + CSC_KEY_PASSWORD: ${{ secrets.CSC_KEY_PASSWORD }} + ``` + +4. **Update electron-builder.yml:** + ```yaml + mac: + notarize: + teamId: ${env.APPLE_TEAM_ID} + ``` + +## Auto-Updates + +The app is configured to check for updates from GitHub Releases. + +### How it works: +1. User installs the app +2. On launch, app checks GitHub Releases for newer version +3. If found, prompts user to download and install + +### Configuration + +The `publish` section in `electron-builder.yml` configures the update server: + +```yaml +publish: + provider: github + owner: aethex + repo: aethex-desktop + releaseType: release +``` + +### Testing Updates + +1. Build version 1.0.0 and install +2. Push version 1.0.1 to GitHub Releases +3. Launch the app - it should detect and offer the update + +## Customization + +### App Icons + +Replace files in `build/icons/`: +- `icon.ico` - Windows (256x256 multi-size) +- `icon.icns` - macOS (512x512 multi-size) +- `icon.png` - Linux (512x512) + +See `build/icons/README.md` for conversion instructions. + +### Installer Graphics + +**Windows NSIS:** +- `build/installerHeader.bmp` - 150x57 pixels +- `build/installerSidebar.bmp` - 164x314 pixels + +**macOS DMG:** +- `build/icons/icon.icns` - Volume icon +- (Optional) Add `build/dmg-background.png` (540x380 pixels) and update electron-builder.yml with `dmg.background: build/dmg-background.png` + +### License + +Add a `LICENSE` file to the root directory to display during Windows installation. + +## Troubleshooting + +### "App is damaged" on macOS +- App is not signed or notarized +- Run: `xattr -cr /Applications/AeThex\ Desktop\ Terminal.app` + +### Windows SmartScreen warning +- App is not code-signed +- Users can click "More info" > "Run anyway" + +### Linux AppImage won't run +```bash +chmod +x AeThex*.AppImage +./AeThex*.AppImage +``` + +### Build fails with "icon not found" +- Ensure `build/icons/icon.ico` exists for Windows builds +- Ensure `build/icons/icon.icns` exists for macOS builds + +## Version Management + +Update version in `package.json` before creating a release tag: + +```json +{ + "version": "1.0.0" +} +``` + +The version is used in: +- Installer filename +- Auto-update checks +- About dialog diff --git a/electron-builder.yml b/electron-builder.yml index af402476..dd76ca0a 100644 --- a/electron-builder.yml +++ b/electron-builder.yml @@ -1,17 +1,99 @@ appId: com.aethex.desktop productName: AeThex Desktop Terminal +copyright: Copyright (c) 2025 AeThex +artifactName: "${productName}-${version}-${os}-${arch}.${ext}" + +directories: + output: dist + buildResources: build + files: - - "dist/**" + - "dist/desktop/**" - "electron/**" - "services/**" + - "package.json" + +extraResources: + - from: "build/icons" + to: "icons" + asar: true npmRebuild: false buildDependenciesFromSource: false + win: - target: nsis + target: + - target: nsis + arch: + - x64 icon: build/icons/icon.ico + publisherName: AeThex + requestedExecutionLevel: asInvoker + +nsis: + oneClick: false + perMachine: false + allowToChangeInstallationDirectory: true + createDesktopShortcut: true + createStartMenuShortcut: true + shortcutName: AeThex Terminal + menuCategory: Development + installerIcon: build/icons/icon.ico + uninstallerIcon: build/icons/icon.ico + installerHeaderIcon: build/icons/icon.ico + license: LICENSE + deleteAppDataOnUninstall: false + mac: - target: dmg + target: + - target: dmg + arch: + - x64 + - arm64 category: public.app-category.developer-tools icon: build/icons/icon.icns + darkModeSupport: true + hardenedRuntime: true + gatekeeperAssess: false + entitlements: build/entitlements.mac.plist + entitlementsInherit: build/entitlements.mac.plist +dmg: + iconSize: 80 + contents: + - x: 130 + y: 220 + type: file + - x: 410 + y: 220 + type: link + path: /Applications + +linux: + target: + - target: AppImage + arch: + - x64 + - target: deb + arch: + - x64 + icon: build/icons + category: Development + maintainer: AeThex + synopsis: AeThex Desktop Terminal + description: Desktop terminal application for the AeThex development platform + +appImage: + artifactName: "${productName}-${version}-${arch}.${ext}" + +deb: + depends: + - libnotify4 + - libxtst6 + - libnss3 + +publish: + provider: github + owner: aethex + repo: aethex-desktop + releaseType: release diff --git a/tsconfig.json b/tsconfig.json index c6f974fa..de5ece9b 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -37,7 +37,8 @@ "server/**/*", "shared/**/*", "vite.config.ts", - "vite.config.server.ts" + "vite.config.server.ts", + "vite.desktop.config.ts" ], "exclude": ["node_modules", "dist"] }