Open source

DevGo

Every project on your machine, your GitHub, your servers — one keystroke to where you work.

v1.0.0Released 16 September 2026MITView on GitHub

Point it at the folders that hold your projects — on the local drives, inside the WSL distros, on a Mac’s disk — and it lists every one with its stack, its package manager and its git branch, finds the one you want in a few keystrokes, and opens it in the editor, terminal or coding agent you already use. The repositories you own on GitHub and the machines you ssh into each get a lane of their own; expand a server and it shows the apps running on it, with the actions the server itself declares.

It is not an editor, a terminal or a git client. It opens the door and gets out of the way — up in about half a second with your list already on it, holding no token and no password, and never starting a WSL distro you did not ask for.

The four lanes on Windows. Every row carries the stack it was detected as, its package manager and the branch it is on.
The same app on a Mac: three lanes, no WSL.
Right-click on an app the server reported. The actions are the server’s own, read from devgo-actions.json beside its inventory script.
A form action, prefilled from the server’s own inventory. The line it will type is shown as you fill it in; Preview adds --dry-run and changes nothing.
The palette runs anything DevGo can do.
Every binding, read from the same table the handler uses.
Five themes, text size in the same steps as Ctrl+= and Ctrl+-, and transparency that is capped at 60 percent so text stays readable.

Why a launcher

The projects live on two filesystems. The web stack sits inside a WSL distro and the systems stack on the Windows drives, and every working day started the same way: find the folder, remember which side it is on, open a terminal there, attach the tmux session, open the editor. Then the same again for the next project. GitHub was worse — open the site, find the repository, find the branch — and the servers were a third copy of the problem, each with its own aliases and its own folders to remember.

DevGo is that routine made into one window. It was written first in C# on WinForms, rebuilt in Rust with Tauri as a private prototype that ran every day from July, and this public repository was then built from an empty tree in a single sitting in September 2026 — the commit log is the record.

What it does

Four lanes, equal columns

Windows (or Mac), WSL, GitHub and Servers sit side by side from 1900 px, fold into two rows from 1400, and stack below that; no lane ever spans two. A search box over each lane filters that lane — Ctrl+K puts you in the first, Ctrl+G in GitHub’s.

Workspaces that read what they hold

A workspace is a folder of projects: pick one, scan the usual roots and tick what was found, or drop a folder on the window. Depth 1 to 5, with an ignore list. Each workspace is a collapsible group in your order — drag a header, Alt+↑/↓ — and refreshes on its own without touching the others.

What a row tells you

Stack badges — turbo, next, rust, go, python, docker, node — the package manager, a mark when dependencies are not installed, the git branch with a dot when the tree is dirty, and recent or frequent when a row has earned it. A branch chip opens every branch the last fetch knew about on GitHub, GitLab, Bitbucket, Codeberg or Gitea.

Finding one

The search box is focused the instant the window appears and matches fuzzily — dvgo finds devgo-app. Three sort orders cycle from it: frecency, last commit, A–Z. Pin a project with Ctrl+S and it floats to the top. A summon hotkey brings the window up from anywhere, search ready.

Any editor, any terminal, any agent

A target is a program plus how to hand it a directory. Detected here: VS Code and Insiders, Cursor, Windsurf, Zed, Sublime, the JetBrains IDEs; Windows Terminal, Alacritty, WezTerm, the Mac terminals; Neovim, Vim and Emacs inside each distro; and Claude Code, Codex, OpenCode and Gemini CLI as agents. Ctrl+Enter, Shift+Enter, Ctrl+Alt+Enter; Alt+Enter opens editor and terminal together. A WSL project opens where it lives — Remote-WSL, or a terminal inside the distro.

Sessions that outlive everything

With the multiplexer on, a terminal launch opens a named session with the windows you listed — tmux inside the distro, psmux on Windows, tmux on a Mac — reconciled on every launch so windows you opened by hand survive. Close the terminal, close DevGo, reboot the distro: the row says live and launching again reattaches.

GitHub, through gh

Every repository you own and your organisations’, fetched when you ask and cached to disk. A repo already cloned into a workspace carries a local badge that follows the disk. Clone one into a workspace — or tick several and clone them in turn, inside the distro for a WSL workspace — add any owner/name without cloning, and sort them into named groups.

Servers that describe themselves

Import ~/.ssh/config and every Host becomes a row. Enter opens a terminal on the box in a tmux session that survives. Expand it and one ssh lists its folders — and, when the box carries a small inventory script, its apps with their domain, pm2 dot and ports, plus the actions the server declares for itself: logs, restart, nginx config, a database tunnel, a backup check.

Forms with a preview

A server can declare a form action. New nginx site asks for the app, the domain, the port, the shape, www and HTTPS, and shows the exact line it will type as you type, validated by the same Rust that sends it. Preview runs it with --dry-run and changes nothing; Create writes it, tests it, and hands over to certbot in a tmux window where sudo asks.

WSL, watched rather than polled

The title-bar chip is a light: lit while the WSL VM is up, hollow when it is not, with the running count beside it. It is read from the process table — the VM’s own process appearing or disappearing — so a distro started from any terminal lights it within two seconds, and wsl.exe is never asked on a timer. From it, stop one distro or shut down all of WSL.

A palette, a tray, one instance

Ctrl+Shift+P lists every action DevGo can do, recents first. Closing the window hides it to the tray, and the tray’s right-click launches a recent project without the window ever appearing. Launch DevGo again and it shows the one you already have.

Settings, and a config that travels

One page per concern: Workspaces, Editors & Terminals, tmux / psmux, GitHub, Shortcuts, Scanning, Appearance, Config, Servers, Help, About. Five themes, a transparency knob, text size from 85 to 150 percent. Config exports workspaces, targets and settings as one JSON file and imports them on the next machine.

Decisions, and what they cost

Every one of these is recorded in the repository itself. They are here because a choice explained is worth more than a feature listed.

  1. WSL never boots on launch

    Reading a WSL workspace whose distro is off would start the VM, so DevGo does not. It shows the last list, marked cached · WSL stopped, and only Refresh and opening a project are allowed to start a distro — because you asked. Its one wsl.exe call at launch is --list --running, which cannot.

  2. Up in half a second, from cache

    The last known list paints before anything scans; the scan, the git pass and the GitHub lane come after, off the main thread. Measured on the machine it was built on, release build, five runs: window visible 435–588 ms after a clean quit, the first list on screen about 50 ms before the window. The script that prints the number ships in the repo.

  3. The network is something you ask for

    The GitHub list is fetched when you press the button, never on launch, on focus or on a badge pass, and never on the UI thread. Live search — the one place a keystroke reaches the network — is off until you turn it on. This replaced an earlier rule of no network at all: managing GitHub by hand turned out to be the larger problem, so the promise became narrower and kept.

  4. No token, no password of its own

    GitHub is reached through the gh you are already logged into, so gh auth logout signs out everywhere. Servers are launched by alias so your ssh config’s key and options apply; DevGo stores an alias, a host and a key path, and nothing else.

  5. The server runs its own actions

    An action is typed into a tmux window on the server and the terminal attaches to it. sudo asks there. DevGo never holds a password, never runs a script itself, never parses what came back — and an action line never rides the terminal’s own command line, because cmd would parse it first. A launcher on a laptop cannot become the thing that has root on the box.

  6. A cache that heals

    The last good scan of every workspace is kept. A drive still attaching at boot is retried three times and never overwrites what was known. A listing that errors part-way is marked unavailable, never shown as a shorter list — the cache only ever holds a complete scan. A config file that cannot be parsed goes to .bak and is left alone.

  7. Every shortcut is declared once

    The handler, the footer hints, the menus and Settings › Shortcuts all read one table in src/shortcuts.ts. A binding cannot drift out of step with its label because there is only one place for it to be.

  8. A contrast contract, enforced at build

    Every text token is at least 4.5:1 on every surface it can land on, in every theme, and the lane hues sit at least 60° apart — checked by a script the build runs, so a theme that fails does not ship. Disabled is a token, not an opacity, so the gate can defend it too.

  9. See-through is paid for only when it is on

    A window born transparent holds about 30 MB more than an opaque one — one 2560×1440 alpha surface in the process, the rest in WebView2’s GPU process — and transparency is a creation flag. So the window is created see-through only when the knob is above zero; from opaque, the knob takes effect at the next launch, and the panel says so.

  10. A launcher is nobody’s child

    Whatever started DevGo — an agent’s shell included — what DevGo opens gets a clean top-level environment: no session markers, no NO_COLOR, no GIT_EDITOR=true. An agent launched from it is its own session, not a child of the one that launched the launcher.

  11. Greyed with the reason

    A target that cannot open this project is shown disabled and says why — no WSL form, not found on Windows — rather than failing after the click. A Windows launch without psmux falls back to a plain shell and says so. Toasts are one sentence, with the fix where there is one.

  12. Not features, on purpose

    No git operations beyond clone — no commit, push, diff or merge — no pull requests, no issues, no CI, no creating repositories, no second forge. lazygit and gh dash do those well; DevGo opens the folder.

  13. Unsigned, and said so

    Builds are unsigned on both platforms and the README says exactly what SmartScreen and Gatekeeper will show. Each release is built by GitHub Actions from a v* tag, so the installer on the page is that tag’s tree and nothing more.

How it is put together

React 19 · Tailwind              Rust · Tauri 2
lanes · palette · footer   IPC   scan     markers, depth, WSL cache
shortcuts.ts (one table)  ────▶ launch   targets, tmux / psmux
                          ◀────  gh · git · ssh   spawned off the UI thread
                                 prefs    JSON in app-data, .bak on failure

React draws the lanes and owns nothing that can block; Rust owns the disk, the processes and the state, and every process it spawns comes back as an event.

Language mix

  • Rust56.6%
  • TypeScript38.4%
  • Shell2.2%
  • PowerShell1.1%
Platforms
Windows · WSL · macOS
Runtime
Tauri 2, Rust on the back
Interface
React 19, Tailwind
Window up
435–588 ms, measured
Executable
9.8 MB
GitHub
Through gh, on request
Servers
ssh by alias, tmux on the box
Stored data
JSON in app-data, local
Secrets held
None
Telemetry
None
Licence
MIT
  • Rust
  • Tauri 2
  • TypeScript
  • React 19
  • Tailwind
  • bun

Everything you can type or press

Keyboard

Every binding is declared once in src/shortcuts.ts; the handler, the footer hints and Settings › Shortcuts all read that table. On a Mac, Ctrl reads Cmd and Alt reads Opt.

Ctrl+Shift+P
Command palette
Ctrl+K / Ctrl+G
Focus search / focus GitHub search
F5
Refresh projects
↑ ↓ Home End
Move the selection
→ ←
Expand / collapse a workspace
Enter
Open the selected project
Ctrl+Enter
Open in editor
Shift+Enter
Open terminal
Alt+Enter
Open both
Ctrl+Alt+Enter
Open in agent
Ctrl+S
Pin / unpin
Ctrl+Shift+D
Run dev script…
Ctrl+Shift+G
Open remote in browser
Ctrl+Shift+E
Reveal in Explorer (Finder)
Ctrl+Shift+C
Copy Windows path (copy path on a Mac)
Ctrl+Shift+W
Copy WSL path (Windows only)
Ctrl+N / Delete
Add / remove a workspace
Alt+↑ Alt+↓
Move a workspace up / down
Ctrl+,
Settings
Ctrl+= Ctrl+- Ctrl+0
Text bigger / smaller / 100 %
Ctrl+Q
Quit
Ctrl+Alt+Space
Summon (global, rebindable)

Optional tools, per lane

DevGo runs without any of these; each one lights up the lane that wants it.

gh
The GitHub lane. gh auth login once; DevGo stores no token.
ssh
The Servers lane. Launched by alias, so your config applies.
psmux
Sessions that survive, on Windows. winget install marlocarlo.psmux
tmux
The same inside a distro, on a Mac, and on the server.

Where your data lives

One file, on your machine.

Windows
%APPDATA%\app.zetta.devgo
macOS
~/Library/Application Support/app.zetta.devgo

Workspaces, targets, settings and the project cache, as JSON. A file that cannot be parsed is backed up as .bak, never overwritten. Config › Export writes the lot as one file for another machine; the cache stays behind because its paths are machine-local. Help › Reveal in Explorer opens the folder.

Build it yourself

Needs Rust stable and bun. Linux builds from the same crate but has not been run yet, so treat it as untested.

bun install
bun tauri dev        # dev build with hot reload
bun tauri build      # release; bundles land in src-tauri/target/release/bundle/

Each platform builds only its own artifacts; the release workflow in the repository does all of them at once.

Download

v1.0.016 September 2026

Choose a build

2 downloads of this release. Checksums and release notes are on the releases page.

The macOS builds are unsigned, so Gatekeeper will call the app damaged on first run. It is not — the repository has the one command that clears it, and the reason the Intel build is missing.