{"slug": "show-hn-desk-open-source-macos-workspace-for-cli-coding-agents", "title": "Show HN: Desk - Open-source macOS workspace for CLI coding agents", "summary": "Developer s-nish released Desk, an open-source macOS workspace that runs command-line coding agents such as Claude Code, Codex, Gemini CLI, Cursor Agent, Grok and OpenCode in one window, distributed as a Desk.dmg download from GitHub. Desk assigns a separate config folder per project — CLAUDE_CONFIG_DIR, CODEX_HOME and GH_CONFIG_DIR, with extra accounts in folders like ~/.claude-<name> — so each terminal and chat opens signed in to the right account, and the app states it never stores or sends user tokens. The release is built for Apple silicon and is not yet notarized, so browser downloaders must approve it via System Settings ▸ Privacy & Security ▸ Open Anyway, while the provided curl command skips that prompt.", "body_md": "**Every agent. One desk.**\n\nA calm macOS workspace for Claude Code, Codex and friends.\n\nProjects, terminals, files, git and chat in one window, and the right account for every project.\n\n[**Download for macOS**](https://github.com/s-nish/desk/releases/latest/download/Desk.dmg) · [Website](https://github.com/s-nish/desk/tree/main/site) · [Report an issue](https://github.com/s-nish/desk/issues)\n\n<sub>The screenshot follows your GitHub theme. Switch between light and dark to see both.</sub>\n\n| <sub>**Claude Code**</sub> | <sub>** Codex**</sub> | <sub>** Gemini CLI**</sub> | <sub>** Cursor Agent**</sub> | <sub>** Grok**</sub> | <sub>** OpenCode**</sub> | <sub>** GitHub**</sub> | \n\nDesk runs the command-line tools you already have installed and signed in. It never stores or sends your tokens.\n\n| **The right account, every time** | Pick a Claude Code, Codex and GitHub account per project. Every tab opens already signed in as the right you. | \n| **Terminal or chat** | Run agents in real terminals, or as a conversation with attachments, permission modes and a worktree per chat. | \n| **Files beside the session** | Browse and edit with syntax highlighting. Preview images, PDFs and CSV. Unsaved buffers survive a restart. | \n| **Review before you ship** | Stage, commit and open pull requests. Comment on a diff line and send it to the agent. Desk never pushes on its own. | \n| **A browser for your dev server** | Dock it next to the agent. Design mode picks an element and hands it over as context. | \n| **Limits at a glance** | Usage rings for every account: blue, cantaloupe from 80%, red at the limit. | \n| **Quit without fear** | Open files, unsaved buffers, splits and tab order all come back. | \n\n| <sub>**Terminals and history.** Every past conversation, one click away.</sub> | <sub>**Files.** The tree and editor stay next to the session.</sub> | \n| <sub>**Git.** Review, commit and open PRs with the project's GitHub account.</sub> | <sub>**Chat and browser.** A conversation view with a browser docked beside it.</sub> | \n\n| <sub>**Appearance.** 24 app themes, dark and light.</sub> | <sub>**Terminal.** 18 palettes with a live preview.</sub> | \n| <sub>**Editor.** Syntax colours, previewed per language.</sub> | <sub>**Accounts.** Seven tools, as many accounts as you need.</sub> | \n\nDesk opens in **Electric**: Midnight `#02070A`, Electric Blue `#0297DE` and a touch of Cantaloupe `#FC734D`, with serif headings, pill buttons and an animated pixel-wave backdrop on Home. The four **pixel themes** are Electric, Electric Light, Ember and Aurora. Turn the animation off from the sidebar or **Settings ▸ Appearance**. It always stays still when Reduce motion is on.\n\n**From Terminal:**\n\n```\ncurl -fL https://github.com/s-nish/desk/releases/latest/download/Desk.dmg -o ~/Downloads/Desk.dmg && open ~/Downloads/Desk.dmg\n```\n\n**Or by hand:** download [**Desk.dmg**](https://github.com/s-nish/desk/releases/latest/download/Desk.dmg) from the latest release.\n\nThen drag Desk to Applications, and install and sign in to the agents you use, such as `claude` or `codex`. Desk picks them up on launch.\n\nTip\n\nDesk isn't notarized yet. If you downloaded it in a browser, macOS asks on first launch: open **System Settings ▸ Privacy & Security** and choose **Open Anyway**. The Terminal command above skips that prompt.\n\nNote\n\nThe release is built for Apple silicon. On an Intel Mac, [build from source](#develop).\n\nAn account is a config folder. Desk sets the right folder for every terminal and chat it opens.\n\n| Tool | Variable | Default folder | Extra accounts | \n|---|---|---|---|\n| Claude Code | `CLAUDE_CONFIG_DIR` | `~/.claude` | `~/.claude-<name>` | \n| Codex | `CODEX_HOME` | `~/.codex` | `~/.codex-<name>` | \n| GitHub | `GH_CONFIG_DIR` | `~/.config/gh` | `~/.config/gh-<name>` | \n\nDesk finds existing folders on launch. **Add account** creates a new folder and runs the tool's own sign-in inside it. To show which email is signed in, Desk reads that one field locally: `oauthAccount.emailAddress` from `.claude.json`, and only the `email` claim from Codex's `auth.json`.\n\nImportant\n\n**Pull requests are untrusted code.** When you check out or review someone else's pull request, Desk asks first and marks the worktree untrusted. Agents there start without the branch's own settings, hooks and MCP servers (`--setting-sources user --strict-mcp-config`), in plan mode for Claude Code and a read-only sandbox for Codex.\n\n| Keys | Action | Keys | Action | \n|---|---|---|---|\n| `⌘``⇧`` P` | Command palette | `⌘`` P` | Open file in project | \n| `⌘``⇧`` F` | Search and replace | `⌘`` O` | Add project folder | \n| `⌘``\\` | Toggle split panes | `⌘`` B` /`⌘``⇧`` B` | Toggle projects / files | \n| `⌘`` T` | New Claude Code tab | `⌘`` K` | Clear terminal | \n| `⌘`` W` | Close tab | `⌘`` 1` –`9` | Switch tabs | \n| `⌘`` S` | Save file | `⌥``⌘``↑` /`↓` | Switch projects | \n| `⌘``,` | Settings | `⇧`` Enter` | Newline in Claude Code / Codex | \n\nDrop folders on the window to add projects. Drop files on a terminal to paste their paths.\n\n## **More details**: workspace, terminal, editor and appearance\n\n**Workspace**\n\n- **Home** appears whenever nothing is open: every project as a card with one-click Claude Code, Codex and Shell sessions, plus recent conversations.\n- **Recovery** restores open files, unsaved buffers, tab selection and split layout. Changed files on disk show a conflict before overwrite. Terminal tabs restore as restart cards.\n- **Tab order:** drag tabs to reorder, or focus one and use`⌥``⇧``←` /`→` .`Esc` cancels a drag.\n- **Split panes:** click a pane to target it, drag the divider or use its arrow keys to resize.\n- **Source control** covers the repository root, including when the project is a subfolder. Unsaved editor buffers are not included in commits.\n- **Project search** respects ignore files and skips binary files and build folders. Replace previews every change and skips dirty buffers.\n\n**Terminal**\n\n- 12 original palettes plus 6 neutral ones, individual colour overrides and smooth scrolling. Text contrast is corrected to 7:1 where xterm supports it.\n- 20,000 lines of history. Incoming output never moves you to the bottom; use **Latest output** or`⇧`` End` to return.\n\n**Editor**\n\n- Eight file colour themes: Match Desk, VS Code Dark, GitHub Dark, Dracula, Nord, GitHub Light, Solarized Light and Monochrome.\n- Syntax highlighting follows filenames, with lazy-loaded support for many languages.\n\n**Appearance**\n\n- 24 themes, or match your system. Comfortable or compact spacing, panel visibility and optional account colours.\n- Preferences are saved on this Mac.\n\nRequires Rust ([rustup](https://rustup.rs)) and Node 20+.\n\n```\nnpm install\nnpm run tauri dev           # live-reloading dev build\nnpm run tauri build         # release Desk.app and .dmg in src-tauri/target/release/bundle\ncd src-tauri && cargo test  # backend tests\n```\n\n| Path | What lives there | \n|---|---|\n| `src-tauri/src` | Rust backend: `pty.rs` terminals,`accounts.rs` account discovery,`files.rs` tree and editor I/O,`gh.rs` GitHub | \n| `src` | React UI. `terminals.ts` and`editors.ts` keep xterm.js and CodeMirror alive outside React, so sessions survive tab and project switches | \n| `site` | The landing page: plain HTML, CSS and JS | \n\nApp state is saved to `~/Library/Application Support/Desk/state.json`.\n\n## **Validation**\n\n```\nnpm run build\nnpm run test:backend\nnpm run dev -- --host 127.0.0.1 --port 1421\n# In another terminal (uses an installed Chrome, isolated data, mocked IPC):\nnpm run test:ui\nnpm run test:appearance\n```\n\nSet `CHROME_PATH` to use a different Chrome, or `DESK_TEST_URL` for a different dev-server address. The UI smoke test covers restoration, split panes, search and replace, Git controls, the command palette and quit-time persistence. Appearance checks cover theme contrast, system theme changes, terminal palettes, scrollback and alternate-screen navigation.\n\n<sub>Claude, Codex, Gemini, Cursor, Grok, OpenCode and GitHub are trademarks of their owners. Desk is independent and not affiliated with them. Logos from [Lobe Icons](https://lobehub.com/icons) (MIT).</sub>", "url": "https://wpnews.pro/news/show-hn-desk-open-source-macos-workspace-for-cli-coding-agents", "canonical_source": "https://github.com/s-nish/desk", "published_at": "2026-11-09 19:30:38+00:00", "updated_at": "2026-11-09 19:53:08.844250+00:00", "lang": "en", "topics": ["ai-agents", "ai-tools", "developer-tools", "ai-products"], "entities": ["Desk", "s-nish", "Claude Code", "Codex", "Gemini CLI", "Cursor Agent", "Grok", "OpenCode"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/show-hn-desk-open-source-macos-workspace-for-cli-coding-agents", "markdown": "https://wpnews.pro/news/show-hn-desk-open-source-macos-workspace-for-cli-coding-agents.md", "text": "https://wpnews.pro/news/show-hn-desk-open-source-macos-workspace-for-cli-coding-agents.txt", "jsonld": "https://wpnews.pro/news/show-hn-desk-open-source-macos-workspace-for-cli-coding-agents.jsonld"}}