Commit graph

98 commits

Author SHA1 Message Date
Copilot
7f5487d9ac
Remove mock-heavy OSC52 Vitest coverage (#2975)
The issue called out that the OSC52 unit tests were mostly validating
mock setup rather than meaningful behavior. This PR trims that
low-signal coverage by removing the Vitest suite for OSC52.

- **Scope**
  - Deleted `frontend/app/view/term/osc-handlers.test.ts`.
  - No production/runtime code changes.

- **Rationale reflected in changes**
- Removes brittle, mock-dominant tests for logic considered too simple
for this unit-test shape.
  - Keeps the codebase focused on higher-value test coverage.

```diff
- frontend/app/view/term/osc-handlers.test.ts
```

<!-- START COPILOT CODING AGENT TIPS -->
---

 Let Copilot coding agent [set things up for
you](https://github.com/wavetermdev/waveterm/issues/new?title=+Set+up+Copilot+instructions&body=Configure%20instructions%20for%20this%20repository%20as%20documented%20in%20%5BBest%20practices%20for%20Copilot%20coding%20agent%20in%20your%20repository%5D%28https://gh.io/copilot-coding-agent-tips%29%2E%0A%0A%3COnboard%20this%20repo%3E&assignees=copilot)
— coding agent works faster and does higher quality work when set up for
your repo.

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: sawka <2722291+sawka@users.noreply.github.com>
2026-03-04 16:24:42 -08:00
Copilot
624476fa33
Add terminal cursor style/blink config with block-level overrides (#2933)
Adds support for configuring terminal cursor style and blink behavior in
terminal blocks, with hierarchical resolution (block metadata →
connection overrides → global settings). New keys are `term:cursor`
(`block`/`underline`/`bar`, default `block`) and `term:cursorblink`
(`bool`, default `false`).

- **Config surface: new terminal keys**
  - Added to global settings schema/types:
    - `pkg/wconfig/settingsconfig.go`
  - Added to block metadata typing:
    - `pkg/waveobj/wtypemeta.go`
  - Added default values:
    - `pkg/wconfig/defaultconfig/settings.json`
      - `"term:cursor": "block"`
      - `"term:cursorblink": false`

- **Frontend terminal behavior (xterm options)**
  - `frontend/app/view/term/termwrap.ts`
- Added `setCursorStyle()` with value normalization (`underline`/`bar`
else fallback `block`)
    - Added `setCursorBlink()`
- Applies both options on terminal construction via
`getOverrideConfigAtom(...)`
  - `frontend/app/view/term/term-model.ts`
    - Subscribes to `term:cursor` and `term:cursorblink` override atoms
- Propagates live updates to `term.options.cursorStyle` /
`term.options.cursorBlink`
    - Cleans up subscriptions in `dispose()`

- **Generated artifacts**
  - Regenerated config/type outputs after Go type additions:
    - `schema/settings.json`
    - `pkg/wconfig/metaconsts.go`
    - `pkg/waveobj/metaconsts.go`
    - `frontend/types/gotypes.d.ts`

- **Docs**
  - Updated config reference and default config example:
    - `docs/docs/config.mdx`

```ts
// termwrap.ts
this.setCursorStyle(globalStore.get(getOverrideConfigAtom(this.blockId, "term:cursor")));
this.setCursorBlink(globalStore.get(getOverrideConfigAtom(this.blockId, "term:cursorblink")) ?? false);

// term-model.ts (live updates)
const termCursorAtom = getOverrideConfigAtom(blockId, "term:cursor");
this.termCursorUnsubFn = globalStore.sub(termCursorAtom, () => {
    this.termRef.current?.setCursorStyle(globalStore.get(termCursorAtom));
});
```

<!-- START COPILOT CODING AGENT TIPS -->
---

🔒 GitHub Advanced Security automatically protects Copilot coding agent
pull requests. You can protect all pull requests by enabling Advanced
Security for your repositories. [Learn more about Advanced
Security.](https://gh.io/cca-advanced-security)

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: sawka <2722291+sawka@users.noreply.github.com>
Co-authored-by: sawka <mike@commandline.dev>
2026-02-25 12:40:20 -08:00
Copilot
195277de45
Generate WaveEvent as a typed discriminated union with explicit null payloads for no-data events (#2899)
This updates WaveEvent typing to be event-aware instead of `data?: any`,
while keeping safe fallback behavior for unmapped events. It also
codifies known no-payload events as `null` payloads and documents event
payload expectations alongside the Go event constants.

- **Event registry + payload documentation (Go)**
- Added `AllEvents` in `pkg/wps/wpstypes.go` as the canonical list of
Wave event names.
  - Added/updated inline payload annotations on `Event_*` constants.
- Marked confirmed no-payload events with `// type: none` (e.g.
`route:up`, `route:down`, `workspace:update`, `waveapp:appgoupdated`).

- **Dedicated WaveEvent TS generation path**
- Added `pkg/tsgen/tsgenevent.go` with `event -> reflect.Type` metadata
(`WaveEventDataTypes`).
  - Supports three cases:
    - mapped concrete type → strong TS payload type
    - mapped `nil` → `data?: null` (explicit no-data contract)
    - unmapped event → `data?: any` (non-breaking fallback)

- **Custom WaveEvent output and default suppression**
- Suppressed default struct-based `WaveEvent` emission in
`gotypes.d.ts`.
  - Added generated `frontend/types/waveevent.d.ts` containing:
    - `WaveEventName` string-literal union from `AllEvents`
    - discriminated `WaveEvent` union keyed by `event`.

- **Generator wiring + focused coverage**
- Hooked custom event generation into
`cmd/generatets/main-generatets.go`.
  - Added `pkg/tsgen/tsgenevent_test.go` assertions for:
    - typed mapped events
    - explicit `null` for known no-data events
    - `any` fallback for unmapped events.

```ts
type WaveEvent = {
  event: WaveEventName;
  scopes?: string[];
  sender?: string;
  persist?: number;
  data?: any;
} & (
  { event: "block:jobstatus"; data?: BlockJobStatusData } |
  { event: "route:up"; data?: null } |
  { event: "workspace:update"; data?: null } |
  { event: "some:future:event"; data?: any } // fallback if unmapped
);
```

<!-- START COPILOT CODING AGENT TIPS -->
---

💬 We'd love your input! Share your thoughts on Copilot coding agent in
our [2 minute survey](https://gh.io/copilot-coding-agent-survey).

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: sawka <2722291+sawka@users.noreply.github.com>
Co-authored-by: sawka <mike@commandline.dev>
2026-02-20 17:04:03 -08:00
Mike Sawka
0cc6c454a9
detect if omz is installed and shell completion mode in zsh (#2891) 2026-02-19 10:22:56 -08:00
Mike Sawka
0fb25daf24
Durable Session PR #5 (Icon Flyover, More Bug Fixes, Corner Cases) (#2825)
* Track wave version when job was created (for future backward compat)
* New Flyover Menu off of "shell durability" icon.  Help + Actions + UX
* Bug with conn typeahead not closing when clicking disconnect
* Auto-reconnect jobs that have been disconnected (check for "gone"
state)
* Disable tab indicator stuff (only indicates tab not block)
* Fix bug with dev logging path on connserver
* Fix bugs with restarting blockcontrollers on startup
* Fix bugs with getting HasExited status from job manager
* Fix startup files, quoting, tilde, etc in start job flow
* ...
2026-02-05 10:15:22 -08:00
Mike Sawka
ff9923f486
Session Durability Checkpoint (#2821)
Working on bug fixes and UX. Streams restarting, fixed lots of bugs,
timing issues, concurrency bugs. Get status shipped to the FE to drive
"shield" state display. Deal with stale streams.

Also big UX changes to the block headers. Specialize the terminal
headers to prioritize the connection (sense of place), remove old
terminal icon and word "Terminal" from the header. Also drop "Web" and
"Preview" labels on web/preview blocks.

Added `wsh focusblock` command.
2026-02-03 11:49:52 -08:00
Mike Sawka
73bb5beb3b
Tab Indicators, Confirm on Quit, etc (#2811)
* Adds a Confirm on Quit dialog (and new config to disable it)
* New MacOS keybinding for Cmd:ArrowLeft/Cmd:ArrowRight to send Ctrl-A
and Ctrl-E respectively
* Fix Ctrl-V regression on windows to allow config setting to override
* Remove questionnaire in bug template
* Full featured tab indicators -- icon, color, priority, clear features.
Can be manipulated by new `wsh tabindicator` command
* Hook up BEL to new tab indicator system. BEL can now play a sound
and/or set an indicator (controlled by two new config options)
2026-01-29 17:04:29 -08:00
Mike Sawka
01a26d59e6
Persistent Terminal Sessions (+ improvements and bug fixes) (#2806)
Lots of updates across all parts of the system to get this working. Big
changes to routing, streaming, connection management, etc.

* Persistent sessions behind a metadata flag for now
* New backlog queue in the router to prevent hanging
* Fix connection Close() issues that caused hangs when network was down
* Fix issue with random routeids (need to be generated fresh each time
the JWT is used and not fixed) so you can run multiple-wsh commands at
once
* Fix issue with domain sockets changing names across wave restarts
(added a symlink mechanism to resolve new names)
* ClientId caching in main server
* Quick reorder queue for input to prevent out of order delivery across
multiple hops
* Fix out-of-order event delivery in router (remove unnecessary go
routine creation)
* Environment testing and fix environment variables for remote jobs (get
from connserver, add to remote job starts)
* Add new ConnServerInit() remote method to call before marking
connection up
* TODO -- remote file transfer needs to be fixed to not create OOM
issues when transferring large files or directories
2026-01-28 13:30:48 -08:00
Mike Sawka
ae3e9f05b7
new job manager / framework for creating persistent remove sessions (#2779)
lots of stuff here.

introduces a streaming framework for the RPC system with flow control.
new authentication primitives for the RPC system. this is used to create
a persistent "job manager" process (via wsh) that can survive
disconnects. and then a jobcontroller in the main server that can
create, reconnect, and manage these new persistent jobs.

code is currently not actively hooked up to anything minus some new
debugging wsh commands, and a switch in the term block that lets me test
viewing the output.

after PRing this change the next steps are more testing and then
integrating this functionality into the product.
2026-01-21 16:54:18 -08:00
Mike Sawka
e3c9984e68
removed pinned tabs feature (#2737) 2026-01-02 21:12:03 -08:00
Mike Sawka
2b243627c3
very large refactor of wshrouter (#2732)
the PR spiraled and ended up being much larger than anticipated.

it is a refactor of wshrouter to have it track "links" as opposed to
just routes. this lets us simplify a lot of things when it comes to
multi-level routing.

* now the router can handle unauthenticated links directly, instead of a
weird limbo in wshproxy
* no more wshmultiproxy
* no more "authtoken" weirdness
* more straightforward handling in connserver (when using router option)

also adds more debugging, more logging, some windows fixes, other wsl
fixes
2026-01-01 17:44:00 -08:00
Mike Sawka
73e56193e7
implement openai chat completions api -- enables local model support (#2600) 2025-11-26 11:43:19 -08:00
Mike Sawka
cc51509fe7
add new setting term:macoptionismeta (#2589) 2025-11-21 10:54:58 -08:00
Mike Sawka
3b97084471
fix tsunami scaffold in build (#2564) 2025-11-14 16:35:37 -08:00
Mike Sawka
347eef289d
more builder updates (#2553)
* 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
2025-11-13 22:47:46 -08:00
Mike Sawka
7ac2f25b04
big improvements to waveapp builder (#2550)
* 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
2025-11-13 17:54:17 -08:00
Mike Sawka
4da6a39303
New AI Thinking Control (#2543)
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.
2025-11-11 19:46:10 -08:00
Mike Sawka
a7d76d3dae
add ability to change thinking/maxtokens from waveai context menu (#2504) 2025-10-31 17:58:07 -07:00
Mike Sawka
a19cb6f300
Add Write File Tools to WaveAI (#2492)
also updates ROADMAP.md, and fixes a node pruning bug on the FE, and
adds a new diff viewer that we can view the write_text_file and
edit_text_file diffs in. adds a backup file system that can be used to restore AI edited files back to their original states.
2025-10-31 14:40:03 -07:00
Mike Sawka
ba573c4bcb
tsunami builder 3 (checkpoint) (#2487)
Got preview hooked up, log output hooked up, environment tab hooked
up... the controller, restarting the apps. it is actually working! still
lots to do and lots of hard coding to fix, but it is coming together...
2025-10-28 13:59:02 -07:00
Mike Sawka
ef5a59e710
tsunami app builder 2 (#2486) 2025-10-27 16:37:15 -07:00
Mike Sawka
755d9783c9
waveapps builder window (scaffolding, restructure AI panel to work in both builder and tab windows) (#2482) 2025-10-26 17:48:01 -07:00
Mike Sawka
2e0b3d2569
implement more OSC 16162 for fish, pwsh, and bash (#2462) 2025-10-20 17:29:38 -07:00
Copilot
665facbc7c
Add mobile user agent emulation for web widgets (#2454)
This PR adds support for mobile user agent emulation in web widgets,
enabling developers to test mobile-responsive websites directly within
WaveTerm.

## Changes

### New Meta Key: `web:useragenttype`

Added a new metadata key that accepts the following values:
- `"default"` (or `null`) - Uses the standard browser user agent
- `"mobile:iphone"` - Emulates iPhone Safari (iOS 17.0)
- `"mobile:android"` - Emulates Android Chrome (Android 13)

### User Interface

**Settings Menu**: Added a "User Agent Type" submenu to web widget
settings (accessible via right-click → Settings) with radio button
options for Default, Mobile: iPhone, and Mobile: Android.

**Visual Indicator**: When a mobile user agent is active, a mobile
device icon appears in the widget's header toolbar with an appropriate
tooltip indicating the current emulation mode.

### Implementation Details

The implementation leverages Electron's webview `useragent` attribute to
override the default user agent string. The setting is persisted in the
block's metadata and automatically applied when the webview is rendered.

User agent strings used:
- **iPhone**: `Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X)
AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148
Safari/604.1`
- **Android**: `Mozilla/5.0 (Linux; Android 13) AppleWebKit/537.36
(KHTML, like Gecko) Chrome/120.0.6099.43 Mobile Safari/537.36`

## Use Cases

This feature is particularly useful for:
- Testing mobile-responsive web designs
- Debugging mobile-specific website behaviors
- Viewing mobile versions of websites without needing physical devices
- Web development workflows that require testing across different user
agents

## Files Changed

- `pkg/waveobj/wtypemeta.go` - Added `WebUserAgentType` field to
metadata type
- `frontend/types/gotypes.d.ts` - Generated TypeScript types for the new
meta key
- `frontend/app/view/webview/webview.tsx` - Implemented user agent
selection UI and webview configuration
- `pkg/waveobj/metaconsts.go` - Generated Go constants for the new meta
key


Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: sawka <2722291+sawka@users.noreply.github.com>
2025-10-17 17:45:32 -07:00
Mike Sawka
6a173a6227
working on more terminal context (#2444)
* add automatic OSC 7 support to bash and zsh
* add new wave OSC 16162 (planck length) to get up-to-date shell
information into blockrtinfo. currently implemented only for zsh. bash
will not support as rich of data as zsh, but we'll be able to do some.
* new rtinfo will be used to provide better context for AI in the
future, and to make sure AI is running safe commands.
* added a small local machine description to tab context (so AI knows
we're running on MacOS, Linux, or Windows)
2025-10-17 12:19:40 -07:00
Mike Sawka
50cf6b589b
add an onboarding upgrade modal (#2433) 2025-10-14 20:21:10 -07:00
Mike Sawka
822f05e379
Big Onboarding Updates (#2428) 2025-10-13 16:39:37 -07:00
Mike Sawka
d272a4ec03
New AIPanel (#2370)
Massive PR, over 13k LOC updated, 128 commits to implement the first pass at the new Wave AI panel.  Two backend adapters (OpenAI and Anthropic), layout changes to support the panel, keyboard shortcuts, and a huge focus/layout change to integrate the panel seamlessly into the UI.

Also fixes some small issues found during the Wave AI journey (zoom fixes, documentation, more scss removal, circular dependency issues, settings, etc)
2025-10-07 13:32:10 -07:00
Mike Sawka
5a95e827bf
layout simplification (#2387)
The current layout system uses a complex bidirectional atom architecture
that forces every layout change to round-trip through the backend
WaveObject, even though **the backend never reads this data** - it only
queues actions via `PendingBackendActions`. By switching to a "write
cache" pattern where local atoms are the source of truth and backend
writes are fire-and-forget, we can eliminate ~70% of the complexity
while maintaining full persistence.

----

Every layout change (split, close, focus, magnify) currently follows
this flow:

```
User action
  ↓
treeReducer() mutates layoutState
  ↓
layoutState.generation++  ← Only purpose: trigger the write
  ↓
Bidirectional atom setter (checks generation)
  ↓
Write to WaveObject {rootnode, focusednodeid, magnifiednodeid}
  ↓
WaveObject update notification
  ↓
Bidirectional atom getter runs
  ↓
ALL dependent atoms recalculate (every isFocused, etc.)
  ↓
React re-renders with updated state
```

---

## Proposed "Write Cache" Architecture

### Core Concept

```
User action
  ↓
Update LOCAL atom (immediate, synchronous)
  ↓
React re-renders (single tick, all atoms see new state)
  ↓
[async, fire-and-forget] Persist to WaveObject
```

### Key Principles

1. **Local atoms are source of truth** during runtime
2. **WaveObject is persistence layer** only (read on init, write async)
3. **Backend actions still work** via `PendingBackendActions`
4. **No generation tracking needed** (no need to trigger writes)
2025-10-03 10:10:07 -07:00
Mike Sawka
50cc08a769
add tsunami view in wave (#2350)
checkpoint.  good to merge.  we have a working tsunami view inside of wave (with lots of caveats).  but enough for some dev testing.  merge so we dont drift too far from main and while we're at a stable point.
2025-09-15 12:58:59 -07:00
Mike Sawka
56f03896cb
implement cmd:jwt and fix remote execution of commands (#2292) 2025-08-26 16:23:48 -07:00
Mike Sawka
b81b824b7d
fix some telemetry events (#2289) 2025-08-26 16:08:39 -07:00
Mike Sawka
a85b658cd7
migrate to react 19 (#2272)
migrate to react 19 + fix lingering typescript errors and weirdness.
2025-08-25 21:17:15 -07:00
Mike Sawka
66164ac15e
term shiftenternewline config for claude code Shift+Enter support (#2285) 2025-08-22 14:08:48 -07:00
Mike Sawka
d36bd388e4
new replace, split-horizontal, and split-vertical layout actions... hook up cmd-d and cmd-shift-d... (#1931)
Co-authored-by: Evan Simkowitz <esimkowitz@users.noreply.github.com>
2025-02-10 16:32:23 -08:00
Mike Sawka
a73381296d
web bookmarks (#1930) 2025-02-07 16:11:40 -08:00
Mike Sawka
1913cc5c99
initscript -- support for local files, and overrides in connections.json (#1818) 2025-01-23 15:41:13 -08:00
Mike Sawka
ec07b172e5
pull cmd:env and initscripts into wave terminals (#1793) 2025-01-22 16:04:08 -08:00
Mike Sawka
ba5f929b3f
conn updates 3 (#1711)
lots of misc connection refactoring / fixes:

* adds blocklogger as a way to writing logging information from the backend directly to the a terminal block
* use blocklogger in conncontroller
* use blocklogger in sshclient
* fix remote name in password prompt
* use sh -c to get around shell weirdness
* remove cmd.exe special cases
* use GetWatcher().GetFullConfig() rather than re-reading the config file
* change order of things we do when establishing a connection.  ask for wsh up front.  then do domain socket, then connserver
* reduce number of sessions required in the common case when wsh is already installed.  running the connserver is now a "multi-command" which checks if it is installed, then asks for the version
* send jwt token over stdin instead of in initial command string
* fix focus bug for frontend conn modal
* track more information in connstatus
* simplify wshinstall function
* add nowshreason
* other misc cleanup
2025-01-10 14:09:32 -08:00
Mike Sawka
55f03730bc
add term:allowbracketedpaste, default false (#1688) 2025-01-07 10:55:26 -08:00
Evan Simkowitz
b51ff834b2
Happy new year! (#1684)
Update all 2024 references to 2025
2025-01-04 20:56:57 -08:00
Mike Sawka
91a54442b7
implement web:hidenav (#1639), and file:/// urls (#1638) (#1645) 2024-12-30 16:51:00 -08:00
Mike Sawka
eff12635d7
transparent terminal themes (#1561) 2024-12-19 10:41:28 -08:00
Evan Simkowitz
0a3dadb628
Add wsh wavepath command for getting Wave paths (#1545) 2024-12-17 14:11:40 -08:00
Mike Sawka
f1cd6b933d
relative markdown text (#1489) 2024-12-16 16:04:07 -08:00
Mike Sawka
38deb28da5
webview zoom (#1531) 2024-12-16 14:16:21 -08:00
Mike Sawka
7386fc19f7
activity update + dont allow empty workspace names (#1393) 2024-12-05 10:35:54 -08:00
Mike Sawka
72f36a9639
wsh run (#1376)
implements `wsh run` command.  lots of fixes (and new options) for command blocks.  cleans up the UX/UI for command blocks.  lots of bug fixes for blockcontrollers.  other minor bug fixes.

also makes editor:* vars into settings override atoms.
2024-12-04 14:16:50 -08:00
Evan Simkowitz
aa77b2c259
Pinned tabs (#1375)
![image](https://github.com/user-attachments/assets/a4072368-b204-4eed-bb65-8e3884687f9a)

This functions very similarly to VSCode's pinned tab feature. To pin a
tab, you can right-click on it and select "Pin tab" from the context
menu. Once pinned, a tab will be fixed to the left-most edge of the tab
bar, in order of pinning. Pinned tabs can be dragged around like any
others. If you drag an unpinned tab into the pinned tabs section (any
index less than the highest-index pinned tab), it will be pinned. If you
drag a pinned tab out of the pinned tab section, it will be unpinned.
Pinned tabs' close button is replaced with a persistent pin button,
which can be clicked to unpin them. This adds an extra barrier to
accidentally closing a pinned tab. They can still be closed from the
context menu.
2024-12-04 13:34:22 -08:00
Evan Simkowitz
90e31dfa48
Delete a tab when it's out of blocks, cascade to window (#1374)
Updates `DeleteBlock` to close its parent tab if the tab has no more
blocks. This will also cascade to close the workspace if it no longer
has any tabs, same for window.

I had to move some block-related functionality around on the backend.
2024-12-03 09:38:46 -08:00