Platform Support
Chord is developed and tested primarily on macOS. Other platforms work to varying degrees: most features are platform-agnostic, but a few depend on OS-specific machinery and degrade or no-op elsewhere. This page lists where features really work, where they fall back, and what to install on each OS.
Quick matrix
Section titled “Quick matrix”| Feature | macOS | Linux | Windows | WSL |
|---|---|---|---|---|
| Core TUI (modes, transcript, sessions) | ✅ | ✅ | ⚠️ (best-effort) | ✅ |
chord headless JSON control plane |
✅ | ✅ | ✅ | ✅ |
Worktrees (chord --worktree, chord worktree …) |
✅ | ✅ | ✅ | ✅ |
prevent_sleep (idle-sleep prevention) |
✅ | ❌ (no-op) | ❌ (no-op) | ❌ (no-op) |
ime_switch_target (auto IM switch on mode change) |
✅1 | ⚠️2 | ✅3 | ⚠️4 |
desktop_notification (terminal notifications) |
⚠️5 | ⚠️5 | ⚠️5 | ⚠️5 |
Clipboard image/PDF attachment (Ctrl+V / Alt+V) |
✅ | ⚠️6 | ⚠️6 | ⚠️6 |
| Terminal-rendered images (Kitty / iTerm2) | ⚠️7 | ⚠️7 | ⚠️7 | ⚠️7 |
| LSP — gopls / typescript / rust-analyzer | ✅8 | ✅8 | ✅8 | ✅8 |
| LSP — Pyright with project venv auto-discovery | ✅9 | ✅9 | ✅10 | ✅9 (WSL Linux venvs only — see below) |
| MCP servers (stdio / HTTP) | ✅ | ✅ | ✅ | ✅ |
| Power-aware idle handling | ✅ | ❌ (no-op) | ❌ (no-op) | ❌ (no-op) |
Legend: ✅ supported · ⚠️ supported with caveats · ❌ not supported / no-op.
Per-feature details
Section titled “Per-feature details”prevent_sleep
Section titled “prevent_sleep”macOS uses caffeinate(1) under the hood. On Linux / Windows / WSL this setting is a no-op. If you depend on always-on behavior elsewhere, configure your OS power settings directly.
The first-run setup wizard asks about prevent_sleep only on macOS, and only as an explicit opt-in confirmation. It is intended for longer-running agent sessions where idle sleep would be disruptive.
ime_switch_target
Section titled “ime_switch_target”When you switch from Insert mode to Normal mode, Chord can call im-select (or im-select.exe) to switch to a configured input method (typically the system English layout) and restore the previous one when you switch back to Insert.
On supported platforms, the first-run setup wizard can also ask for this value. Skip it unless you actively use a non-Latin IME and want more reliable Normal-mode shortcuts.
ime_switch_target: com.apple.keylayout.ABC # macOS example# ime_switch_target: 1033 # Windows example (locale id)Install im-select separately. The variable name is just a string: Chord passes it verbatim to im-select, so the format depends on the platform-specific tool.
desktop_notification (terminal notifications)
Section titled “desktop_notification (terminal notifications)”When enabled, Chord emits terminal notification escape sequences when the agent actually ran and then stopped (a completed, cancelled, or loop-finished turn, or all SubAgents finishing) and for permissions, questions, Handoff, loop decisions, and notify-protocol corrections waiting for input. User-initiated navigation that settles into idle (session / model-pool / MCP switches, idle slash commands) stays silent. There is no Chord-side notifier daemon; the terminal is responsible for surfacing the notification.
Chord auto-selects the protocol by terminal. Unsupported terminals usually ignore the sequence.
In practice:
- Ghostty / WezTerm / Windows Terminal: Chord attempts OSC 777
- iTerm2: Chord uses OSC 9
- Other terminals: Chord conservatively falls back to OSC 9
Inside tmux you may need set -g allow-passthrough on for notifications to reach the host terminal.
Most terminals (including Ghostty and iTerm2) suppress notification banners and sounds while they are the focused application, so an OSC notification sent while you are looking at the terminal is usually silent. Chord therefore pairs every notification with a terminal bell (BEL), which terminals treat as an attention signal instead of a notification. Set desktop_notification_foreground: false if you want everything silent while the terminal is focused.
Bell sound is off by default in many terminals and how to enable it varies per terminal/system:
- Ghostty (macOS ≥ 1.3, GTK ≥ 1.2): add
bell-features = system,audioto the Ghostty config (system plays the alert sound;audiocan also play a custom file viabell-audio-pathandbell-audio-volume). Other features likeattention(Dock bounce) andtitle(🔔 prefix) are enabled by default. - iTerm2: Settings → Profiles → Terminal → Notification Center alerts; silence can be toggled per-profile, and “Silence bell” must be off for the bell to reach the notification center.
- kitty:
enable_audio_bell/visual_bell_durationinkitty.conf. - tmux: bells are routed through
monitor-bell/bell-actionper window; setset -g bell-action anyto be alerted in other windows. - Windows Terminal: bells play the system sound by default; configure or mute it in Terminal settings → Advanced → Bell notification style.
Terminals not listed here may ignore BEL entirely or only flash the window; check the terminal’s own documentation for bell/attention options.
Clipboard image/PDF attachment
Section titled “Clipboard image/PDF attachment”Ctrl+V or Alt+V reads an image or PDF from the system clipboard and adds it as an attachment. The read and any image conversion run asynchronously, so the TUI remains responsive; sending is temporarily held until the read finishes. Ordinary terminal paste events, including the usual macOS Cmd+V, are text-only and never probe clipboard attachments.
Chord reads the clipboard through each platform’s own backend: the native library on Linux and Windows, and the system osascript on macOS. Clipboard PNG is preferred, then TIFF on macOS, followed by JPEG, WebP, BMP, and GIF. Formats other than PNG and JPEG are converted to one of the two; any image longer than 2000px on its longest edge is scaled down, PNG and JPEG included (animated WebP and GIF use their first frame). If both PDF and image representations are present, PDF takes priority. If no supported attachment is available, Chord shows a warning and does not fall back to text.
Inline image attachments are capped at 5 per composer message. Literal placeholder text like [image1] is not special by itself; only Chord-inserted inline placeholders are backed by real attachments.
Common cases:
- macOS + iTerm2 / WezTerm / Ghostty: use
Ctrl+Vfor clipboard attachments andCmd+Vfor text. - macOS + cmux: use
Ctrl+Vfor clipboard attachments.Cmd+Vmay be intercepted by cmux and converted into pasted temporary-file path text. - Linux Wayland / X11:
Ctrl+Vuses the local clipboard when the compositor exposes data-control or an X11/XWayland display is available. - Windows Terminal / WSL hosted by it: use
Alt+V; Windows Terminal reservesCtrl+Vfor ordinary text paste by default. WSLg BMP clipboard images are normalized before attachment. - Inside tmux / SSH: the Chord process reads the clipboard of the machine where it runs, not automatically the terminal client’s clipboard.
On macOS the probe runs in a short-lived osascript process, so the clipboard framework never loads in Chord itself and its memory is reclaimed as soon as the read finishes. Nothing extra needs to be installed: the read is built into chord.
When clipboard attachment access is unavailable, you can still bind insert_attach_file and attach images/PDFs by path from the composer.
Terminal-rendered images
Section titled “Terminal-rendered images”Chord currently auto-detects and enables:
- Kitty graphics (kitty, Ghostty)
- iTerm2 inline images (iTerm2, WezTerm)
If neither protocol is available, image attachments are still sent to the model; they just are not previewed in the TUI.
Notes:
- Sixel is not currently implemented as a Chord backend
- Inside
tmux/zellij, image preview is conservatively disabled by default to avoid common passthrough / placeholder issues - Advanced users can override auto-detection with
CHORD_IMAGE_BACKEND=kitty|iterm2|none, plusCHORD_IMAGE_INLINE=0|1andCHORD_IMAGE_FULLSCREEN=0|1
Pyright venv auto-discovery
Section titled “Pyright venv auto-discovery”When no Python interpreter is configured for Pyright, Chord searches upward from the LSP root for the nearest project-local venv without crossing the Chord project root, in this order:
- Unix-like (macOS, Linux, WSL):
.venv/bin/python→venv/bin/python→env/bin/python - Windows:
.venv\Scripts\python.exe→venv\Scripts\python.exe→env\Scripts\python.exe
WSL auto-discovery intentionally does not pick up Windows venvs under Scripts\python.exe. If you work inside WSL, create a Linux venv inside WSL, or set python.pythonPath explicitly under lsp.pyright.options.
For more, see Customization: LSP.
Terminal compatibility
Section titled “Terminal compatibility”Most “this works on macOS but not on my Linux box” reports really come down to the terminal emulator, not the OS. Recommended terminals where Chord behaves best:
- iTerm2 (macOS): image preview, terminal notifications, clipboard image paste
- Ghostty (cross-platform): image preview, terminal notifications (tries OSC 777)
- WezTerm (cross-platform): image preview, terminal notifications (tries OSC 777), clipboard image paste
- kitty (Linux/macOS): image preview, terminal notifications
- macOS Terminal.app works for basic TUI use, but it does not reliably deliver modified
Enterkeys (for exampleShift+Enter). UseCtrl+Jfor newline in the composer, or switch to iTerm2 / Ghostty / WezTerm for full key behavior.
Key disambiguation note: in terminal multiplexers like tmux / zellij, modified keys such as Shift+Enter can be lost or rewritten unless the host chain is configured for extended keys. When in doubt, use Ctrl+J for newline (it works everywhere).
tmux and screen add a layer between Chord and your terminal; some features (terminal notifications, certain image flows) require explicit pass-through configuration, and Chord currently disables image preview by default inside tmux / zellij.
What Windows users should expect
Section titled “What Windows users should expect”Chord runs on Windows but is not the primary platform. Concretely:
- TUI works in modern terminals (Windows Terminal, WezTerm).
prevent_sleepis a no-op: use Windows power settings.ime_switch_targetworks withim-select.exe.- File paths in tool calls follow Windows conventions; backslashes are preserved verbatim.
shell(foreground commands and background jobs) remains non-interactive on Windows too, but timeout/cancellation cleanup uses direct process termination instead of Unix-style session/process-group control; descendant process cleanup may therefore be less complete than on Unix.- If you hit a Windows-specific bug, it is more likely to be undiscovered than a deliberate limitation. Capture a diagnostics bundle with
Ctrl+Gand report it.
What WSL users should expect
Section titled “What WSL users should expect”WSL behaves like Linux for the most part:
- Chord runs as a Linux binary inside WSL; sessions and config use Linux paths (
~/.config/chord/, etc.). prevent_sleepis a no-op; use Windows power settings on the host.ime_switch_targettypically goes through Windows interop (im-select.exe).- Pyright venv auto-discovery uses Linux venvs (
.venv/bin/pythonetc.) inside WSL; Windows-styleScripts\python.exevenvs are intentionally not selected. - Terminal capabilities depend on the Windows terminal hosting WSL (Windows Terminal, WezTerm, Ghostty).
Reporting platform-specific issues
Section titled “Reporting platform-specific issues”When reporting a bug that you suspect is platform-related, include:
- OS and version
- Terminal emulator and version
- Whether you are inside
tmux/screen/ WSL - A diagnostics bundle (
Ctrl+G)
See Troubleshooting: When to check logs for log location and bundle layout.
Related
Section titled “Related”Footnotes
Section titled “Footnotes”-
Requires the
im-selectbinary inPATH(im-select.exeon Windows). Install separately; Chord ships only the integration, not the binary itself. ↩ -
im-selectis a macOS-first tool; on Linux you need a compatible build or a wrapper script with the same CLI. ↩ -
Use
im-select.exe(e.g. from https://github.com/daipeihust/im-select#-windows). ↩ -
Inside WSL, IM switching usually targets the host (Windows) IM. You typically run
im-select.exeover interop and may need PATH or wrapper setup. ↩ -
Notification support is a terminal capability, not an OS capability. Chord auto-selects a notification escape sequence by terminal (OSC 9 or OSC 777). Some terminals may ignore unsupported sequences; see Terminal compatibility below. ↩ ↩2 ↩3 ↩4
-
Ctrl+V/Alt+Vreads the system clipboard through a native backend. Availability still depends on the local display/clipboard environment; remote SSH sessions usually expose the remote host clipboard, not the terminal client’s clipboard. Windows Terminal reservesCtrl+V, so useAlt+Vthere and in WSL sessions hosted by it. ↩ ↩2 ↩3 -
Image rendering currently auto-detects Kitty graphics and iTerm2 inline images (Ghostty uses Kitty; WezTerm uses iTerm2). When the terminal does not support those, image attachments are still sent to the model but are not previewed in the TUI.
tmux/zellijare disabled by default for safety. ↩ ↩2 ↩3 ↩4 -
Requires the relevant language server installed locally (e.g.
gopls,typescript-language-server,rust-analyzer). Chord does not bundle them. ↩ ↩2 ↩3 ↩4 -
On Unix-like systems Chord searches upward from the LSP root for the nearest
.venv/bin/python,venv/bin/python, orenv/bin/python. ↩ ↩2 ↩3 -
On Windows Chord probes
.venv\Scripts\python.exe,venv\Scripts\python.exe,env\Scripts\python.exe. ↩