-
Notifications
You must be signed in to change notification settings - Fork 3.9k
feat(tui): [EXPERIMENTAL] Vim-style window system with extensible plugin views #6448
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
vtemian
wants to merge
30
commits into
sst:dev
Choose a base branch
from
vtemian:feat/tui-window-system
base: dev
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+17,033
−75
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
- Fix z.record() to use two arguments (z.string(), z.any())
- Fix bold prop by using span with style={{ bold: true }}
- Add missing focused property to window objects in tests
- Regenerate SDK types to include window keybinds
- Replace let with closure pattern for idCounter
- Remove unused import (createSignal) and variable (removedRatio)
- Fix any type casts using proper type narrowing with Match
- Add tests for resizeWindow and equalizeWindows operations
- Add RouteLayoutBridgeProvider to sync route changes with layout
- Update LayoutRenderer to parse viewID format (home, session:{id})
- Replace route Switch in App with LayoutRenderer component
- Clean up unused imports (Switch, Match, Home, Session)
- Session component accepts optional sessionID prop, falls back to route - ViewRenderer passes sessionID to Session when rendering from layout - LayoutProvider.navigateFocusedWindow() updates only the focused window - Prompt uses layout navigation in multi-window mode, route in single-window - Route-layout-bridge syncs window→route (not route→window) to prevent overwriting window views on focus change
- Initial layout window uses 'home' viewID (was 'session' with no ID) - Split commands create new windows with 'home' view - Each new window can then create its own independent session
- Changed Match condition from 'true' to 'session()' to prevent accessing undefined - Added optional chaining for session().share access
All navigation that changes views now uses layout.navigateFocusedWindow() to update the window's viewID, preventing the route-layout-bridge from fighting against route.navigate() calls. Updated components: - app.tsx: startup navigation, new session, session deleted - dialog-session-list.tsx: selecting sessions from list - dialog-fork-from-timeline.tsx: forking sessions - dialog-message.tsx: forking from message - dialog-subagent.tsx: opening subagent sessions
navigateFocusedWindow now calls WindowFocusRegistry.focus() after updating the viewID, ensuring the prompt receives focus when switching between sessions or views.
Changed currentSessionID from a plain function to createMemo to ensure proper SolidJS reactivity tracking when props.sessionID changes.
Using <Show keyed> forces the Session component to fully remount when switching between sessions, ensuring all internal state is fresh and avoiding stale closures or cached values.
…sion The textarea wasn't receiving Enter key events on older sessions because the prompt wasn't focused after navigation. Fixed by having Session's global keyboard handler explicitly focus and submit the prompt when Enter is pressed and there are no pending permissions.
Reading session() before calling prompt.submit() forces SolidJS reactivity to update, fixing a timing issue where the prompt wasn't ready on older sessions.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Relates to #6032
novim.mp4
Vim-Style Window System
Vim-style splits with
Ctrl+X+hjklnavigation. Independent sessions per pane. Extensible plugin views (Tree/List/Text/Form) enable NERDTree-style browsers and custom tool windows.Why This Matters
Platform, Not Chat Client: Run a session in one pane, browse files in another, review diffs in a third.
Plugin-First Architecture: Plugins register views via
ViewRegistry.register(id, view), users open them withlayout.navigateFocusedWindow(id). Window system handles focus, borders, resizing.Future-Proof: Layout tree supports floating windows, tabs, saved layouts without architectural changes.
Keybindings
Ctrl+X -Ctrl+X |Ctrl+X H/J/K/LCtrl+X QCtrl+X =Ctrl+X +/_/>/<Known Limitations