Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 74 additions & 0 deletions .github/workflows/build-linux.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
name: Build - Linux

on:
push:
tags:
- 'v*'
workflow_dispatch:

jobs:
build-linux:
name: Build Linux (Ubuntu)
runs-on: ubuntu-latest

Comment thread
coderabbitai[bot] marked this conversation as resolved.
strategy:
matrix:
arch: [x64]

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: Install Linux build dependencies
run: |
sudo apt-get update
sudo apt-get install -y libarchive-tools

- name: Build Electron app for Linux
run: npm run electron:build:linux
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Verify build artifacts
run: |
echo "=== Checking deb ==="
DEB=$(ls release/*.deb 2>/dev/null)
if [ -z "$DEB" ]; then echo "ERROR: No .deb found"; exit 1; fi
DEB_SIZE=$(stat --format=%s "$DEB")
echo "deb: $DEB ($DEB_SIZE bytes)"
if [ "$DEB_SIZE" -lt 52428800 ]; then echo "ERROR: deb too small (<50MB)"; exit 1; fi
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated

echo "=== Checking deb metadata ==="
dpkg-deb --info "$DEB"

echo "=== Checking deb is a valid ELF package ==="
MAIN_BIN=$(dpkg-deb --contents "$DEB" | grep -m1 "opt/Dorothy/dorothy$" | awk '{print $NF}')
if [ -z "$MAIN_BIN" ]; then echo "ERROR: dorothy binary not found in deb"; exit 1; fi
echo "Main binary found: $MAIN_BIN"

echo "=== All checks passed ==="

- name: Upload deb artifact
uses: actions/upload-artifact@v4
with:
name: Dorothy-Linux-deb-${{ matrix.arch }}
path: release/*.deb
if-no-files-found: warn

- name: Upload to GitHub Release
if: startsWith(github.ref, 'refs/tags/v')
uses: softprops/action-gh-release@v2
with:
files: |
release/*.deb
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
12 changes: 12 additions & 0 deletions electron/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,18 @@ import * as fs from 'fs';
import * as path from 'path';
import * as os from 'os';

if (process.platform === 'linux') {
// Ignore EPIPE errors on stdout/stderr (happens when launched from desktop entries)
process.stdout?.on?.('error', (err: NodeJS.ErrnoException) => {
if (err.code === 'EPIPE') return;
throw err;
});
process.stderr?.on?.('error', (err: NodeJS.ErrnoException) => {
if (err.code === 'EPIPE') return;
throw err;
});
}

// Types
import type { AppSettings, AgentStatus } from './types';

Expand Down
34 changes: 33 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
{
"name": "dorothy",
"version": "1.2.5",
"description": "Agent Control Center - manage AI coding agents from a single desktop app",
"author": "Charlie85270",
"private": true,
"main": "electron/dist/main.js",
"scripts": {
Expand All @@ -15,7 +17,9 @@
"electron:dev": "concurrently \"npm run dev\" \"npm run electron:start\"",
"electron:start": "wait-on http://localhost:3000 && tsc -p electron/tsconfig.json && NODE_ENV=development electron .",
"electron:build": "bash -c 'set -e; mv src/app/api src/app/_api_backup; mv src/app/icon.tsx src/app/_icon_backup.tsx 2>/dev/null || true; trap \"mv src/app/_api_backup src/app/api 2>/dev/null; mv src/app/_icon_backup.tsx src/app/icon.tsx 2>/dev/null\" EXIT; ELECTRON_BUILD=1 next build; tsc -p electron/tsconfig.json; cd mcp-orchestrator && npm install && npm run build && cd ..; cd mcp-telegram && npm install && npm run build && cd ..; cd mcp-kanban && npm install && npm run build && cd ..; cd mcp-vault && npm install && npm run build && cd ..; cd mcp-socialdata && npm install && npm run build && cd ..; cd mcp-x && npm install && npm run build && cd ..; cd mcp-world && npm install && npm run build && cd ..; electron-builder --mac'",
"electron:pack": "tsc -p electron/tsconfig.json && cd mcp-orchestrator && npm install && npm run build && cd .. && cd mcp-telegram && npm install && npm run build && cd .. && cd mcp-kanban && npm install && npm run build && cd .. && cd mcp-vault && npm install && npm run build && cd .. && cd mcp-socialdata && npm install && npm run build && cd .. && cd mcp-x && npm install && npm run build && cd .. && cd mcp-world && npm install && npm run build && cd .. && electron-builder --dir --mac"
"electron:build:linux": "bash -c 'set -e; mv src/app/api src/app/_api_backup; mv src/app/icon.tsx src/app/_icon_backup.tsx 2>/dev/null || true; trap \"mv src/app/_api_backup src/app/api 2>/dev/null; mv src/app/_icon_backup.tsx src/app/icon.tsx 2>/dev/null\" EXIT; ELECTRON_BUILD=1 next build; tsc -p electron/tsconfig.json; cd mcp-orchestrator && npm install && npm run build && cd ..; cd mcp-telegram && npm install && npm run build && cd ..; cd mcp-kanban && npm install && npm run build && cd ..; cd mcp-vault && npm install && npm run build && cd ..; cd mcp-socialdata && npm install && npm run build && cd ..; cd mcp-x && npm install && npm run build && cd ..; cd mcp-world && npm install && npm run build && cd ..; electron-builder --linux'",
"electron:pack": "tsc -p electron/tsconfig.json && cd mcp-orchestrator && npm install && npm run build && cd .. && cd mcp-telegram && npm install && npm run build && cd .. && cd mcp-kanban && npm install && npm run build && cd .. && cd mcp-vault && npm install && npm run build && cd .. && cd mcp-socialdata && npm install && npm run build && cd .. && cd mcp-x && npm install && npm run build && cd .. && cd mcp-world && npm install && npm run build && cd .. && electron-builder --dir --mac",
"electron:pack:linux": "tsc -p electron/tsconfig.json && cd mcp-orchestrator && npm install && npm run build && cd .. && cd mcp-telegram && npm install && npm run build && cd .. && cd mcp-kanban && npm install && npm run build && cd .. && cd mcp-vault && npm install && npm run build && cd .. && cd mcp-socialdata && npm install && npm run build && cd .. && cd mcp-x && npm install && npm run build && cd .. && cd mcp-world && npm install && npm run build && cd .. && electron-builder --dir --linux"
},
"build": {
"appId": "io.dorothy.app",
Expand Down Expand Up @@ -117,6 +121,34 @@
"zip"
]
},
"linux": {
"category": "Development",
"icon": "public/icon-512.png",
"target": [
"deb"
],
"desktop": {
"StartupNotify": "true",
"Categories": "Development;IDE;"
},
"executableArgs": ["--no-sandbox"]
},
Comment thread
coderabbitai[bot] marked this conversation as resolved.
"deb": {
"maintainer": "Charlie85270",
"fpm": ["--after-install", "build/linux/after-install.sh"],
"depends": [
"libgtk-3-0",
"libnotify4",
"libnss3",
"libxss1",
"libxtst6",
"xdg-utils",
"libatspi2.0-0",
"libuuid1",
"libsecret-1-0"
],
Comment thread
coderabbitai[bot] marked this conversation as resolved.
"artifactName": "Dorothy-${version}-${arch}.deb"
},
"dmg": {
"title": "Dorothy",
"contents": [
Expand Down