con un clic
add-config
// Guide for adding new configuration settings to Wave Terminal. Use when adding a new setting to the configuration system, implementing a new config key, or adding user-customizable settings.
// Guide for adding new configuration settings to Wave Terminal. Use when adding a new setting to the configuration system, implementing a new config key, or adding user-customizable settings.
Guide for implementing a new view type in Wave Terminal. Use when creating a new view component, implementing the ViewModel interface, registering a new view type in BlockRegistry, or adding a new content type to display within blocks.
Guide for creating WaveEnv narrowings in Wave Terminal. Use when writing a named subset type of WaveEnv for a component tree, documenting environmental dependencies, or enabling mock environments for preview/test server usage.
Guide for adding new RPC calls to Wave Terminal. Use when implementing new RPC commands, adding server-client communication methods, or extending the RPC interface with new functionality.
Guide for adding new Electron APIs to Wave Terminal. Use when implementing new frontend-to-electron communications via preload/IPC.
Guide for creating and displaying context menus in Wave Terminal. Use when implementing right-click menus, adding context menu items, creating submenus, or handling menu interactions with checkboxes and separators.
Guide for working with Wave Terminal's WPS (Wave PubSub) event system. Use when implementing new event types, publishing events, subscribing to events, or adding asynchronous communication between components.
| name | add-config |
| description | Guide for adding new configuration settings to Wave Terminal. Use when adding a new setting to the configuration system, implementing a new config key, or adding user-customizable settings. |
This guide explains how to add a new configuration setting to Wave Terminal's hierarchical configuration system.
Wave Terminal uses a hierarchical configuration system with:
pkg/wconfig/settingsconfig.goschema/settings.jsonpkg/wconfig/defaultconfig/settings.json~/.config/waveterm/settings.jsonpkg/waveobj/wtypemeta.godocs/docs/config.mdxSettings cascade from defaults → user settings → connection config → block overrides.
Edit pkg/wconfig/settingsconfig.go and add your new field to the SettingsType struct:
type SettingsType struct {
// ... existing fields ...
// Add your new field with appropriate JSON tag
MyNewSetting string `json:"mynew:setting,omitempty"`
// For different types:
MyBoolSetting bool `json:"mynew:boolsetting,omitempty"`
MyNumberSetting float64 `json:"mynew:numbersetting,omitempty"`
MyIntSetting *int64 `json:"mynew:intsetting,omitempty"` // Use pointer for optional ints
MyArraySetting []string `json:"mynew:arraysetting,omitempty"`
}
Naming Conventions:
term:, window:, ai:, web:, app:)omitempty tag to exclude empty values from JSONType Guidelines:
*int64 and *float64 for optional numeric values*bool for optional boolean values (or bool if default is false)string for text values[]string for arraysfloat64 for numbers that can be decimalsNamespace Organization:
app:* - Application-level settingsterm:* - Terminal-specific settingswindow:* - Window and UI settingsai:* - AI-related settingsweb:* - Web browser settingseditor:* - Code editor settingsconn:* - Connection settingsIf your setting should support block-level overrides, also add it to pkg/waveobj/wtypemeta.go:
type MetaTSType struct {
// ... existing fields ...
// Add your new field with matching JSON tag and type
MyNewSetting *string `json:"mynew:setting,omitempty"` // Use pointer for optional values
// For different types:
MyBoolSetting *bool `json:"mynew:boolsetting,omitempty"`
MyNumberSetting *float64 `json:"mynew:numbersetting,omitempty"`
MyIntSetting *int `json:"mynew:intsetting,omitempty"`
MyArraySetting []string `json:"mynew:arraysetting,omitempty"`
}
Block Metadata Guidelines:
*string, *bool, *int, *float64) for optional overridesIf your setting should have a default value, add it to pkg/wconfig/defaultconfig/settings.json:
{
"ai:preset": "ai@global",
"ai:model": "gpt-5-mini",
// ... existing defaults ...
"mynew:setting": "default value",
"mynew:boolsetting": true,
"mynew:numbersetting": 42.5,
"mynew:intsetting": 100
}
Default Value Guidelines:
false is the correct defaultAdd your new setting to the configuration table in docs/docs/config.mdx:
| Key Name | Type | Function |
| ------------------- | -------- | ----------------------------------------- |
| mynew:setting | string | Description of what this setting controls |
| mynew:boolsetting | bool | Enable/disable some feature |
| mynew:numbersetting | float | Numeric setting for some parameter |
| mynew:intsetting | int | Integer setting for some configuration |
| mynew:arraysetting | string[] | Array of strings for multiple values |
Documentation Guidelines:
<VersionBadge version="v0.14" />Run the generate task to automatically regenerate the JSON schema and TypeScript types:
task generate
What this does:
task build:schema (automatically generates JSON schema from Go structs)frontend/types/gotypes.d.tsImportant: The JSON schema in schema/settings.json is automatically generated from the Go struct definitions - you don't need to edit it manually.
Access your new setting in React components:
import { getOverrideConfigAtom, getSettingsKeyAtom, useAtomValue } from "@/store/global";
// In a React component
const MyComponent = ({ blockId }: { blockId: string }) => {
// Use override config atom for hierarchical resolution
// This automatically checks: block metadata → connection config → global settings → default
const mySettingAtom = getOverrideConfigAtom(blockId, "mynew:setting");
const mySetting = useAtomValue(mySettingAtom) ?? "fallback value";
// For global-only settings (no block overrides)
const globalOnlySetting = useAtomValue(getSettingsKeyAtom("mynew:globalsetting")) ?? "fallback";
return <div>Setting value: {mySetting}</div>;
};
Frontend Configuration Patterns:
// 1. Settings with block-level overrides (recommended for most view/display settings)
const termFontSize = useAtomValue(getOverrideConfigAtom(blockId, "term:fontsize")) ?? 12;
// 2. Global-only settings (app-wide settings that don't vary by block)
const appGlobalHotkey = useAtomValue(getSettingsKeyAtom("app:globalhotkey")) ?? "";
// 3. Connection-specific settings
const connStatus = useAtomValue(getConnStatusAtom(connectionName));
When to use each pattern:
getOverrideConfigAtom() for settings that can vary by block or connection (most UI/display settings)getSettingsKeyAtom() for app-level settings that are always global?? operatorAccess settings in Go code:
// Get the full config
fullConfig := wconfig.GetWatcher().GetFullConfig()
// Access your setting
myValue := fullConfig.Settings.MyNewSetting
// For optional values (pointers)
if fullConfig.Settings.MyIntSetting != nil {
intValue := *fullConfig.Settings.MyIntSetting
// Use intValue
}
Use case: Add a setting to hide the AI button globally
pkg/wconfig/settingsconfig.go)type SettingsType struct {
// ... existing fields ...
AppHideAiButton bool `json:"app:hideaibutton,omitempty"`
}
pkg/wconfig/defaultconfig/settings.json){
"app:hideaibutton": false
}
docs/docs/config.mdx)| app:hideaibutton <VersionBadge version="v0.14" /> | bool | Hide the AI button in the tab bar (defaults to false) |
task generate
import { getSettingsKeyAtom } from "@/store/global";
const TabBar = () => {
const hideAiButton = useAtomValue(getSettingsKeyAtom("app:hideaibutton"));
if (hideAiButton) {
return null; // Don't render AI button
}
return <button>AI</button>;
};
# Set in settings file
wsh setconfig app:hideaibutton=true
# Or edit ~/.config/waveterm/settings.json
{
"app:hideaibutton": true
}
Use case: Add a terminal bell sound setting that can be overridden per block
pkg/wconfig/settingsconfig.go)type SettingsType struct {
// ... existing fields ...
TermBellSound string `json:"term:bellsound,omitempty"`
}
pkg/waveobj/wtypemeta.go)type MetaTSType struct {
// ... existing fields ...
TermBellSound *string `json:"term:bellsound,omitempty"` // Pointer for optional override
}
pkg/wconfig/defaultconfig/settings.json){
"term:bellsound": "default"
}
docs/docs/config.mdx)| term:bellsound <VersionBadge version="v0.14" /> | string | Sound to play for terminal bell ("default", "none", or custom sound file path) |
task generate
import { getOverrideConfigAtom } from "@/store/global";
const TerminalView = ({ blockId }: { blockId: string }) => {
// Use override config for hierarchical resolution
const bellSoundAtom = getOverrideConfigAtom(blockId, "term:bellsound");
const bellSound = useAtomValue(bellSoundAtom) ?? "default";
const playBellSound = () => {
if (bellSound === "none") return;
// Play the bell sound
};
return <div>Terminal with bell: {bellSound}</div>;
};
# Set globally in settings file
wsh setconfig term:bellsound="custom.wav"
# Set for current block only
wsh setmeta term:bellsound="none"
# Set for specific block
wsh setmeta --block BLOCK_ID term:bellsound="beep"
# Or edit ~/.config/waveterm/settings.json
{
"term:bellsound": "custom.wav"
}
Each namespace can have a "clear" field for resetting all settings in that namespace:
AppClear bool `json:"app:*,omitempty"`
TermClear bool `json:"term:*,omitempty"`
*bool, *int64, *float64) for truly optional settingsSettings can be overridden at the block level using metadata:
import { RpcApi } from "@/app/store/wshclientapi";
import { TabRpcClient } from "@/app/store/wshrpcutil";
import { WOS } from "@/store/global";
// Set block-specific override
await RpcApi.SetMetaCommand(TabRpcClient, {
oref: WOS.makeORef("block", blockId),
meta: { "mynew:setting": "block-specific value" },
});
task generateProblem: TypeScript types not updated, schema out of sync
Solution: Always run task generate after modifying Go structs
Problem: Settings uses string, metadata uses *int
Solution: Ensure types match (except metadata uses pointers for optionals)
Problem: Component breaks if setting is undefined
Solution: Always use ?? operator with fallback:
const value = useAtomValue(getSettingsKeyAtom("key")) ?? "default";
Problem: Using getSettingsKeyAtom() for settings that need block overrides
Solution: Use getOverrideConfigAtom() for any setting in MetaTSType
term:fontsize not term:fsbool for simple on/off settings (no pointer if false is default)*bool only if you need to distinguish unset from false*int64/*float64 for optional numeric valuesstring for text, paths, or enum-like values[]string for lists<VersionBadge version="v0.x" />When adding a new configuration setting:
SettingsType in pkg/wconfig/settingsconfig.goMetaTSType in pkg/waveobj/wtypemeta.go (if block override needed)pkg/wconfig/defaultconfig/settings.json (if needed)docs/docs/config.mdxtask generate to update TypeScript typesgetOverrideConfigAtom or getSettingsKeyAtom) in frontenddocs/docs/config.mdx - User-facing configuration docspkg/wconfig/settingsconfig.go - Go struct definitionspkg/waveobj/wtypemeta.go - Block metadata definitions