-
-
Notifications
You must be signed in to change notification settings - Fork 14
Jump
Jump is purple's universal fuzzy search bar. Press : from any screen to find any host, tunnel, container, snippet or action across your entire SSH config in one keystroke. Recent picks persist across sessions and lead the empty-state list. Field prefixes scope the query to a single SSH directive.
Comparable to Linear's Cmd+K or Raycast, but in your terminal.
Five sources, one ranked list:
| Source | What gets searched |
|---|---|
| Hosts | Alias, hostname, tags, provider, SSH User, IdentityFile, ProxyJump, Vault SSH role |
| Tunnels | Host alias, bind port, destination |
| Containers | Container name, image, host alias (cached, no live SSH on open) |
| Snippets | Snippet name, command preview |
| Actions | All 50 keyboard-reachable actions across the TUI, with hidden aliases |
Results are ranked with nucleo (the Helix editor's fuzzy matcher). Sections appear in a fixed order (Hosts, Tunnels, Containers, Snippets, Actions) so muscle memory survives.
A typical purple user has 50 to 500 hosts spread across multiple cloud providers, plus dozens of named tunnels, containers and snippets. Three keys (/, : and the navigation tabs) used to map to three different mental models. Jump collapses that into one bar with one trigger.
Concrete example. You configured User eric for many servers. The hostname doesn't contain "eric" anywhere. Type eric in Jump and every server you log in as eric appears with a dim via eric hint next to it.
Scope a query to a single SSH directive. The unscoped fuzzy search remains the default; prefixes are opt-in precision.
| Prefix | Searches | Example |
|---|---|---|
user: |
SSH User directive |
user:deploy finds every host configured for the deploy user |
host: |
Hostname only (skips alias) |
host:10.0 finds every host with 10.0 in the hostname |
proxy: |
ProxyJump chains |
proxy:bastion-eu finds every host that bounces through bastion-eu |
vault: |
Vault SSH role |
vault:prod-admin finds every host signed with the prod-admin role |
tag: |
User tags only |
tag:web finds every host tagged "web" |
Field-prefix syntax mirrors the existing tag: precedent in purple's host search.
When Jump matches on a field that is not part of the visible row, a dim hint appears inline so the match makes sense. Examples:
- Match on
User:fast1 eric 128.199.60.111 via eric - Match on
ProxyJump:web-01 web.prod 1.2.3.4 via bastion-eu - Match on
vault_ssh:db-01 db.internal 10.0.0.5 vault: prod-admin
Without these hints, a query like eric would surface hosts the user could not visually explain.
Opening Jump with an empty query shows two sections:
-
Recent: your last picks (any kind), persisted to
~/.purple/recents.json. Most recent first. Capped at 50 entries. -
Actions: top 6 actions sampled across categories so the first impression covers Hosts, Tunnels, Containers, Files, Vault, Keys. Header reads
Actions 6 of Nwhere N is the live total. Scroll past the cap by typing or pressing the down arrow.
The first row is not selected by default. The eye lands on the input field. Pressing the down arrow reveals the cursor on row 0 and continues from there.
| Key | Action |
|---|---|
: |
Open Jump from the Hosts, Tunnels, Containers or Keys tab |
| Type any character | Filter |
↑ / ↓
|
Move selection. First press reveals the cursor on row 0 |
Tab |
Jump to the next section header |
Enter |
Open the selected hit. Hosts switch tabs and connect, tunnels jump to the row in the Tunnels tab, containers switch to the Containers tab and place the cursor on the matching row, snippets open the snippet picker, actions execute |
Backspace on empty query |
Close Jump |
Esc |
Close Jump |
Selecting a hit and pressing Enter does different things depending on the kind:
| Kind | Dispatch |
|---|---|
| Host | Switch to Hosts tab, select the host, trigger the connect flow |
| Tunnel | Switch to Tunnels tab, place the cursor on the matching tunnel row, then fire Enter so the tunnel starts or stops in the same gesture |
| Container | Switch to the Containers tab, place the cursor on the matching container row, then fire Enter so the shell opens in the same gesture. Falls back to the host divider when the group is folded (no auto-Enter on the divider), then to the first visible row when the cache no longer carries the container |
| Snippet | Open the Snippet picker on the currently selected host (or warn if no host is selected) |
| Action | Synthesise the action's keypress (including modifiers like Ctrl-a or Ctrl-k) for the right handler, switching tab first when the action's target is on a different tab |
The same action can exist on multiple tabs with different meanings (e.g. a is Hosts: Add host on Hosts, Tunnels: Add tunnel on Tunnels and Containers: Add host on Containers). Jump shows them all. A small mode-match boost surfaces the contextually-relevant one when you type a query that matches several of them, so typing sort on the Tunnels tab prefers Tunnels: Sort over Hosts: Sort.
Jump's recent log lives at ~/.purple/recents.json. It contains aliases, snippet names and tunnel ports. It does not contain hostnames, IP addresses, IdentityFile paths or any credential. The file is written via the same atomic-write helper as the rest of purple's persistent state and is gated behind demo mode (no writes when --demo is active). Schema is versioned for forward compatibility.
| Product | Where it runs | Cross-source search |
|---|---|---|
Linear Cmd+K
|
Web | Issues, projects, members, commands |
| Raycast | macOS | Apps, snippets, scripts, extensions |
| Spotlight | macOS | Files, apps, web |
| Jump (purple) | Terminal TUI | Hosts, tunnels, containers, snippets, actions |
| fzf | Terminal | Single source per invocation |
| Telescope (Neovim) | Neovim | Single source per picker |
The closest TUI precedent for one bar over many sources is Zellij's session manager, but it doesn't index host/SSH-config data the way Jump does.
Does Jump connect over SSH when I open it? No. Containers are searched against the local cache only. Hosts and tunnels read from the parsed SSH config in memory. Opening Jump triggers no network activity.
Where do recents go?
~/.purple/recents.json, atomic write, max 50 entries. Demo mode skips persistence entirely.
Can I disable Recent? The file is harmless to delete (purple regenerates an empty one on next open). A preference flag is not currently exposed.
Does Jump work from inside a form (e.g. while editing a host)?
No. : is a literal character inside form fields. Jump opens from the Hosts and Tunnels overview screens.
How is Jump different from purple's / filter?
/ filters the visible list of the current tab in place (no jump). Jump opens an overlay, searches across all sources, and switches tab as needed. Two complementary keys.
Why six actions in the empty state, not all 50?
A wall of 50 rows competes with the input field for attention. The top 6 sample one action per priority category (Hosts, Tunnels, Containers, Files, Vault, Keys). The full list is one keystroke away. The header reads Actions 6 of 50 so the truncation is explicit.
What's the score floor on actions?
Action-source hits need to clear a higher fuzzy-match score (~30 in nucleo's scale) than data-source hits. Without this, a query like eric would drag in Containers: List containers because e/r/i/c happen to scatter across the label without semantic intent.
- Keybindings: full keyboard reference for the TUI
-
Tags and Search: the in-place
/filter on the host list - SSH Tunnels: the dedicated Tunnels tab Jump can land you on
- Container Management: the Container screen Jump opens
- Command Snippets: the Snippet picker Jump opens
Getting started
Features
- Jump
- Cloud Providers
- File Explorer
- Command Snippets
- Password Management
- Vault SSH Certificates
- Container Management
- SSH Tunnels
- Keys
- Tags and Search
- Host Patterns
- Themes
- MCP Server
- Whats New
Reference