連理 — intertwined branches. A unified manager for git worktrees and jujutsu (jj) workspaces, driven by teravars-powered TOML configuration with per-host / per-OS overrides and a shared base include mechanism.
Status: 0.1.0 — MVP shipped. All seven verbs (add / list /
remove / cd / exec / prune / config) work on git and jj
backends. Shell wrappers generated by renri shell-init. See
ROADMAP.md for what's next.
The existing crop of worktree CLIs (gwq, wtp, Phantom, claude-squad, Worktrunk, …) all assume git, all use a different config format, and none of them treat jj workspaces as first-class peers. The teams shipping AI-parallel-dev workflows have their config and conventions re-implemented across N tools.
renri aims to be the local CLI that:
- Auto-detects git or jj, dispatches to the right backend, exposes
one verb set (
add/list/remove/cd/exec/prune/config). - Configures with TOML + Tera via the teravars library, so a
single
renri.tomlcaninclude = ["team-base.toml"], render{% if system.host == "thinkpad" %} ...for per-machine overrides, and use the standardenv(...)/is_windows()helpers. - Falls back to interactive picker for any required argument that
was omitted on the command line —
renri cdopens a fuzzy filter, butrenri cd feature/fooswitches directly.--non-interactivedisables the fallback for scripts and CI. - Treats jj workspaces honestly — surfaces
update-stale, ships the prune behaviour thatjj workspace forgetis missing, handles the colocated-git+jj case wheregit worktree addrequires-b.
# renri.toml
include = ["{{ env(name='RENRI_TEAM_BASE', default='') }}"]
[layout]
worktree_root = "{{ env(name='HOME') }}/wt"
worktree_path = "{{ vcs.owner }}/{{ vcs.repo }}/{{ vcs.branch | replace(from='/', to='-') }}"
[[hooks.post_create]]
type = "copy"
files = [".env.example -> .env"]
[[hooks.post_create]]
type = "command"
run = "pnpm install"
{% if system.os == "windows" %}
[[hooks.post_create]]
type = "command"
shell = "pwsh"
run = "Write-Host 'Welcome to {{ vcs.branch }}'"
{% endif %}renri add feature/auth # creates the worktree, runs hooks
renri cd feature/auth # prints the path (or opens picker if no arg)
renri exec feature/auth -- pnpm test
renri prune # gc stale worktrees / forgotten jj workspacesFor renri cd to actually change the parent shell's directory,
source the snippet from renri shell-init:
# bash / zsh
eval "$(renri shell-init bash)"
# fish
renri shell-init fish | source
# pwsh — add to $PROFILE:
Invoke-Expression (& renri shell-init powershell)renri ships as an APM package. One command gives the renri skill to every detected agent client (Copilot / Claude Code / Cursor / OpenCode / Codex / Gemini):
apm install yukimemi/renriThe skill source lives at .apm/skills/renri/SKILL.md; APM compiles
it into the right format for each agent on install.
An MCP server is planned for v0.2 so MCP-compatible AI clients can
drive renri verbs directly without going through bash.
(none yet — added as needed.)
MIT.