Skip to content
hackrdotshPublic

About

an AI-enabled jujutsu tui

Topics

Resources

Contributing

Stars

5 stars

Watchers

0 watching

Forks

Repository files navigation

gojo

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

Go Bubble Tea jj v0.44+ MIT

gojo log view: commit graph with change IDs, authors, dates, bookmarks, a conflicted merge marked ×, and a dirty working copy

Features

  • 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
  • Image diffs — before/after previews using the Kitty graphics protocol
  • 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
  • Terminal task status — OSC 7501 reports AI generation and background actions as indeterminate work, with completion, failure, and permission prompts in supporting terminals
  • Undo / redo — one-key jj undo / jj redo
  • Graph rendering — native jj graph output with styled nodes (@/○/◆) and edges

Views

Captured live with VHS — see the gallery on gojo.rocks.

Diff panel Conflict resolution
diff panel — file summary + chroma-highlighted diff with word-level changes conflict resolution — side-by-side 3-way merge, pick l / r / both per hunk and apply with ⏎
Bookmark mode Help
bookmark mode — create, move, rename, track, with tab-completion help — the full keybinding reference, one ? away

Installation

Install script (auto-detect)

curl -fsSL https://gojo.rocks/install.sh | sh

Detects 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.

Windows (Scoop)

scoop bucket add gojo https://github.com/hackrdotsh/gojo
scoop install gojo/gojo

Scoop installs both gojo and its jj runtime dependency. Windows amd64 and arm64 packages are available.

Homebrew

brew tap hackrdotsh/gojo https://github.com/hackrdotsh/gojo
brew install --cask gojo

This 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/NixOS

nix run github:hackrdotsh/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.

Debian / Ubuntu

Each GitHub release ships a .deb (gojo_<version>_linux_<arch>.deb):

apt install ./gojo_<version>_linux_amd64.deb

jujutsu is a recommended dependency (packaged on Debian 13+ and Ubuntu 24.10+); on older releases apt skips it and you install jj yourself.

Fedora / RHEL

Each GitHub release ships an RPM (gojo_<version>_linux_<arch>.rpm):

dnf install ./gojo_<version>_linux_x86_64.rpm

jujutsu is a weak recommendation, so dnf pulls in jj automatically on Fedora 39+ (older releases simply skip it).

openSUSE (Tumbleweed / Leap)

The same RPM from the GitHub release works here:

zypper install ./gojo_<version>_linux_x86_64.rpm

zypper honors the weak jujutsu recommendation (packaged in Tumbleweed's official repos; on Leap, install jj separately if it isn't offered).

Arch Linux (and derivatives)

Each GitHub release ships a pacman package (gojo_<version>_linux_<arch>.pkg.tar.zst):

pacman -U gojo_<version>_linux_x86_64.pkg.tar.zst

The package depends on jujutsu (in [extra]), so pacman pulls jj in automatically.

From source

Requires Go 1.26+ and jj in $PATH.

go build -o gojo .
./gojo

Requirements

  • Go 1.26+ (to build)
  • jj (Jujutsu VCS) v0.44+ in $PATH
  • A jj repository (run gojo inside any .jj directory)

Image previews

Open a revision with enter to see its changed images side by side: before on the left, after on the right. Added and deleted images mark the missing side as “not present”. Previews scroll and collapse with their file headers.

PNG, JPEG, GIF, WebP, BMP, and TIFF are supported (GIF shows the first frame). Previews preserve aspect ratio and transparency. They require a terminal with Kitty graphics and Unicode placeholder support, such as Kitty 0.28+. Other terminals show image metadata instead. Direct terminal transmission works over SSH; multiplexers that filter graphics commands are not supported.

Images larger than 16 MiB or 24 megapixels show a size notice. Unsupported or damaged images show a notice in the affected pane. For merge commits, the before pane reports that the merged-parent preview is unavailable rather than showing an arbitrary parent.

Configuration

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: "

Editor schemas

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 = "" # unbind

Use 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.

ChatGPT subscription

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.

  1. Run codex login and choose Sign in with ChatGPT. If you only use nix run, enter nix shell github:hackrdotsh/gojo first to access the bundled codex command.

  2. 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"
  3. Start gojo and press D on 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.

Keybindings

Global

Key Action
? Help
q Quit / close panel
ctrl+c Force quit

Log view

Key Action
↑/k, ↓/j Navigate commits
G Jump to last commit
Home Jump to first commit
enter Open diff panel
/ Search revisions (including the divergent label)
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

Cleaning up divergent revisions

Divergent versions share a change ID. Each is marked divergent with its commit ID in the log and search results. Press /, type divergent (or the shared change ID), choose a version with the arrow keys, and press enter to jump to its row. Press enter again to inspect that version's diff, then close the diff and press a to abandon exactly that commit. u undoes the abandon. The current working-copy revision cannot be abandoned.

Diff panel

Key Action
↑/k, ↓/j Scroll
enter / q Close panel

Conflict view

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

Bookmark mode

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

Git mode

Press g to enter, then:

Key Action
f jj git fetch
p jj git push
r Remote mode
esc Cancel

Remote mode

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

Project structure

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

Dependencies

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.

License

MIT

About

an AI-enabled jujutsu tui

Topics

Resources

Contributing

Stars

5 stars

Watchers

0 watching

Forks

Releases

Contributors

Languages