A macOS desktop app for keeping git projects in order: category folders, the repositories inside them, and their state at a glance — which have uncommitted changes, which are ahead of the remote, which have not been touched in months.
Built for personal use, from a written spec. It manages folders and remotes, not branches and commits: nothing here rewrites history inside a repository.
Dashboard · Categories · Clone
The app does not invent a database of projects — the filesystem is the model. A first-level folder is a category, and any folder inside it holding a .git is a project.
~/Documents/DevProjects/ ← root, configurable
├── work/ ← category
│ └── project-a/ ← project
└── pet/
- Dashboard of every project with git status, last commit, and ahead / behind counts
- Categories: create, rename, delete, move projects between them
- Clone from GitHub or Gitea straight into a category, or create an empty project
- Multiple accounts, GitHub and self-hosted Gitea alike; the repository list is paginated
- Remotes viewed and edited without leaving the app;
fetchacross selected projects to refresh ahead / behind - Open a project in the configured editor or in Finder
- Search, filter by category, and sort by status or by how long ago a project was touched
npm install
npm run app:dev # app window plus the Nuxt dev server on 127.0.0.1:4310
npm run app:build # .app and .dmg in src-tauri/target/release/bundlePort 4310 is deliberate: 3000 usually has something else on it, and Tauri would happily open that project instead. With the port taken the dev server fails (strictPort) rather than quietly moving next door.
npm test # Vitest — formatting, filters, sorting (54 tests)
cd src-tauri && cargo test # Rust — remote URL parsing, file operations (30 tests)| Layer | Where | Responsible for |
|---|---|---|
| Categories and projects | src-tauri/src/fsops.rs |
creating, renaming, deleting and scanning folders, moving projects |
| Git | src-tauri/src/git.rs |
status --porcelain, rev-list @{u}...HEAD, log -1, clone, remote URL parsing |
| GitHub / Gitea API | src-tauri/src/remote.rs |
paginated repository lists, token validation |
| Settings and tokens | src-tauri/src/settings.rs |
JSON in the app config directory; tokens in the Keychain |
| Screens | app/pages/ |
dashboard, categories, clone, settings |
| State | app/composables/ |
status cache, dialogs, toasts |
| Pure functions | app/utils/ |
date formatting, filters and sorting — the tested part |
- Tokens live only in the macOS Keychain (service
dev.gitspace.tokens).settings.jsonholds an id, a provider and an instance URL, nothing else. - Deleting a project or a category moves it to the Trash, not
rm -rf— the operation stays reversible from Finder. Paths are checked to be inside the configured root before anything is moved. - Statuses are read in batches of 12 paths, up to 8 git calls in parallel, and cached: the list renders immediately and the badges fill in as answers arrive. Refresh is a button, not a poll.
- The editor is launched through
/bin/sh -lc. A GUI application does not inheritPATHfrom~/.zshrc, socodewould simply not be found. - TLS is the system's (
native-tls), so corporate Gitea instances with self-signed certificates from the keychain work without extra flags.
| Layer | Technology |
|---|---|
| Shell | Tauri 2 |
| Frontend | Nuxt 4 (Vue 3), static generate |
| Backend | Rust — filesystem, git invocations, HTTP |
| Tests | Vitest + cargo test |
| Language | TypeScript |
MIT


