Rename to claudify, add docs and .deb packaging
- Rename package from claude-app to claudify (v0.1.0) - Add README.md with install/usage instructions - Add CLAUDE.md with architecture, build, and known issues - Add .desktop file for application menu integration - Build target set to .deb only - Remove failed CSD button workarounds, document upstream bug - Remove gtk dependency (no longer needed) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
6b2c8ffa08
commit
101c91c4d8
9 changed files with 136 additions and 38 deletions
51
CLAUDE.md
Normal file
51
CLAUDE.md
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
# Claudify
|
||||||
|
|
||||||
|
Native desktop wrapper for [claude.ai](https://claude.ai) built with Tauri v2 and WebKitGTK.
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
- **Tauri v2** with Rust backend, system WebKitGTK webview on Linux
|
||||||
|
- **Direct webview navigation** to `https://claude.ai` (not iframe — claude.ai blocks iframes via CSP)
|
||||||
|
- **No frontend code** — `src/index.html` is a placeholder required by Tauri's build system; the actual UI is claude.ai loaded via `WebviewUrl::External`
|
||||||
|
- All app logic lives in `src-tauri/src/lib.rs` inside the `setup()` closure
|
||||||
|
|
||||||
|
## Key Files
|
||||||
|
|
||||||
|
| File | Purpose |
|
||||||
|
|------|---------|
|
||||||
|
| `src-tauri/src/lib.rs` | All app logic: window, tray, notifications, navigation filter |
|
||||||
|
| `src-tauri/src/main.rs` | Entry point, calls `claudify::run()` |
|
||||||
|
| `src-tauri/tauri.conf.json` | Tauri config: app identity, bundle targets, security |
|
||||||
|
| `src-tauri/capabilities/` | Tauri v2 permission grants for local window and remote claude.ai |
|
||||||
|
| `src-tauri/Cargo.toml` | Rust dependencies |
|
||||||
|
|
||||||
|
## Building
|
||||||
|
|
||||||
|
### Prerequisites
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Debian/Ubuntu system packages
|
||||||
|
sudo apt install libwebkit2gtk-4.1-dev libxdo-dev librsvg2-dev libayatana-appindicator3-dev
|
||||||
|
|
||||||
|
# Tauri CLI
|
||||||
|
cargo install tauri-cli --version "^2.0" --locked
|
||||||
|
```
|
||||||
|
|
||||||
|
### Build
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cargo tauri build # Produces .deb in target/release/bundle/deb/
|
||||||
|
cargo tauri dev # Development mode with hot reload
|
||||||
|
```
|
||||||
|
|
||||||
|
## Known Issues
|
||||||
|
|
||||||
|
- **CSD titlebar buttons non-interactive after hide/show** — Upstream bug in TAO's client-side decoration handling. Titlebar buttons (minimize/maximize/close) become unresponsive after the window is hidden to tray and restored. The close button still works via the tray menu. No known workaround — GTK decoration layout overrides, header bar replacement, resize nudges, and present() were all attempted without success. Tracked at:
|
||||||
|
- https://github.com/tauri-apps/tauri/issues/11856
|
||||||
|
- https://github.com/tauri-apps/tao/issues/1046
|
||||||
|
|
||||||
|
## Conventions
|
||||||
|
|
||||||
|
- Keep all app logic in `lib.rs` — avoid splitting into multiple modules unless complexity demands it
|
||||||
|
- Navigation allowlist in `is_allowed_navigation()` — add new OAuth providers here if needed
|
||||||
|
- Test changes with `cargo tauri dev` before building .deb
|
||||||
56
README.md
Normal file
56
README.md
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
# Claudify
|
||||||
|
|
||||||
|
A native Linux desktop app for [claude.ai](https://claude.ai). Not a browser — a dedicated app that lives in your system tray, persists login sessions, and forwards notifications natively.
|
||||||
|
|
||||||
|
Built with [Tauri v2](https://v2.tauri.app/) and WebKitGTK.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- **System tray** — hide/show from tray icon, left-click toggles visibility
|
||||||
|
- **Session persistence** — cookies and localStorage persist across restarts
|
||||||
|
- **Native notifications** — browser Notification API bridged to desktop notifications
|
||||||
|
- **Navigation guard** — only claude.ai, Anthropic, and OAuth provider domains load in-app; all other links open in your default browser
|
||||||
|
- **Lightweight** — uses system WebKitGTK, no bundled browser engine (~5MB .deb)
|
||||||
|
|
||||||
|
## Install
|
||||||
|
|
||||||
|
### From .deb
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo dpkg -i claudify_0.1.0_amd64.deb
|
||||||
|
```
|
||||||
|
|
||||||
|
Requires `libwebkit2gtk-4.1-0` and `libayatana-appindicator3-1` (pulled automatically via `apt`).
|
||||||
|
|
||||||
|
### From source
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Install system dependencies
|
||||||
|
sudo apt install libwebkit2gtk-4.1-dev libxdo-dev librsvg2-dev libayatana-appindicator3-dev
|
||||||
|
|
||||||
|
# Install Tauri CLI
|
||||||
|
cargo install tauri-cli --version "^2.0" --locked
|
||||||
|
|
||||||
|
# Build
|
||||||
|
cargo tauri build
|
||||||
|
```
|
||||||
|
|
||||||
|
The .deb will be at `src-tauri/target/release/bundle/deb/claudify_0.1.0_amd64.deb`.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
Launch `claudify` from your application menu or terminal.
|
||||||
|
|
||||||
|
- **Close button** hides the window to the system tray (app keeps running)
|
||||||
|
- **Tray icon left-click** toggles window visibility
|
||||||
|
- **Tray icon right-click** shows menu: Hide/Show Claude, Quit
|
||||||
|
- **Ctrl+Plus/Minus** zooms in/out
|
||||||
|
- **External links** open in your default browser
|
||||||
|
|
||||||
|
## Known Issues
|
||||||
|
|
||||||
|
- Window titlebar buttons (minimize/maximize/close) become non-interactive after hiding and restoring the window from the system tray. This is an [upstream bug](https://github.com/tauri-apps/tauri/issues/11856) in Tauri's GTK client-side decoration handling ([tao#1046](https://github.com/tauri-apps/tao/issues/1046)). Use the tray icon to hide/show and quit.
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
MIT
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "claude-app",
|
"name": "claudify",
|
||||||
"version": "1.0.0",
|
"version": "0.1.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"description": "Claude desktop app"
|
"description": "Native desktop wrapper for claude.ai"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
5
src-tauri/Cargo.lock
generated
5
src-tauri/Cargo.lock
generated
|
|
@ -448,10 +448,9 @@ dependencies = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "claude-app"
|
name = "claudify"
|
||||||
version = "1.0.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"gtk",
|
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"tauri",
|
"tauri",
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
[package]
|
[package]
|
||||||
name = "claude-app"
|
name = "claudify"
|
||||||
version = "1.0.0"
|
version = "0.1.0"
|
||||||
description = "Claude desktop app"
|
description = "Native desktop wrapper for claude.ai"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
|
|
@ -15,9 +15,6 @@ serde = { version = "1", features = ["derive"] }
|
||||||
serde_json = "1"
|
serde_json = "1"
|
||||||
url = "2"
|
url = "2"
|
||||||
|
|
||||||
[target.'cfg(target_os = "linux")'.dependencies]
|
|
||||||
gtk = { version = "0.18", features = ["v3_24"] }
|
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["custom-protocol"]
|
default = ["custom-protocol"]
|
||||||
custom-protocol = ["tauri/custom-protocol"]
|
custom-protocol = ["tauri/custom-protocol"]
|
||||||
|
|
|
||||||
9
src-tauri/claudify.desktop
Normal file
9
src-tauri/claudify.desktop
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
[Desktop Entry]
|
||||||
|
Categories=Network;WebBrowser;
|
||||||
|
Comment=Native desktop wrapper for claude.ai
|
||||||
|
Exec=claudify
|
||||||
|
Icon=claudify
|
||||||
|
Keywords=claude;ai;anthropic;chat;
|
||||||
|
Name=Claudify
|
||||||
|
Terminal=false
|
||||||
|
Type=Application
|
||||||
|
|
@ -97,9 +97,9 @@ pub fn run() {
|
||||||
.plugin(tauri_plugin_opener::init())
|
.plugin(tauri_plugin_opener::init())
|
||||||
.invoke_handler(tauri::generate_handler![send_notification])
|
.invoke_handler(tauri::generate_handler![send_notification])
|
||||||
.setup(|app| {
|
.setup(|app| {
|
||||||
// NOTE: Decorations disabled due to upstream bug where CSD titlebar
|
// KNOWN ISSUE: CSD titlebar buttons become non-interactive after
|
||||||
// buttons become non-interactive after hide()/show() on Linux.
|
// hide()/show() on Linux. No workaround found. Use tray icon instead.
|
||||||
// Tracked at: https://github.com/tauri-apps/tauri/issues/11856
|
// https://github.com/tauri-apps/tauri/issues/11856
|
||||||
// https://github.com/tauri-apps/tao/issues/1046
|
// https://github.com/tauri-apps/tao/issues/1046
|
||||||
let webview_window = WebviewWindowBuilder::new(
|
let webview_window = WebviewWindowBuilder::new(
|
||||||
app,
|
app,
|
||||||
|
|
@ -109,7 +109,6 @@ pub fn run() {
|
||||||
.title("Claude")
|
.title("Claude")
|
||||||
.inner_size(1200.0, 800.0)
|
.inner_size(1200.0, 800.0)
|
||||||
.min_inner_size(400.0, 300.0)
|
.min_inner_size(400.0, 300.0)
|
||||||
.resizable(true)
|
|
||||||
// Standard WebKit user agent so claude.ai serves the full experience
|
// Standard WebKit user agent so claude.ai serves the full experience
|
||||||
.user_agent("Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Safari/605.1.15")
|
.user_agent("Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Safari/605.1.15")
|
||||||
.initialization_script(NOTIFICATION_BRIDGE_JS)
|
.initialization_script(NOTIFICATION_BRIDGE_JS)
|
||||||
|
|
@ -124,21 +123,6 @@ pub fn run() {
|
||||||
})
|
})
|
||||||
.build()?;
|
.build()?;
|
||||||
|
|
||||||
// Replace the default GTK header bar with one that has no buttons.
|
|
||||||
// The standard CSD buttons become non-interactive after hide()/show()
|
|
||||||
// due to upstream bug: https://github.com/tauri-apps/tauri/issues/11856
|
|
||||||
#[cfg(target_os = "linux")]
|
|
||||||
{
|
|
||||||
use gtk::prelude::*;
|
|
||||||
if let Ok(gtk_win) = webview_window.gtk_window() {
|
|
||||||
let header = gtk::HeaderBar::new();
|
|
||||||
header.set_show_close_button(false);
|
|
||||||
header.set_title(Some("Claude"));
|
|
||||||
header.show();
|
|
||||||
gtk_win.set_titlebar(Some(&header));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// -- System tray --
|
// -- System tray --
|
||||||
let toggle_item =
|
let toggle_item =
|
||||||
MenuItem::with_id(app, "toggle", "Hide Claude", true, None::<&str>)?;
|
MenuItem::with_id(app, "toggle", "Hide Claude", true, None::<&str>)?;
|
||||||
|
|
|
||||||
|
|
@ -2,5 +2,5 @@
|
||||||
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
|
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
claude_app::run();
|
claudify::run();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"productName": "Claude",
|
"productName": "claudify",
|
||||||
"version": "1.0.0",
|
"version": "0.1.0",
|
||||||
"identifier": "no.naiv.claude-app",
|
"identifier": "no.naiv.claudify",
|
||||||
"build": {
|
"build": {
|
||||||
"frontendDist": "../src"
|
"frontendDist": "../src"
|
||||||
},
|
},
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
},
|
},
|
||||||
"bundle": {
|
"bundle": {
|
||||||
"active": true,
|
"active": true,
|
||||||
"targets": ["deb", "appimage"],
|
"targets": ["deb"],
|
||||||
"icon": [
|
"icon": [
|
||||||
"icons/32x32.png",
|
"icons/32x32.png",
|
||||||
"icons/128x128.png",
|
"icons/128x128.png",
|
||||||
|
|
@ -27,7 +27,9 @@
|
||||||
],
|
],
|
||||||
"linux": {
|
"linux": {
|
||||||
"deb": {
|
"deb": {
|
||||||
"depends": ["libwebkit2gtk-4.1-0", "libayatana-appindicator3-1"]
|
"depends": ["libwebkit2gtk-4.1-0", "libayatana-appindicator3-1"],
|
||||||
|
"section": "web",
|
||||||
|
"desktopTemplate": "claudify.desktop"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue