Skip to content

Commit 2f92e23

Browse files
authored
more config updates (secrets, waveai, ai:provider) (#2631)
1 parent f57873e commit 2f92e23

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+2707
-426
lines changed

aiprompts/aimodesconfig.md

Lines changed: 709 additions & 0 deletions
Large diffs are not rendered by default.

cmd/server/main-server.go

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,9 @@ func doShutdown(reason string) {
9191

9292
// watch stdin, kill server if stdin is closed
9393
func stdinReadWatch() {
94+
defer func() {
95+
panichandler.PanicHandler("stdinReadWatch", recover())
96+
}()
9497
buf := make([]byte, 1024)
9598
for {
9699
_, err := os.Stdin.Read(buf)
@@ -109,6 +112,9 @@ func startConfigWatcher() {
109112
}
110113

111114
func telemetryLoop() {
115+
defer func() {
116+
panichandler.PanicHandler("telemetryLoop", recover())
117+
}()
112118
var nextSend int64
113119
time.Sleep(InitialTelemetryWait)
114120
for {
@@ -120,6 +126,42 @@ func telemetryLoop() {
120126
}
121127
}
122128

129+
func sendNoTelemetryUpdate(telemetryEnabled bool) {
130+
ctx, cancelFn := context.WithTimeout(context.Background(), 5*time.Second)
131+
defer cancelFn()
132+
clientData, err := wstore.DBGetSingleton[*waveobj.Client](ctx)
133+
if err != nil {
134+
log.Printf("telemetry update: error getting client data: %v\n", err)
135+
return
136+
}
137+
if clientData == nil {
138+
log.Printf("telemetry update: client data is nil\n")
139+
return
140+
}
141+
err = wcloud.SendNoTelemetryUpdate(ctx, clientData.OID, !telemetryEnabled)
142+
if err != nil {
143+
log.Printf("[error] sending no-telemetry update: %v\n", err)
144+
return
145+
}
146+
}
147+
148+
func setupTelemetryConfigHandler() {
149+
watcher := wconfig.GetWatcher()
150+
if watcher == nil {
151+
return
152+
}
153+
currentConfig := watcher.GetFullConfig()
154+
currentTelemetryEnabled := currentConfig.Settings.TelemetryEnabled
155+
156+
watcher.RegisterUpdateHandler(func(newConfig wconfig.FullConfigType) {
157+
newTelemetryEnabled := newConfig.Settings.TelemetryEnabled
158+
if newTelemetryEnabled != currentTelemetryEnabled {
159+
currentTelemetryEnabled = newTelemetryEnabled
160+
go sendNoTelemetryUpdate(newTelemetryEnabled)
161+
}
162+
})
163+
}
164+
123165
func backupCleanupLoop() {
124166
defer func() {
125167
panichandler.PanicHandler("backupCleanupLoop", recover())
@@ -232,6 +274,9 @@ func beforeSendActivityUpdate(ctx context.Context) {
232274
}
233275

234276
func startupActivityUpdate(firstLaunch bool) {
277+
defer func() {
278+
panichandler.PanicHandler("startupActivityUpdate", recover())
279+
}()
235280
ctx, cancelFn := context.WithTimeout(context.Background(), 5*time.Second)
236281
defer cancelFn()
237282
activity := wshrpc.ActivityUpdate{Startup: 1}
@@ -476,11 +521,17 @@ func main() {
476521
maybeStartPprofServer()
477522
go stdinReadWatch()
478523
go telemetryLoop()
524+
setupTelemetryConfigHandler()
479525
go updateTelemetryCountsLoop()
480526
go backupCleanupLoop()
481527
go startupActivityUpdate(firstLaunch) // must be after startConfigWatcher()
482528
blocklogger.InitBlockLogger()
483-
go wavebase.GetSystemSummary() // get this cached (used in AI)
529+
go func() {
530+
defer func() {
531+
panichandler.PanicHandler("GetSystemSummary", recover())
532+
}()
533+
wavebase.GetSystemSummary()
534+
}()
484535

485536
webListener, err := web.MakeTCPListener("web")
486537
if err != nil {

cmd/testai/main-testai.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ func testOpenAIComp(ctx context.Context, model, message string, tools []uctypes.
166166
opts := &uctypes.AIOptsType{
167167
APIType: uctypes.APIType_OpenAIChat,
168168
APIToken: apiKey,
169-
BaseURL: "https://api.openai.com/v1/chat/completions",
169+
Endpoint: "https://api.openai.com/v1/chat/completions",
170170
Model: model,
171171
MaxTokens: 4096,
172172
ThinkingLevel: uctypes.ThinkingLevelMedium,
@@ -216,7 +216,7 @@ func testOpenRouter(ctx context.Context, model, message string, tools []uctypes.
216216
opts := &uctypes.AIOptsType{
217217
APIType: uctypes.APIType_OpenAIChat,
218218
APIToken: apiKey,
219-
BaseURL: "https://openrouter.ai/api/v1/chat/completions",
219+
Endpoint: "https://openrouter.ai/api/v1/chat/completions",
220220
Model: model,
221221
MaxTokens: 4096,
222222
ThinkingLevel: uctypes.ThinkingLevelMedium,

docs/docs/ai-presets.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
sidebar_position: 3.6
33
id: "ai-presets"
4-
title: "AI Presets"
4+
title: "AI Presets (Deprecated)"
55
---
66
:::warning Deprecation Notice
77
The AI Widget and its presets are being replaced by [Wave AI](./waveai.mdx). Please refer to the Wave AI documentation for the latest AI features and configuration options.

docs/docs/connections.mdx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ id: "connections"
44
title: "Connections"
55
---
66

7+
import { VersionBadge } from "@site/src/components/versionbadge";
8+
79
# Connections
810

911
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, local WSL connections, and AWS S3 buckets.
@@ -156,6 +158,7 @@ In addition to the regular ssh config file, wave also has its own config file to
156158
| 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.|
157159
| 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.|
158160
| 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. |
161+
| ssh:passwordsecretname | A string specifying the name of a secret stored in the [secret store](/secrets) to use as the SSH password. When set, this password will be automatically used for password authentication instead of prompting the user. <VersionBadge version="v0.13" /> |
159162
| 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. |
160163
| 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.|
161164
| 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.|

docs/docs/faq.mdx

Lines changed: 0 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,6 @@ title: "FAQ"
66

77
# FAQ
88

9-
### How do I enable Claude Code support with Shift+Enter?
10-
11-
Wave supports Claude Code and similar AI coding tools that expect Shift+Enter to send an escape sequence + newline (`\u001b\n`) instead of a regular carriage return. This can be enabled using the `term:shiftenternewline` configuration setting.
12-
13-
To enable this globally for all terminals:
14-
```bash
15-
wsh setconfig term:shiftenternewline=true
16-
```
17-
18-
To enable this for just a specific terminal block:
19-
```bash
20-
wsh setmeta term:shiftenternewline=true
21-
```
22-
23-
You can also set this in your [settings.json](./config) file:
24-
```json
25-
"term:shiftenternewline": true
26-
```
27-
289
### How can I see the block numbers?
2910

3011
The block numbers will appear when you hold down Ctrl-Shift (and disappear once you release the key combo).
@@ -48,87 +29,6 @@ Just remember in JSON, backslashes need to be escaped. So add this to your [sett
4829

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

51-
### How do I make new blocks or splits inherit my shell’s current directory?
52-
53-
Wave uses a special escape sequence (OSC 7) to track the shell’s working directory and maintain the working directory of new terminal blocks and splits. Wave listens for these sequences to update its `cmd:cwd` metadata. That metadata is copied to new blocks when you:
54-
55-
- Open a new terminal block (Alt N / Cmd N)
56-
- Split a pane (Cmd D / Cmd Shift D)
57-
58-
Not all shells emit this escape sequence, so new blocks or splits may start in your home directory instead. To ensure your shell emits the OSC 7 escape sequence, add the following to your shell startup/config file and restart Wave (or source your config).
59-
60-
#### Bash
61-
62-
Add to `~/.bashrc` or `~/.bash_profile`:
63-
64-
```bash
65-
# Emit OSC 7 on each prompt to tell terminal about new working directory
66-
__update_cwd() {
67-
# Only run in interactive shells
68-
[[ $- == *i* ]] || return
69-
# Only run if attached to a terminal
70-
[ -t 1 ] || return
71-
# Redirect to tty so output doesn't show in shell
72-
printf "\033]7;file://%s%s\007" "$HOSTNAME" "${PWD// /%20}" > /dev/tty
73-
}
74-
if [[ -n "$PROMPT_COMMAND" ]]; then
75-
export PROMPT_COMMAND="__update_cwd; $PROMPT_COMMAND"
76-
else
77-
export PROMPT_COMMAND="__update_cwd"
78-
fi
79-
```
80-
81-
#### Zsh
82-
83-
Add to `~/.zshrc`:
84-
85-
```zsh
86-
# Emit OSC 7 escape on directory change and prompt
87-
function _wave_emit_cwd() {
88-
printf "\033]7;file://%s%s\007" "$HOSTNAME" "${PWD// /%20}" > /dev/tty
89-
}
90-
autoload -U add-zsh-hook
91-
add-zsh-hook chpwd _wave_emit_cwd
92-
add-zsh-hook precmd _wave_emit_cwd
93-
```
94-
95-
#### Fish
96-
97-
> Fish shell (v4.0.0 and later) emits OSC 7 by default—no config required.
98-
99-
For older Fish versions, add to `~/.config/fish/config.fish`:
100-
101-
```fish
102-
# Emit OSC 7 on each PWD change
103-
function _wave_emit_cwd --on-variable PWD
104-
printf "\033]7;file://%s%s\007" (hostname) (string replace ' ' '%20' $PWD) > /dev/tty
105-
end
106-
```
107-
108-
After configuring, open a new block or split (Alt T / Cmd T, Alt N / Cmd N, Cmd D / Cmd Shift D) and verify blocks start in your current directory.
109-
110-
#### Verifying Current Directory Preservation
111-
112-
1. Open a Wave terminal block.
113-
2. `cd` into a project folder, e.g. `cd ~/projects/foo`.
114-
3. Right-click on the block's title bar and select "Copy BlockId" to retrieve the block’s ID.
115-
4. Use the copied BlockId to retrieve the block’s metadata:
116-
117-
```bash
118-
# Example: replace BLOCK_ID with your actual block reference
119-
wsh getmeta --block BLOCK_ID
120-
```
121-
122-
5. Confirm the output JSON contains a `cmd:cwd` field, for example:
123-
124-
```json
125-
{
126-
"cmd:cwd": "/Users/you/projects/foo",
127-
...
128-
}
129-
```
130-
131-
6. Open a new block or split the pane—both should start in `/Users/you/projects/foo`.
13232

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

docs/docs/secrets.mdx

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
---
2+
sidebar_position: 3.2
3+
id: "secrets"
4+
title: "Secrets"
5+
---
6+
7+
import { VersionBadge } from "@site/src/components/versionbadge";
8+
9+
# Secrets
10+
11+
<VersionBadge version="v0.13" />
12+
13+
Wave Terminal provides a secure way to store sensitive information like passwords, API keys, and tokens. Secrets are stored encrypted in your system's native keychain (macOS Keychain, Windows Credential Manager, or Linux Secret Service), ensuring your sensitive data remains protected.
14+
15+
## Why Use Secrets?
16+
17+
Secrets in Wave Terminal allow you to:
18+
19+
- **Store SSH passwords** - Automatically authenticate to SSH connections without typing passwords
20+
- **Manage API keys** - Keep API tokens, keys, and credentials secure
21+
- **Share across sessions** - Access your secrets from any terminal block or remote connection
22+
- **Avoid plaintext storage** - Never store sensitive data in configuration files or scripts
23+
24+
## Opening the Secrets UI
25+
26+
There are several ways to access the secrets management interface:
27+
28+
1. **From the widgets bar** (recommended):
29+
- Click the **<i className="fa-gear fa-solid fa-sharp"/>** settings icon on the widgets bar
30+
- Select **Secrets** from the menu
31+
32+
2. **From the command line:**
33+
```bash
34+
wsh secret ui
35+
```
36+
37+
38+
The secrets UI provides a visual interface to view, add, edit, and delete secrets.
39+
40+
## Managing Secrets via CLI
41+
42+
Wave Terminal provides a complete CLI for managing secrets from any terminal block:
43+
44+
```bash
45+
# List all secret names (not values)
46+
wsh secret list
47+
48+
# Get a specific secret value
49+
wsh secret get MY_SECRET_NAME
50+
51+
# Set a secret (format: name=value, no spaces around =)
52+
wsh secret set GITHUB_TOKEN=ghp_xxxxxxxxxx
53+
wsh secret set DB_PASSWORD=super_secure_password
54+
55+
# Delete a secret
56+
wsh secret delete MY_SECRET_NAME
57+
```
58+
59+
## Secret Naming Rules
60+
61+
Secret names must match the pattern: `^[A-Za-z][A-Za-z0-9_]*$`
62+
63+
This means:
64+
- Must start with a letter (A-Z or a-z)
65+
- Can only contain letters, numbers, and underscores
66+
- Cannot contain spaces or special characters
67+
68+
**Valid names:** `MY_SECRET`, `ApiKey`, `ssh_password_1`
69+
**Invalid names:** `123_SECRET`, `my-secret`, `secret name`
70+
71+
## Using Secrets with SSH Connections
72+
73+
<VersionBadge version="v0.13" />
74+
75+
Secrets can be used to automatically provide passwords for SSH connections, eliminating the need to type passwords repeatedly.
76+
77+
### Configure in connections.json
78+
79+
Add the `ssh:passwordsecretname` field to your connection configuration:
80+
81+
```json
82+
{
83+
"myserver": {
84+
"ssh:hostname": "example.com",
85+
"ssh:user": "myuser",
86+
"ssh:passwordsecretname": "SERVER_PASSWORD"
87+
}
88+
}
89+
```
90+
91+
Then store your password as a secret:
92+
93+
```bash
94+
wsh secret set SERVER_PASSWORD=my_actual_password
95+
```
96+
97+
Now when Wave connects to `myserver`, it will automatically use the password from your secret store instead of prompting you.
98+
99+
### Benefits
100+
101+
- **Security**: Password stored encrypted in your system keychain
102+
- **Convenience**: No need to type passwords for each connection
103+
- **Flexibility**: Update passwords by changing the secret, not the configuration
104+
105+
## Security Considerations
106+
107+
- **Encrypted Storage**: Secrets are stored encrypted in your Wave configuration directory. The encryption key itself is protected by your operating system's secure credential storage (macOS Keychain, Windows Credential Manager, or Linux Secret Service).
108+
109+
- **No Plaintext**: Secrets are never stored unencrypted in logs or accessible files.
110+
111+
- **Access Control**: Secrets are only accessible to Wave Terminal.
112+
113+
114+
## Storage Backend
115+
116+
Wave Terminal automatically detects and uses the appropriate secret storage backend for your operating system:
117+
118+
- **macOS**: Uses the macOS Keychain
119+
- **Windows**: Uses Windows Credential Manager
120+
- **Linux**: Uses the Secret Service API (freedesktop.org specification)
121+
122+
:::warning Linux Secret Storage
123+
On Linux systems, Wave requires a compatible secret service backend (typically GNOME Keyring or KWallet). These are usually pre-installed with your desktop environment. If no compatible backend is detected, you won't be able to set secrets, and the UI will display a warning.
124+
:::
125+
126+
## Troubleshooting
127+
128+
### "No appropriate secret manager found"
129+
130+
This error occurs on Linux when no compatible secret service backend is available. Install GNOME Keyring or KWallet and ensure the secret service is running.
131+
132+
### Secret not found
133+
134+
Ensure the secret name is spelled correctly (names are case-sensitive) and that the secret exists:
135+
136+
```bash
137+
wsh secret list
138+
```
139+
140+
### Permission denied on Linux
141+
142+
The secret service may require you to unlock your keyring. This typically happens after login. Consult your desktop environment's documentation for keyring management.
143+
144+
## Related Documentation
145+
146+
- [Connections](/connections) - Learn about SSH connections and configuration
147+
- [wsh Command Reference](/wsh-reference#secret) - Complete CLI command documentation for secrets

0 commit comments

Comments
 (0)