Repository navigation
How Workspace Files Work
A workspace file saves a set of folders, so the user can reopen them in one click. Nibtree writes .nibtree-workspace files and also reads and updates VS Code .code-workspace files. This page also covers which folders reopen when the app starts. The rest of the workspace is in How workspaces work, and the user side in Workspaces.
- Teams share VS Code workspace files. Reading them, and keeping their other content when we save, means one file works in both apps.
- Paths should move with the folders. Folder paths are stored relative to the file when they share a parent folder with it, so a project checked out somewhere else still opens.
- The app should start where you left it, and stay closed when you closed the folder on purpose.
workspace_file.rs is plain JSON with comments (JSONC): strip_jsonc removes comments and trailing commas before parsing. read resolves each folders[].path against the file's folder and reports the ones that no longer exist, so the UI can open the rest and show a note.
flowchart TD
Change["Add or remove a folder<br/>in a linked workspace"] --> Sync["syncWorkspaceFile"]
Sync --> Write["workspace_file::write(file, folders)"]
Write --> Entries["folder_entries: reuse existing entries<br/>(names, unknown or missing folders)"]
Entries --> Splice{"Replace only the folders array<br/>and read it back the same?"}
Splice -->|"yes"| Keep["Text with comments and other keys kept"]
Splice -->|"no"| Whole["Print the whole file again,<br/>without comments"]
Keep --> Atomic["write_atomically:<br/>temporary file, then rename"]
Whole --> Atomic
write keeps existing folder entries, so a VS Code name survives, and so do entries it cannot open (missing folders or uri folders). It replaces only the folders array in the original text and falls back to writing the whole file, without comments, if that edit would not read back correctly. It writes through a temporary file, like config.rs, and through a symlink to its target. syncWorkspaceFile in repo.svelte.ts rewrites a linked file after every add or remove.
On start, App.svelte opens a command line argument first, else the steps from the pure sessionSteps (in settingsData.ts): lastSessionFile, then lastSession. The most recent folder is used only when state.json never recorded a session (sessionRecorded), so after Close Folder the welcome screen shows. closeWorkspace() records the empty session.
| File | What it does |
|---|---|
src-tauri/src/workspace_file.rs |
JSONC parsing, relative paths, rewriting folders, the atomic write |
src-tauri/src/commands/workspace.rs |
read_workspace_file and write_workspace_file
|
src/lib/stores/repo.svelte.ts |
syncWorkspaceFile, closeWorkspace
|
src/lib/views/repoPicker.ts |
Open and Save Workspace pickers |
src/lib/stores/settingsData.ts |
sessionSteps, parseState
|
Stay compatible with .code-workspace. Teams share one file with VS Code, so we only touch folders.
Edit the text, not the parsed value. Printing the parsed JSON again would drop comments and reorder keys. Splicing the array keeps the file as the user wrote it.
An empty recorded session means "closed on purpose". Falling back to a recent folder is only for old state files from before sessions were recorded.
Close Folder did not stay closed.
- The issue: after Close Folder and a restart, the app reopened the most recent folder.
-
Why it happened: closing saved an empty session, which the start code treated like "never had one", falling back to
recentRepos[0]. -
The fix and why we chose it:
parseStatenotes whether state.json recorded a session (sessionRecorded), and the puresessionStepsfalls back to a recent folder only for old state without one. An empty recorded session means "closed on purpose".
Saving a workspace file lost VS Code folder names and comments.
- The issue: adding or removing a folder dropped folder names, comments and folders not found, and a crash mid-write could leave half a file.
-
Why it happened:
writerebuiltfoldersas plain{ path }entries, printed the whole file again and wrote it in place. -
The fix and why we chose it:
writereuses entries, edits only thefoldersarray (kept only if it parses back to the same folders) and writes through a temporary file. Comments inside the array itself are still lost.
-
src-tauri/src/workspace_file.rs: comments and trailing commas, relative paths, round trips that keep other keys, VS Code files with missing folders, invalid files, kept names and unknown entries, addingfoldersto a file without them, and writing through a symlink. -
src/lib/stores/settingsData.test.ts:sessionStepsandparseState.
- Update this page when the file format, the write or the start order change.
- Update Workspaces for visible changes.
These pages are generated from docs/wiki. To correct something, open a pull request against the source file; edits made here are overwritten.
Using Nibtree
- Getting Started
- Welcome Screen
- Workspaces
- Files Panel
- File Operations
- File Icons
- Rounded Panels
- Editor and Tabs
- Pin Reorder and Wrap Tabs
- Single Tab Title
- Split Editor
- New File and Unsaved Changes
- Unload Hidden Tabs
- Editing Code
- Code Appearance
- Markdown Editor
- Image and PDF Preview
- Search Everywhere
- Recent Files
- Navigation Bar
- Find and Replace
- Changes and Commits
- Sign In Prompts
- Commit Box Layout
- Repository Actions
- Commit Options
- Ignoring Files
- Diffs
- Inline Diffs
- Staging View
- Revert a Change
- Resolving Conflicts
- Merge Tool
- Blame
- History and Log
- Merge Commits
- Branches and Tags
- Branches Popup
- Remotes
- Stashes
- Shelf
- Git Menu
- Git Dialogs
- Interactive Rebase
- Worktrees
- AI Agents
- AI Tasks
- AI Usage
- Keep Computer Awake
- Submodules
- Git LFS
- GitHub
- Git Console
- Terminal
- Terminal Features
- Scripts
- Navigation
- Menus
- Settings
- Settings Search
- Color Themes
- Settings Terminal and Automation
- Settings Files
- Updates
- Status Bar and Help
- Notifications
- Memory Use
- Clear Cache
- MCP and CLI
- Git Mergetool
- Keyboard Shortcuts
- Keyboard Shortcuts Editor
- Troubleshooting
- Troubleshooting Git
Developers
- Developer Guide
- Architecture
- Project Layout
- Backend
- How Folder Watching Works
- Folder Watching Bugs We Fixed
- How Workspace Files Work
- How the Preview Scheme Works
- Backend Services
- How Terminal Features Work
- Terminal Bugs We Fixed
- Frontend
- How the Rich Markdown Editor Works
- Rich Markdown Bugs We Fixed
- Git Menu Links
- Menu Keys and Routing
- Frontend Modules
- Blame Bugs We Fixed
- Project Color And Title Bar
- One Diff View
- Diff Bugs We Fixed
- Merge Tool Layouts
- Merge Tool Bugs We Fixed
- Color Theme Bugs We Fixed
- How the Connected Diff Works
- Rounded Panels Bugs We Fixed
- Update Bugs We Fixed
- Status Bar Bugs We Fixed
- MCP and CLI Bugs We Fixed
- Repository Actions Bugs We Fixed
- How the Changes Tab Works
- CodeMirror Patterns
- How the Cursor Works
- How Editor Features Work
- How the Path Bar Works
- Commands and Events
- Settings Reference
- Commands Workspace and Changes
- Commands Branches and Remotes
- Commands History and Extras
- Commands App and Tools
- Testing
- Test Suites
- Debugging
- Debugging with MCP
- Measuring Setting Memory
- How Terminal Memory Is Measured
- How Markdown Diagrams Work
- Releases and CI
- Publishing the Wiki
- Versioning and Changelog
- Browser Version Packages
- Browser Release Checks
- Docker Image
- Platforms and Signing
- Windows Support
- Windows Bugs We Fixed
- Windows MCP and CLI
- Docs and Screenshots
- UI Library
- UI Library MCP
- UI Library Bugs
- UI Library Migration
- Contributing
How features work
- Welcome screen
- Workspaces and folders
- Files panel
- File operations
- File icons
- Editor and tabs
- Pin, reorder and wrap tabs
- Single tab title
- Split editor
- New File and unsaved changes
- Unload hidden tabs
- Editing code
- Code appearance
- Markdown editor
- Image and PDF preview
- Search Everywhere
- Recent Files
- Navigation Bar
- Find and replace
- Changes and commits
- Sign-in prompts
- Commit box layout
- Repository actions
- Commit options
- Ignoring files
- Diffs
- Inline diffs
- Staging view
- Revert a change
- Resolving conflicts
- Merge tool
- Blame
- History and log
- Merge commits
- Commit tabs
- Branches and tags
- Branches popup
- Remotes
- Stashes
- Shelf
- Git menu
- Git dialogs
- Interactive rebase
- Worktrees
- AI agents
- AI usage
- Keep computer awake
- AI tasks
- Submodules
- Git LFS
- GitHub account
- Git Console
- Back and Forward
- Integrated terminal
- Scripts tool window
- Menu bar
- Settings
- Search in Settings
- Color themes
- Rounded panels
- Updates and release channels
- Status bar and help links
- Notifications
- Memory readout and memory log
- Clear Cache
- MCP server and command line tool
- git mergetool mode