Commit graph

351 commits

Author SHA1 Message Date
Mike Sawka
7ef0bcd87f
preview updates (mock electron api, wos checks) (#2986)
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-06 16:50:41 -08:00
Copilot
0ab26ef947
Add a mousedown handler to also signal user activity in the app (#2976)
`mousedown` activity signaling was structured such that async telemetry
concerns leaked into event handling. This change moves fire-and-forget
behavior to the model boundary and keeps telemetry failures non-fatal.

- **`mousedown` handler path**
- `AppKeyHandlers` now calls `GlobalModel.getInstance().setIsActive()`
directly (no async wrapper in the handler).

- **`GlobalModel.setIsActive` structure**
  - `setIsActive()` is now synchronous (`void`).
  - Throttle logic remains unchanged.
- Electron telemetry call is executed via `util.fireAndForget(...)`
inside `setIsActive()`.

- **Telemetry error containment**
- `getApi().setIsActive()` is wrapped in `try/catch` inside the
fire-and-forget callback.
- Errors are logged with `console.log("setIsActive error", e)` and do
not bubble.

- **Focused coverage**
  - Added `frontend/app/store/global-model.test.ts` for:
    - fire-and-forget invocation + throttling behavior
    - error logging/swallowing on rejected telemetry call

```ts
setIsActive(): void {
    const now = Date.now();
    if (now - this.lastSetIsActiveTs < GlobalModel.IsActiveThrottleMs) {
        return;
    }
    this.lastSetIsActiveTs = now;
    util.fireAndForget(async () => {
        try {
            await getApi().setIsActive();
        } catch (e) {
            console.log("setIsActive error", e);
        }
    });
}
```

<!-- 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-03-04 16:25:53 -08:00
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
Mike Sawka
98c374b8cd
quick updates to get apptype (#2969) 2026-03-03 15:19:23 -08:00
Mike Sawka
b5d23e544e
v0.14.1 Release Notes and Onboarding (#2966) 2026-03-03 08:58:31 -08:00
Copilot
b2f3129aa0
Add wsh debugterm (#2947)
`wsh debugterm` currently decodes terminal bytes sourced from backend
block files. This extends it with a stdin-driven path so FE-emitted
payloads like `["...", "..."]` can be decoded directly without requiring
block lookup/RPC in that mode.

- **CLI surface**
  - Added new mode: `--mode stdin`
  - Updated mode help text to: `hex`, `decode`, `stdin`
  - Centralized mode validation via `getDebugTermMode()`

- **Execution path split**
  - Added mode-aware pre-run (`debugTermPreRun`):
    - `stdin` mode: skips RPC setup
    - `hex`/`decode`: keeps existing RPC setup behavior
  - `stdin` mode now:
    - reads all stdin
    - parses JSON as `[]string`
    - concatenates entries and runs existing decode formatter

- **Parsing support**
  - Added `parseDebugTermStdinData([]byte) ([]byte, error)`
  - Error messaging explicitly requires a JSON array of strings

- **Tests**
  - Added focused coverage for:
    - valid stdin JSON array parsing + decoded output
    - invalid stdin JSON input

```go
stdinData, _ := io.ReadAll(WrappedStdin)
termData, err := parseDebugTermStdinData(stdinData) // expects []string JSON
if err != nil { return err }
WriteStdout("%s", formatDebugTermDecode(termData))
```

<!-- 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>
Co-authored-by: sawka <mike@commandline.dev>
2026-02-27 10:24:26 -08:00
Mike Sawka
8306c6bbe7
remove orphaned style.scss, make windowtype.ts, small CSS cleanup (#2939)
also duplicates rules.md for kilocode which was not picking it up from
the .roo directory
2026-02-25 16:07:13 -08:00
Copilot
ed7fa40300
Refine RemoteFileMultiInfoCommand semantics: dedup inputs, per-path stat errors, and cancellation (#2935)
This follow-up tightens the new multi-file remote stat RPC behavior to
match expected usage: duplicate input paths are skipped, per-path stat
failures no longer fail the entire call, and cancellation is respected
during iteration.

- **RPC response model**
  - Added `staterror` to `FileInfo`:
    - `StatError string \`json:"staterror,omitempty"\``
  - Generated TS type now exposes `staterror?: string` on `FileInfo`.

- **`RemoteFileMultiInfoCommand` behavior updates**
- **Dedup:** if an input path key is already present in the result map,
the loop continues.
- **Non-fatal stat failures:** on `fileInfoInternal` error, the command
now emits a `FileInfo` entry for that input with:
    - resolved `path`, `dir`, `name`
    - `staterror` populated with `err.Error()`
    - continues processing remaining paths.
- **Cancellation:** checks `ctx.Err()` at the top of each iteration and
returns immediately if canceled.

- **PR scope cleanup**
  - Removed the previously added test file from this PR per request.

```go
if _, found := rtn[path]; found {
    continue
}
if ctx.Err() != nil {
    return nil, ctx.Err()
}
fileInfo, err := impl.fileInfoInternal(cleanedPath, false)
if err != nil {
    rtn[path] = wshrpc.FileInfo{
        Path:      wavebase.ReplaceHomeDir(cleanedPath),
        Dir:       computeDirPart(cleanedPath),
        Name:      filepath.Base(cleanedPath),
        StatError: err.Error(),
    }
    continue
}
```

<!-- 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>
2026-02-25 12:52:50 -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
96ad7a5c5b
Wire deterministic context-menu close signaling across Electron and renderer (#2932)
Context-menu opens previously produced renderer callbacks only on
selection (0 or 1 events). This change makes the lifecycle
deterministic: every menu open now emits exactly one completion signal,
with `null` on cancel and item id on selection.

- **Main process: single terminal callback per popup**
  - Updated `emain/emain-menu.ts` to use `menu.popup({ callback })`.
  - Tracks whether a menu item click occurred during the popup.
- Emits `contextmenu-click: null` only when the menu closes without
selection.
  - Suppresses duplicate close events when a click already fired.

- **Preload + API typing: nullable context-menu callback payload**
  - Updated preload bridge and `frontend/types/custom.d.ts` so:
    - `onContextMenuClick` now accepts `(id: string | null) => void`.
- Keeps existing channel semantics while allowing explicit cancel
signal.

- **Renderer context menu model: close/select/cancel hooks**
  - Extended `showContextMenu` with optional `opts`:
    - `onSelect?: (item) => void`
    - `onCancel?: () => void`
    - `onClose?: (item: MenuItem | null) => void`
  - Execution order on selection:
    1. original item `click`
    2. `onSelect`
    3. `onClose`
  - Execution order on cancel:
    1. `onCancel`
    2. `onClose(null)`

- **Targeted behavior tests**
  - Expanded `frontend/app/store/contextmenu.test.ts` to verify:
    - singleton wiring still initializes once,
    - selection path ordering (`click -> onSelect -> onClose`),
    - cancel path ordering (`onCancel -> onClose(null)`).

```ts
ContextMenuModel.getInstance().showContextMenu(menu, e, {
    onSelect: (item) => { /* after item.click */ },
    onCancel: () => { /* close without selection */ },
    onClose: (itemOrNull) => { /* always called */ },
});
```

<screenshot>

Not applicable — this is a behavioral/API flow change in native context
menu lifecycle rather than a visual UI update.

</screenshot>

<!-- 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-25 12:39:48 -08:00
Copilot
200863bbbc
Remove unused frontend notification system and dev-only updater notification UI (#2929)
This PR removes the legacy notification pipeline from the frontend
(`pushNotification`, removal helpers, notification atoms/types, and
notification UI components). The updater status notification path was
only wired through this system and dev-only rendering in `App`, so the
entire path is deleted.

- **Store/API cleanup**
  - Removed notification functions from `frontend/app/store/global.ts`:
    - `pushNotification`
    - `removeNotificationById`
    - `removeNotification`
    - internal add/update helper
- Removed notification API exposure from `frontend/wave.ts`
(`window.pushNotification`, `window.removeNotificationById`).

- **Global atom/type cleanup**
- Removed notification atoms from `frontend/app/store/global-atoms.ts`:
    - `notifications`
    - `notificationPopoverMode`
- Removed notification-related fields/types from
`frontend/types/custom.d.ts`:
    - `GlobalAtomsType.notifications`
    - `GlobalAtomsType.notificationPopoverMode`
    - `NotificationType`
    - `NotificationActionType`

- **UI removal**
- Removed notification rendering from `frontend/app/app.tsx` by deleting
the `NotificationBubbles` import and dev-guarded render branch.
- Deleted the entire notification UI module under
`frontend/app/notification/`:
    - `notificationbubbles.tsx/.scss`
    - `notificationitem.tsx/.scss`
    - `notificationpopover.tsx`
    - `updatenotifier.tsx`
    - `usenotification.tsx`

- **Representative diff**
  ```tsx
  // before (app.tsx)
import { NotificationBubbles } from
"./notification/notificationbubbles";
  ...
  {isDev() ? <NotificationBubbles></NotificationBubbles> : null}

  // after
  // notification import and render removed
  ```

<screenshot>

UI reference provided for this change set:  

https://github.com/user-attachments/assets/6f56b16f-95c9-4a5e-ada8-18ecdc9a1ff8

</screenshot>

<!-- 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>
2026-02-24 12:49:13 -08:00
Copilot
1c5f2f9840
Remove unused FlashError pipeline (UI + global state + style/type surface) (#2928)
`FlashError` was legacy UI/state that was never wired into real runtime
flows (only self-referenced and window-exported for ad-hoc testing).
This PR removes that dead path end-to-end to reduce global surface area
and stale styling/types.

- **Scope: UI removal (`frontend/app/app.tsx`)**
- Deleted the `FlashError` component and its render site (`<FlashError
/>`).
- Removed now-unused imports tied to that component (`removeFlashError`,
`Fragment`, `useState`).

- **Scope: global store cleanup (`frontend/app/store/global.ts`,
`frontend/app/store/global-atoms.ts`)**
  - Removed `pushFlashError` / `removeFlashError`.
- Removed `flashErrors` atom from global atom initialization and
registry.
- Kept notification path intact (`pushNotification`,
`removeNotificationById`, etc.).

- **Scope: external/debug surface cleanup (`frontend/wave.ts`)**
- Removed `pushFlashError` from imports and from `window` export wiring.

- **Scope: type + style cleanup (`frontend/types/custom.d.ts`,
`frontend/app/app.scss`, `frontend/app/theme.scss`)**
  - Removed `GlobalAtomsType.flashErrors`.
  - Removed `FlashErrorType`.
- Removed `.flash-error-container` style block and related z-index token
`--zindex-flash-error-container`.

```ts
// before
(window as any).pushFlashError = pushFlashError;

// after
(window as any).pushNotification = pushNotification;
```

- **`<screenshot>`**
- User-provided screenshot URL (if suitable for PR timeline context):

https://github.com/user-attachments/assets/aacc2e61-a65c-4dbf-bfcc-f9f99a490f20

<!-- 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>
2026-02-24 12:11:38 -08:00
Mike Sawka
110e2b90a1
update eslint to v9 (and fix all eslint errors) (#2923) 2026-02-23 18:42:17 -08:00
Mike Sawka
9abd590176
UI only preview server (+ deployments) (#2919)
adds a new "preview server" for UI testing. hooking up to cloudflare
pages deployments. for now, just a test "about modal" component. will
add more later.
2026-02-23 12:48:28 -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
John Feustel
b9067fb60b
Add app:focusfollowscursor setting (off/on/term) for hover-based block focus (#2908)
This PR adds a new app setting to control whether block focus follows
cursor movement:

  - `app:focusfollowscursor: "off" | "on" | "term"`
  - Default is `"off"` (no behavior change unless enabled)

  ## What changed

  - Added hover-focus behavior on block pointer enter.
  - Added guardrails so hover focus does not trigger when:
  - touch input is used
  - pointer buttons are pressed (drag/select scenarios)
  - modal is open
  - pointer events are disabled
  - block is resizing
  - Added config key plumbing across settings types and schema:
  - `pkg/wconfig/settingsconfig.go`
  - `pkg/wconfig/metaconsts.go`
  - `schema/settings.json`
- `pkg/wconfig/defaultconfig/settings.json` ->
`"app:focusfollowscursor": "off"`
  - Added docs for the new key and default example:
  - `docs/docs/config.mdx`

  ## Behavior

  - `"off"`: do not focus on cursor movement
  - `"on"`: focus follows cursor for all block types
  - `"term"`: focus follows cursor only for terminal blocks
2026-02-20 14:47:26 -08:00
Copilot
e8d4cddb5a
Add optional per-workspace widget visibility via workspaces in widgets.json (#2898)
This change adds an optional `workspaces` field to widget config entries
so widgets can be scoped to specific workspace UUIDs. Widgets with no
`workspaces` field (or an empty array) continue to render globally,
preserving current `widgets.json` behavior.

- **Config model updates**
- Added `workspaces []string` to `wconfig.WidgetConfigType` with
`json:"workspaces,omitempty"`.
- Updated frontend generated type `WidgetConfigType` with `workspaces?:
string[]`.

- **Sidebar widget filtering**
- `frontend/app/workspace/widgets.tsx` now applies workspace-aware
filtering when building the sidebar widget list:
    - include if `workspaces` is missing or empty
    - include if current `workspace.oid` is present in `workspaces`
    - otherwise exclude
  - Existing `defwidget@ai` filtering logic remains intact.

- **Isolated filtering logic + coverage**
  - Added `frontend/app/workspace/widgetfilter.ts` with:
    - `shouldIncludeWidgetForWorkspace(widget, workspaceId)`
- Added focused tests in `frontend/app/workspace/widgetfilter.test.ts`
for:
    - missing/empty `workspaces`
    - matching/non-matching workspace IDs
    - missing active workspace ID

```ts
function shouldIncludeWidgetForWorkspace(widget: WidgetConfigType, workspaceId?: string): boolean {
  const workspaces = widget.workspaces;
  return !Array.isArray(workspaces) || workspaces.length === 0 || (workspaceId != null && workspaces.includes(workspaceId));
}
```

- **Screenshot**
-
<screenshot>https://github.com/user-attachments/assets/b1727003-793b-4eff-8fc1-00eac9c50b83</screenshot>

<!-- 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-19 16:14:22 -08:00
Mike Sawka
1840de4a13
New Context Menu Item + Wsh Command to Save Scrollback of a Terminal Widget (#2892)
This pull request adds a new command-line feature for exporting terminal
scrollback, improves the accuracy of scrollback extraction (especially
for wrapped lines), and introduces a "Save Session As..." menu option in
the frontend to make exporting session logs more user-friendly. The
changes touch both the backend CLI and the frontend, ensuring users can
easily capture and save terminal output for processing or archiving.
2026-02-19 12:49:57 -08:00
Mike Sawka
65fce27f00
feat: add tab:confirmclose setting to prompt before closing tabs (#2893)
- Add tab:confirmclose boolean config option to SettingsType (Go),
schema/settings.json, and gotypes.d.ts
- Update close-tab IPC handler to use ipcMain.handle (async) and accept
confirmClose param
- Show a native confirmation dialog via dialog.showMessageBoxSync when
confirmClose is true
- Update preload.ts to use ipcRenderer.invoke for close-tab, returning
Promise<boolean>
- Update closeTab type signature in custom.d.ts to return
Promise<boolean>
- Update tabbar.tsx and keymodel.ts to await closeTab result and only
delete layout model on confirmed close
- Document tab:confirmclose in docs/docs/config.mdx

---------

Co-authored-by: kiloconnect[bot] <240665456+kiloconnect[bot]@users.noreply.github.com>
2026-02-19 12:49:16 -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
facefdd12e
job events, terminal command types, connect error codes (#2855) 2026-02-10 20:23:06 -08:00
Mike Sawka
0c5a820797
new config: app:hideaibutton, app:disablectrlshiftarrows, app:disablectrlshiftdisplay (#2850)
| app:hideaibutton <VersionBadge version="v0.14" /> | bool | Set to true
to hide the AI button in the tab bar (defaults to false) |
| app:disablectrlshiftarrows <VersionBadge version="v0.14" /> | bool |
Set to true to disable Ctrl+Shift+Arrow keybindings for block navigation
(defaults to false) |
| app:disablectrlshiftdisplay <VersionBadge version="v0.14" /> | bool |
Set to true to disable the Ctrl+Shift visual indicator display (defaults
to false) |
2026-02-10 09:41:49 -08:00
Mike Sawka
1949aabbd9
new rpc call to get focused block data from a tab (#2833) 2026-02-09 21:51:12 -08:00
Mike Sawka
458fcc2a5d
New ConnMonitor to Track "Stalled" Connection State for SSH Conns (#2846)
* ConnMonitor to track stalled connections
* New Stalled Overlay to show feedback when we think a connection is
stalled
* New Icon in ConnButton to show stalled connections
* Callbacks in domain socket and PTYs to track activity
2026-02-09 17:11:55 -08:00
Mike Sawka
45b197243e
First Cut at Durable Sessions Docs + Onboarding (#2847) 2026-02-09 17:01:17 -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
Geoff Hudik
78ab9e0b94
Add configurable verbosity for OpenAI Responses API (#2776)
# Add configurable verbosity for OpenAI Responses API

Fixes #2775

## Problem

Models like `gpt-5.2-codex` and other newer OpenAI models only support
`medium` reasoning and verbosity levels, but the codebase was using
`low` by default. This caused 400 Bad Request errors:

```
Failed to stream openai-responses chat: openai 400 Bad Request:
Unsupported value: 'low' is not supported with the 'gpt-5.2-codex' model.
Supported values are: 'medium'.
```


## Solution

This PR implements a scalable, user-configurable approach instead of
hardcoding model-specific constraints:

1. **Changed default verbosity** from `"low"` to `"medium"` - more
widely supported across OpenAI models
2. **Added `ai:verbosity` config option** - allows users to configure
verbosity per model in `waveai.json`
3. **Changed rate limit fallback** from `low` to `medium` thinking level
for better compatibility
4. **Removed hardcoded model checks** - solution is scalable for future
models

## Changes

### Backend Changes
- `pkg/aiusechat/openai/openai-convertmessage.go` - Use configurable
verbosity with safe defaults
- `pkg/aiusechat/uctypes/uctypes.go` - Add `Verbosity` field to
`AIOptsType`
- `pkg/aiusechat/usechat.go` - Pass verbosity from config to options
- `pkg/wconfig/settingsconfig.go` - Add `Verbosity` to
`AIModeConfigType`

### Schema Changes
- `schema/waveai.json` - Add `ai:verbosity` with enum values
(low/medium/high)
- `frontend/types/gotypes.d.ts` - Auto-generated TypeScript types

### Configuration Example

Users can now configure both thinking level and verbosity per model:

```json
{
  "openai-gpt52-codex": {
    "display:name": "GPT-5.2 Codex",
    "ai:provider": "openai",
    "ai:model": "gpt-5.2-codex",
    "ai:thinkinglevel": "medium",
    "ai:verbosity": "medium"
  }
}
```
2026-02-04 18:31:57 -08:00
Mike Sawka
a70c788ae6
More Durable Shell Bug Fixes (#2822)
* Lots of work on ResyncController, issues with stale data, and
connection switching
* Add+Fix termination messages for shell controller
* Prune done/detached jobs on a timer
* Remove circular dependencies from wcore, use blockclose event in both
jobcontroller and blockcontroller instead of direct calls
* Fix concurrency bugs with job termination
* Send object update events when modifying the block datastructure in
jobcontroller
2026-02-04 11:10:21 -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
93b7269304
Do not allow large/recursive file transfers (for now), remove s3 and wavefile fs implementations (#2808)
Big simplification. Remove the FileShare interface that abstracted
wsh://, s3://, and wavefile:// files.
It produced a lot of complexity for very little usage. We're just going
to focus on the wsh:// implementation since that's core to our remote
workflows.

* remove s3 implementation (and connections, and picker items for
preview)
* remove capabilities for FE
* remove wavefile backend impl as well
* simplify wsh file remote backend
* remove ability to copy/move/ls recursively
* limit file transfers to 32m

the longer term fix here is to use the new streaming RPC primitives.
they have full end-to-end flow-control built in and will not create
pipeline stalls, blocking other requests, and OOM issues.

these other impls had to be removed (or fixed) because transferring
large files could cause stalls or crashes with the new router
infrastructure.
2026-01-28 14:28:31 -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
31a8714454
rpc streaming primitives (#2759)
built some streaming primitives with windowing for rpc streams. not
hooked up to anything yet (or the WshRpc)
2026-01-08 16:14:56 -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
3084e9d226
introduce new models -- specifically tab model which has a react provider for prop drilling (#2694) 2025-12-18 17:39:37 -08:00
Mike Sawka
3c3c665ac2
fix tool approval lifecycle to match SSE connection, not keep-alives (#2693)
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
2025-12-18 16:43:59 -08:00
Mike Sawka
667de56198
updates to allow wave ai panel to function without telemetry with BYOK/local models (#2685)
* lots of changes to how aimodes are shown on frontend
* backend now requires aimode to be sent with request
* diagnostic ping
2025-12-16 09:06:56 -08:00
Mike Sawka
fbb0c4d052
windows, have a new "local" conn option for Git Bash if installed (#2666) 2025-12-12 14:05:48 -08:00
Mike Sawka
a5599e9105
QoL and Layout Fixes for Windows (#2661)
* 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
2025-12-11 17:50:02 -08:00
Mike Sawka
c9c6192fc9
minor v0.13 fixes (#2649) 2025-12-08 21:58:54 -08:00
Mike Sawka
ea68aec9f4
v0.13 Release Notes, Docs Updates, Onboarding Updates (#2642) 2025-12-08 16:29:19 -08:00
Mike Sawka
f6bd5930ad
AI model compatibility, other misc fixes for release (#2641) 2025-12-05 16:23:54 -08:00
Mike Sawka
0c60f2c8a7
set Ctrl+V as a paste accelerator by default on windows (#2640) 2025-12-05 16:00:14 -08:00
Mike Sawka
2f92e23ece
more config updates (secrets, waveai, ai:provider) (#2631) 2025-12-05 10:10:43 -08:00
Mike Sawka
d1ebcc9d07
new waveconfig widget, consolidate config/help in widget sidebar (#2604) 2025-11-28 11:56:59 -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
1f4835643b
remove storybook, tasks, and dependencies (#2593) 2025-11-24 13:36:00 -08:00
Mike Sawka
cc51509fe7
add new setting term:macoptionismeta (#2589) 2025-11-21 10:54:58 -08:00