Repository navigation
Contributing
Thank you for helping! This page lists the rules for code, commits and pull requests. Each rule has a short reason, because a rule you understand is easier to follow. The same rules are in CLAUDE.md at the repository root, which is worth reading once.
- Set up the project with the Developer Guide.
- Branch from
develop. It is the default branch, and all work lands there by pull request. - Read the developer page for the area you are changing, and the feature's
How-...-Works.mdchapter if there is one. Its "Bugs we fixed" section tells you what went wrong before.
These are organization rules and apply to TypeScript, Svelte, JavaScript and Rust alike.
Layout is not a matter of taste: Prettier (.prettierrc.json, with the Svelte plugin) formats src/, ui/ and scripts/ at 120 columns with semicolons, trailing commas and double quotes. Run bun run format before you commit; CI runs bun run format:check and fails on any file it would change. Generated files and the hand-compacted design token JSON are listed in .prettierignore.
-
Every
ifhas braces. No single-lineifwithout a block. When someone later adds a second line, it can never fall outside the condition by accident. - End statements with semicolons in TS and JS. Relying on automatic semicolon insertion causes rare but confusing bugs.
- Put a trailing comma after the last item of multi-line objects, arrays and argument lists. Adding an item then changes one line in the diff, not two.
-
Name parameters after the thing they hold:
repoPath,filePath,commitId,branchName,stashIndex, never justidorpath. A workspace has many repositories, paths and ids at once, and the name should say which one you have. In Rust the same names are snake_case (repo_path). -
Default missing values so they never throw:
?? null,?? [],unwrap_or_default(). Data from GitHub, from a hand-edited settings file or from an odd repository can be missing, and a missing field should show as empty, not crash the app. - Never use the em-dash character, anywhere: code, comments, UI text, commits, docs. Use a colon, a comma or a hyphen. It keeps text consistent and easy to type, and the wiki check rejects it.
- Comments are sparse and explain why. The code already says what it does.
-
Svelte 5 runes only (
$state,$derived,$effect,$props),onclick-style attributes and noexport let. Use$state.rawfor big arrays and objects that are replaced. See Frontend. -
Colors come from the CSS tokens in the UI library's
styles/colors.css, so light and dark themes both keep working. -
UI text is short and plain. Destructive actions ask first with
dialogs.confirm({ danger: true }). -
Put tricky logic in a pure
.tsmodule with a test. See Testing. -
Keep platform-specific code behind
cfgor runtime checks. Windows and Linux builds are planned.
type:[GM-N] one-line summary
The ticket goes in square brackets right after the colon, with no space before the bracket. Then comes a single-line summary. For example:
feat:[GM-21] reopen closed tabs with Shift+Cmd+T
fix:[GM-22] keep the blame gutter after an undo
docs:[GM-23] explain the IPC bridge
| Type | Use it for | Needs a new beta before stable? |
|---|---|---|
feat |
a new feature | yes |
fix |
a bug fix | yes |
feat! or fix!
|
a breaking change (suggests a major version) | yes |
docs |
documentation only | no |
test |
tests only | no |
chore |
tooling, CI, dependencies, release commits | no |
flowchart TD
A["What does the commit change?"] --> B{"Does it change<br/>what users run?"}
B -->|"yes, new ability"| F["feat:[GM-N]"]
B -->|"yes, repairs something"| X["fix:[GM-N]"]
B -->|"no"| C{"What then?"}
C -->|"docs"| D["docs:[GM-N]"]
C -->|"tests"| T["test:[GM-N]"]
C -->|"tooling or CI"| H["chore:[GM-N]"]
F --> Beta["must ship in a beta first"]
X --> Beta
D --> Free["may ride along into stable"]
T --> Free
H --> Free
Why does the type matter so much? The release tools read it. feat and fix decide the next version number, and any commit that is not docs, test or chore counts as "untried": a stable release refuses to ship it until it has been in a beta. See Versioning and Changelog.
The ticket. Ask the maintainer for a ticket number if you do not have one. bun scripts/version.ts next-ticket prints the next free GM number.
-
Author identity. For this repository, the maintainer commits as
MD. Shibbir Ahmed <shibbirweb@gmail.com>, set in the repository's local git config. If you commit on the maintainer's behalf, and that config is missing, pass-c user.name="MD. Shibbir Ahmed" -c user.email="shibbirweb@gmail.com". Never commit with some other global identity by accident: checkgit config user.emailfirst. -
No
Co-Authored-Bylines. Keep the message to the format above. -
User-visible changes add a changelog line under
## [Unreleased]inCHANGELOG.md, in the same commit. -
Never commit build output:
node_modules,build,.svelte-kit,src-tauri/target,src-tauri/gen. -
Do commit lockfiles:
bun.lockandsrc-tauri/Cargo.lock. CI installs with--frozen-lockfileand--lockedand fails without them. - Never edit the version or create release tags by hand. The release workflows do both.
-
Commit or push only when asked is the rule for tools and AI assistants working in this repository, as
CLAUDE.mdsays.
Issues use the forms in .github/ISSUE_TEMPLATE/:
-
bug_report.yml(labeledbug, titled[Bug]: ...) asks what happened, the steps to reproduce, the Nibtree version, the operating system, thegit --versionoutput and any screenshots. Report a Bug in the app (Settings, About, the status bar help menu or the welcome screen) opens this form with the version and operating system already filled in, using the field idsversionandplatform(seebugReportUrlinsrc/lib/update/releases.ts). Keep those ids if you edit the form, or the pre-filling stops working. -
feature_request.yml(labeledenhancement, titled[Feature]: ...) asks what the person wants to do, how it should work and what they tried instead. The app links to it from the same places. -
config.ymlkeeps blank issues allowed and adds a link to the releases page, for people looking for release notes.
When you triage a bug, first reproduce it with a demo script (see Debugging). Ask for the missing steps or versions if you cannot. A confirmed bug gets a GM ticket before work starts.
- Open them against
develop. - Keep each one focused on one change. Small pull requests get reviewed faster and are easier to undo.
- Fill in the three sections of
.github/pull_request_template.md: What and why, Test plan (it starts with one empty bullet) and Docs, the checklist below. - Write the test plan as plain bullet points, never checkboxes. Say what you ran and what you checked by hand, and say plainly what you could not check, such as a visual detail.
- CI must pass. Run the checks in Testing locally first, all clean.
A good test plan looks like this:
## Test plan
- bun run format:check, bun run check, bun run test, cargo test and cargo clippy are clean
- Opened scripts/make-conflict-repo.sh output and resolved both.txt in the merge tool
- Not checked: the dark theme colors of the new button
The Docs section of the pull request template asks four things:
- The user page and developer chapter in
docs/wikiare updated, or there is no user-visible change. - Screenshots are retaken with
bun scripts/screenshots.ts <name>if the UI changed. - A bug fix is recorded under "Bugs we fixed" in the feature's developer chapter: the issue, why it happened, and why this fix.
-
CHANGELOG.mdhas a line under Unreleased for anything user-visible.
Two more are not in the template but matter just as much: a new feature is in features.json with both pages and its screenshots, and bun scripts/build-wiki.ts --check passes (CI runs it too).
Step by step recipes for each of these are in Docs and Screenshots.
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