tie the tool approvals to the lifecycle of the SSE connection, NOT FE
keepalive packets. this prevents timeouts when the FE hasn't rendered
the tools (or FE tool rendering lifecycle issues). also allows immediate
timeouts on refresh.
other small fixes: convert to use wshclient in wshcmd-*.go files,
cleanup in SSE code
* remove title bar on windows windows
* re-integrate native controls into our tab bar
* remove menu completely (weird "Alt" activation)
* actually fix Ctrl-V in terminal
* clamp zoom levels better (0.4 - 2.6)
* simplify macos / windows drag regions (keep responsive to zoom)
* fix settings schemas for windows
We were too conservative by defaulting ignorebrackedpastemode in
xterm.js to true. it should have been set to false. this solves issues
with pasting multi-line strings into zsh, claude code, etc.
add a new context menu option to more easily disable if you're in a
weird ssh session or a REPL that doesn't support bracketedpaste.
- [x] Add new API type constant for Google Gemini in uctypes.go
- [x] Create gemini directory under pkg/aiusechat/
- [x] Implement gemini-backend.go with streaming chat support
- [x] Implement gemini-convertmessage.go for message conversion
- [x] Implement gemini-types.go for Google-specific types
- [x] Add gemini backend to usechat-backend.go
- [x] Support tool calling with structured arguments
- [x] Support image upload (base64 inline data)
- [x] Support PDF upload (base64 inline data)
- [x] Support file upload (text files, directory listings)
- [x] Build verification passed
- [x] Add documentation for Gemini backend usage
- [x] Security scan passed (CodeQL found 0 issues)
- [x] Code review passed with no comments
- [x] Revert tsunami demo go.mod/go.sum files (per feedback - twice)
- [x] Add `--gemini` flag to main-testai.go for testing
- [x] Fix schema validation for tool calling (clean unsupported fields)
- [x] Preserve non-map property values in schema cleaning
## Summary
Successfully implemented a complete Google Gemini backend for WaveTerm's
AI chat system. The implementation:
- **Follows existing patterns**: Matches the structure of OpenAI and
Anthropic backends
- **Fully featured**: Supports all required capabilities including tool
calling, images, PDFs, and files
- **Properly tested**: Builds successfully with no errors or warnings
- **Secure**: Passed CodeQL security scanning with 0 issues
- **Well documented**: Includes comprehensive package documentation with
usage examples
- **Minimal changes**: Only affects backend code under pkg/aiusechat
(tsunami demo files reverted twice)
- **Testable**: Added `--gemini` flag to main-testai.go for easy testing
with SSE output
- **Schema compatible**: Cleans JSON schemas to remove fields
unsupported by Gemini API while preserving valid structure
## Testing
To test the Gemini backend using main-testai.go:
```bash
export GOOGLE_APIKEY="your-api-key"
cd cmd/testai
go run main-testai.go --gemini 'What is 2+2?'
go run main-testai.go --gemini --model gemini-1.5-pro 'Explain quantum computing'
go run main-testai.go --gemini --tools 'Help me configure GitHub Actions monitoring'
```
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: sawka <2722291+sawka@users.noreply.github.com>
this fixes a rare case where a workspace tries to load a tab that
doesn't exist. this allows the UI to load even despite that condition.
in addition it fixes the "delete tab" path so, even if the tab doesn't
exist, it will get cleaned up correctly out of the workspace.
* roundtrip image filenames correctly
* fix scrolling issue where the thumbs-up/thumbs-down buttons were cut
off
* update ai-sdk / ai-sdk react to current versions
* fix a focus issue when moving to AI panel using ctrl:shift:arrowleft
Created an interface in aiusechat for the backend providers. Use that
interface throughout the usechat code. Isolate the backend
implementations to only the new file usechat-backend.go.
* Kebab Menu + Switch App Functionality
* Updated Secrets Tab (still more to do, but closer)
* Better Error Handling (Switch to Secrets Tab)
* Add AppInit functionality to Tsunami (fixes initialization issues and
races with embedded assets, and error handling)
* Tsunami - ListStaticFiles
* Tsunami - More Robust Manifest generation (even when there are extra
stdout messages)
* load manifest metadata into the FE
* builder only edits draft/ apps (convert local => draft)
* gofmt app.go after saving (AI tools and manual user save)
* dont open duplicate builder windows
* remix app context menu in waveapp
* add icon/iconcolor in appmeta and implement in the wave block frame
* build manifest
* working on secrets injection (secretstore + secret-bindings.json)
* tool progress indicators
* build output and errors injected as the result of the edit calls so AI
gets instant feedback on edits
* change edits to not be atomic (allows AI to make better progress)
* updated binary location for waveapps
* publish button
* new partial json parser (for sending incremental tool progress
indication)
* updated tsunami view to use new embedded scaffold + config vars
* lots of work on cleaning up the output so it is more useful to users +
AI agents
* fix builder init flow
Create an AI Thinking Dropdown in Wave AI.
Quick, Balanced, or Deep which map to gpt-5-mini, gpt-5 (low thinking),
or gpt-5 (medium thinking). Also default down to Quick when no premium
requests.
## Plan: Add RenameLocalApp function to waveappstore
- [x] Analyze existing code patterns in waveappstore.go
- [x] Implement RenameLocalApp(appName string, newAppName string) error
function
- Validate newAppName using existing validation
- Check if local/[appname] exists and rename to local/[newAppName] if it
does
- Check if draft/[appname] exists and rename to draft/[newAppName] if it
does
- Handle errors appropriately including rollback on partial failure
- [x] Add documentation comments
- [x] Run security checks (CodeQL - no issues found)
## Summary
Successfully implemented `RenameLocalApp(appName string, newAppName
string) error` function that:
- Renames local apps in both `local/` and `draft/` namespaces
- Validates app names and checks for conflicts
- Implements proper error handling with rollback on partial failure
- Passes all security checks with zero vulnerabilities
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: sawka <2722291+sawka@users.noreply.github.com>
Handle both types of paste data. Write utility functions to normalize
paste events to {text; image}[]. Fix duplication issue (call
preventDefault() early). Handle multiple image pasting (by adding a
slight delay). Convert Ctrl:Shift:v to use a *native paste* which allows
capturing of images!
## Summary
This PR includes three terminal input improvements that enhance the
experience when using interactive CLI tools and IME input:
1. **Shift+Enter newline support**: Enable Shift+Enter to insert
newlines by default
2. **Image paste support**: Allow pasting images by saving them as
temporary files and pasting the file path
3. **IME duplicate input fix**: Fix duplicate text when switching input
methods during composition
## Motivation
### Shift+Enter for newlines
Currently, pressing Shift+Enter in the terminal behaves the same as
Enter, making it difficult to input multi-line commands or text in
interactive CLI tools. This change enables Shift+Enter to insert
newlines by default, matching common terminal emulator behavior.
### Image paste support
Interactive AI tools like Claude Code support receiving images through
file paths, but Wave Terminal currently doesn't support pasting images.
This change implements image paste functionality similar to iTerm2's
behavior: when an image is pasted, it's saved to a temporary file and
the path is pasted into the terminal.
### IME duplicate input fix
When using Chinese/Japanese/Korean IME in the terminal, switching input
methods with Capslock during composition causes the composed text to be
sent twice, resulting in duplicate output (e.g., "你好" becomes "你好你好").
This issue severely impacts users who frequently switch between
languages.
## Changes
### Shift+Enter newline (`frontend/app/view/term/term-model.ts`)
- Change default `shiftenternewline` config from `false` to `true`
- Send standard newline character (`\n`) instead of escape sequence
(`\^[\n`)
### Image paste (`frontend/app/view/term/term-model.ts`,
`frontend/app/view/term/termwrap.ts`)
- Add `handlePaste()` method to intercept Cmd+Shift+V paste events
- Add `handleImagePasteBlob()` to save images to `/tmp` and paste the
file path
- Detect image data in clipboard using both
`ClipboardEvent.clipboardData` and Clipboard API
- Support both screenshot paste and file copy scenarios
- Add 5MB size limit for pasted images
- Temporary files are created with format:
`waveterm_paste_[timestamp].[ext]`
### IME duplicate input fix (`frontend/app/view/term/termwrap.ts`,
`frontend/app/view/term/term-model.ts`)
**IME Composition Handling:**
- Track composition state (isComposing, composingData, etc.) in TermWrap
- Register compositionstart/update/end event listeners on xterm.js
textarea
- Block all data sends during composition, only allow after
compositionend
- Prevents xterm.js from sending intermediate data during
compositionupdate phase
**Deduplication Logic:**
- Implement 50ms time window deduplication for both IME and paste
operations
- Track first send after composition, block duplicate sends from
Capslock switching
- Ensure Ctrl+Space and Fn switching work correctly (single send only)
**Edge Case Handling:**
- Add blur event handler to reset composition state on focus loss
- Add Escape key handling to cancel composition in progress
## Testing
### Shift+Enter
1. Open a terminal in Wave
2. Press Shift+Enter
3. Verify that a newline is inserted instead of executing the command
### Image paste
1. Take a screenshot and copy it to clipboard (or copy an image file in
Finder)
2. In a terminal running Claude Code, paste the image (Cmd+V or
Cmd+Shift+V)
3. Verify that the image path appears and Claude Code recognizes it
### IME Input Testing
**IME Input:**
- [x] macOS Zhuyin IME + Capslock switching - no duplicate output ✅
- [x] macOS Zhuyin IME + Ctrl+Space switching - normal single input ✅
- [x] macOS Zhuyin IME + Fn switching - normal single input ✅
**Regression Testing:**
- [x] English keyboard input - normal operation ✅
- [x] Shift+Enter multiline input - works correctly ✅
- [x] Text paste (Cmd+Shift+V) - no duplicates ✅
- [x] Image paste - works correctly ✅
- [x] Basic command execution (ls, echo, etc.) - normal ✅
- [x] Cmd+K clear terminal - works correctly ✅
- [x] Copy selected text (Cmd+Shift+C) - works correctly ✅
## Demo
https://github.com/user-attachments/assets/8341cdf9-6c57-413e-b940-89e50cc79ff0https://github.com/user-attachments/assets/d3a6e72a-f488-45c1-ab58-88391639455ahttps://github.com/user-attachments/assets/ac178abd-caf3-40bf-9ef7-7cc0567a32c3
All features have been tested successfully on macOS with Claude Code in
Wave Terminal.
adds a new secret store protected by electron's safeStorage API.
currently just hooked up to the CLI via a new wsh command: `wsh secret`.
will be used to power secrets in tsunami later (and for config +
connections)