diff --git a/apps/desktop/index.html b/apps/desktop/index.html index dfea0c0..56dcbe6 100644 --- a/apps/desktop/index.html +++ b/apps/desktop/index.html @@ -3,6 +3,7 @@ + ClaudePrism | LaTeX Writing Workspace diff --git a/apps/desktop/public/favicon.ico b/apps/desktop/public/favicon.ico new file mode 100644 index 0000000..1e5c3eb Binary files /dev/null and b/apps/desktop/public/favicon.ico differ diff --git a/apps/desktop/public/icon-192.png b/apps/desktop/public/icon-192.png new file mode 100644 index 0000000..8891ff8 Binary files /dev/null and b/apps/desktop/public/icon-192.png differ diff --git a/apps/desktop/src-tauri/Cargo.lock b/apps/desktop/src-tauri/Cargo.lock index 30aea1f..0e1b080 100644 --- a/apps/desktop/src-tauri/Cargo.lock +++ b/apps/desktop/src-tauri/Cargo.lock @@ -317,6 +317,9 @@ dependencies = [ "dotenvy", "git2", "hmac", + "objc2", + "objc2-app-kit", + "objc2-foundation", "reqwest 0.12.28", "serde", "serde_json", diff --git a/apps/desktop/src-tauri/Cargo.toml b/apps/desktop/src-tauri/Cargo.toml index 0621059..fcbda78 100644 --- a/apps/desktop/src-tauri/Cargo.toml +++ b/apps/desktop/src-tauri/Cargo.toml @@ -28,3 +28,8 @@ base64 = "0.22" dotenvy = "0.15" git2 = "0.20" chrono = "0.4" + +[target.'cfg(target_os = "macos")'.dependencies] +objc2 = "0.6" +objc2-app-kit = { version = "0.3", features = ["NSApplication", "NSImage", "NSRunningApplication"] } +objc2-foundation = { version = "0.3", features = ["NSData"] } diff --git a/apps/desktop/src-tauri/icons/128x128.png b/apps/desktop/src-tauri/icons/128x128.png index fc231b2..782b802 100644 Binary files a/apps/desktop/src-tauri/icons/128x128.png and b/apps/desktop/src-tauri/icons/128x128.png differ diff --git a/apps/desktop/src-tauri/icons/128x128@2x.png b/apps/desktop/src-tauri/icons/128x128@2x.png new file mode 100644 index 0000000..6b02b9c Binary files /dev/null and b/apps/desktop/src-tauri/icons/128x128@2x.png differ diff --git a/apps/desktop/src-tauri/icons/256x256.png b/apps/desktop/src-tauri/icons/256x256.png index efc6cad..6b02b9c 100644 Binary files a/apps/desktop/src-tauri/icons/256x256.png and b/apps/desktop/src-tauri/icons/256x256.png differ diff --git a/apps/desktop/src-tauri/icons/32x32.png b/apps/desktop/src-tauri/icons/32x32.png index cf0039d..90a8975 100644 Binary files a/apps/desktop/src-tauri/icons/32x32.png and b/apps/desktop/src-tauri/icons/32x32.png differ diff --git a/apps/desktop/src-tauri/icons/icon.icns b/apps/desktop/src-tauri/icons/icon.icns index 071abd1..5c2bac8 100644 Binary files a/apps/desktop/src-tauri/icons/icon.icns and b/apps/desktop/src-tauri/icons/icon.icns differ diff --git a/apps/desktop/src-tauri/icons/icon.png b/apps/desktop/src-tauri/icons/icon.png index 071abd1..110feda 100644 Binary files a/apps/desktop/src-tauri/icons/icon.png and b/apps/desktop/src-tauri/icons/icon.png differ diff --git a/apps/desktop/src-tauri/src/lib.rs b/apps/desktop/src-tauri/src/lib.rs index c275e71..813730b 100644 --- a/apps/desktop/src-tauri/src/lib.rs +++ b/apps/desktop/src-tauri/src/lib.rs @@ -6,6 +6,26 @@ use std::process::Command; use std::sync::Mutex; use tauri::Manager; +#[cfg(target_os = "macos")] +fn set_macos_app_icon() { + use objc2::{AnyThread, MainThreadMarker}; + use objc2_foundation::NSData; + use objc2_app_kit::{NSApplication, NSImage}; + + let icon_bytes = include_bytes!("../icons/icon.png"); + + // We're in the setup callback which runs on the main thread + if let Some(mtm) = MainThreadMarker::new() { + unsafe { + let data = NSData::with_bytes(icon_bytes); + if let Some(image) = NSImage::initWithData(NSImage::alloc(), &data) { + let app = NSApplication::sharedApplication(mtm); + app.setApplicationIconImage(Some(&image)); + } + } + } +} + struct SidecarState { child: Option, } @@ -49,6 +69,10 @@ pub fn run() { .manage(claude::ClaudeProcessState::default()) .manage(zotero::ZoteroOAuthState::default()) .setup(|app| { + // Set macOS Dock icon (dev mode doesn't use bundle, so set it at runtime) + #[cfg(target_os = "macos")] + set_macos_app_icon(); + // In dev mode, the sidecar is started separately (via pnpm dev:desktop) // In production, start the sidecar from the bundled resources let sidecar_path = if let Ok(path) = std::env::var("SIDECAR_PATH") { diff --git a/apps/desktop/src-tauri/tauri.conf.json b/apps/desktop/src-tauri/tauri.conf.json index 679de66..b285e8e 100644 --- a/apps/desktop/src-tauri/tauri.conf.json +++ b/apps/desktop/src-tauri/tauri.conf.json @@ -25,5 +25,14 @@ "csp": "default-src 'self'; script-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com; connect-src 'self' http://localhost:3001 https://api.zotero.org https://fonts.googleapis.com https://fonts.gstatic.com; img-src 'self' asset: http://asset.localhost data: blob:; worker-src 'self' blob:" } }, + "bundle": { + "icon": [ + "icons/32x32.png", + "icons/128x128.png", + "icons/128x128@2x.png", + "icons/icon.icns", + "icons/icon.png" + ] + }, "plugins": {} } diff --git a/apps/desktop/src/components/project-picker.tsx b/apps/desktop/src/components/project-picker.tsx index 4050d8a..9bfab95 100644 --- a/apps/desktop/src/components/project-picker.tsx +++ b/apps/desktop/src/components/project-picker.tsx @@ -5,7 +5,6 @@ import { FolderPlusIcon, ClockIcon, XIcon, - FileTextIcon, } from "lucide-react"; import { useProjectStore } from "@/stores/project-store"; import { useDocumentStore } from "@/stores/document-store"; @@ -184,7 +183,7 @@ export function ProjectPicker() {
- + ClaudePrism

ClaudePrism

AI-powered LaTeX writing workspace diff --git a/apps/desktop/tsconfig.tsbuildinfo b/apps/desktop/tsconfig.tsbuildinfo new file mode 100644 index 0000000..178bdd1 --- /dev/null +++ b/apps/desktop/tsconfig.tsbuildinfo @@ -0,0 +1 @@ +{"root":["./src/app.tsx","./src/main.tsx","./src/vite-env.d.ts","./src/components/project-picker.tsx","./src/components/assistant-ui/tooltip-icon-button.tsx","./src/components/claude-chat/chat-composer.tsx","./src/components/claude-chat/chat-messages.tsx","./src/components/claude-chat/claude-chat-drawer.tsx","./src/components/claude-chat/markdown-renderer.tsx","./src/components/claude-chat/proposed-changes-panel.tsx","./src/components/claude-chat/tool-widgets.tsx","./src/components/ui/button.tsx","./src/components/ui/context-menu.tsx","./src/components/ui/dialog.tsx","./src/components/ui/dropdown-menu.tsx","./src/components/ui/input.tsx","./src/components/ui/label.tsx","./src/components/ui/select.tsx","./src/components/ui/separator.tsx","./src/components/ui/sheet.tsx","./src/components/ui/skeleton.tsx","./src/components/ui/sonner.tsx","./src/components/ui/textarea.tsx","./src/components/ui/toggle.tsx","./src/components/ui/tooltip.tsx","./src/components/workspace/history-panel.tsx","./src/components/workspace/sidebar.tsx","./src/components/workspace/workspace-layout.tsx","./src/components/workspace/zotero-panel.tsx","./src/components/workspace/editor/editor-toolbar.tsx","./src/components/workspace/editor/image-preview.tsx","./src/components/workspace/editor/latex-editor.tsx","./src/components/workspace/editor/problems-panel.tsx","./src/components/workspace/editor/search-panel.tsx","./src/components/workspace/editor/selection-toolbar.tsx","./src/components/workspace/preview/pdf-preview.tsx","./src/components/workspace/preview/pdf-viewer.tsx","./src/hooks/use-claude-events.ts","./src/hooks/use-keyboard-shortcuts.ts","./src/hooks/use-mobile.ts","./src/lib/latex-compiler.ts","./src/lib/utils.ts","./src/lib/zotero-api.ts","./src/lib/tauri/fs.ts","./src/stores/claude-chat-store.ts","./src/stores/document-store.ts","./src/stores/history-store.ts","./src/stores/project-store.ts","./src/stores/proposed-changes-store.ts","./src/stores/zotero-store.ts"],"version":"5.9.3"} \ No newline at end of file diff --git a/package.json b/package.json index ec583db..b5d87a5 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "scripts": { "dev:web": "pnpm turbo dev --filter=@claude-prism/web --filter=@claude-prism/latex-api", "dev:desktop": "pnpm --filter=@claude-prism/desktop-sidecar dev & pnpm --filter=@claude-prism/desktop tauri dev", + "build:desktop": "pnpm --filter=@claude-prism/desktop tauri build", "lint": "pnpm exec biome check", "lint:fix": "pnpm exec biome check --fix" },