waveterm Documentation

An open-source, AI-integrated, cross-platform terminal for seamless workflows

RAW Doc

File: README.md

Wave Terminal

Wave is an open-source, AI-integrated terminal for macOS, Linux, and Windows. It works with any AI model. Bring your own API keys for OpenAI, Claude, or Gemini, or run local models via Ollama and LM Studio. No accounts required.

Wave also supports durable SSH sessions that survive network interruptions and restarts, with automatic reconnection. Edit remote files with a built-in graphical editor and preview files inline without leaving the terminal.

Key Features

  • Wave AI - Context-aware terminal assistant that reads your terminal output, analyzes widgets, and performs file operations
  • Durable SSH Sessions - Remote terminal sessions survive connection interruptions, network changes, and Wave restarts with automatic reconnection
  • Flexible drag & drop interface to organize terminal blocks, editors, web browsers, and AI assistants
  • Built-in editor for editing remote files with syntax highlighting and modern editor features
  • Rich file preview system for remote files (markdown, images, video, PDFs, CSVs, directories)
  • Quick full-screen toggle for any block - expand terminals, editors, and previews for better visibility, then instantly return to multi-block view
  • AI chat widget with support for multiple models (OpenAI, Claude, Azure, Perplexity, Ollama)
  • Command Blocks for isolating and monitoring individual commands
  • One-click remote connections with full terminal and file system access
  • Secure secret storage using native system backends - store API keys and credentials locally, access them across SSH sessions
  • Rich customization including tab themes, terminal styles, and background images
  • Powerful wsh command system for managing your workspace from the CLI and sharing data between terminal sessions
  • Connected file management with wsh file - seamlessly copy and sync files between local and remote SSH hosts

Wave AI

Wave AI is your context-aware terminal assistant with access to your workspace:

  • Terminal Context: Reads terminal output and scrollback for debugging and analysis
  • File Operations: Read, write, and edit files with automatic backups and user approval
  • CLI Integration: Use wsh ai to pipe output or attach files directly from the command line
  • BYOK Support: Bring your own API keys for OpenAI, Claude, Gemini, Azure, and other providers
  • Local Models: Run local models with Ollama, LM Studio, and other OpenAI-compatible providers
  • Free Beta: Included AI credits while we refine the experience
  • Coming Soon: Command execution (with approval)

Learn more in our Wave AI documentation and Wave AI Modes documentation.

Installation

Wave Terminal works on macOS, Linux, and Windows.

Platform-specific installation instructions can be found here.

You can also install Wave Terminal directly from: www.waveterm.dev/download.

Minimum requirements

Wave Terminal runs on the following platforms:

  • macOS 11 or later (arm64, x64)
  • Windows 10 1809 or later (x64)
  • Linux based on glibc-2.28 or later (Debian 10, RHEL 8, Ubuntu 20.04, etc.) (arm64, x64)

The WSH helper runs on the following platforms:

  • macOS 11 or later (arm64, x64)
  • Windows 10 or later (x64)
  • Linux Kernel 2.6.32 or later (x64), Linux Kernel 3.1 or later (arm64)

Roadmap

Wave is constantly improving! Our roadmap will be continuously updated with our goals for each release. You can find it here.

Want to provide input to our future releases? Connect with us on Discord or open a Feature Request!

Building from Source

See Building Wave Terminal.

Contributing

Wave uses GitHub Issues for issue tracking.

Find more information in our Contributions Guide, which includes:

Sponsoring Wave โค๏ธ

If Wave Terminal is useful to you or your company, consider sponsoring development.

Sponsorship helps support the time spent building and maintaining the project.

License

Wave Terminal is licensed under the Apache-2.0 License. For more information on our dependencies, see here.


File: docs/docs/ai-presets.mdx


:::warning Deprecation Notice
The AI Widget and its presets are being replaced by Wave AI. Please refer to the Wave AI documentation for the latest AI features and configuration options.
:::

Wave's AI widget can be configured to work with various AI providers and models through presets. Presets allow you to define multiple AI configurations and easily switch between them using the dropdown menu in the AI widget.

How AI Presets Work

AI presets are defined in ~/.config/waveterm/presets/ai.json. You can easily edit this file using:

bash
wsh editconfig presets/ai.json

Each preset defines a complete set of configuration values for the AI widget. When you select a preset from the dropdown menu, those configuration values are applied to the widget. If no preset is selected, the widget uses the default values from settings.json.

Here's a basic example using Claude:

json
{
  "ai@claude-sonnet": {
    "display:name": "Claude 3 Sonnet",
    "display:order": 1,
    "ai:*": true,
    "ai:apitype": "anthropic",
    "ai:model": "claude-3-5-sonnet-latest",
    "ai:apitoken": "<your anthropic API key>"
  }
}

To make a preset your default, add this single line to your settings.json:

json
{
  "ai:preset": "ai@claude-sonnet"
}

:::info
You can quickly set your default preset using the setconfig command:

bash
wsh setconfig ai:preset=ai@claude-sonnet

This is easier than editing settings.json directly!
:::

Provider-Specific Configurations

Anthropic (Claude)

To use Claude models, create a preset like this:

json
{
  "ai@claude-sonnet": {
    "display:name": "Claude 3 Sonnet",
    "display:order": 1,
    "ai:*": true,
    "ai:apitype": "anthropic",
    "ai:model": "claude-3-5-sonnet-latest",
    "ai:apitoken": "<your anthropic API key>"
  }
}

OpenAI

To use OpenAI's models:

json
{
  "ai@openai-gpt41": {
    "display:name": "GPT-4.1",
    "display:order": 2,
    "ai:*": true,
    "ai:model": "gpt-4.1",
    "ai:apitoken": "<your OpenAI API key>"
  }
}

Local LLMs (Ollama)

To connect to a local Ollama instance:

json
{
  "ai@ollama-llama": {
    "display:name": "Ollama - Llama2",
    "display:order": 3,
    "ai:*": true,
    "ai:baseurl": "http://localhost:11434/v1",
    "ai:name": "llama2",
    "ai:model": "llama2",
    "ai:apitoken": "ollama"
  }
}

Note: The ai:apitoken is required but can be any value as Ollama ignores it. See Ollama OpenAI compatibility docs for more details.

Azure OpenAI

To connect to Azure AI services:

json
{
  "ai@azure-gpt4": {
    "display:name": "Azure GPT-4",
    "display:order": 4,
    "ai:*": true,
    "ai:apitype": "azure",
    "ai:baseurl": "<your Azure AI base URL>",
    "ai:model": "<your model deployment name>",
    "ai:apitoken": "<your Azure API key>"
  }
}

Note: Do not include query parameters or api-version in the ai:baseurl. The ai:model should be your model deployment name in Azure.

Perplexity

To use Perplexity's models:

json
{
  "ai@perplexity-sonar": {
    "display:name": "Perplexity Sonar",
    "display:order": 5,
    "ai:*": true,
    "ai:apitype": "perplexity",
    "ai:model": "llama-3.1-sonar-small-128k-online",
    "ai:apitoken": "<your perplexity API key>"
  }
}

Google (Gemini)

To use Google's Gemini models from Google AI Studio:

json
{
  "[email protected]": {
    "display:name": "Gemini 2.0",
    "display:order": 6,
    "ai:*": true,
    "ai:apitype": "google",
    "ai:model": "gemini-2.0-flash-exp",
    "ai:apitoken": "<your Google AI API key>"
  }
}

OpenRouter

To use OpenRouter's models:

json
{
  "ai@openrouter": {
    "display:name": "OpenRouter (Qwen)",
    "display:order": 7,
    "ai:*": true,
    "ai:model": "qwen/qwen3-next-80b-a3b-thinking",
    "ai:apitoken": "<openrouter-key>",
    "ai:baseurl": "https://openrouter.ai/api/v1"
  }
}

Multiple Presets Example

You can define multiple presets in your ai.json file:

json
{
  "ai@claude-sonnet": {
    "display:name": "Claude 3 Sonnet",
    "display:order": 1,
    "ai:*": true,
    "ai:apitype": "anthropic",
    "ai:model": "claude-3-5-sonnet-latest",
    "ai:apitoken": "<your anthropic API key>"
  },
  "ai@openai-gpt41": {
    "display:name": "GPT-4.1",
    "display:order": 2,
    "ai:*": true,
    "ai:model": "gpt-4.1",
    "ai:apitoken": "<your OpenAI API key>"
  },
  "ai@ollama-llama": {
    "display:name": "Ollama - Llama2",
    "display:order": 3,
    "ai:*": true,
    "ai:baseurl": "http://localhost:11434/v1",
    "ai:name": "llama2",
    "ai:model": "llama2",
    "ai:apitoken": "ollama"
  },
  "ai@perplexity-sonar": {
    "display:name": "Perplexity Sonar",
    "display:order": 4,
    "ai:*": true,
    "ai:apitype": "perplexity",
    "ai:model": "llama-3.1-sonar-small-128k-online",
    "ai:apitoken": "<your perplexity API key>"
  }
}

The display:order value determines the order in which presets appear in the dropdown menu.

Remember to set your default preset in settings.json:

json
{
  "ai:preset": "ai@claude-sonnet"
}

Using a Proxy

If you need to route AI requests through an HTTP proxy, you can add the ai:proxyurl setting to any preset:

json
{
  "ai@claude-with-proxy": {
    "display:name": "Claude 3 Sonnet (via Proxy)",
    "display:order": 1,
    "ai:*": true,
    "ai:apitype": "anthropic",
    "ai:model": "claude-3-5-sonnet-latest",
    "ai:apitoken": "<your anthropic API key>",
    "ai:proxyurl": "http://proxy.example.com:8080"
  }
}

The proxy URL should be in the format http://host:port or https://host:port. This setting works with all AI providers except Wave Cloud AI (the default).


File: docs/docs/config.mdx


import { Kbd } from "@site/src/components/kbd";
import { PlatformProvider, PlatformSelectorButton } from "@site/src/components/platformcontext";
import { VersionBadge, DeprecatedBadge } from "@site/src/components/versionbadge";

Wave's configuration files are located at ~/.config/waveterm/.

The main configuration file is settings.json (~/.config/waveterm/settings.json).

The file is structured as a mostly flat JSON file. Instead of using sub-objects we prefer to
use ":" as level separators.

:::info

The easiest way to edit your config files is to use the wsh editconfig command which will open your Wave config file in our built-in preview editor.

text
wsh editconfig

:::

Configuration Keys

Key Name Type Function
app:globalhotkey string A systemwide keybinding to open your most recent wave window. This is a set of key names separated by :. For more info, see Customizable Systemwide Global Hotkey
app:dismissarchitecturewarning bool Disable warnings on app start when you are using a non-native architecture for Wave. For more info, see Why does Wave warn me about ARM64 translation when it launches?.
app:defaultnewblock string Sets the default new block (Cmd:n, Cmd:d). "term" for terminal block, "launcher" for launcher block (default = "term")
app:showoverlayblocknums bool Set to false to disable the Ctrl+Shift block number overlay that appears when holding Ctrl+Shift (defaults to true)
app:ctrlvpaste bool On Windows/Linux, when null (default) uses Control+V on Windows only. Set to true to force Control+V on all non-macOS platforms, false to disable the accelerator. macOS always uses Command+V regardless of this setting
app:confirmquit bool Set to false to disable the quit confirmation dialog when closing Wave Terminal (defaults to true, requires app restart)
app:hideaibutton bool Set to true to hide the AI button in the tab bar (defaults to false)
app:disablectrlshiftarrows bool Set to true to disable Ctrl+Shift block-navigation keybindings (Arrow and h/j/k/l) (defaults to false)
app:disablectrlshiftdisplay bool Set to true to disable the Ctrl+Shift visual indicator display (defaults to false)
app:focusfollowscursor string Controls whether block focus follows cursor movement: "off" (default), "on" (all blocks), or "term" (terminal blocks only)
app:tabbar string Controls the position of the tab bar: "top" (default) for a horizontal tab bar at the top of the window, or "left" for a vertical tab bar on the left side of the window
ai:preset string the default AI preset to use
ai:baseurl string Set the AI Base Url (must be OpenAI compatible)
ai:apitoken string your AI api token
ai:apitype string defaults to "open_ai", but can also set to "azure" (forspecial Azure AI handling), "anthropic", or "perplexity"
ai:name string string to display in the Wave AI block header
ai:model string model name to pass to API
ai:apiversion string for Azure AI only (when apitype is "azure", this will default to "2023-05-15")
ai:orgid string
ai:maxtokens int max tokens to pass to API
ai:timeoutms int timeout (in milliseconds) for AI calls
ai:proxyurl string HTTP proxy URL for AI API requests (does not apply to Wave Cloud AI)
conn:askbeforewshinstall bool set to false to disable popup asking if you want to install wsh extensions on new machines
conn:localhostdisplayname string override the display name for localhost in the UI (e.g., set to "My Laptop" or "Local", or set to empty string to hide the name)
term:fontsize float the fontsize for the terminal block
term:fontfamily string font family to use for terminal block
term:disablewebgl bool set to true to disable WebGL acceleration in terminal (default false)
term:localshellpath string set to override the default shell path for local terminals
term:localshellopts string[] set to pass additional parameters to the term:localshellpath (example: ["-NoLogo"] for PowerShell will remove the copyright notice)
term:copyonselect bool set to false to disable terminal copy-on-select
term:scrollback int size of terminal scrollback buffer, max is 10000
term:theme string preset name of terminal theme to apply by default (default is "default-dark")
term:transparency float64 set the background transparency of terminal theme (default 0.5, 0 = not transparent, 1.0 = fully transparent)
term:allowbracketedpaste bool allow bracketed paste mode in terminal (default false)
term:shiftenternewline bool when enabled, Shift+Enter sends escape sequence + newline (\u001b\n) instead of carriage return, useful for claude code and similar AI coding tools (default false)
term:macoptionismeta bool on macOS, treat the Option key as Meta key for terminal keybindings (default false)
term:cursor string terminal cursor style. valid values are block (default), underline, and bar
term:cursorblink bool when enabled, terminal cursor blinks (default false)
term:bellsound bool when enabled, plays the system beep sound when the terminal bell (BEL character) is received (default false)
term:bellindicator bool when enabled, shows a visual indicator in the tab when the terminal bell is received (default false)
term:osc52 string controls OSC 52 clipboard behavior: always (default, allows OSC 52 at any time) or focus (requires focused window and focused block)
term:durable bool makes remote terminal sessions durable across network disconnects (defaults to false)
term:showsplitbuttons bool when enabled, shows split horizontal and vertical buttons in the terminal block header (defaults to false)
editor:minimapenabled bool set to false to disable editor minimap
editor:stickyscrollenabled bool enables monaco editor's stickyScroll feature (pinning headers of current context, e.g. class names, method names, etc.), defaults to false
editor:wordwrap bool set to true to enable word wrapping in the editor (defaults to false)
editor:fontsize float64 set the font size for the editor (defaults to 12px)
editor:inlinediff bool set to true to show diffs inline instead of side-by-side, false for side-by-side (defaults to undefined which uses Monaco's responsive behavior)
preview:showhiddenfiles bool set to false to disable showing hidden files in the directory preview (defaults to true)
preview:defaultsort string sets the default sort column for directory preview. "name" (default) sorts alphabetically by name ascending; "modtime" sorts by last modified time descending (newest first)
markdown:fontsize float64 font size for the normal text when rendering markdown in preview. headers are scaled up from this size, (default 14px)
markdown:fixedfontsize float64 font size for the code blocks when rendering markdown in preview (default is 12px)
web:openlinksinternally bool set to false to open web links in external browser
web:defaulturl string default web page to open in the web widget when no url is provided (homepage)
web:defaultsearch string search template for web searches. e.g. https://www.google.com/search?q={query}. "{query}" gets replaced by search term
autoupdate:enabled bool enable/disable checking for updates (requires app restart)
autoupdate:intervalms float64 time in milliseconds to wait between update checks (requires app restart)
autoupdate:installonquit bool whether to automatically install updates on quit (requires app restart)
autoupdate:channel string the auto update channel "latest" (stable builds), or "beta" (updated more frequently) (requires app restart)
tab:preset string a "bg@" preset to automatically apply to new tabs. e.g. bg@green. should match the preset key. deprecated in favor of tab:background
tab:background string a "bg@" preset to automatically apply to new tabs. e.g. bg@green. should match the preset key
tab:confirmclose bool if set to true, a confirmation dialog will be shown before closing a tab (defaults to false)
widget:showhelp bool whether to show help/tips widgets in right sidebar
window:transparent bool set to true to enable window transparency (cannot be combined with window:blur) (macOS and Windows only, requires app restart, see note on Windows compatibility)
window:blur bool set to enable window background blurring (cannot be combined with window:transparent) (macOS and Windows only, requires app restart, see note on Windows compatibility)
window:opacity float64 0-1, window opacity when window:transparent or window:blur are set
window:bgcolor string set the window background color (should be hex: #xxxxxx)
window:reducedmotion bool set to true to disable most animations
window:tilegapsize int set to change override default gap size (in CSS pixels) between blocks
window:magnifiedblockopacity float64 change the opacity of a magnified block (must be between 0 and 1, defaults to 0.6)
window:magnifiedblocksize float64 change the size of a magnified block as a percentage of the dimensions of its parent layout (must be between 0 and 1, defaults to 0.9)
window:magnifiedblockblurprimarypx int change the blur in CSS pixels that is applied directly behind a magnified block (see backdrop-filter for more info on how this gets applied)
window:magnifiedblockblursecondarypx int change the blur in CSS pixels that is applied to the visible portions of non-magnified blocks when a block is magnified (see backdrop-filter for more info on how this gets applied)
window:maxtabcachesize int number of tabs to cache. when tabs are cached, switching between them is very fast. (defaults to 10)
window:showmenubar bool set to use the OS-native menu bar (Windows and Linux only, requires app restart)
window:nativetitlebar bool set to use the OS-native title bar, rather than the overlay (Windows and Linux only, requires app restart)
window:disablehardwareacceleration bool set to disable Chromium hardware acceleration to resolve graphical bugs (requires app restart)
window:fullscreenonlaunch bool set to true to launch the foreground window in fullscreen mode (defaults to false)
window:savelastwindow bool when true, the last window that is closed is preserved and is reopened the next time the app is launched (defaults to true)
window:confirmonclose bool when true, a prompt will ask a user to confirm that they want to close a window if it has an unsaved workspace with more than one tab (defaults to true)
window:dimensions string set the default dimensions for new windows using the format "WIDTHxHEIGHT" (e.g. "1920x1080"). when a new window is created, these dimensions will be automatically applied. The width and height values should be specified in pixels.
telemetry:enabled bool set to enable/disable telemetry

For reference, this is the current default configuration (v0.14.0):

json
{
    "ai:preset": "ai@global",
    "ai:model": "gpt-5-mini",
    "ai:maxtokens": 4000,
    "ai:timeoutms": 60000,
    "app:defaultnewblock": "term",
    "app:confirmquit": true,
    "app:hideaibutton": false,
    "app:disablectrlshiftarrows": false,
    "app:disablectrlshiftdisplay": false,
    "app:focusfollowscursor": "off",
    "autoupdate:enabled": true,
    "autoupdate:installonquit": true,
    "autoupdate:intervalms": 3600000,
    "conn:askbeforewshinstall": true,
    "conn:wshenabled": true,
    "editor:minimapenabled": true,
    "web:defaulturl": "https://github.com/wavetermdev/waveterm",
    "web:defaultsearch": "https://www.google.com/search?q={query}",
    "window:tilegapsize": 3,
    "window:maxtabcachesize": 10,
    "window:nativetitlebar": true,
    "window:magnifiedblockopacity": 0.6,
    "window:magnifiedblocksize": 0.9,
    "window:magnifiedblockblurprimarypx": 10,
    "window:fullscreenonlaunch": false,
    "window:magnifiedblockblursecondarypx": 2,
    "window:confirmclose": true,
    "window:savelastwindow": true,
    "telemetry:enabled": true,
    "term:bellsound": false,
    "term:bellindicator": false,
    "term:osc52": "always",
    "term:cursor": "block",
    "term:cursorblink": false,
    "term:copyonselect": true,
    "term:durable": false,
    "waveai:showcloudmodes": true,
    "waveai:defaultmode": "waveai@balanced",
    "preview:defaultsort": "name"
}

:::warning

If you installed Wave pre-v0.9.0 your configuration file will be located at
~/.waveterm/config/settings.json. This includes all of the other configuration
files as well: termthemes.json, presets.json, and widgets.json.

:::

Environment Variable Resolution

To avoid putting secrets directly in config files, Wave supports environment variable resolution using $ENV:VARIABLE_NAME or $ENV:VARIABLE_NAME:fallback syntax. This works for any string value in any config file (settings.json, presets.json, ai.json, etc.).

json
{
  "ai:apitoken": "$ENV:OPENAI_APIKEY",
  "ai:baseurl": "$ENV:AI_BASEURL:https://api.openai.com/v1"
}

WebBookmarks Configuration

WebBookmarks allows you to store and manage web links with customizable display preferences. The bookmarks are stored in a JSON file (bookmarks.json) as a key-value map where the key (id) is an arbitrary identifier for the bookmark. By convention, you should start your ids with "bookmark@". In the web widget, you can pull up your bookmarks using

Bookmark Structure

Each bookmark follows this structure (only url is required):

json
{
  "url": "https://example.com",
  "title": "Example Site",
  "iconurl": "https://example.com/custom-icon.png",
  "display:order": 1
}

Fields

Field Type Description
url string Required. The URL of the bookmark.
title string Optional. A display title for the bookmark.
icon string Optional, rarely used. Overrides the default favicon with an icon name.
iconcolor string Optional, rarely used. Sets a custom color for the specified icon.
iconurl string Optional. Provides a custom icon URL, useful if the favicon is incorrect (e.g., for dark mode compatibility).
display:order float64 Optional. Defines the order in which bookmarks appear.

Example `bookmarks.json`

json
{
  "bookmark@google": {
    "url": "https://www.google.com",
    "title": "Google"
  },
  "bookmark@claude": {
    "url": "https://claude.ai",
    "title": "Claude AI"
  },
  "bookmark@wave": {
    "url": "https://waveterm.dev",
    "title": "Wave Terminal",
    "display:order": -1
  },
  "bookmark@wave-github": {
    "url": "https://github.com/wavetermdev/waveterm",
    "title": "Wave Github",
    "iconurl": "https://github.githubassets.com/favicons/favicon-dark.png"
  },
  "bookmark@chatgpt": {
    "url": "https://chatgpt.com",
    "iconurl": "https://cdn.oaistatic.com/assets/favicon-miwirzcw.ico"
  },
  "bookmark@wave-pulls": {
    "url": "https://github.com/wavetermdev/waveterm/pulls",
    "title": "Wave Pull Requests",
    "iconurl": "https://github.githubassets.com/favicons/favicon-dark.png"
  }
}

Behavior

  • If iconurl is set, it fetches the icon from the specified URL instead of the site's default favicon.
  • Bookmarks are sorted based on display:order (if provided), otherwise by id.
  • icon and iconcolor are rarely needed since the default behavior fetches the site's favicon.
  • favicons are refreshed every 24-hours

Terminal Theming

User-defined terminal themes are located in ~/.config/waveterm/termthemes.json.

This JSON file is structured as an object, with each sub-key defining a theme.
Themes are applied by right-clicking on the terminal's header bar and selecting an entry from the "Themes" sub-menu. Alternatively they can be applied to
the block's metadata key term:theme. This uses the JSON key value as the identifier. Note, for best consistency all colors should be of the format "#rrggbb" or "#rrggbbaa" (aa = alpha channel for transparency).

text
wsh setmeta this term:theme="default-dark"

Here is an example of defining a full terminal theme. All of the built-in themes are defined here: https://github.com/wavetermdev/waveterm/blob/main/pkg/wconfig/defaultconfig/termthemes.json (if you'd like to add a popular terminal theme, please submit a PR!)

json
{
  "default-dark": {
    "display:name": "Default Dark",
    "display:order": 1,
    "black": "#757575",
    "red": "#cc685c",
    "green": "#76c266",
    "yellow": "#cbca9b",
    "blue": "#85aacb",
    "magenta": "#cc72ca",
    "cyan": "#74a7cb",
    "white": "#c1c1c1",
    "brightBlack": "#727272",
    "brightRed": "#cc9d97",
    "brightGreen": "#a3dd97",
    "brightYellow": "#cbcaaa",
    "brightBlue": "#9ab6cb",
    "brightMagenta": "#cc8ecb",
    "brightCyan": "#b7b8cb",
    "brightWhite": "#f0f0f0",
    "gray": "#8b918a",
    "cmdtext": "#f0f0f0",
    "foreground": "#c1c1c1",
    "selectionBackground": "",
    "background": "#00000077",
    "cursorAccent": ""
  }
}

:::info

You can easily open the termthemes.json config file by running:

text
wsh editconfig termthemes.json

:::

Key Name Type ANSI FG# ANSI BG# Function
display:name string the name as it will appear in the UI context menu
display:order float entries in the context menu are sorted by display:order
black CSS color 30 40 color for black
red CSS color 31 41 color for red
green CSS color 32 42 color for green
yellow CSS color 33 43 color for yellow
blue CSS color 34 44 color for blue
magenta CSS color 35 45 color for magenta
cyan CSS color 36 46 color for cyan
white CSS color 37 47 color for white
brightBlack CSS color 90 100 color for bright black
brightRed CSS color 91 101 color for bright red
brightGreen CSS color 92 102 color for bright green
brightYellow CSS color 93 103 color for bright yellow
brightBlue CSS color 94 104 color for bright blue
brightMagenta CSS color 95 105 color for bright magenta
brightCyan CSS color 96 106 color for bright cyan
brightWhite CSS color 97 107 color for bright white
gray CSS color currently unused
cmdtext CSS color currently unused
foreground CSS color foreground color (default when no color code is applied)
background CSS color background color (default when no color code is applied), must have alpha channel (#rrggbbaa) if you want the terminal to be transparent
cursorAccent CSS color color for cursor
selectionBackground CSS color background color for selected text

Customizable Systemwide Global Hotkey

Wave allows settings a custom global hotkey to open your most recent window from anywhere in your computer. This has the name "app:globalhotkey" in the settings.json file and takes the form of a series of key names separated by the : character.

Examples

As a practical example, suppose you want a value of F5 as your global hotkey. Then you can simply set the value of "app:globalhotkey" to "F5" and reboot Wave to make that your global hotkey.

As a less practical example, suppose you use the combination of the keys Ctrl, Option, and e. Then the value for this keybinding would be "Ctrl:Option:e".

Allowed Key Names

We support the following key names:

  • Ctrl
  • Cmd
  • Shift
  • Alt
  • Option
  • Meta
  • Super
  • Digits (non-numpad) represented by c{Digit0} through c{Digit9}
  • Letters a though z
  • F keys F1 through F20
  • Soft keys Soft1 through Soft4. These are essentially the same as F21 through F24.
  • Space represented as either Space or a literal space  &nbsp;
  • Enter (This is labeled as return on Mac)
  • Tab
  • CapsLock
  • NumLock
  • Backspace (This is labeled as delete on Mac)
  • Delete
  • Insert
  • The arrow keys ArrowUp, ArrowDown, ArrowLeft, and ArrowRight
  • Home
  • End
  • PageUp
  • PageDown
  • Esc
  • Volume controls AudioVolumeUp, AudioVolumeDown, AudioVolumeMute
  • Media controls MediaTrackNext, MediaTrackPrevious, MediaPlayPause, and MediaStop
  • PrintScreen
  • Numpad keys represented by c{Numpad0} through c{Numpad9}
  • The numpad decimal represented by Decimal
  • The numpad plus/add represented by Add
  • The numpad minus/subtract represented by Subtract
  • The numpad star/multiply represented by Multiply
  • The numpad slash/divide represented by Divide

File: docs/docs/connections.mdx


import { VersionBadge } from "@site/src/components/versionbadge";

Connections

Wave allows users to connect to various machines and unify them together in a way that preserves the unique behavior of each. At the moment, this extends to SSH remote connections and local WSL connections.

Access a Connection in a Block

The easiest way to access connections is to click the icon. From there, you can type one of the following to depending on the connection you want:

For SSH Connections:

  • [user]@[host]
  • [host]
  • [user]@[host]:[port]

For WSL Connections:

  • wsl://<distribution name>

Alternatively, if the connection already exists in the dropdown list, you can either click it or navigate to it with arrow keys and press enter to connect.

Different Types of Connections

As there are several different types of connections, not all of the types have access to the same features. SSH and WSL connections can always work in terminal widgets, and if wsh shell extensions are installed, they can also work in preview widgets and the sysinfo widget.

What are wsh Shell Extensions?

wsh is a small program that helps manage waveterm regardless of which machine you are currently connected to. It is always included on your host machine, but you also have the option to install it when connecting to SSH and WSL Connections. If it is installed on the connection, it is installed at ~/.waveterm/bin/wsh. Then, when wave connects to your connection (and only when wave connects to your connection), the following happens:

  • ~/.waveterm/bin is added to your PATH for that individual session. This allows the user to use the wsh command without providing the complete path.
  • Several environment variables are injected into the session to make certain tasks with wsh easier. These are listed below.
  • The user-defined environment variables in the cmd:env entry ofconnections.json are injected into the session.
  • The user-defined initialization scripts located in connections.json are run. For more information on these scripts, see the section below.

If this fails for some reason, Wave will attempt to run without wsh. You will see this indicated by a small `` icon in the block header. For more info on what wsh is capable of, see wsh command. And if you wish to view the source code of wsh, you can find it here.

With wsh installed, you have the ability to view certain widgets from the remote machine as if it were your host, for instance the files and sysinfo widgets. In addition, wsh can be used to influence the widgets across various machines. As a simple example, you can close a widget on the host machine by using the wsh command in a terminal window on a remote machine. For more information on what you can accomplish with wsh, take a look here.

Additional Environment Variables

As mentioned above, wsh injects a few environment variables in remote sessions for the user's convenience. These are listed below:

Variable Name Description
TERM_PROGRAM Set to waveterm in wave.
WAVETERM This is set to 1 in wave.
WAVETERM_BLOCKID The id of the block containing your current terminal widget.
WAVETERM_CLIENTID The id of the RPC Client being used by your current terminal widget.
WAVETERM_CONN The name of the remote connection being used by your current terminal widget.
WAVETERM_TABID The id of the tab containing your current terminal widget.
WAVETERM_VERSION The current semver version of wave.
WAVETERM_WORKSPACEID The id of thw workspace containing your current terminal widget.

Initialization Scripts

Wave provides you with options for running initialization scripts on your remote machines when connecting to them. These are defined in connections.json and can take either the form of the path of a script or a short script written directly in the file. If multiple scripts are defined, the most specific one relevant to the current shell is applied. The keywords for the scripts are:

Script Keyword Shells Where Applied
cmd:initscript all shells
cmd:initscript.sh bash and zsh
cmd:initscript.bash bash
cmd:initscript.zsh zsh
cmd:initscript.pwsh pwsh
cmd:initscript.fish fish

Add a New Connection to the Dropdown

The SSH values that are loaded into the dropdown by default are obtained by parsing the internal config/connections.json file in addition to your ~/.ssh/config and /etc/ssh/ssh_config files. Adding a new connection can be added in a couple ways:

  • adding a new Host to one of your ssh config files, typically the ~/.ssh/config file
  • adding a new entry in the internal config/connections.json file
  • manually typing your connection into the connection box (if this successfully connects, the connection will be added to the internal config/connections.json file)
  • use wsh ssh [user]@[host] in your terminal (if this successfully connects, the connection will be added to the internal config/connections.json file)

WSL connections are added by searching the installed WSL distributions as they appear in the Windows Registry. They also exist in the config/connections.json file similarly to SSH connections.

SSH Config Parsing

At the moment, we are capable of parsing any SSH config file that does not contain the Match keyword. This keyword is incompatible with a library we are using, but we are hoping to fix that soon. While all other valid keywords are parsed, we only support the functionality of a small subset of them at the moment:

Keyword Description
Host The pattern to match when attempting to connect via [user]@[host]. We list hosts that do not contain any wildcards characters (*, ?, or !). Even if a host pattern contains wildcards, it will still be parsed when determining the values associated with the keys as usual.
User The user of the SSH remote connection. This will default to the current user on the local machine if not specified.
HostName The real host name of the machine to log into. An IP address can be used if desired. This will default to the Host if not specified.
Port The port to connect to the remote on. 22 is the default if not specified.
IdentityFile This can be specified more than once per host. It gives the path to a private identity file (id_rsa, id_ed25519, id_ecdsa, etc.) that is used to authenticate the connection. Each will be tried in order, and they can be encrypted with a passphrase if desired. If no value is set, the default is to try in order: ~/.ssh/id_rsa, ~/.ssh/id_ecdsa, ~/.ssh/id_ecdsa_sk, ~/.ssh/id_ed25519_sk, ~/.ssh/id_dsa.
BatchMode If set to true, user interaction via password, challenge/response, and publickey passphrase authentication will be disabled. It is set to false by default.
PubkeyAuthentication (partial) This is used to specify if pubkey authentication should be attempted. It is partially implementented as the unbound and host-bound values simply work the same as the yes value. The default is yes.
PasswordAuthentication This is used to specify if password authentication should be attempted. The default is yes.
KbdInteractiveAuthentication This is used to specify if keyboard-interactive authentication should be attempted. The default is yes.
PreferredAuthentications (partial) Specifies the order the client should attempt to authenticate in. It is partially implemented as it does not support gssapi-with-mic or hostbased authentication. The default is publickey,keyboard-interactive,password
AddKeysToAgent (partial) This option will automatically add keys and their corresponding passphrase to your running ssh agent if it is enabled. It is partially supported as it can only accept yes and no as valid inputs. Other inputs such as confirm or a time interval will behave the same as no. The default value is no.
IdentityAgent Specifies the Unix Domain Socket used to communicate with the SSH Agent. This is used to overwrite the SSH_AUTH_SOCK identity agent.
IdentitiesOnly Specifies that only the specified authentication identity files should be used. This is either the default files or the ones specified with the IdentityFile keyword. It can accept yes or no. The default value is no.
ProxyJump Specifies one or more jump proxies in a comma separated list. Each will be visited sequentially using TCP forwarding before connecting to the desired connection (also using TCP forwarding). It can be set to none to disable the feature.
UserKnownHostsFile Provides the location of one or more user host key database files for recording trusted remote connections. The filenames are entered in the same string and separated by whitespace. The default value is "~/.ssh/known_hosts ~/.ssh/known_hosts2".
GlobalKnownHostsFile Provides the location of one or more global host key database files for recording trusted remote connections. The filenames are entered in the same string and separated by whitespace. The default value is "/etc/ssh/ssh_known_hosts /etc/ssh/ssh_known_hosts2".

Example SSH Config Host

For a quick example, a host in your config file may look like:

text
Host myhost
   User username
   HostName 203.0.113.254
   IdentityFile ~/.ssh/id_rsa
   AddKeysToAgent yes

You would then be able to access this connection with myhost or username@myhost. And if you wanted to manually specify a port such as port 2222, you could do that by either adding Port 2222 to the config file or connecting to username@myhost:2222.

Internal SSH Configuration

In addition to the regular ssh config file, wave also has its own config file to manage separate variables. These include

Keyword Description
conn:wshenabled This boolean allows wsh to be used for your connection, if it is set to false, wsh will never be used for that connection. It defaults to true.
conn:askbeforewshinstall This boolean is used to prompt the user before installing wsh. If it is set to false, wsh will automatically be installed instead without prompting. It defaults to true.
conn:wshpath A string indicating the path to the wsh executable on the connection. It defaults to "~/.waveterm/bin/wsh".
conn:shellpath A string indicating the path to the shell executable on the connection. If not set, the output of $SHELL on the connection will be used.
conn:ignoresshconfig This boolean allows wave to ignore the ~/.ssh/config file for resolving keywords for this connection. The regular defaults will be used, but all changes to those must be specified in the connections.json file instead. This defaults to false.
display:hidden This boolean hides the connection from the dropdown list. It defaults to false
display:order This float determines the order of connections in the connection dropdown. It defaults to 0.
term:fontsize This int can be used to override the terminal font size for blocks using this connection. The block metadata takes priority over this setting. It defaults to null which means the global setting will be used instead.
term:fontfamily This string can be used to specify a terminal font family for blocks using this connection. The block metadata takes priority over this setting. It defaults to null which means the global setting will be used instead.
term:theme This string can be used to specify a terminal theme for blocks using this connection. The block metadata takes priority over this setting. It defaults to null which means the global setting will be used instead.
cmd:env A json object with key value pairs of environment variables and the value they should be set to for this remote. This only works if wsh is enabled.
cmd:initscript A script or a path to a script that runs when initializing this connection with any shell. This only works if wsh is enabled.
cmd:initscript.sh A script or a path to a script that runs when initializing this connection with POSIX shells like bash or zsh. This only works if wsh is enabled.
cmd:initscript.bash A script or a path to a script that runs when initializing this connection with the bash shell. This only works if wsh is enabled.
cmd:initscript.zsh A script or a path to a script that runs when initializing this connection with the zsh shell. This only works if wsh is enabled.
cmd:initscript.pwsh A script or a path to a script that runs when initializing this connection with the pwsh shell. This only works if wsh is enabled.
cmd:initscript.fish A script or a path to a script that runs when initializing this connection with the fish shell. This only works if wsh is enabled.
ssh:user A string that indicates the username of the connection. Can be used to override the value in ~/.ssh/config or to set it if the ssh config is being ignored.
ssh:hostname A string representing the internal hostname of the connection. Can be used to override the value in ~/.ssh/config or to set it if the ssh config is being ignored.
ssh:port A string to indicate the numerical port to connect on. Can be used to override the value in ~/.ssh/config or to set it if the ssh config is being ignored.
ssh:identityfile A list of strings containing the paths to identity files that will be used. If a wsh ssh command using the -i flag is successful, the identity file will automatically be added here. These are used before the ~/.ssh/config values.
ssh:identitiesonly A boolean indicating if only the specified identity files should be used. This means only the files set with the ssh:identityfile flag or the defaults. Can be used to override the value in ~/.ssh/config or to set it if the ssh config is being ignored.
ssh:batchmode A boolean indicating if password and passphrase prompts should be skipped. Can be used to override the value in ~/.ssh/config or to set it if the ssh config is being ignored.
ssh:pubkeyauthentication A boolean indicating if public key authentication is enabled. Can be used to override the value in ~/.ssh/config or to set it if the ssh config is being ignored.
ssh:passwordauthentication A boolean indicating if password authentication is enabled. Can be used to override the value in ~/.ssh/config or to set it if the ssh config is being ignored.
ssh:passwordsecretname A string specifying the name of a secret stored in the secret store to use as the SSH password. When set, this password will be automatically used for password authentication instead of prompting the user.
ssh:kbdinteractiveauthentication A boolean indicating if keyboard interactive authentication is enabled. Can be used to override the value in ~/.ssh/config or to set it if the ssh config is being ignored.
ssh:preferredauthentications A list of strings indicating an ordering of different types of authentications. Each authentication type will be tried in order. This supports "publickey", "keyboard-interactive", and "password" as valid types. Other types of authentication are not handled and will be skipped. Can be used to override the value in ~/.ssh/config or to set it if the ssh config is being ignored.
ssh:addkeystoagent A boolean indicating if the keys used for a connection should be added to the ssh agent. Can be used to override the value in ~/.ssh/config or to set it if the ssh config is being ignored.
ssh:identityagent A string giving the path to the unix domain socket of the identity agent. Can be used to overwrite the value in ~/.ssh/config or to set it if the ssh config is being ignored.
ssh:proxyjump A list of strings specifying the names of hosts that must be successively visited with tcp forwarding to establish a connection. Can be used to overwrite the value in ~/.ssh/config or to set it if the ssh config is being ignored.
ssh:userknownhostsfile A list containing the paths of any user host key database files used to keep track of authorized connections. Can be used to overwrite the value in ~/.ssh/config or to set it if the ssh config is being ignored.
ssh:globalknownhostsfile A list containing the paths of any global host key database files used to keep track of authorized connections. Can be used to overwrite the value in ~/.ssh/config or to set it if the ssh config is being ignored.

SSH Agent Detection

Wave resolves the identity agent path in this order:

  • If ssh:identityagent (or IdentityAgent in SSH config) is set for the connection, that socket or pipe is used.
  • If not set on Windows, Wave falls back to the built-in OpenSSH agent pipe \\.\pipe\openssh-ssh-agent. Ensure the OpenSSH Authentication Agent service is running.
  • If not set on macOS/Linux, Wave queries your shell environment for SSH_AUTH_SOCK to detect the agent path automatically.

Example Internal Configurations

Here are a couple examples of things you can do using the internal configuration file connections.json:

Hiding a Connection

Suppose you have a connection named github.com in your ~/.ssh/config file that shows up as [email protected] in the connections dropdown. While it does belong in the config file for authentication reasons, it makes no sense to be in the dropdown since it doesn't involve connecting to a remote environment. In that case, you can hide it as in the example below:

json
{
    <... other connections go here ...>,
    "[email protected]" : {
        "display:hidden": true
    },
    <... other connections go here ...>
}

Moving a Connection

Suppose you have a connection named rarelyused that shows up as myusername@rarelyused:9999 in the connections dropdown. Since it's so rarely used, you would prefer to move it later in the list. In that case, you can move it as in the example below:

json
{
    <... other connections go here ...>,
    "myusername@rarelyused:9999" : {
        "display:order": 100
    },
    <... other connections go here ...>
}

Theming a Connection

Suppose you have a connection named myhost that shows up as myusername@myhost in the connections dropdown. You use this connection a lot, but you keep getting it mixed up with your local connections. In this case, you can use the internal configuration file to style it differently. For example:

json
{
    <... other connections go here ...>,
    "myusername@myhost" : {
        "term:theme": "warmyellow",
        "term:fontsize": 16,
        "term:fontfamily": "menlo"
    },
    <... other connections go here ...>
}

This style, font size, and font family will then only apply to the widgets that are using this connection.

Entirely Defined Internally

Suppose you want to set up a connection but have no desire to learn the syntax of ~/.ssh/config. In this case, you can entirely define the connection in your connections.json file. For example:

json
{
    <... other connections go here ...>,
    "myusername@myhost" : {
        "ssh:hostname": "190.0.2.0",
        "ssh:identityfile": ["~/.ssh/myidentityfile"],
        "ssh:identitiesonly": true,
        "ssh:addkeystoagent": true
    },
    <... other connections go here ...>
}

This will create a connection without that connection needing to be in the ~/.ssh/config file. A couple additional options are set as well as an example of how that can be done.

Disabling wsh for a Connection

While Wave provides an option disable wsh when first connecting to a remote, there are cases where you may wish to disable it afterward. The easiest way to do this is by editing the connections.json file. Suppose the connection shows up in the dropdown as root@wshless. Then you can disable it manually with the following line:

json
{
    <... other connections go here ...>,
    "root@wshless" : {
        "conn:enablewsh": false,
    },
    <... other connections go here ...>
}

Note that this same line gets added to your connections.json file automatically when you choose to disable wsh in gui when initially connecting.

Managing Connections with the CLI

The wsh command gives some commands specifically for interacting with the connections. You can view these here.

Troubleshooting Connections

Log Files

If there are issues with connections, the easiest first step is to enable debugging in a terminal widget that is trying to connect. To do this, click the `` button and hover over the Debug Connection item. From there you can select two log levels, Info and Verbose. After this, debug info will print out to the terminal during the connection.

If this is not sufficient, it is also possible to view the full log file. To do this, you can run the command wsh wavepath log to get the location of a log file.

Known Limitations

In the case that there is an error setting up wsh, your connection will still launch without wsh. However, depending on the debug info, there are a few things that can cause this.

Shell Type

Wave is capable of injecting wsh in the following shells:

  • bash
  • zsh
  • pwsh (powershell)
  • fish

If the shell is different than those, it is possible the wsh command will not work by default. The easiest way to fix this at the moment is the switch the shell type. This can be done by setting the conn:shellpath value with a path to one of the above shells in the connections.json file for the connection you are trying to use. Alternatively, you can use the chsh command to change the shell in that connection, but this will also take effect outside of wave. Once this is done, restart wave for the changes to take effect.

AllowTcpForwarding in sshd

Some systems have sshd configured to disable TCP forwarding by default. This can be found on the connection in the /etc/ssh/sshd_config file. In that file, search for the line containing AllowTcpForwarding. If this is set to no, it is likely the reason wsh will not work on your connection. In order to get wsh working, set the value for AllowTcpForwarding to either yes or local (they both provide different levels of permission but both work in this case). Then, restart the sshd service with whichever method your remote machine provides. Once that is done, restart wave, so it can reconnect with this change.


File: docs/docs/customization.mdx


Tab Themes

Right click on any tab to bring up a menu which allows you to rename the tab and select different backgrounds.

It is also possible to create your own background themes using custom colors, gradients, images and more by editing your backgrounds.json config file. To see how Wave's built-in tab backgrounds are defined, you can check out the default backgrounds.json file.

To apply a tab background to all new tabs by default, set the key tab:background in your Wave Config File to one of the background preset keys (e.g. "bg@ocean-depths"). The available built-in background keys can be found in the default backgrounds.json file.

Terminal Customization

Terminal Theme

Right click in the header area of any terminal block to bring up a menu which allows you to set a terminal
theme for that terminal.

You can set the default theme for all terminals (which haven't had their theme manually overridden) by editing your settings.json file and adding the key term:theme and setting it to the appropriate key. The keys can be found
in the default termthemes.json file.

If you add your own termthemes.json file in the config directory, you can also add your own custom terminal themes (just follow the same format).

Font Size

From the same context menu you can also change the font-size of the terminal. To change the default font size across all of your (non-overridden) terminals, you can set the config key term:fontsize to the size you want. e.g. { "term:fontsize": 14}.

Font Family

There is no UI to edit your default terminal font family. But, it can be overridden. In your settings.json file you can add the key term:fontfamily and set it to a font that is installed on your local system. If type a font that is not installed, or use a non-monospace font, your terminal will look terrible (don't do that ๐Ÿ™‚), delete the key to return to using the default.

Widgets Sidebar

See Custom Widgets for detailed documentation around changing what appears in your right widget sidebar.

Using widgets.json, you'll be able to remove any default widgets and add widgets of your own. You can fully customize the icons, colors, text, and defaults (like directories, webpages, AI model, remote connection, commands, etc.) of your custom widgets.

You can also suppress the help widgets in the bottom right by setting the config key widget:showhelp to false.

Tab Backgrounds

Wave supports powerful custom backgrounds for your tabs using images, patterns, gradients, and colors. The quickest way to set an image background is using the wsh setbg command:

bash
# Set an image background with 50% opacity (default)
wsh setbg ~/pictures/background.jpg

# Set a color background (use quotes to prevent # being interpreted as a shell comment)
wsh setbg "#ff0000"          # hex color
wsh setbg forestgreen        # CSS color name

# Adjust opacity
wsh setbg --opacity 0.3 ~/pictures/light-pattern.png
wsh setbg --opacity 0.7      # change only opacity of current background

# Image positioning options
wsh setbg --tile ~/pictures/texture.png          # create tiled pattern
wsh setbg --center ~/pictures/logo.png           # center without scaling
wsh setbg --center --size 200px ~/pictures/logo.png  # center with specific size (px, %, auto)

# Remove background
wsh setbg --clear

You can use any JPEG, PNG, GIF, WebP, or SVG image as your background. The --center option is particularly useful for logos or icons where you want to maintain the original size.

To preview the metadata for any background without applying it, use the --print flag:

bash
wsh setbg --print "#ff0000"

For more advanced customization options including gradients, colors, and saving your own custom backgrounds, check out our Tab Backgrounds documentation.


File: docs/docs/customwidgets.mdx


Custom Widgets

Wave allows users to create their own widgets to uniquely customize their experience for what works for them. While we plan on greatly expanding on this in the future, it is already possible to make some widgets that you can access at the press of a button. All widgets can be created by modifying the <WAVETERM_HOME>/config/widgets.json file. By adding a widget to this file, it is possible to add widgets to the widget bar. By default, the widget bar looks like this:

By adding additional widgets, it is possible to get a widget bar that looks like this:

The Structure of a Widget

All widgets share a similar structure that roughly looks like the example below:

json
"<widget name>": {
    "icon": "",
    "label": "",
    "color": "",
    "blockdef": {
        "meta": {
            "view": "term",
            "controller": "cmd",
            "cmd": ""
        }
    }
}

This consists of a couple different parts. First and foremost, each widget has a unique identifying name. The value associated with this name is the outer WidgetConfigType. It is outlined in red below:

This WidgetConfigType is shared between all types of widgets. That is to say, all widgets—regardless of type— will use the same keys for this. The accepted keys are:

Key Description
"display:order" (optional) Overrides the order of widgets with a number in case you want the widget to be different than the order provided in the widgets.json file. Defaults to 0.
"icon" (optional) The name of a font awesome icon. Defaults to "browser".
"color" (optional) A string representing a color as would be used in CSS. Hex codes and custom CSS properties are included. This defaults to "var(--secondary-text-color)" which is a color wave uses for text that should be differentiated from other text. Out of the box, it is "#c3c8c2".
"label" (optional) A string representing the label that appears underneath the widget. It will also act as a tooltip on hover if the "description" key isn't filled out. It is null by default.
"description" (optional) A description of what the widget does. If it is specified, this serves as a tooltip on hover. It is null by default.
"magnified" (optional) A boolean indicating whether or not the widget should launch magnfied. It is false by default.
"blockdef" This is where the the non-visual portion of the widget is defined. Note that all further definition takes place inside a meta object inside this one.
:::info

Font Awesome Icons

Font Awesome provides a ton of useful icons that you can use as a widget icon in your app. At its simplest, you can just provide the icon name and it will be used. For example, the string "house", will provide an icon containing a house. We also allow you to apply a few different styles to your icon by modifying the name as follows:

format description
<icon name> The plain icon with no additional styles applied.
solid@<icon name> Adds the fa-solid class to the icon to fill in the content with a fill color rather than leaving it a background.
regular@<icon name> Adds the fa-regular class to the icon to ensure the content will not have a fill color and will use a standard outline instead.
brands@<icon name> This is required to add the required fa-brands class to an icon associated with a brand. Without this, brand icons will not render properly. This will not work with icons that aren't brand icons.

:::

The other options are part of the inner MetaTSType (outlined in blue in the image). This contains all of the details about how the widget actually works. The valid keys vary with each type of widget. They will be individually explored in more detail below.

Terminal and CLI Widgets

A terminal widget, or CLI widget, is a widget that simply opens a terminal and runs a CLI command. They tend to look something like the example below:

json
{
    <... other widgets go here ...>,
    "<widget name>": {
        "icon": "",
        "label": "",
        "color": "",
        "blockdef": {
            "meta": {
                "view": "term",
                "controller": "cmd",
                "cmd": ""
            }
        }
    },
    <... other widgets go here ...>
}

The WidgetConfigType takes the usual options common to all widgets. The MetaTSType can include the keys listed below:

Key Description
"view" A string that specifies the general type of widget. In the case of custom terminal widgets, this must be set to "term".
"controller" A string that specifies the type of command being used. For more persistent shell sessions, set it to "shell". For one off commands, set it to "cmd". When "cmd" is set, the widget has an additional refresh button in its header that allows the command to be re-run.
"cmd" (optional) When the "controller" is set to "cmd", this option provides the actual command to be run. Note that because it is run as a command, there is no shell session unless you are launching a command that contains a shell session itself. Defaults to an empty string.
"cmd:args" (optional, array of strings) arguments to pass to the cmd
"cmd:shell" (optional) if cmd:shell if false (default), then we use cmd + cmd:args (suitable to pass to execve). if cmd:shell is true, then we just use cmd, and cmd can include spaces, and shell syntax (like pipes or redirections, etc.)
"cmd:interactive" (optional) When the "controller" is set to `"term", this boolean adds the interactive flag to the launched terminal. Defaults to false.
"cmd:login" (optional) When the "controller" is set to "term", this boolean adds the login flag to the term command. Defaults to false.
"cmd:runonstart" (optional) The command will rerun when the block is created or the app is started. Without it, you must manually run the command. Defaults to true.
"cmd:runonce" (optional) Runs on start, but then sets "cmd:runonce" and "cmd:runonstart" to false (so future runs require manual restarts)
"cmd:clearonstart" (optional) When the cmd runs, the contents of the block are cleared out. Defaults to false.
"cmd:closeonexit" (optional) Automatically closes the block if the command successfully exits (exit code = 0)
"cmd:closeonexitforce" (optional) Automatically closes the block if when the command exits (success or failure)
"cmd:closeonexitdelay (optional) Change the delay between when the command exits and when the block gets closed, in milliseconds, default 2000
"cmd:env" (optional) A key-value object represting environment variables to be run with the command. Defaults to an empty object.
"cmd:cwd" (optional) A string representing the current working directory to be run with the command. Currently only works locally. Defaults to the home directory.
"cmd:nowsh" (optional) A boolean that will turn off wsh integration for the command. Defaults to false.
"cmd:jwt" (optional) A boolean that forces adding JWT token to the environment. Required for running waveapps as widgets (both local and remote). Defaults to false.
"term:localshellpath" (optional) Sets the shell used for running your widget command. Only works locally. If left blank, wave will determine your system default instead.
"term:localshellopts" (optional) Sets the shell options meant to be used with "term:localshellpath". This is useful if you are using a nonstandard shell and need to provide a specific option that we do not cover. Only works locally. Defaults to an empty string.
"cmd:initscript" (optional) for "shell" controller only. an init script to run before starting the shell (can be an inline script or an absolute local file path)
cmd:initscript.sh" (optional) same as cmd:initscript but applies to bash/zsh shells only
cmd:initscript.bash" (optional) same as cmd:initscript but applies to bash shells only
cmd:initscript.zsh" (optional) same as cmd:initscript but applies to zsh shells only
cmd:initscript.pwsh" (optional) same as cmd:initscript but applies to pwsh/powershell shells only
cmd:initscript.fish" (optional) same as cmd:initscript but applies to fish shells only

Example Local Shell Widgets

If you have multiple shells installed on your machine, there may be times when you want to use a non-default shell. For cases like this, it is easy to create a widget for each.

Suppose you want a widget to launch a fish shell. Once you have fish installed on your system, you can define a widget as

json
{
    <... other widgets go here ...>,
    "fish" : {
        "icon": "fish",
        "color": "#4abc39",
        "label": "fish",
        "blockdef": {
            "meta": {
                "view": "term",
                "controller": "shell",
                "term:localshellpath": "/usr/local/bin/fish",
                "term:localshellopts": "-i -l"
            }
        }
    },
    <... other widgets go here ...>
}

This adds an icon to the widget bar that you can press to launch a terminal running the fish shell.

:::info
It is possible that fish is not in your path. If this is true, using "fish" as the value of "term:localshellpath" will not work. In these cases, you will need to provide a direct path to it. This is often somewhere like "/usr/local/bin/fish", but it may be different on your system.
:::

If you want to do the same for something like Powershell Core, or pwsh, you can define the widget as

json
{
    <... other widgets go here ...>,
    "pwsh" : {
        "icon": "rectangle-terminal",
        "color": "#2671be",
        "label": "pwsh",
        "blockdef": {
            "meta": {
                "view": "term",
                "controller": "shell",
                "term:localshellpath": "pwsh"
            }
        }
    },
    <... other widgets go here ...>
}

This adds an icon to the widget bar that you can press to launch a terminal running the pwsh shell.

:::info
It is possible that pwsh is not in your path. If this is true, using "pwsh" as the value of "term:localshellpath" will not work. In these cases, you will need to provide a direct path to it. This could be somewhere like "/usr/local/bin/pwsh" on a Unix system or "C:\\Program&nbsp;Files\\PowerShell\\7\\pwsh.exe" on
Windows. but it may be different on your system. Also note that both pwsh.exe and pwsh work on Windows, but only pwsh works on Unix systems.
:::

Example Remote Shell Widgets

If you want to open a terminal widget for a particular connection (SSH or WSL), you can use the connection meta key. The connection key's value should match connections.json (or what's in your connections dropdown menu). Note that you should only use the canonical name (do not use any custom "display:name" that you've set). For WSL that might look like wsl://Ubuntu, and for SSH connections that might look like user@remotehostname.

json
{
	<... other widgets go here ...>,
	"remote-term": {
		"icon": "rectangle-terminal",
		"label": "remote",
		"blockdef": {
			"meta": {
				"view": "term",
				"controller": "shell",
				"connection": "<connection>"
			}
		}
	},
	<... other widgets go here ...>
}

Example Cmd Widgets

Here are a few simple cmd widgets to serve as examples.

Suppose I want a widget that will run speedtest-go when opened. Then, I can define a widget as

json
{
    <... other widgets go here ...>,
    "speedtest" : {
        "icon": "gauge-high",
        "label": "speed",
        "blockdef": {
            "meta": {
                "view": "term",
                "controller": "cmd",
                "cmd": "speedtest-go --unix",
                "cmd:clearonstart": true
            }
        }
    },
    <... other widgets go here ...>
}

This adds an icon to the widget bar that you can press to launch a terminal running the speedtest-go --unix command.

Using "cmd" for the "controller" is the simplest way to accomplish this. "cmd:clearonstart" isn't necessary, but it makes it so every time the command is run (which can be done by right clicking the header and selecting Force Controller Restart), the previous contents are cleared out.

Now suppose I wanted to run a TUI app, for instance, dua. Well, it turns out that you can more or less do the same thing:

json
{
    <... other widgets go here ...>,
    "dua" : {
        "icon": "brands@linux",
        "label": "dua",
        "blockdef": {
            "meta": {
                "view": "term",
                "controller": "cmd",
                "cmd": "dua"
            }
        }
    },
    <... other widgets go here ...>
}

This adds an icon to the widget bar that you can press to launch a terminal running the dua command.

Because this is a TUI app that does not return anything when closed, the "cmd:clearonstart" option doesn't change the behavior, so it has been excluded.

Web Widgets

Sometimes, it is desireable to open a page directly to a website. That can easily be accomplished by creating a custom "web" widget. They have the following form in general:

json
{
    <... other widgets go here ...>,
    "<widget name>": {
        "icon": "",
        "label": "",
        "color": "",
        "blockdef": {
            "meta": {
                "view": "web",
                "url": ""
            }
        }
    },
    <... other widgets go here ...>
}

The WidgetConfigType takes the usual options common to all widgets. The MetaTSType can include the keys listed below:

Key Description
"view" A string that specifies the general type of widget. In the case of custom web widgets, this must be set to "web".
"url" This string is the url of the current page. As part of a widget, it will serve as the page the widget starts at. If not specified, this will default to the globally configurable "web:defaulturl" which is https://github.com/wavetermdev/waveterm on a fresh install.
"pinnedurl" (optional) This string is the url the homepage button will take you to. If not specified, this will default to the globally configurable "web:defaulturl" which is https://github.com/wavetermdev/waveterm on a fresh install.

Example Web Widgets

Say you want a widget that automatically starts at YouTube and will use YouTube as the home page. This can be done using:

json
{
    <... other widgets go here ...>,
    "youtube" : {
        "icon": "brands@youtube",
        "label": "youtube",
        "blockdef": {
            "meta": {
                "view": "web",
                "url": "https://youtube.com",
                "pinnedurl": "https://youtube.com"
            }
        }
    },
    <... other widgets go here ...>
}

This adds an icon to the widget bar that you can press to launch a web widget on the youtube homepage.

Alternatively, say you want a web widget that opens to github as if it were a bookmark, but will use google as its home page after that. This can easily be done with:

json
{
    <... other widgets go here ...>,
    "github" : {
        "icon": "brands@github",
        "label": "github",
        "blockdef": {
            "meta": {
                "view": "web",
                "url": "https://github.com",
                "pinnedurl": "https://google.com"
            }
        }
    },
    <... other widgets go here ...>
}

This adds an icon to the widget bar that you can press to launch a web widget on the github homepage.

Sysinfo Widgets

The Sysinfo Widget is intentionally kept to a very small subset of possible values that we will expand over time. But it is still possible to configure your own version of it—for instance, if you want to load a different plot by default. The general form of this widget is:

json
{
    <... other widgets go here ...>,
    "<widget name>": {
        "icon": "",
        "label": "",
        "color": "",
        "blockdef": {
            "meta": {
                "view": "sysinfo",
                "graph:numpoints": ,
                "sysinfo:type": ,
            }
        }
    },
    <... other widgets go here ...>
}

The WidgetConfigType takes the usual options common to all widgets. The MetaTSType can include the keys listed below:

Key Description
"view" A string that specifies the general type of widget. In the case of custom sysinfo widgets, this must be set to "sysinfo".
"graph:numpoints" The maximum amount of points that can be shown on the graph. Equivalently, the number of seconds the graph window covers. This defaults to 100.
"sysinfo:type" A string representing the collection of types to show on the graph. Valid values for this are "CPU", "Mem", "CPU + Mem", and All CPU. Note that these are case sensitive. If no value is provided, the plot will default to showing "CPU".

Example Sysinfo Widgets

Suppose you have a build process that lasts 3 minutes and you'd like to be able to see the entire build on the sysinfo graph. Also, you would really like to view both the cpu and memory since both are impacted by this process. In that case, you can set up a widget as follows:

json
{
    <... other widgets go here ...>,
    "3min-info" : {
        "icon": "circle-3",
        "label": "3mininfo",
        "blockdef": {
            "meta": {
                "view": "sysinfo",
                "graph:numpoints": 180,
                "sysinfo:type": "CPU + Mem"
            }
        }
    },
    <... other widgets go here ...>
}

This adds an icon to the widget bar that you can press to launch the CPU and Memory plots by default with 180 seconds of data.

Now, suppose you are fine with the default 100 points (and 100 seconds) but would like to show all of the CPU data when launched. In that case, you can write:

json
{
    <... other widgets go here ...>,
    "all-cpu" : {
        "icon": "chart-scatter",
        "label": "all-cpu",
        "blockdef": {
            "meta": {
                "view": "sysinfo",
                "sysinfo:type": "All CPU"
            }
        }
    },
    <... other widgets go here ...>
}

This adds an icon to the widget bar that you can press to launch All CPU plots by default.

Overriding Default Widgets

Wave ships with 5 default widgets in the widgets bar (terminal, files, web, ai, and sysinfo). You can modify or remove these by overriding their config in widgets.json. The names of the 5 widgets, in order, are:

  • defwidget@terminal
  • defwidget@files
  • defwidget@web
  • defwidget@ai
  • defwidget@sysinfo

To remove any of them, just set that key to null in your widgets.json file.

To see their definitions, to copy/paste them, or to understand how they work, you can view all of their definitions on GitHub - default widgets.json


File: docs/docs/faq.mdx


import { VersionBadge } from "@site/src/components/versionbadge";

FAQ

How can I see the block numbers?

The block numbers will appear when you hold down Ctrl-Shift (and disappear once you release the key combo).

How do I make a remote connection?

There is a button in the header. Click the or
and type the [user]@[host] that you wish to connect to.

On Windows, how can I use Git Bash as my default shell?

Wave automatically detects Git Bash installations and adds them to the connection dropdown. Simply click the or button in the block header and select "Git Bash" from the list.

Alternatively, you can manually set Git Bash as your default shell by setting the configuration variable term:localshellpath to
the location of the Git Bash "bash.exe" binary. By default it is located at "C:\Program Files\Git\bin\bash.exe".
Just remember in JSON, backslashes need to be escaped. So add this to your settings.json file:

json
"term:localshellpath": "C:\\Program Files\\Git\\bin\\bash.exe"

Can I use WSH outside of Wave?

wsh is an internal CLI for extending control over Wave to the command line, you can learn more about it here. To prevent misuse by other applications, wsh requires an access token provided by Wave to work and will not function outside of the app.

Why does Wave warn me about ARM64 translation when it launches?

macOS and Windows both have compatibility layers that allow x64 applications to run on ARM computers. This helps more apps run on these systems while developers work to add native ARM support to their applications. However, it comes with significant performance tradeoffs.

To get the best experience using Wave, it is recommended that you uninstall Wave and reinstall the version that is natively compiled for your computer. You can find the right version by consulting our Installation Instructions.

You can disable this warning by setting app:dismissarchitecturewarning=true in your configurations.

How do I join the beta builds of Wave?

Wave publishes to two channels, latest and beta. If you've installed the app for macOS, Windows, or Linux via DEB or RPM, you can set the following configurations in your settings.json (see Configuration for more info):

json
"autoupdate:enabled": true,
"autoupdate:channel": "beta"

If you've installed via Snap, you can use the following command:

sh
sudo snap install waveterm --classic --beta

Can I use Wave AI without enabling telemetry?

Yes! Wave AI is normally disabled when telemetry is not enabled. However, you can enable Wave AI features without telemetry by configuring your own custom AI model (either a local model or using your own API key).

To enable Wave AI without telemetry:

  1. Configure a custom AI mode (see Wave AI documentation)
  2. Set waveai:defaultmode to your custom mode's key in your Wave settings

Once you've completed both steps, Wave AI will be enabled and you can use it completely privately without telemetry. This allows you to use local models like Ollama or your own API keys with providers like OpenAI, OpenRouter, or others.


File: docs/docs/gettingstarted.mdx


import { PlatformProvider, PlatformSelectorButton, PlatformItem } from "@site/src/components/platformcontext";
import { Kbd } from "@site/src/components/kbd";

Wave Terminal is a modern terminal that includes graphical capabilities like web browsing, file previews, and AI assistance alongside traditional terminal features. This guide will help you get started.

Installation

Platform requirements

  • Supported architectures: Apple Silicon, x64

  • Supported OS version: macOS 11 Big Sur or later

  • Supported architectures: x64

  • Supported OS version: Windows 10 1809 or later, Windows 11

:::note

ARM64 is planned, but is currently blocked by upstream dependencies (see Windows ARM Support).

:::

  • Supported architectures: x64, ARM64
  • Supported OS version: must have glibc-2.28 or later (Debian >=10, RHEL >=8, Ubuntu >=20.04, etc.)

Package managers

Homebrew

bash
brew install --cask wave

Windows Package Manager

powershell
winget install CommandLine.Wave

Chocolatey

powershell
choco install wave

Snap

bash
sudo snap install --classic waveterm

Other options available: AUR package (community maintained), Nix package (community maintained)

You can also download installers directly from our Downloads page.

Core Concepts

Tabs and Blocks

  • Tabs: Like browser tabs, these help organize your work. Create new tabs with .
  • Blocks: The building blocks of Wave. Each block can be a terminal, web browser, file preview, or other widget.
  • Layout: Blocks can be dragged, dropped, and resized to create your ideal layout.

Key Features

  1. Terminal Features

    • Works with common shells (bash, zsh, fish)
    • Supports standard terminal features (readline, control sequences, etc)
    • Includes the wsh command for interacting with Wave's GUI features
    • GPU accelerated (on most platforms)
  2. Graphical Widgets

    • Preview files (images, video, markdown, code with syntax highlighting)
    • Browse web pages
    • Ask questions and get AI help directly from the terminal (set up multiple AI models)
    • Basic system monitoring graphs
  3. Remote Connections

    • Easy SSH connections with the connection button
    • WSL integration on Windows
    • Consistent experience across local and remote sessions

Quick Start Guide

  1. Open Your First New Tab

    • New Wave tabs start with a single terminal block
    • Use it just like your regular terminal
    • Create additional terminal blocks with
  2. Try Some Basic Commands

    bash
    # View a file or directory
    wsh view ~/Documents
    
    # Open a webpage
    wsh web open github.com
    
    # Get AI assistance
    wsh ai -m "how do I find large files in my current directory?" -s
  3. Customize Your Layout

    • Drag block headers to rearrange them
    • Hover between blocks to resize them
    • Right-click tab headers for background options
    • Right-click block headers for block-specific options
  4. Connect to Remote Machines

    • Click the button
    • Enter username@hostname for SSH connections
    • Or select a WSL distribution on Windows

Next Steps

Getting Help


File: docs/docs/index.mdx


import { Card, CardGroup } from "@site/src/components/card";

Welcome to Wave Terminal

Wave is an open-source terminal that combines traditional terminal features with graphical capabilities like file previews, web browsing, and AI assistance. It runs on MacOS, Linux, and Windows.

Modern development involves constantly switching between terminals and browsers - checking documentation, previewing files, monitoring systems, and using AI tools. Wave brings these graphical tools directly into the terminal, letting you control them from the command line. This means you can stay in your terminal workflow while still having access to the visual interfaces you need.

Check out Getting Started for installation instructions.

:::info

If you have a question, please feel free to ask us in Discord. If you'd like to file a bug/enchancement, please use Github Issues. These docs are also open-source and we do accept PRs for docs here. You can click the "Edit this page" link at the bottom of the page to get taken directly to the editor page for that document in GitHub.

:::

Other References:

Roadmap

Want to provide input to our future releases? Connect with us on Discord or open a Feature Request!

Looking for WaveLegacy documentation?

WaveLegacy docs can be found at legacydocs.waveterm.dev.


File: docs/docs/keybindings.mdx


import { Kbd, KbdChord } from "@site/src/components/kbd";
import { PlatformProvider, PlatformSelectorButton } from "@site/src/components/platformcontext";
import { VersionBadge } from "@site/src/components/versionbadge";

Here's the set of default keybindings available in Wave. It is split into sections.
Some keybindings are always active. Others are only active for certain types of blocks.

Note that these are the MacOS keybindings (they use "Cmd"). For Windows and Linux,
replace "Cmd" with "Alt" (note that "Ctrl" is "Ctrl" on both Mac, Windows, and Linux).

Chords are shown with a + between the keys. You have 2 seconds to hit the 2nd chord key after typing the first key. Hitting Escape after an initial chord key will always be a no-op.

Global Keybindings

Key Function
Open a new tab
Open a new block (defaults to a terminal block with the same connection and working directory). Switch to launcher using app:defaultnewblock setting
Toggle WaveAI panel visibility
Split horizontally, open a new block to the right
Split vertically, open a new block below
Split vertically, open a new block above
Split vertically, open a new block below
Split horizontally, open a new block to the left
Split horizontally, open a new block to the right
Open a new window
Close the current block
Close the current tab
Magnify / Un-Magnify the current block
Open the "connection" switcher
Refocus the current block (useful if the block has lost input focus)
Show block numbers
Focus WaveAI input
Switch to block number
/ Move left, right, up, down between blocks
Replace the current block with a launcher block
Rename the current tab
Switch to tab number
/ Switch tab left
/ Switch tab right
Switch to workspace number
Refresh the UI
Toggle terminal multi-input mode

File Preview Keybindings

Key Function
Any regular character (e.g. "a", "b") will filter the file list
Clears the filter
/ Change file selection up/down
Open the currently selected file/directory
Move "up" a directory (parent directory)
Back, move to the previously selected file/directory
Forward (opposite of back)
Open a new file (accepts relative paths to the current directory)
When file editor is open, save file
For files that can be previewed or edited (markdown, CSVs), switches between preview and edit mode
When file editor is open, revert changes

Web Keybindings

Key Function
Focus the URL input bar
When the URL input bar is focused, will focus the web content
Reload webpage
Back
Forward
Find in webpage
Open a bookmark

WaveAI Keybindings

Key Function
Toggle WaveAI panel
Focus WaveAI input
Clear AI Chat

Terminal Keybindings

Key Function
Copy
Paste
Paste (Windows Only)
Clear Terminal
Find in Terminal
Scroll to top
Scroll to bottom
Scroll to top (macOS only)
Scroll to bottom (macOS only)
Move to beginning of line (macOS only)
Move to end of line (macOS only)
Scroll up one page
Scroll down one page

Process Viewer Keybindings

Key Function
Pause / resume live updates
Open process filter / search
Close search bar

Customizeable Systemwide Global Hotkey

Wave allows setting a custom global hotkey to focus your most recent window from anywhere in your computer. For more information on this, see the config docs.