Skip to main content

Launch Claude Code agents on GitHub repos with isolated workspaces and optional Docker dev environments

Project description

luv

A CLI that launches Claude Code agents on GitHub repos with isolated workspaces and optional Docker dev environments.

luv clones a repo, creates a branch, and drops you into a Claude session ready to work. When the repo ships a .luv/settings.json, it spins up Docker Compose automatically so every command runs in the right environment.

Install

# With uv (recommended)
uv tool install luv-cli

# With pip
pip install luv-cli

Requirements: Claude Code CLI and GitHub CLI (gh) must be installed and authenticated.

Quick start

# Configure your default GitHub org (one-time setup)
luv --init

# Create a new workspace and launch Claude
luv my-repo "add user authentication"

# Use a different org inline
luv other-org/my-repo "fix the bug"

# Reopen workspace #42
luv my-repo 42

# Open any GitHub PR by URL
luv -l https://github.com/org/repo/pull/123

# Open a shell instead of Claude
luv -n my-repo 42

# Resume last Claude session
luv -r my-repo 42

# Clean up fully-merged workspaces
luv --clean

How it works

  1. Clones the repo into ~/prs/{repo}-{number}/
  2. Creates a new branch luv-{number}
  3. Trusts the project in Claude Code config
  4. Launches Claude with Opus 4.8 at max effort; prompt-less sessions auto-run /effort ultracode as their first input to enter ultracode mode

All workspaces live under ~/prs/. The number comes from the repo's GitHub issue counter to avoid collisions.

Commands

Command Description
luv --init Configure default GitHub org
luv [org/]<repo> [prompt...] Create a new workspace and launch Claude
luv [org/]<repo> <number> [prompt] Reopen an existing workspace
luv -l <PR URL> [prompt] Open any GitHub PR by URL
luv [org/]<repo> -pr <number> [prompt] Open a PR by repo + number
luv --clean Delete workspaces where the branch is fully pushed/merged
luv --clean -f Force delete all workspaces
luv --clean --safe -f Force delete only workspaces older than 24h

Flags

Flag Description
-n Navigate: open a shell instead of Claude
-r Resume: resume the last Claude session
-p Launch Claude in plan permission mode (default: bypassPermissions)
-nit Non-interactive: run claude -p <prompt> and exit (no REPL); streams stream-json events to stdout
-m MODEL Claude model to use (default: claude-opus-4-8); passed through to claude --model, so aliases like opus/sonnet/haiku work
-e Env: pass LUV_* environment variables (with prefix stripped) into the session
-f, --force Skip safety checks (with --clean)
--safe With --clean -f, only delete workspaces older than 24h (mtime)

Docker dev environments

If a repo contains .luv/settings.json with a compose_file key, luv automatically starts a Docker Compose environment and runs Claude inside the dev-environment container.

Setup

1. Create .luv/settings.json in your repo:

{
  "compose_file": ".luv/docker-compose.yml"
}

The compose_file path is relative to the repo root.

2. Create the Docker Compose file:

services:
  dev-environment:
    image: your-org/dev-env:latest
    volumes:
      - .:/workspace
    working_dir: /workspace
    stdin_open: true
    tty: true
    depends_on:
      - postgres

  postgres:
    image: postgres:16
    environment:
      POSTGRES_PASSWORD: dev

The dev-environment service must have Claude Code installed in its image.

How Docker mode works

  1. Detects .luv/settings.json with compose_file key
  2. Tears down any stale environment from a previous run
  3. Starts docker compose up -d --build with a unique project name (luv-{repo}-{number}) for network/volume isolation
  4. Verifies the dev-environment service is running
  5. Runs Claude inside the container via docker compose exec
  6. The repo is volume-mounted, so all file changes and git commits are visible on the host
  7. On exit (including Ctrl-C), tears down the environment with docker compose down -v

Docker mode works with all flags: -n opens a bash shell in the container, -r resumes a Claude session in the container.

Workspace cleanup

luv --clean scans ~/prs/ and safely removes workspaces that are fully pushed. It checks:

  • Working tree is clean (no uncommitted changes)
  • No unpushed commits
  • If the remote branch is gone, verifies the PR was merged and local HEAD matches

Use luv --clean -f to skip all safety checks and delete everything. Add --safe (i.e. luv --clean --safe -f) to restrict force-delete to workspaces whose folder mtime is older than 24 hours, leaving recently-touched workspaces alone.

Configuration

Run luv --init to set your default GitHub org. This saves to ~/.luv/config.json.

You can also pass org/repo inline to override the default for any command (e.g., luv other-org/my-repo).

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

luv_cli-0.0.21.tar.gz (12.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

luv_cli-0.0.21-py3-none-any.whl (12.4 kB view details)

Uploaded Python 3

File details

Details for the file luv_cli-0.0.21.tar.gz.

File metadata

  • Download URL: luv_cli-0.0.21.tar.gz
  • Upload date:
  • Size: 12.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for luv_cli-0.0.21.tar.gz
Algorithm Hash digest
SHA256 88e48932ef4c12449c8a9454670c3335a292b08cdf51892e58afd31b6930adc4
MD5 bfd233380cef5de7a7021e7722726ad7
BLAKE2b-256 913b5997828e8b502fc7ab659f68efd144ae8eb35132476a10759a3d0ec7de60

See more details on using hashes here.

Provenance

The following attestation bundles were made for luv_cli-0.0.21.tar.gz:

Publisher: publish.yml on FailproofAI/luv

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file luv_cli-0.0.21-py3-none-any.whl.

File metadata

  • Download URL: luv_cli-0.0.21-py3-none-any.whl
  • Upload date:
  • Size: 12.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for luv_cli-0.0.21-py3-none-any.whl
Algorithm Hash digest
SHA256 9b6900fe040b1407c4658f386f040c60c8f2af1baef4a2c62eb53915179c6873
MD5 a479f4ec20a36e456c7ae0ea6557d082
BLAKE2b-256 417cf67d56102cccac82bfa3d81ce5e3b680f62c353ede93ad21c551d1cbddb0

See more details on using hashes here.

Provenance

The following attestation bundles were made for luv_cli-0.0.21-py3-none-any.whl:

Publisher: publish.yml on FailproofAI/luv

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page