Skip to content

btraceio/drydock

Repository files navigation

Drydock

Drydock is a macOS desktop application for managing local Git repositories and the claude CLI sessions you run against them. Each repository gets a sidebar entry with live branch and dirty-state indicators; each Claude session runs in an embedded terminal inside the app — a real Ghostty terminal surface, not a reimplementation and with no external multiplexer (tmux, screen) involved.

The goal is a single window where you can see every repo you work in, start or resume a claude session per repo in its own tab, and keep an eye on session activity, Git status, and your changes without leaving the app.

Features

  • Repository sidebar — add/remove local Git repositories; live branch and dirty indicators; open a repo in Finder or your external editor.
  • Embedded terminal sessions — run the real claude CLI in embedded Ghostty terminal tabs, one per session, with session activity surfaced in the UI.
  • Git & GitHub awareness — repository status, review, and search surfaces built around the repos you register.
  • Persistent state — registered repositories and window layout persist across restarts.
  • Remote repositories over SSH — register a repo on a remote host via ambient SSH auth; sessions run claude on the host, the sidebar shows live indicators. Remote sessions show a neutral 'session ended — resume to reconnect' state on exit; worktrees, diffs, Explorer/Review, and activity badges are unavailable. Requires git and claude on the host's non-interactive PATH, a POSIX login shell, and an already-accepted host key.

Drydock is macOS-only and runs natively on both Apple Silicon (arm64) and Intel (x86_64).

Requirements

Run ./scripts/verify-environment.sh to check most prerequisites automatically.

Tool Version Notes
JDK 26 Gradle toolchain used to compile and run the app (sdk install java 26.0.1-tem).
JDK (for Gradle itself) ≤ 24 Gradle 8.11.1 cannot run on JDK 26; its launcher needs an older JDK. See below.
Gradle 8.11.1 Provided by the checked-in wrapper (./gradlew); no separate install.
zig 0.15.2 exactly Required to build vendored libghostty (brew install zig@0.15). Not 0.16.x.
Xcode Full Xcode + Metal Toolchain Needed to compile Ghostty's Metal shaders. Install the component once with xcodebuild -downloadComponent MetalToolchain.
git recent 2.x
claude CLI recent The session Drydock manages.

Gradle on JDK 26. Gradle 8.11.1 throws on a JDK 26 JVM, so two JDKs are in play: an older one (verified with JDK 23) launches Gradle, and the JDK 26 toolchain compiles and runs the app. If your default java is JDK 26, point Gradle at an older JDK for its launcher:

export JAVA_HOME=~/.sdkman/candidates/java/23.0.1-tem
export PATH="$JAVA_HOME/bin:$PATH"

Gradle's toolchain support then auto-detects the installed JDK 26 for the app.

Run with jbang (no JDK/Gradle needed)

If you have jbang installed, you can run Drydock without installing a JDK, Gradle, or the native toolchain:

jbang drydock@btraceio/drydock

Use the catalog alias (above), not the bare io.btrace:drydock:0.1.0 Maven coordinate: the alias carries the required JDK version and JVM flags, which a plain coordinate cannot. If jbang launches on an older JVM — you'll see InvalidModuleDescriptorException: Unsupported major.minor version 68.0 while reading a JavaFX module — jbang could not provision JDK 26. Fix it with jbang jdk install 26 (and jbang version --update if jbang is old), then re-run with jbang --fresh drydock@btraceio/drydock.

jbang provisions a Temurin JDK 26 and JavaFX automatically. The app's classes and the required native libraries (libghostty, libdrydockterminalhost, for both Apple Silicon and Intel) ship inside the io.btrace:drydock Maven Central jar; on first launch they are extracted to ~/Library/Caches/drydock/native/.

First launch downloads the JDK and dependencies, so it's slower than subsequent runs. A few warnings on startup are benign and can be ignored: WARNING: Unknown module: javafx.graphics (JavaFX runs from the classpath, so the export flag is a harmless no-op), a jbang/Gson reflective-final-field warning, and — only when run without a display — CVDisplayLink error lines.

Limitations vs. the packaged app. A jbang launch is a plain JVM process, not a signed/notarized .app bundle: no Finder double-click and no bundle identity (the dock name and Bot-in-dock icon are still set). For the polished, double-clickable app, build the .app with ./gradlew appImage. The dylib load relies on Temurin's disable-library-validation entitlement; a non-Temurin JDK may refuse to load them.

Building and running

Ghostty is vendored as a pinned Git submodule, so initialize submodules first:

git submodule update --init

Then compile, run tests, and launch the app:

./gradlew clean test run

./gradlew run opens the Drydock window: a repository sidebar on the left and the workspace (terminal tabs) on the right. Registered repositories and window layout persist across restarts under ~/Library/Application Support/. Close the window (or Cmd+Q) to exit.

To build a self-contained runtime image (JDK 26 + JavaFX 26 + the app + native libraries, for both macOS architectures) that runs without Gradle or a configured JAVA_HOME:

./gradlew runtimeImage
build/image/bin/drydock

.app/.dmg packaging is not implemented yet; build from source or use the runtime image.

Releasing

See docs/RELEASING.md for how releases are staged to Maven Central and finalized.

Contributing

The design, milestone reports, and native-integration findings live in docs/:

Native code lives at the edges: the AppKit host shim in native-host/ (built by ./gradlew buildNativeHost) and the FFM bindings under app/src/main/java/app/drydock/terminal/. Ghostty itself is pinned at third_party/ghostty (tag v1.3.1) and built by scripts/build-ghostty.sh — CPU-architecture selection stays isolated in the native boundary package and must not leak into UI, Git, or persistence code.

Build the native pieces directly with:

./gradlew buildGhosttyNative   # libghostty, both architectures
./gradlew buildNativeHost      # the AppKit host shim, both architectures

About

A simple GUI for multi-project, multi-worktree work with Claude CLI

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages