Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
37 changes: 37 additions & 0 deletions .github/workflows/release-macos.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: Release macOS

on:
workflow_dispatch:

jobs:
build-macos:
runs-on: macos-latest

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: latest

- name: Install dependencies
run: bun install

- name: Rebuild native modules for Electron
run: bun run rebuild

- name: Build and Package (macOS)
run: bun run package --mac
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Upload macOS artifacts
uses: actions/upload-artifact@v4
with:
name: macos-release
path: |
release/*.dmg
release/*.zip
if-no-files-found: error
36 changes: 36 additions & 0 deletions .github/workflows/release-windows.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: Release Windows

on:
workflow_dispatch:

jobs:
build-windows:
runs-on: windows-latest

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: latest

- name: Install dependencies
run: bun install

- name: Rebuild native modules for Electron
run: bun run rebuild

- name: Build and Package (Windows)
run: bun run package --win
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Upload Windows artifacts
uses: actions/upload-artifact@v4
with:
name: windows-release
path: |
release/*.exe
if-no-files-found: error
22 changes: 17 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,23 @@ Download the latest release from the [Releases page](https://github.com/mberrish
1. Download the `.dmg` file (choose `arm64` for Apple Silicon or `x64` for Intel Macs)
2. Open the `.dmg` file
3. Drag clipai to your Applications folder
4. On first launch, you may see "clipai cannot be opened because it is from an unidentified developer"
- Right-click (or Control-click) on clipai in Applications
- Click "Open"
- Click "Open" again in the dialog
- This only needs to be done once
4. **Important:** Remove macOS quarantine (required for unsigned apps)

Open Terminal and run:
```bash
xattr -cr /Applications/clipai.app
```

This is safe - it just removes the quarantine flag that macOS adds to downloaded files. Required because the app is not code-signed.

5. Launch clipai from Applications

**Alternative method if you see "unidentified developer" warning:**
- Right-click (or Control-click) on clipai in Applications
- Click "Open"
- Click "Open" again in the dialog

**Note:** If you see "app is damaged and can't be opened", you must use the Terminal command above.

**Windows Users:**

Expand Down
5 changes: 4 additions & 1 deletion bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,11 @@
"react": "^19.2.1",
"react-dom": "^19.2.1",
"sqlite-vec": "^0.1.7-alpha.2",
"sqlite-vec-darwin-arm64": "^0.1.7-alpha.2",
"vite": "^7.2.7",
"wait-on": "^9.0.3"
},
"optionalDependencies": {
"sqlite-vec-darwin-arm64": "^0.1.7-alpha.2",
"sqlite-vec-windows-x64": "^0.1.7-alpha.2"
}
}
6 changes: 3 additions & 3 deletions src/main/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import Database from "better-sqlite3";
import { app } from "electron";
import { join } from "path";
import log from "electron-log";
import * as sqliteVec from "sqlite-vec";
import type { ClipboardItem } from "../models/ClipboardItem.ts";

export class DatabaseManager {
Expand All @@ -23,13 +22,14 @@ export class DatabaseManager {
log.info("Journal mode set");

log.info("Loading sqlite-vec extension...");
const sqliteVec = require("sqlite-vec");
let loadablePath = sqliteVec.getLoadablePath();

// Fix path for Electron asar packaging
if (loadablePath.includes('.asar')) {
loadablePath = loadablePath.replace(
join('app.asar', 'node_modules'),
join('app.asar.unpacked', 'node_modules')
'app.asar' + (process.platform === 'win32' ? '\\' : '/') + 'node_modules',
'app.asar.unpacked' + (process.platform === 'win32' ? '\\' : '/') + 'node_modules'
);
}

Expand Down
42 changes: 27 additions & 15 deletions src/main/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
Menu,
shell,
globalShortcut,
dialog,
} from "electron";
import { join, dirname } from "path";
import { fileURLToPath } from "url";
Expand Down Expand Up @@ -255,26 +256,37 @@ function registerGlobalShortcut(shortcut: string = "CommandOrControl+Shift+V") {
app.whenReady().then(() => {
log.info("App ready");

configManager = new ConfigManager();
databaseManager = new DatabaseManager();
embeddingService = new EmbeddingService(configManager);
try {
configManager = new ConfigManager();
databaseManager = new DatabaseManager();
embeddingService = new EmbeddingService(configManager);

app.setLoginItemSettings({
openAtLogin: true,
});
app.setLoginItemSettings({
openAtLogin: true,
});

if (app.dock) {
app.dock.hide();
}
if (app.dock) {
app.dock.hide();
}

createWindow();
createTray();
createWindow();
createTray();

const config = configManager.getConfig();
registerGlobalShortcut(config.globalShortcut);
const config = configManager.getConfig();
registerGlobalShortcut(config.globalShortcut);

if (!app.isPackaged) {
win?.show();
if (!app.isPackaged) {
win?.show();
}
} catch (error) {
log.error("Failed to start app:", error);
dialog.showErrorBox(
"Failed to Start",
`The application failed to start:\n\n${
error instanceof Error ? error.message : String(error)
}`
);
app.quit();
}
});

Expand Down