Skip to content

release: v0.3.1#79

Merged
gnoviawan merged 15 commits intomainfrom
release/v0.3.1
Mar 12, 2026
Merged

release: v0.3.1#79
gnoviawan merged 15 commits intomainfrom
release/v0.3.1

Conversation

@gnoviawan
Copy link
Owner

Summary

  • Release v0.3.1 with all changes since v0.3.0

Included Changes

⚠️ Merge with merge commit (no squash) to preserve commit history for changelogs.

🤖 Generated with Claude Code

gnoviawan and others added 15 commits March 9, 2026 07:45
* fix: use shell.path instead of shell.name when spawning terminal

When users select "PowerShell 7" from the shell dropdown, the terminal
was spawning with Windows PowerShell 5 instead. This happened because
the frontend passed shell.name ("pwsh") to the spawn function, but the
backend's resolve_shell_path() couldn't find pwsh.exe in PATH and fell
back to powershell.exe.

By passing shell.path (the already-detected absolute path), we bypass
PATH resolution entirely and use the correct shell executable.

Fixes #59

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: store shell path instead of name in defaultShell settings

The defaultShell setting was storing shell.name (e.g., "pwsh") instead
of shell.path (e.g., "C:\Program Files\PowerShell\7\pwsh.exe"). This
caused the backend to fail PATH resolution and fall back to the wrong
shell (Windows PowerShell 5 instead of PowerShell 7).

Changes:
- AppPreferences.tsx: Use shell.path as option value
- ProjectSidebar.tsx: Use shell.path for project default shell
- Display shell.displayName for cleaner UI

Fixes #59

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: resolve shell names to paths for backward compatibility

Added resolveShellToPath helper function that:
- Returns shell as-is if it's already a path (contains \ or /)
- Looks up the path from available shells if it's just a name
- Falls back to the original value if lookup fails

This ensures backward compatibility for users who have shell names
stored in their settings from before the fix. Now both old (name-only)
and new (full path) settings work correctly.

Applied to:
- createDefaultTerminal: resolves shell before spawning
- restoreFromLayout: resolves shell when restoring persisted terminals

Fixes #59

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: prioritize explicit shell paths over PATH in detection and resolution

The shell detection and resolution were checking PATH entries before
explicit paths, causing the wrong PowerShell version to be found.

Changes:
- lib.rs: Check PowerShell 7 explicit paths BEFORE PATH entries in
  get_available_shells()
- manager.rs: Check explicit paths BEFORE PATH entries in
  resolve_shell_path()

This ensures PowerShell 7 (C:\Program Files\PowerShell\7\pwsh.exe) is
found and used when installed, rather than falling back to Windows
PowerShell 5 (powershell.exe) from PATH.

Fixes #59

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: remove -NoProfile flag to load PowerShell user profile

The -NoProfile flag was preventing PowerShell from loading the user's
profile, which contains custom prompts, aliases, and other settings.

Changes:
- Removed -NoProfile from PowerShell spawn arguments
- Kept -NoLogo to hide the copyright banner

Users will now see their custom PowerShell prompts (e.g., Oh My Posh,
Starship, or custom profile configurations) when terminals spawn.

Fixes #59

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: code review findings for shell resolution

1. lib.rs: Removed pwsh/pwsh.exe from is_builtin_windows_shell()
   - pwsh is NOT a built-in shell and must be resolved from PATH
   - Only cmd, powershell, and wsl are true Windows built-ins

2. manager.rs: Moved PowerShell handling BEFORE generic *.exe lookup
   - Ensures name-only tokens like "pwsh" hit explicit paths first
   - Prevents generic resolver from short-circuiting PowerShell handling

3. use-terminal-restore.ts: Added basename matching in resolveShellToPath()
   - Now matches by s.name OR basename of s.path
   - Allows "pwsh.exe" to match shell with path ending in "pwsh.exe"

Fixes #59

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: normalize shell selection display for legacy settings

The dropdowns used shell.path as option values, but older saved settings
may have plain shell names stored. This broke the selection display
because the stored name didn't match the option path.

Changes:
- AppPreferences.tsx: Normalize stored defaultShell for display by
  finding matching shell (by name or basename) and using its path
- ProjectSidebar.tsx: Update isSelected check to match by path,
  name, or basename for legacy compatibility

This ensures users with older name-based settings see the correct
selected shell in the UI while new full-path settings work as before.

Fixes #59

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: resolve ESLint warnings for CI

- use-terminal-restore.ts: Capture projectId at effect run time and
  add eslint-disable comment for intentional ref access in cleanup
- WorkspaceLayout.tsx: Note that handleCreateTerminalInPane cannot be
  in deps array as it's defined after this useEffect

Fixes CI lint failures

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: code review findings - separate PowerShell resolution and fix TDZ

- manager.rs: Separate "pwsh" and "powershell" resolution paths
  - "pwsh" now checks PowerShell 7/6 paths then pwsh.exe
  - "powershell" now checks Windows PowerShell 5 path then powershell.exe
  - Previously both tokens used the same mixed path list

- WorkspaceLayout.tsx: Fix temporal dead zone (TDZ) error
  - Moved handleCreateTerminalInPane and handleNewTerminal callbacks
    above the keyboard shortcuts useEffect
  - Added handleCreateTerminalInPane to useEffect dependency array
  - Fixes TypeScript "used before declaration" error

Fixes #59

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: update ProjectSidebar test for path-based shell storage

The app now stores full shell paths instead of shell names for defaultShell.
Update the ProjectSidebar submenu test to expect the full path value passed
to onUpdateProject.

This aligns the test with the current implementation and fixes the failing
CI test job.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
* fix: preserve live terminal sessions across project switches

Keep live PTY-backed terminals and project workspace layouts stable when switching projects, while guarding restore flows against stale async updates and focus drift.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: address PR review type issues

Tighten the follow-up test typings and remove the unused project parameter from terminal restore selection to keep the PR green under typecheck.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: harden terminal restore cancellation

Sync live terminal selection with workspace activation and guard restore helpers against stale async mutations. Tighten restore regression tests so cancelled errors cannot spawn fallback terminals.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: align editor persistence tests with restore flow

Update editor persistence expectations to match the current project-switch restore sequence and latest-call behavior. Keep the full Vitest suite green after the terminal restore follow-up changes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: clean up cancelled restore PTYs

Kill spawned PTYs when project switches cancel terminal restoration so background processes are not orphaned. Add regression coverage for both layout restore and default terminal creation cancellation paths.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: harden terminal restore race handling

Track restore ownership so stale effects cannot clear active restore state, reuse the correct pane when reselecting live terminals, and clean up spawned PTYs during cancellation while resetting the restore spawn guard per session.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Flush pending debounced persistence writes before app close and route context bar setting updates through a dedicated hook so the latest settings survive shutdown.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* fix: persist workspace panel visibility across restarts (#40)

Move sidebar and file explorer visibility into global app settings so panel state survives restarts and project switches. Serialize immediate writes, add rollback on failure, and wait on close so the latest toggle is not lost.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: address review feedback for workspace panel persistence (#40)

Capture panel write payloads in the persistence queue, tighten close-request typing, and reuse shared shortcut callback types. This keeps rollback behavior deterministic and aligns the Tauri window API with async close coordination.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* chore: start issue 41 env runtime support

Open a draft branch for the project-specific environment variable runtime support work before implementation begins.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: add project-specific environment variable runtime support (#68)

Implements Issue #41 - Project-specific environment variable runtime support

Changes:
- Add PersistedEnvVariable type and envVars field to PersistedProject
- Add .env file parsing utility with parseEnvFile and mergeEnvVars functions
- Add env-resolution helper for terminal spawn with variable expansion
- Extend DialogApi with selectFile method for .env file selection
- Update ProjectSettings to support .env import with error handling
- Pass resolved env vars through all terminal spawn paths:
  - WorkspaceLayout handleCreateTerminalInPane
  - use-terminal-restore restoreFromLayout and createDefaultTerminal
  - use-snapshots restoreFromSnapshot
- Print one-time terminal info line when env vars are applied
- Add comprehensive test coverage for env-parser utility

Technical details:
- Supports Unix ($VAR, ${VAR}) and Windows (%VAR%) variable references
- Only expands against inherited system/process env, not other project vars
- Normalizes env vars on save (trims keys, filters empty)
- Shows warnings for invalid lines during .env import

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: address code review findings for env var runtime support

- Fix race condition in handleImportEnvFile by capturing project ID and using
  functional state updates
- Make inheritedEnv parameter required in resolveEnvForSpawn and add TODO
  for fetching system env from backend
- Use hasProjectEnv flag to conditionally pass env to terminal spawn
- Add env notice check in ConnectedTerminal for external terminal ID path
- Add TODO comments about secure storage for secret env var values

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
#70)

* fix: terminal kill panic and preserve sessions across project switches

- Wrap cleanup_terminal_resources_sync in spawn_blocking to prevent
  tokio runtime panic when blocking on AsyncMutex fields
- Make kill() and kill_all() async to properly handle blocking cleanup
- Remove PTY kill loop from project-switch flow to preserve live sessions
- Add tests for multi-project terminal preservation

Fixes runtime panic: "Cannot block the current thread from within a runtime"
when switching projects with active terminals.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: remove useless assert in test

* fix: ensure kill_all completes before app exits

Use ExitRequestApi.prevent_exit() to block shutdown, run kill_all()
in async task, then call app_handle.exit(0) when cleanup completes.
This ensures PTY children are properly killed before the app exits.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* fix: terminal scrollback truncation on project switch

- Add updateTerminalScrollback action to terminal store
- Create syncScrollbackToStore helper to sync scrollback to memory
- Update saveTerminalLayout and auto-save to sync scrollback before write
- Add comprehensive tests for new functionality

This ensures terminal scrollback is preserved in memory when switching
between projects, preventing truncation of terminal history.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: clarify syncScrollbackToStore comments for project-switch context

Updated inline comments to explicitly state that syncScrollbackToStore
updates the in-memory store's pendingScrollback, not the disk write payload.
This clarifies that the purpose is preserving scrollback across project
switches when xterm instances are disposed.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat: enhanced file explorer operations

- Add multi-select support with Ctrl+Click, Shift+Click, and Ctrl+A
- Implement clipboard operations (copy, cut, paste) with internal state
- Add duplicate file/folder functionality
- Add external operations: Open in Terminal, Open with External App, Show in File Manager
- Implement keyboard shortcuts: Ctrl+C/X/V, F2, Delete, Ctrl+A
- Add folders-first sorting (directories A-Z, then files A-Z)
- Remove .gitignore filtering while keeping ALWAYS_IGNORE patterns
- Add @tauri-apps/plugin-shell and @tauri-apps/plugin-opener dependencies

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: CI failures - correct opener permissions and remove conflicting shortcuts

- Fix opener plugin permission names (open-item -> open-path, reveal-item-in-folder -> reveal-item-in-dir)
- Remove conflicting keyboard shortcuts (ctrl+c, ctrl+v, ctrl+a) from file explorer global shortcuts
  These were interfering with terminal clipboard functionality
- Add mocks for shell and opener plugins in test setup
- Add Store mock to plugin-store mock to fix test errors

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
…onality (#73)

* feat: add project-specific command history filtering and clear functionality

- Add project filter dropdown to CommandHistoryModal ("This Project" / "All Projects")
- Add "Clear History" button with confirmation dialog for current project
- Disable Clear History button when viewing "All Projects" mode
- Add loading state during clear operation with double-submit protection
- Handle persistence failure: keep confirm dialog open, show error toast
- Reset confirmation state when modal closes to prevent stale dialogs
- Add error handling with toast notification for persistence failures
- Add useAllCommandHistory hook returning sorted entries (newest-first)
- Add comprehensive tests for filter and clear functionality

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: improve command history clear flow and dialog loading state

- Persist empty array before clearing in-memory state to prevent
  inconsistency on persistence failure
- Add isLoading prop to ConfirmDialog to disable buttons during
  async operations

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
Remove Framer Motion Reorder component which conflicted with native
drag events. Implement single native HTML5 drag system for both:
- Intra-pane tab reordering (drag tabs left/right within tab bar)
- Cross-pane tab movement (drag tabs to different panes/splits)

Changes:
- Extended DropPosition type with 'before'/'after' for tab-relative drops
- Added reorderPreview state and handleTabReorder to PaneDndContext
- Replaced Reorder.Group/Item with plain divs and native drag handlers
- Added visual drop indicator line for tab reorder preview
- Added CSS transitions for smooth tab movement
- Updated tests to remove Framer Motion mocks and test native drag

Co-authored-by: Claude <noreply@anthropic.com>
* style: redesign UI with Codex dark theme aesthetic

- Update CSS variables for darker background (#121212) and subtle grays
- Increase border-radius from 4px to 8px for modern rounded corners
- Standardize hover/focus states to use bg-secondary across components
- Update all UI components for consistent styling:
  - button, card, input, select, dialog, dropdown-menu
  - tabs, tooltip, scroll-area, sidebar, context-menu
  - menubar, navigation-menu
- Refresh ProjectSidebar and WorkspaceLayout layouts
- Update TitleBar with consistent styling

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* style: remove panel borders and add rounded corners for Codex aesthetic

- Remove border-r from ProjectSidebar, add rounded-xl with margin
- Add rounded-xl to FileExplorer container with margin
- Add rounded-xl to main content area in WorkspaceLayout
- Add rounded-xl to terminal pane content area
- Creates floating card-style panels matching Codex reference

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* style: make scrollbar thinner (6px) for minimal Codex aesthetic

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* style: reduce scrollbar to 4px for ultra-minimal look

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* style: use background color for title bar, remove border

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* style: reduce tab text size from text-sm to text-xs

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* style: make ResizableHandle transparent for cleaner panel separation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: restructure File Explorer as separate panel

- Move FileExplorer outside ResizablePanelGroup to be sibling of main content
- Fix FileExplorer to have fixed width (w-64) like ProjectSidebar
- Creates proper visual hierarchy: background -> sidebar -> main content -> file explorer
- All panels now float separately with rounded corners

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: wrap FileExplorer in PaneDndProvider for drag-drop context

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: properly separate main content and file explorer with flex layout

- Wrap center content in flex-1 min-w-0 container
- Wrap file explorer in flex-shrink-0 container
- Prevents overlap between main content and right sidebar

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: restructure layout - separate FileExplorer from main content

- Move FileExplorer outside main element to be sibling
- Main content: flex-1 with m-2 mr-0 (margin only on left)
- FileExplorer: flex-shrink-0 with w-64, m-2 (margin only on right)
- Creates proper floating panels at same level: ProjectSidebar | MainContent | FileExplorer
- Remove rounded-xl m-1 from PaneContent to prevent overflow

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: add h-full to terminal containers for proper display

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: restructure layout with proper padding and height

- Move padding to parent container (p-2) instead of individual margins
- Add h-full to all containers for proper flex height propagation
- Fix terminal blank screen by ensuring proper height chain
- Add gap between panels using ml-2/mr-2 instead of m-2

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: resolve layout and terminal issues after sidebar redesign

- Show "Connecting..." loading state instead of blank when PTY ID is pending
- Prevent Ctrl+B from toggling file explorer when xterm terminal is focused
- Add overflow-hidden and min-w-0 to prevent main content width overflow

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: review fixes - tab contrast, terminal shortcut guard, menu radius, version label

- Change active tab bg from bg-card to bg-muted for contrast
- Split xterm out of isInEditor into separate isInTerminal boolean
- Fix ContextMenuSubTrigger rounded-md to rounded-sm for consistency
- Replace bottom New Project button with Termul version label

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: clear stale file explorer on project removal, allow sidebar toggle in terminal

- Clear explorer root path when activeProject becomes null
- Guard FileExplorer render on activeProject?.path being truthy
- Remove isInTerminal check from configurable sidebarToggle shortcut

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* test: update ProjectSidebar test for version label replacing new project button

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: guard against empty path in explorer root sync and clean up stale watcher

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Three issues prevented tab DnD from working:

1. Tauri's dragDropEnabled defaults to true, which intercepts all drag
   events at the native WebView2 level on Windows, preventing HTML5 DnD
   events from reaching the DOM. Set to false in tauri.conf.json.

2. PR #75 split PaneDndProvider into two separate instances (one for
   PaneRenderer, one for FileExplorer), so isDragging state set in one
   provider was invisible to children of the other. Reunified into a
   single provider wrapping both.

3. The tab bar container div lacked an onDragOver handler, causing the
   browser to show a no-drop cursor when dragging over gaps between tabs.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
# Conflicts:
#	package-lock.json
#	package.json
#	src-tauri/Cargo.toml
#	src-tauri/tauri.conf.json
@gnoviawan gnoviawan merged commit 03b917d into main Mar 12, 2026
3 of 4 checks passed
@coderabbitai
Copy link

coderabbitai bot commented Mar 12, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9876a2fd-9945-4178-abac-a899bf039b11

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

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch release/v0.3.1

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.

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.

1 participant