Skip to content

Conversation

@sgeraldes
Copy link

Summary

Transforms Wave Terminal's JSON-based settings panel into a dynamic GUI with proper controls for each setting type (toggles, dropdowns, text inputs, sliders, color pickers, etc.) - similar to VS Code's settings UI.

Features

  • Settings Registry: Comprehensive metadata system for all settings with type definitions, labels, descriptions, validation rules
  • GUI Controls: 10 specialized control components (toggle, select, slider, number, text, color, font, path, stringlist, control-factory)
  • Visual Settings View: Main settings panel with category sidebar, VS Code-style layout
  • Search & Filter: Full-text search across settings with modified/category filters
  • Persistence Layer: Debounced saves with optimistic updates via existing RPC system
  • External Sync: Auto-syncs when settings change externally (other windows, manual JSON edits)
  • Integration: Seamlessly integrates with existing WaveConfig infrastructure

Implementation

  • 8 specification documents in .claude/specs/
  • 30+ new files created
  • Uses Jotai atoms for reactive state management
  • Proper TypeScript types throughout
  • Accessibility support (ARIA labels, keyboard navigation)

Commits (7)

  1. f664606e - Settings metadata schema and registry
  2. 21c7d74c - Search and filter system
  3. c61fc19a - GUI control components
  4. b5636d9e - SCSS styling for visual settings panel
  5. dd52ffda - Settings persistence layer with debounced saves
  6. 9d44383e - Integration with WaveConfig
  7. e66d3682 - Bug fixes from code review

Code Review Issues Fixed

  • Added fullConfigAtom subscription to sync settings when backend updates
  • Fixed race condition in debounced save by updating savedSettingsAtom immediately
  • Fixed number-control state sync using proper useEffect and ref
  • Improved cleanup logic in settings-visual-content to prevent memory leaks

Test plan

  • TypeScript compiles without errors
  • Open Settings (General config file)
  • Verify Visual tab shows GUI controls
  • Toggle a boolean setting and verify it persists
  • Change a numeric setting using slider/number control
  • Search for a setting and verify results
  • Switch between Visual and JSON tabs
  • Verify modified indicator appears on changed settings

🤖 Generated with Claude Code

sebastiangeraldes and others added 29 commits January 22, 2026 03:22
## Tab Base Directory Feature
- Per-tab base directory context (tab:basedir, tab:basedirlock metadata)
- Smart auto-detection from terminal OSC 7 sequences
- All terminals and widgets inherit the tab's base directory
- Tab context menu for configuration
- Stale path detection and recovery after restart

## Security & Validation
- Path validation for OSC 7 terminal escape sequences
- Backend metadata validation to prevent injection attacks
- Optimistic locking for metadata updates (race condition fix)
- Preset metadata validation

## VS Code Style Tab Redesign
- Tab backgrounds use relative white overlays (active/hover/inactive)
- Tab stripe moved from left to top horizontal (manual color only)
- Status indicated via text color (running=blue, finished=green, stopped=red)
- Breadcrumb bar below tabs showing active tab's base directory
- App menu moved from tab bar to breadcrumb bar
- Transparent button styling with subtle hover effects

## Other Improvements
- Tab color customization via context menu
- Reactive tab status icons using Jotai atoms
- Reusable preset menu builder
- showOpenDialog API for file picker dialogs

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1. OSC 7 debounce cleanup: Call cleanupOsc7DebounceForTab() when tabs
   are closed to prevent memory leaks from orphaned timers.

2. Smart auto-detection logic: Add missing basedir value check per
   CLAUDE.md spec. OSC 7 now only updates tab:basedir when it's empty
   or equals "~", respecting user-set directories.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The previous fix only addressed simpleCloseStaticTab() in keymodel.ts,
but missed handleCloseTab() in tabbar.tsx which handles the UI close
button. This ensures cleanup for all tab close paths.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- tab-model.ts: Call recomputeTerminalStatus() when finishedUnread changes
- objectservice.go: Add metadata validation to UpdateObjectMetaWithVersion and UpdateObjectMetaIfNotLocked
- wstore.go: Properly handle DBUpdate errors in optimistic locking functions
- Various improvements to WPS broadcast handling and terminal status tracking

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Critical:
- validators.go: Fix UNC path validation - use correct indices for server/share segments

Major:
- widgets.tsx: Clone blockdef before modification to avoid mutating cached config
- workspace.tsx/scss: Make menu button keyboard-accessible using semantic button element
- pathutil.ts: Normalize Windows separators for blocked path checking
- pathutil.ts: Allow empty paths through quick validation for OSC 7 basedir clearing
- presetutil.ts: Implement wildcard prefix matching for bg:* allowlist entries

Minor:
- global.ts: Guard against empty string tab IDs in activeTabAtom
- tab.tsx: Wrap UpdateObjectMeta with fireAndForget to avoid unhandled promise
- term-model.ts: Use readAtom helper for safe atom reads

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Replace private import from @xterm/xterm/src/browser/renderer/shared/Types
  with public type import from @xterm/xterm
- Replace core._renderService.dimensions with terminal.dimensions public API
- Add null check for terminal.dimensions (may be undefined before open())
- Replace scrollbar DOM measurement (core.viewport._viewportElement/scrollArea)
  with constant DEFAULT_SCROLLBAR_WIDTH = 15 (matching xterm.js)
- Remove core._renderService.clear() call (resize handles re-render internally)
- Preserve noScrollbar flag for macOS scrollbar behavior
- Update file comments to reflect xterm.js 6.1.0 update

This refactoring is required for the xterm.js 6.1.0 upgrade as the private
APIs used previously were removed in xterm.js 6.x viewport/scrollbar overhaul.

Related: spec-001-fitaddon-refactor.md

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Update all @xterm/* packages to latest beta versions to enable:
- Synchronized Output (DEC mode 2026) for TUI animation fixes
- Public terminal.dimensions API (added in 6.1.0)

Package versions:
- @xterm/xterm: 5.5.0 → 6.1.0-beta.106
- @xterm/addon-fit: 0.10.0 → 0.12.0-beta.106
- @xterm/addon-search: 0.15.0 → 0.17.0-beta.106
- @xterm/addon-serialize: 0.13.0 → 0.15.0-beta.106
- @xterm/addon-web-links: 0.11.0 → 0.13.0-beta.106
- @xterm/addon-webgl: 0.18.0 → 0.20.0-beta.105

Relates to: wavetermdev#2787

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Update xterm.css to match xterm.js 6.1.0 CSS structure
- Add new DomScrollableElement scrollbar classes
- Add scrollbar slider styles for new xterm-scrollable-element
- Keep legacy webkit-scrollbar styles for compatibility
- Add VS Code scrollbar shadow and visibility class support

Relates to: wavetermdev#2787

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add scrollbar width validation to prevent invalid dimensions
- Add comments explaining terminal.dimensions initialization state
- Document legacy webkit scrollbar CSS and xterm.js 6.x behavior
- Update FitAddon header comment to reflect all changes

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Replace all powershell commands with pwsh -NoProfile in Taskfile.yml
  to prevent profile scripts from corrupting build output (fixes ldflags
  contamination causing Go linker failures)
- Add -NoProfile flag to PowerShell shell launches in shellexec.go for
  local, remote, and WSL shells to prevent profile loading at runtime

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Document that PowerShell 7 (pwsh) is required for Windows builds.
Windows ships with PowerShell 5.1, but the build system uses pwsh
with -NoProfile to prevent profile scripts from interfering with
build output.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Integrates the following changes:
- Upgrade xterm.js to 6.1.0-beta.106 for DEC mode 2026 support
- Refactor FitAddon to use public terminal.dimensions API
- Update CSS for new DomScrollableElement scrollbar
- Fix PowerShell to use pwsh with -NoProfile

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Mark as personal fork of Wave Terminal
- Document UI/UX enhancements (tab redesign, breadcrumbs, OSC 7)
- Document xterm.js 6.1.0 upgrade and TUI animation fixes
- Document Windows PowerShell 7 build fixes
- Add instructions for syncing with upstream

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Tab Base Directory System (major feature)
  - VS Code-style colored tabs
  - Breadcrumb navigation
  - Smart OSC 7 auto-detection
  - Directory locking
  - Tab presets and color picker
  - Terminal status indicators
- Backend Security & Validation
  - Path/URL validation framework (935 lines)
  - Optimistic locking for concurrency
  - Race condition fixes (TOCTOU prevention)
- Terminal Improvements
  - xterm.js 6.1.0 upgrade
  - OSC 7 debouncing
  - Memory leak prevention
- Electron IPC additions
- Windows PowerShell 7 fixes

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Terminal improvements:
- Add font ligatures support via @xterm/addon-ligatures (Issue wavetermdev#1529)
- Enable with "term:ligatures": true in settings
- Works with ligature fonts (Fira Code, JetBrains Mono, etc.)

PowerShell improvements:
- Source user's $PROFILE in wavepwsh.ps1 integration script
- Custom aliases, functions, and prompts now work in Wave terminals

Other changes:
- Disable WaveAppBuilder in dev mode (requires explicit feature flag)
- Update README and CLAUDE.md with new features
- Add ligatures demo screenshot

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
feat: font ligatures, PowerShell profile loading, disable WaveAppBuilder
Run npm audit fix to address:
- diff: DoS vulnerability (fixed)
- js-yaml: prototype pollution (fixed)
- tar-fs: symlink validation bypass (fixed)
- tar: partial fix (some in electron-builder chain remain)

Remaining vulnerabilities are in build-time transitive dependencies
(mermaid/langium/chevrotain, electron-builder) that require breaking
changes to fully resolve.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add npm overrides section to force lodash-es@4.17.23 which fixes
the prototype pollution vulnerability (GHSA-xxjr-mmjv-4gpg).

Remaining tar vulnerabilities (6 high) are in electron-builder's
dependency chain and require upstream fix - tar@7.5.4+ has ESM
breaking changes incompatible with current electron-builder.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove entire WaveApp/Tsunami framework (vdom, waveapp, builder)
- Remove telemetry requirement for Wave AI cloud modes
- Make telemetry recording functions no-ops for backwards compatibility
- Remove telemetry toggle from onboarding flow
- Clean up frontend components that depended on builder mode
- Update generated TypeScript bindings and Go code

This allows Wave AI to work without requiring telemetry to be enabled.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
… requirements

- Remove entire WaveApp/Tsunami framework
- Remove telemetry requirement for Wave AI cloud modes
- Clean up builder-related UI code

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- README.md: Add telemetry removal section to fork changes
- CLAUDE.md: Remove Tsunami framework section, add telemetry/WaveApp removal notes
- telemetry.mdx: Add fork notice about telemetry being disabled
- waveai.mdx: Remove telemetry reference from privacy section
- waveai-modes.mdx: Remove telemetry requirement note

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Create the foundation for the GUI settings system:
- Add settings-metadata.d.ts with TypeScript types for setting metadata
- Add settings-registry.ts with comprehensive registry of all settings
- Include 14 categories: Terminal, Editor, Window, AI, Web, Connections,
  App, AutoUpdate, Preview, Markdown, Widget, BlockHeader, Telemetry, Debug
- Each setting has: key, label, description, controlType, defaultValue,
  type, validation rules, platform specificity, and search tags
- Provide utility functions: getSettingMetadata, searchSettings,
  getCategoryConfig, getOrderedCategories, getSettingsForPlatform

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implement comprehensive search and filtering for settings, similar to VS Code's settings search:
- settings-search.ts: Search logic with relevance scoring algorithm
- settings-search-input.tsx: Search input component with keyboard shortcuts (Cmd/Ctrl+F, Escape)
- use-settings-search.ts: React hook for managing search state and filtering

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implements reusable React components for each setting control type
as specified in spec-002. These components can be dynamically rendered
based on the settings metadata system.

Components created:
- setting-control.tsx: Base wrapper with label, description, modified indicator
- toggle-control.tsx: Toggle/switch for boolean settings
- number-control.tsx: Number input with +/- buttons and validation
- slider-control.tsx: Range slider with value display
- text-control.tsx: Text input with pattern validation support
- select-control.tsx: Dropdown with dynamic options
- color-control.tsx: Color picker with swatch preview
- font-control.tsx: Font input with live preview
- path-control.tsx: File path input with browse button
- stringlist-control.tsx: List editor with add/remove/reorder
- control-factory.tsx: Factory function for dynamic control rendering
- settings-controls.scss: Consistent styling matching Wave's design system
- index.ts: Barrel export for all components

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Create settings-visual.scss with VS Code-inspired styling including:
- Category sidebar with icons, hover states, and modified indicators
- Search bar with focus states and result counts
- Settings list with sticky category headers
- Filter toolbar for filtering modified settings
- Actions bar with save/reset functionality
- Responsive design for smaller screens
- Accessibility focus states and keyboard navigation
- Animations for smooth transitions and highlighting
- Scrollbar styling for settings panels

This provides the visual polish needed for a professional settings
experience that matches Wave Terminal's design system.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implements Spec 005 - Settings Persistence Layer:

- SettingsService class with debounced saves (500ms)
- Optimistic updates for instant UI feedback
- Error handling with rollback support
- Integration with existing fullConfigAtom via RPC
- Jotai atoms for reactive per-setting state
- useSettingValue hook for components
- Proper sync with WPS config events

Files created:
- frontend/app/store/settings-service.ts - Main service singleton
- frontend/app/store/settings-atoms.ts - Jotai atoms for state
- frontend/app/view/waveconfig/use-setting-value.ts - React hook

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implements Spec 007 - Integration with Existing WaveConfig:

- Created SettingsVisualContent wrapper component that connects
  the visual settings view with WaveConfigViewModel
- Created SettingsVisual component with:
  - Category sidebar with icons and setting counts
  - Search bar with real-time filtering
  - Settings list grouped by category/subcategory
  - Control factory rendering appropriate controls
  - Sticky category headers during scroll
- Added visualComponent to General settings config file
- Visual/JSON tab switching works via existing waveconfig.tsx logic

The settings view now shows a Visual tab for General settings that
renders all settings from the registry with appropriate controls.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add fullConfigAtom subscription to sync settings when backend updates
- Update savedSettingsAtom immediately after save to prevent race condition
- Fix number-control state sync using proper useEffect and ref
- Improve cleanup logic in settings-visual-content to prevent memory leaks

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@CLAassistant
Copy link

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you all sign our Contributor License Agreement before we can accept your contribution.
1 out of 2 committers have signed the CLA.

✅ sgeraldes
❌ sebastiangeraldes
You have signed the CLA already but the status is still pending? Let us recheck it.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 24, 2026

Important

Review skipped

Too many files!

89 files out of 239 files are above the max files limit of 150.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

The `&` parent selector must be at the beginning of a compound selector,
not at the end. Moved textarea styles outside the parent block.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@sgeraldes sgeraldes closed this Jan 25, 2026
@sgeraldes sgeraldes deleted the feature/gui-settings-system branch January 25, 2026 03:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants