A fullscreen terminal UI for jj (Jujutsu VCS), built in Go with Bubble Tea and Lip Gloss. Commit graph, diffs, bookmarks, git remotes, and AI commit messages — without leaving your terminal.
Website: gojo.rocks
- Log view — scrollable commit graph with change IDs, authors, dates, bookmarks, and working copy highlighting
- Diff panel — file status summary + syntax-highlighted diff for any commit
- Conflict resolution — side-by-side 3-way merge view: pick left / right / both per hunk, apply with
jj resolve - Bookmark management — create, delete, move, rename, set, track, untrack, and list bookmarks
- Git integration — fetch, push, and remote management from within the TUI
- AI commit messages — generate a description from a commit's diff via an OpenAI-compatible API or your ChatGPT subscription through Codex CLI
- Undo / redo — one-key
jj undo/jj redo - Graph rendering — native jj graph output with styled nodes (@/○/◆) and edges
Captured live with VHS — see the gallery on gojo.rocks.
| Diff panel | Conflict resolution |
|---|---|
![]() |
![]() |
| Bookmark mode | Help |
![]() |
![]() |
curl -fsSL https://gojo.rocks/install.sh | shDetects your OS/distro and runs the right installer below: macOS
(Homebrew), Arch (pacman), Debian/Ubuntu (apt), Fedora/RHEL (dnf),
openSUSE (zypper), or a plain tarball into ~/.local/bin on other Linux.
NixOS users get pointed at the Nix/NixOS instructions.
scoop bucket add gojo https://github.com/0xhckr/gojo
scoop install gojo/gojoScoop installs both gojo and its jj runtime dependency. Windows amd64 and
arm64 packages are available.
brew tap 0xhckr/gojo https://github.com/0xhckr/gojo
brew install --cask gojoThis installs gojo and pulls in jj (jujutsu) as a runtime dependency
automatically. The explicit URL is needed because the cask lives in the
source repo rather than a separate homebrew- repo. See the post-install
caveat for an optional gj shorthand alias.
nix run github:0xhckr/gojo # run directly
# or, for development:
nix develop # drops you into a shell with Go tooling + Codex
go run .The Nix package bundles Codex CLI as a runtime dependency and exposes codex
for login; the development shell includes it too. See ChatGPT subscription
below to enable AI commit messages with your subscription.
Each GitHub release ships a .deb (gojo_<version>_linux_<arch>.deb):
apt install ./gojo_<version>_linux_amd64.debjujutsu is a recommended dependency (packaged on Debian 13+ and Ubuntu
24.10+); on older releases apt skips it and you install
jj yourself.
Each GitHub release ships an RPM (gojo_<version>_linux_<arch>.rpm):
dnf install ./gojo_<version>_linux_x86_64.rpmjujutsu is a weak recommendation, so dnf pulls in jj automatically on
Fedora 39+ (older releases simply skip it).
The same RPM from the GitHub release works here:
zypper install ./gojo_<version>_linux_x86_64.rpmzypper honors the weak jujutsu recommendation (packaged in Tumbleweed's
official repos; on Leap, install
jj separately if it
isn't offered).
Each GitHub release ships a pacman package
(gojo_<version>_linux_<arch>.pkg.tar.zst):
pacman -U gojo_<version>_linux_x86_64.pkg.tar.zstThe package depends on jujutsu (in [extra]), so pacman pulls jj in
automatically.
Requires Go 1.26+ and jj in $PATH.
go build -o gojo .
./gojo- Go 1.26+ (to build)
- jj (Jujutsu VCS) v0.44+ in
$PATH - A jj repository (run
gojoinside any.jjdirectory)
Gojo reads an optional TOML config file at ~/.config/gojo/gojo.toml. Values
may also be placed under a [tools.gojo] section in ~/.config/jj/config.toml
(the standalone gojo file takes precedence).
#:schema https://gojo.rocks/schemas/gojo.json
# AI provider: "api" (default) or "codex" (ChatGPT subscription)
ai_provider = "api"
# API key for AI-generated commit messages (optional)
ai_api_key = "sk-or-..."
# Base URL of an OpenAI-compatible chat-completions endpoint
# (defaults to https://openrouter.ai/api/v1)
ai_base_url = "https://openrouter.ai/api/v1"
# Model to use
ai_model = "anthropic/claude-sonnet-4"
# Custom prompt template for AI commit messages (optional)
commit_prompt = "You are a software developer. Write a clear, concise commit message given the diff: "Add the #:schema comment above to the top of gojo.toml to enable
autocomplete, hover documentation, and validation in Taplo-compatible editors
(such as VS Code with Even Better TOML). The
configuration schema covers AI settings,
theme selection, and every keybinding context/action. It describes the standalone
gojo file; do not apply it to jj's entire config.toml.
Write keybinding overrides as unquoted dotted keys under [keymap]:
[keymap]
log.down = "j,down"
global.quit = "Q"
diff.absorb = "" # unbindUse this spelling rather than [keymap.log], quoted "log.down" keys, or inline
tables: gojo's minimal TOML parser reads the dotted key directly. JSON Schema
validates the parsed TOML data, so it cannot distinguish every equivalent TOML
spelling. Keep values on a single line.
For custom theme files in ~/.config/gojo/themes/, use the
theme schema instead:
#:schema https://gojo.rocks/schemas/theme.json
name = "My theme"
[dark]
background = "#282a36"
text = "#f8f8f2"
purple = "#bd93f9"The theme schema covers metadata and all [dark]/[light] palette slots,
including hex colors, quoted ANSI indices, and empty values for derived colors.
Use Codex CLI with a ChatGPT plan
that includes Codex. Nix installs Codex automatically with gojo; on other
platforms, install Codex CLI separately and make sure codex is in $PATH.
-
Run
codex loginand choose Sign in with ChatGPT. If you only usenix run, enternix shell github:0xhckr/gojofirst to access the bundledcodexcommand. -
Set this at the top level of
~/.config/gojo/gojo.toml(before any section headers), or under[tools.gojo]in jj's config:ai_provider = "codex"
-
Start gojo and press
Don a commit to generate its description.
Gojo reuses Codex's saved login, including automatic token refresh. With ChatGPT
sign-in, generation uses your plan's Codex allowance. No ai_api_key is needed;
ai_base_url is only used by the API provider.
Leave ai_model unset to use Codex's configured/default model, or set it to a
Codex-supported model name. Remove any API-specific ai_model value when
switching providers. commit_prompt works with both providers.
Generation runs non-interactively in a temporary directory with a read-only sandbox and a 90-second timeout. Gojo supplies the selected commit's diff and applies the resulting description through jj.
| Key | Action |
|---|---|
? |
Help |
q |
Quit / close panel |
ctrl+c |
Force quit |
| Key | Action |
|---|---|
↑/k, ↓/j |
Navigate commits |
G |
Jump to last commit |
Home |
Jump to first commit |
enter |
Open diff panel |
d |
jj describe (opens $EDITOR) |
D |
AI-generate commit message |
e |
jj edit (set working copy) |
n |
jj new (create change) |
a |
jj abandon (remove commit) |
c |
Conflict resolution view (on conflicted commits) |
b |
Bookmark mode |
g |
Git mode |
u |
jj undo |
U |
jj redo |
| Key | Action |
|---|---|
↑/k, ↓/j |
Scroll |
enter / q |
Close panel |
Press c on a conflicted commit (from the log view or diff panel), then:
| Key | Action |
|---|---|
↑/k, ↓/j |
Navigate conflict hunks |
[ / ] |
Switch conflicted file |
l / r / b |
Take left / right / both sides for the hunk |
u |
Clear the hunk's pick |
enter |
Apply the resolution (jj resolve) |
q / esc |
Close view |
Press b to enter, then:
| Key | Action |
|---|---|
c <name> |
Create bookmark |
d <name> |
Delete bookmark |
f <name> |
Forget bookmark |
l |
List bookmarks |
m <name> |
Move bookmark to selected commit |
r <old> <new> |
Rename bookmark |
s <name> |
Set bookmark to selected commit |
t <name> |
Track remote bookmark |
T <name> |
Untrack remote bookmark |
tab |
Autocomplete (cycle suggestions) |
esc |
Cancel |
Press g to enter, then:
| Key | Action |
|---|---|
f |
jj git fetch |
p |
jj git push |
r |
Remote mode |
esc |
Cancel |
Press r in git mode, then:
| Key | Action |
|---|---|
a <name> <url> |
Add remote |
l |
List remotes |
r <name> |
Remove remote |
m <old> <new> |
Rename remote |
s <name> <url> |
Set remote URL |
esc |
Cancel |
main.go Entry point — starts the Bubble Tea program
internal/
jj/
jj.go jj CLI wrapper + log/status parsers
config.go config + TOML loader
ai.go AI commit-message generation (OpenAI-compatible API)
ui/
model.go Bubble Tea model: state, update, view, keybindings
render.go styled-line rendering helpers (Lip Gloss)
styles.go color palette and constants
logview.go commit list with graph
diff.go git-diff parser + chroma syntax highlighting
diffpanel.go diff viewer
helpview.go keybinding reference
go.mod Go module + dependencies
flake.nix Nix dev shell + package
Everything is pure Go — no native FFI, no Node runtime:
The TOML config parser, unified-diff parser, and AI client are implemented in-tree with the standard library.
MIT




