jj-navi is a small Rust CLI that makes Jujutsu workspaces fast to create, switch, inspect, merge, and remove for parallel human and AI-agent workflows.
It is a workspace lifecycle layer over native jj workspace primitives. It should make common parallel-workspace operations obvious without becoming a replacement VCS workflow engine.
The core promise is:
workspace name -> trusted path -> useful action
That promise depends on three things:
- workspace switching is fast and predictable
- workspace paths are validated before use
- many active workspaces are understandable at a glance
- developers using Jujutsu daily
- developers running several parallel tasks
- developers using AI coding agents in separate workspaces
- users migrating from Git worktree workflows
- users who want a lightweight Worktrunk-style UX for JJ
Shipping command families:
navi switch <workspace>navi switch --create <workspace>navi switch --create <workspace> --revision <revset>navi switch -navi switch @navi list [--json] [--compact]navi doctor [--json] [--compact]navi remove <workspace>navi config shell init <bash|zsh>navi config shell install [--shell <bash|zsh>]
Supported binaries:
navinv
- Make switching JJ workspaces fast and predictable.
- Make creating a workspace feel like a mode of switching.
- Make many parallel workspaces understandable without deep JJ knowledge.
- Keep JJ as the source of truth.
- Make workspace removal destructive but guarded and explicit.
- Add merge preview support without hiding JJ semantics.
- Stay small and conservative around destructive actions.
- agent orchestration
- terminal pane, tmux, or iTerm session management
- port allocation
- environment file editing
- dev server launch or process management
- framework-specific monorepo setup
- replacing general JJ commands
- managing Git branches or Git worktrees directly
- PR/CI workflows in the near-term roadmap
- fully automatic merge selection
The intended loop:
navi switch --create feature-one
navi switch --create feature-two
navi switch -
navi list
navi merge preview --from feature-two
navi remove feature-two --yesMental model:
- create or jump with
switch - inspect workspace inventory and active work with
list - merge deliberately with a read-only merge preview before running JJ commands
- remove finished or abandoned workspaces with an explicit destructive guard
- diagnose degraded state with
doctoronly when needed
Keep:
navi list [--json] [--compact]Purpose:
- answer “what work is active across my workspaces?” without requiring users to know JJ snapshot mechanics
- solve stale cross-workspace visibility before merge decisions
- provide both human triage and scriptable JSON
Human output should be compact and scan-friendly. Fields:
- current marker
- workspace name
- path health
- currentness health for workspaces that could not be made current
- compact diff summary
- commit id
- first-line description
- workspace age when created by Navi
JSON output should expose the same concepts with stable field names.
Rules:
listmakes healthy workspace state current before rendering by runningjj util snapshotinternally in each switchable workspace- snapshot mechanics are not exposed as command UX
listdoes not runjj workspace update-staleor auto-repair workspace fileslistdoes not block forever on one workspace; degraded currentness remains visible per row- stale or missing workspaces should remain visible instead of failing the whole command
Change:
navi remove <workspace> [--yes|-y]Purpose:
- retire a local JJ workspace in one command
- keep JJ workspace records and local workspace directories from drifting apart
- make destructive deletion obvious and guarded
Rules:
removerefuses to remove the current workspaceremovevalidates the target workspace path before deletionremoveforgets the JJ workspace and removes Navi metadataremovedeletes the local workspace directory- without
--yes/-y,removemust clearly show the path that will be deleted and ask for confirmation - with
--yes/-y,removeskips confirmation for fast agent/human cleanup - deletion must use Rust filesystem APIs, not shelling out to
rm -rf - failures should say which step failed and what state may remain
Add:
navi merge preview --from <workspace> [--into <workspace>] [--json]Purpose:
- help users consolidate useful work from parallel JJ workspaces
- make the duplicate-first merge pattern visible before mutation
- provide a bridge from
navi listto explicit JJ merge commands
Rules:
- source workspace is always explicit
- target defaults to the current workspace unless
--intois provided previewis read-only and does not mutate JJ state, workspace files, metadata, or bookmarks- source and target paths must be healthy before a preview is produced
- stale, missing, ambiguous, or not-current states stop with guidance instead of guessing
- when the source belongs to another workspace, preview should recommend the safe
jj duplicatethenjj rebasepattern merge applyis out of scope until preview behavior is proven useful
Port and env allocation are out of scope.
Reasoning:
- Vite, Turborepo, Bazel, Rust services, backend stacks, direnv, and custom scripts all express runtime configuration differently
- automatic env-file edits can touch secrets or project-specific conventions
- assigning a single port is not enough for multi-service workspaces
- runtime isolation is a project concern, while Navi’s scope is workspace lifecycle and JJ state
Possible later compromise:
- user-authored workspace notes such as URL, port, or label
- display-only metadata in
list - no automatic allocation or env mutation
switchresolves only validated workspace paths.switch --createcreates workspaces at deterministic paths.switch -returns to the previously recorded workspace.switch @resolves the current workspace explicitly.listshows workspace inventory and degraded path state.listmakes healthy workspaces current before rendering active work.listshows compact diff statistics and workspace age when known.doctorexplains degraded repo, workspace, and shell state.removerefuses to remove the current workspace.remove --yesforgets a non-current workspace and deletes its local directory.
removeclearly warns before destructive directory deletion unless--yes/-yis provided.merge previewreports source, target, and intended JJ commands without applying them.merge previewexplains the duplicate-first pattern for work from another workspace.
Tests should cover external behavior with real JJ repositories where practical.
Priority coverage:
- workspace creation and switching
- degraded path recovery and reporting
- fresh list human output
- fresh list JSON output
- list currentness, skipped workspace reporting, and failure reporting
- list diff summary and workspace age
- guarded destructive remove behavior
- remove
--yes/-yfast path - merge preview read-only behavior
- merge preview preflight behavior
naviandnvparity for user-facing commands
Docs should explain the product in this order:
- what
jj-naviis - the core switch/list workflow
- shell integration
- fresh cross-workspace list behavior
- guarded destructive remove
- merge preview for parallel workspace consolidation
- doctor and degraded-state recovery
- Jujutsu: https://github.com/jj-vcs/jj
- Jujutsu working copy docs: https://docs.jj-vcs.dev/latest/working-copy/
- Jujutsu revsets: https://github.com/jj-vcs/jj/blob/main/docs/revsets.md
- Worktrunk: https://github.com/max-sixty/worktrunk
- Worktrunk docs: https://worktrunk.dev
- jj-ryu: https://github.com/dmmulroy/jj-ryu