{"id":49606218,"url":"https://github.com/pekinlcc/salmonapp","last_synced_at":"2026-05-17T09:02:35.636Z","repository":{"id":355423053,"uuid":"1226127913","full_name":"pekinlcc/SalmonApp","owner":"pekinlcc","description":"Unofficial Linux + macOS desktop client wrapping the Claude Code CLI and Codex CLI. Three-pane chat UI, your existing CLI login, no API key required.","archived":false,"fork":false,"pushed_at":"2026-05-11T05:01:27.000Z","size":1858,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-11T08:37:55.155Z","etag":null,"topics":["ai-coding","anthropic","claude-code","codex-cli","desktop-client","linux","macos","openai","tauri"],"latest_commit_sha":null,"homepage":"https://pekinlcc.github.io/SalmonApp/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pekinlcc.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-01T02:19:51.000Z","updated_at":"2026-05-11T05:01:29.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/pekinlcc/SalmonApp","commit_stats":null,"previous_names":["pekinlcc/salmonapp"],"tags_count":78,"template":false,"template_full_name":null,"purl":"pkg:github/pekinlcc/SalmonApp","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pekinlcc%2FSalmonApp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pekinlcc%2FSalmonApp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pekinlcc%2FSalmonApp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pekinlcc%2FSalmonApp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pekinlcc","download_url":"https://codeload.github.com/pekinlcc/SalmonApp/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pekinlcc%2FSalmonApp/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33017715,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-13T13:14:54.681Z","status":"online","status_checked_at":"2026-05-14T02:00:06.663Z","response_time":57,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai-coding","anthropic","claude-code","codex-cli","desktop-client","linux","macos","openai","tauri"],"created_at":"2026-05-04T13:06:11.671Z","updated_at":"2026-05-14T09:05:48.545Z","avatar_url":"https://github.com/pekinlcc.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# SalmonApp\n\n\u003e A three-pane desktop client for the **Claude Code CLI** and **Codex CLI** — Linux + macOS.\n\u003e\n\u003e SalmonApp wraps a locally-logged-in `claude` or `codex` and reuses its credentials — no second account to manage. See [Releases](https://github.com/pekinlcc/SalmonApp/releases) for the changelog.\n\u003e\n\u003e Note: deliberately named **SalmonApp** (one word) to avoid colliding with the bioinformatics `salmon` package on Linux distros.\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"salmon/src-tauri/icons/icon.png\" alt=\"SalmonApp icon\" width=\"128\" /\u003e\n\u003c/p\u003e\n\n[中文 PRD](PRD.md) · [Mockup](mockup.html) · [Icon candidates](icon-candidates.html)\n\n---\n\n## Why\n\nIf you already use `claude` (Claude Code) or `codex` (OpenAI Codex CLI) in a terminal, you've hit the same speed bumps:\n\n- Long transcripts are painful to read in a scroll-back buffer\n- Multiple projects all share one shell history\n- Tool-call diffs need a second `cat`/`ls` to inspect\n- Switching between Claude and Codex means switching terminals\n\nSalmonApp wraps the CLI you're already running and gives it a chat UI:\n\n| Pane | What it shows |\n|---|---|\n| **Left** | Topic list, grouped by recency, with engine + workdir badges |\n| **Middle** | Markdown-rendered chat, tool-call cards, permission prompts, code blocks with `highlight.js` |\n| **Right** | Tabs: Files (workdir tree) · Diff · Preview (MD / HTML / pptx / docx / xlsx) · Logs · ⛶ fullscreen toggle |\n\nA **Topic** is mentally a *terminal tab pinned to a workdir* — open many at once, each with its own engine + persistent CLI session. Closing a Topic SIGTERMs its child PTY but keeps the CLI's transcript in `~/.claude/...` or `~/.codex/...` exactly as the CLI itself stores it. Re-opening lazily re-spawns via `claude --resume \u003csession-id\u003e` (or the Codex equivalent). Detach / attach, basically.\n\nSalmonApp **does not** speak to Anthropic or OpenAI directly. It owns no API key. Credentials and session storage live entirely with the CLI.\n\n## Install\n\nGrab the latest from [Releases](https://github.com/pekinlcc/SalmonApp/releases/latest).\n\n### Ubuntu / Debian\n\n```bash\n# .deb — installs to /usr/bin/salmonapp and adds an application entry\nsudo apt install ./SalmonApp_*.deb\n\n# OR AppImage — no install, double-click or chmod +x then run\nchmod +x SalmonApp_*.AppImage\n./SalmonApp_*.AppImage\n```\n\nThe `.deb` declares its WebKit / GTK runtime deps; `apt` resolves them. The AppImage bundles them.\n\n### macOS (Apple Silicon + Intel, universal `.dmg`)\n\n\u003e ⚠ The Mac build is **not notarized** — this project has no Apple Developer account. The `.dmg` is signed ad-hoc, which is enough to launch but not enough to satisfy Gatekeeper out of the box. You'll see \"Apple could not verify SalmonApp is free of malware\" on first launch.\n\n```bash\n# 1. Open the .dmg, drag SalmonApp.app into /Applications\n# 2. Tell Gatekeeper to trust it. EITHER:\n\n# (a) Right-click SalmonApp.app → Open → click \"Open\" in the dialog. macOS\n#     remembers the choice; subsequent launches are normal.\n\n# OR (b) clear the quarantine bit from a terminal:\nxattr -dr com.apple.quarantine /Applications/SalmonApp.app\n```\n\n`(b)` is the smoother path if you trust this repo's release pipeline. The `.dmg` is universal (`arm64` + `x86_64`), so the same file works on M-series and Intel Macs.\n\nSalmonApp needs `claude` or `codex` discoverable on PATH. On macOS, GUI apps don't inherit your shell's PATH — SalmonApp walks `$SHELL -ilc 'echo $PATH'` at startup to import it, plus probes `/opt/homebrew/bin`, `/usr/local/bin`, `~/.npm-global/bin`, `~/.bun/bin`, etc. If `npm i -g @anthropic-ai/claude-code` worked in your terminal, it'll be found.\n\n### Prerequisites\n\nYou need at least one of the CLIs already installed and logged in:\n\n```bash\n# Claude Code CLI\nnpm i -g @anthropic-ai/claude-code\nclaude   # follow the auth flow once\n\n# OR Codex CLI\nnpm i -g @openai/codex-cli\ncodex    # auth flow\n```\n\nSalmonApp detects whichever is on `PATH` and offers to use them per-Topic.\n\n### Optional: Office document preview\n\nThe Preview pane renders `.pptx` / `.docx` / `.xlsx` / `.odp` / `.odt` / `.ods` by shelling out to LibreOffice headless and slicing the resulting PDF with `pdftoppm`. Install once:\n\n```bash\n# Linux\nsudo apt install libreoffice-impress libreoffice-writer libreoffice-calc poppler-utils\n\n# macOS (either of these)\nbrew install --cask libreoffice \u0026\u0026 brew install poppler\n# or download LibreOffice.app from libreoffice.org/download/ — SalmonApp\n# probes /Applications/LibreOffice.app/Contents/MacOS/soffice automatically.\n```\n\nWithout these, Office files fall back to a friendly \"binary file\" placeholder instead of crashing the preview.\n\n## Build from source\n\nCommon: Rust toolchain (`rustup` 1.77+) and Node 20+.\n\n### Ubuntu 22.04 / 24.04\n\n```bash\nsudo apt install \\\n    libwebkit2gtk-4.1-dev libssl-dev libayatana-appindicator3-dev \\\n    librsvg2-dev build-essential curl wget file pkg-config\n\ncd salmon\nnpm install\nnpm run tauri:build       # → src-tauri/target/release/bundle/{deb,appimage}/\n```\n\n### macOS\n\n```bash\nxcode-select --install      # if you don't have command-line tools yet\nrustup target add aarch64-apple-darwin x86_64-apple-darwin\n\ncd salmon\nnpm install\nnpm run tauri:build -- --target universal-apple-darwin\n# → src-tauri/target/universal-apple-darwin/release/bundle/{macos,dmg}/\n```\n\nFor native-arch only (faster build, won't run on the other Mac arch):\n\n```bash\nnpm run tauri:build       # → src-tauri/target/release/bundle/{macos,dmg}/\n```\n\n### Development (hot-reload UI + auto-restart Tauri, all platforms)\n\n```bash\nnpm run tauri:dev\n```\n\n## Architecture\n\n```\nsalmon/\n├── src/                    React + TypeScript UI (Vite)\n│   ├── App.tsx                top-level layout, routing between Topics\n│   ├── components/\n│   │   ├── LeftSidebar.tsx       Topic list, search, grouping\n│   │   ├── ChatStream.tsx        Markdown / tool-call rendering\n│   │   ├── Composer.tsx          Input box, /-command pass-through\n│   │   ├── ToolCallCard.tsx      Per-tool result rendering\n│   │   ├── PermissionCard.tsx    Approval prompts (allow / deny)\n│   │   ├── RightPane.tsx         Files / Diff / Preview / Logs tabs\n│   │   ├── NewTopicDialog.tsx    Create-topic flow\n│   │   └── Onboarding.tsx        First-run CLI detection\n│   └── lib/                    invoke() wrappers + types\n└── src-tauri/              Rust backend\n    └── src/\n        ├── lib.rs              Tauri builder, plugin wiring\n        ├── commands.rs         Tauri commands invoked from React\n        ├── engine.rs           PTY child management, JSONL parse loop\n        ├── db.rs               SQLite schema + topic / message CRUD\n        └── types.rs            Shared Rust ↔ TS types\n```\n\nKey choices:\n\n- **Tauri 2** — native window, system WebKit, ~3 MB app vs. an Electron equivalent\n- **Per-Topic PTY** — each Topic owns one `tokio::process::Child` running `claude` (or `codex`) in JSONL streaming mode. Stream events flow through an unbounded mpsc channel and out to the UI as Tauri events.\n- **SQLite** in `~/.local/share/app.salmonapp.desktop/salmon.db` — Topics, messages, tool calls, permission decisions, token counts. Plain text. Export / clear available from the UI.\n- **No API calls from SalmonApp itself** — every model interaction is a child process invocation.\n\n## Limitations\n\n- Single window, single profile — no multi-account\n- No cloud sync, no team workspace (out of scope per [PRD](PRD.md))\n- Windows build not yet wired\n- macOS build is unsigned / unnotarized — first launch needs the `xattr` workaround above\n- Token-usage display only counts what the CLI emits in stream events\n- Office preview blocks the UI thread for ~2-3 s on first render (LibreOffice cold-start); cached after\n\nSee [PRD.md](PRD.md) for the full design rationale and roadmap.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpekinlcc%2Fsalmonapp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpekinlcc%2Fsalmonapp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpekinlcc%2Fsalmonapp/lists"}