A terminal UI for managing your working set of files
You don't need your whole file tree. You need the files you're working on right now.
When building a feature, you jump between the same 6 files constantly — but your editor shows you hundreds. You ask Claude Code "which files are relevant to the auth flow?" and get a list back — but then what? You open them one by one, lose track, and repeat.
ws solves this. It keeps a focused, navigable list of just the files that matter for what you're doing right now. Branch-scoped. Persistent. TUI-first.
ws add src/auth/login.go src/middleware/jwt.go
ws
demo.mp4
This is what ws was built for.
1. Install the plugin, then map a feature
/plugin marketplace add n-filatov/ws
/plugin install ws@n-filatov-ws
/ws:map user authentication flow
Claude searches the codebase, identifies relevant files, and runs ws add for each one automatically.
2. Open ws in a split terminal
wsYou now have a focused, navigable list of exactly the files Claude identified — with git status, tree view, and instant fuzzy search.
3. Navigate during development
Press e to open any file in your editor. Press r to refresh after Claude adds more files. Press / to fuzzy-search when the list grows.
4. Switch branches, keep context
Working sets are per-branch. Check out a different branch and ws shows a completely different set of files. Come back — your context is waiting.
Every git branch has its own working set. Context switches when you do. No manual cleanup, no cross-branch noise.
Files show their current git status inline — M for modified, A for staged, ? for untracked. You always know what's changed.
src/
auth/
login.go M
jwt.go A
middleware/
cors.go ?
Files are rendered as a collapsible directory tree. Single-child directories collapse automatically (src/auth/login.go instead of three levels). Navigate with ← / → to expand or collapse.
Press / and type to instantly filter your working set. Matches are highlighted. Press Esc to return to the full list.
On startup and refresh, ws automatically pulls in any files git knows are modified. Your working set reflects reality.
ws tracks when each branch's working set was last used. When you open it after a while, it offers to clean up sets from branches you've already shipped.
brew tap n-filatov/tap
brew install wscurl -fsSL https://n-filatov.github.io/ws/gpg.key \
| sudo gpg --dearmor -o /usr/share/keyrings/ws.gpg
echo "deb [signed-by=/usr/share/keyrings/ws.gpg] https://n-filatov.github.io/ws ./" \
| sudo tee /etc/apt/sources.list.d/ws.list
sudo apt update && sudo apt install wsgit clone https://github.com/n-filatov/ws
cd ws
make installThis builds the binary and installs it to ~/.local/bin/ws. Make sure ~/.local/bin is in your PATH.
Requirements: Go 1.21+
ws # open the TUI
ws add <file>... # add files to the current branch's working set
ws rm <file> # remove a file
ws list # print all files (one per line, good for scripts)
ws clear # clear the entire working set for this branch| Key | Action |
|---|---|
j / ↓ |
Move down |
k / ↑ |
Move up |
→ |
Expand directory |
← |
Collapse directory |
e |
Open file in editor |
/ |
Fuzzy search |
Esc |
Clear search / quit |
a |
Add a file by path |
d |
Remove selected file |
r |
Refresh (re-sync git status) |
q |
Quit |
ws reads ~/.wsconfig (plain key=value format):
editor=nvim
cleanup_days=14
| Option | Default | Description |
|---|---|---|
editor |
vim |
Editor to open files with (e key) |
cleanup_days |
7 |
Days before a stale working set is flagged for cleanup. Set to 0 to disable. |
Working sets live in ~/.local/share/ws/<repo>/ — outside your repo, never committed.
Each branch gets its own file: .workingset-<branch-name>. No conflicts, no .gitignore entries needed.
Install the plugin for the smoothest experience:
/plugin marketplace add n-filatov/ws
/plugin install ws@n-filatov-ws
| Command | What it does |
|---|---|
/ws:map <feature> |
Find relevant files and add them to your working set |
/ws:install |
Install the ws CLI (detects OS, picks Homebrew / APT / source) |
No plugin? Prompt Claude manually:
Find all files related to the payment processing feature.
For each file you find, run: ws add <filepath>
ws list outputs one path per line — compose it with anything:
vim $(ws list) # open all files in vim
ws list | xargs grep "TODO" # grep across working set only
ws list | xargs wc -l # count linesOfficial extensions integrate ws directly into your editor:
| Editor | Repo | Features |
|---|---|---|
| VS Code | n-filatov/ws-vscode |
Sidebar panel, Explorer badges, status bar, right-click to add |
| Zed | n-filatov/ws-zed |
/ws slash command injects working set into Claude context, tasks |
Both extensions call the ws CLI — no separate setup needed beyond having ws installed.
- lazygit — terminal UI for git. Complementary: use lazygit for commits,
wsfor navigation. - harpoon — neovim plugin for marking files.
wsworks at the terminal level, across any editor. - zoxide — smart directory jumping. Different scope:
wsis for files within a project.
Issues and PRs welcome. The codebase is small — internal/tui/ is where most of the interesting logic lives.