Deep links cannot open Warp: absent from the terminal list and from the TERM_PROGRAM lookup
What happened
Clicking a claude-cli://open?... deep link always opens iTerm2 on my machine, even though Warp is my terminal. There is no setting that changes this, because Warp is not a terminal Claude Code can select.
Two separate gaps cause it.
1. Warp is absent from the terminal list. The macOS list the deep-link launcher chooses from:
[
{name:"iTerm2", bundleId:"com.googlecode.iterm2", app:"iTerm"},
{name:"Ghostty", bundleId:"com.mitchellh.ghostty", app:"Ghostty"},
{name:"Kitty", bundleId:"net.kovidgoyal.kitty", app:"kitty"},
{name:"Alacritty", bundleId:"org.alacritty", app:"Alacritty"},
{name:"WezTerm", bundleId:"com.github.wez.wezterm", app:"WezTerm"},
{name:"Terminal.app", bundleId:"com.apple.Terminal", app:"Terminal", termProgramAliases:["apple_terminal"]}
]
Selection is: stored deepLinkTerminal if it matches an app value, else TERM_PROGRAM, else probe for the first installed entry in list order. With no match, it probes and picks iTerm2 because iTerm2 is first and installed. Setting deepLinkTerminal to "Warp" does not help, because the lookup is f.find(o => o.app === r) and no entry has app: "Warp", so it falls through to the same probe.
2. Warp cannot be learned from TERM_PROGRAM either. The writer that records the preference:
var Xu = {
iterm:"iTerm", "iterm.app":"iTerm", ghostty:"Ghostty",
kitty:"kitty", alacritty:"Alacritty", wezterm:"WezTerm",
apple_terminal:"Terminal"
};
function ps(e) {
let t = O.TERM_PROGRAM;
if (!t) return;
let o = Xu[t.toLowerCase()];
if (!o) return; // Warp exits here
...
b(`Stored deep link terminal preference: ${o}`)
}
Warp sets TERM_PROGRAM=WarpTerminal. "warpterminal" is not a key, so ps() returns early and never stores anything. Running claude inside Warp, however many times, will not teach it. Confirmed on my machine: no deepLinkTerminal is stored in any config file.
Steps to reproduce
- On macOS with Warp installed (and iTerm2 also installed).
- Run
claudeinside Warp and send a prompt, so the URL handler registers. - Run
open "claude-cli://open?cwd=$HOME&q=hello".
Expected
The session opens in Warp, or at minimum there is a supported way to select it.
Actual
The session opens in iTerm2, and no configuration can change it to Warp.
Suggested fix
Add a Warp entry to the terminal list and a TERM_PROGRAM alias:
{name:"Warp", bundleId:"dev.warp.Warp-Stable", app:"Warp", termProgramAliases:["warpterminal"]}
Warp Beta is dev.warp.Warp-Beta.
One caveat worth flagging, since it is probably why Warp was skipped: Warp has no AppleScript equivalent to the "open a window and run this command" path the other terminals use. Its documented URI scheme can open a directory but cannot pre-fill or run a command:
warp://action/new_tab?path=<folder>
warp://action/new_window?path=<folder>
Running a command needs a saved Tab Config (commands = [...] in a .toml) opened via warp://tab_config/<name>.
So two realistic options:
- Full support: write a temporary Tab Config containing the
claudeinvocation and open it withwarp://tab_config/<name>. - Partial support: open
warp://action/new_tab?path=<cwd>and put the prompt on the clipboard, so the user runsclaudeand pastes. Loses the pre-filled prompt but gets the right terminal and directory.
Even the partial option would be a clear improvement over silently landing in a different terminal. If neither is desirable, an explicit deepLinkTerminal escape hatch that accepts an arbitrary bundle id would let users solve it themselves.
Environment
- Claude Code 2.1.246
- macOS (darwin 25.6.0), Apple silicon
- Warp 0.2026.08.19.08.15.01, iTerm2 also installed
- Handler:
~/Applications/Claude Code URL Handler.app,com.anthropic.claude-code-url-handler, verified vialsregisteras the boundclaude-cli:handler