Metadata-Version: 2.4
Name: ghw
Version: 1.0.1
Summary: Per-folder GitHub CLI workspace manager
Requires-Python: >=3.10
Requires-Dist: rich>=13.0.0
Requires-Dist: typer>=0.12.0
Description-Content-Type: text/markdown

# GH Workspace Manager (ghw)

Per-folder GitHub CLI auth for multi-account workflows.

## Why This Exists

You work with multiple GitHub accounts:
- **personal** - Your personal account
- **work** - Your work/employer account
- **client** - Client projects

Example uses: personal + work + freelance clients, or personal + open source + consulting.

GitHub CLI stores auth globally in `~/.config/gh/`. Every `gh auth login` overwrites the previous one. You're constantly switching and losing track.

**Solution**: Each folder uses mise to set `GH_CONFIG_DIR`, and ghw validates before running gh. You cd into a project, gh automatically uses the right account.

## Install

### Required: `mise`

`ghw` requires [mise](https://mise.jdx.dev/) — it is the mechanism that sets `GH_CONFIG_DIR` per project folder. Without it, workspace switching doesn't happen. If you are not using mise, this tool is not for you.

```bash
curl https://mise.run | sh
```

Add to your shell rc (`~/.bashrc` or `~/.zshrc`):

```bash
export MISE_TRUSTED_CONFIG_PATHS="$HOME/src"
eval "$(mise activate bash)"   # or: eval "$(mise activate zsh)"
```

### Install `ghw`

```bash
uv tool install ghw      # recommended
pipx install ghw         # fallback if no uv
uvx ghw                  # zero-install try-it
```

Verify:
```bash
ghw --help
```

## Setup

### 1. Create Workspaces

One per GitHub account you want to use:
```bash
ghw workspace init personal
ghw workspace init work
ghw workspace list
```

Configs live under `~/.config/gh-workspaces/<workspace>/`.

### 2. Add .mise.toml to Each Project

**Lazy way (with init-here):**

```bash
cd ~/src/my-project

# If git remote exists, auto-detect from URL:
git remote add origin git@github.com:personal/myrepo.git
ghw init-here --auto

# Or specify workspace explicitly:
ghw init-here --workspace personal
```

**Manual way:**

Create `~/src/PROJECT/.mise.toml`:

```toml
[env]
# Absolute path required — mise does not expand ~ or $HOME in env values.
# macOS: /Users/<you>/.config/gh-workspaces/personal
# Linux: /home/<you>/.config/gh-workspaces/personal
GH_CONFIG_DIR = "/home/<you>/.config/gh-workspaces/personal"
```

Replace `personal` with `work` or `client` as needed. Tip: `ghw init-here --workspace personal` emits the correct absolute path for your OS automatically.

### 3. Configure mise Auto-Trust

Add to your shell rc (`~/.bashrc` or `~/.zshrc`) so all `.mise.toml` files
under `~/src` are trusted without manual `mise trust`:

```bash
# Must be exported BEFORE `mise activate` so activation picks it up.
export MISE_TRUSTED_CONFIG_PATHS="$HOME/src"
eval "$(mise activate bash)"   # or: eval "$(mise activate zsh)"
```

### 4. Add gh Wrapper Function

Add to the same shell rc:

```bash
gh() {
    if [[ -n "$GH_CONFIG_DIR" ]]; then
        echo "[ghw] Using gh via ghw wrapper (GH_CONFIG_DIR: $GH_CONFIG_DIR)"
        ghw gh "$@"
    else
        command gh "$@"
    fi
}
```

Reload your shell:
```bash
exec $SHELL
```

### 5. Authenticate Each Workspace

```bash
# In a project using personal workspace
cd ~/src/some-project
gh auth login    # Authenticates personal

# In a project using work workspace
cd ~/src/other-project
gh auth login    # Authenticates work (different from personal)
```

Folder names don't matter - the `.mise.toml` in each folder determines the workspace.

## Daily Workflow

```bash
# In a project using personal workspace
cd ~/src/myapp
gh auth status
# [ghw] Using gh via ghw wrapper (GH_CONFIG_DIR: <your-home>/.config/gh-workspaces/personal)
# github.com
# ✓ Logged in to github.com account your-username (keyring)

# Switch to project using work workspace
cd ~/src/client-portal
gh auth status
# [ghw] Using gh via ghw wrapper (GH_CONFIG_DIR: <your-home>/.config/gh-workspaces/work)
# github.com
# ✓ Logged in to github.com account work-account (keyring)

# Outside any project
cd ~
gh auth status
# (no [ghw] message - regular gh)
```

Note: Folder names like `myapp` or `client-portal` are arbitrary. What matters is the `.mise.toml` inside each folder.

## Safety: Strict Validation

**The protection mechanism**: If `GH_CONFIG_DIR` is set but workspace missing, ghw **errors hard**.

```bash
cd ~/src/myapp
export GH_CONFIG_DIR=<your-home>/.config/gh-workspaces/missing
gh auth status
# [ghw] Using gh via ghw wrapper (GH_CONFIG_DIR: <your-home>/.config/gh-workspaces/missing)
# ╭─────────────────────────────────── Error ────────────────────────────────────╮
# │ Workspace config missing at <your-home>/.config/gh-workspaces/missing. Run:  │
# │ ghw workspace init missing                                                   │
# ╰──────────────────────────────────────────────────────────────────────────────╯
```

**No fallback. No silent default. You always know what's happening.**

## Commands

```bash
# Quick setup (lazy way)
ghw init-here --workspace personal    # Create .mise.toml for current project
# OR if git remote is set:
git remote add origin git@github.com:personal/repo.git
ghw init-here --auto            # Auto-detect from git remote

# Workspace management
ghw workspace list              # Show: client, personal, work, test
ghw workspace init new-client   # Create new workspace

# Run gh with validation
ghw gh auth status              # Explicit version
gh auth status                  # Via alias (same thing)

# Diagnostics
ghw doctor                      # Check setup and diagnose issues
ghw --version                   # Show version
```

## How It Works

```
cd ~/src/myapp
↓
mise reads .mise.toml (contains GH_CONFIG_DIR=.../personal)
↓
exports GH_CONFIG_DIR=<your-home>/.config/gh-workspaces/personal
↓
gh auth status (alias)
↓
sees GH_CONFIG_DIR, calls ghw gh auth status
↓
ghw validates workspace exists
↓
runs the real gh (e.g. /opt/homebrew/bin/gh on macOS, /usr/bin/gh on Linux)
```

The folder name (`myapp`) is irrelevant. The `.mise.toml` inside determines the workspace.

## File Locations

```
~/.config/gh-workspaces/          # Your workspaces
├── personal/
├── work/
└── ...

~/.bashrc or ~/.zshrc             # Your gh() wrapper function lives here

~/src/*/                          # Your projects with .mise.toml
```

## Troubleshooting

### Quick Diagnosis

Run `ghw doctor` to check your entire setup:

```bash
ghw doctor
```

This checks:
- ghw is installed correctly
- mise is installed and in shell
- gh is installed
- gh alias is loaded
- Workspaces exist
- GH_CONFIG_DIR detection

### "Workspace config missing"

```bash
ghw workspace init <name>
```

### "ghw command not found"

```bash
cd ~/src/gh-workspace-manager
uv tool install -e .
```

### Alias not working

```bash
# Check if wrapper function loaded
type gh

# Should show "gh is a function", not the raw binary path
# (e.g. /opt/homebrew/bin/gh on macOS, /usr/bin/gh on Linux)

# Reload if needed
exec $SHELL
```

### mise not setting GH_CONFIG_DIR

```bash
# Check mise is in shell
echo $SHELL
mise --version

# Check .mise.toml exists in project folder
cat ~/src/myapp/.mise.toml

# Force reload
cd . && cd ~/src/myapp
env | grep GH
```

## Further Reading

- [docs/guides/quickstart.md](docs/guides/quickstart.md) — condensed setup + daily workflow reference
- [docs/architecture/design.md](docs/architecture/design.md) — component diagram, data flow, trade-offs, alternatives considered

## Development

```bash
cd ~/src/gh-workspace-manager

# Run tests
uv run --group dev pytest tests/ -v

# Reinstall after changes
uv tool install -e .

# Test locally
ghw workspace list
```

## Key Principles

1. **Per-folder only**: .mise.toml in exact folder only, no inheritance
2. **Strict validation**: Error if workspace missing, never fallback
3. **Reminder message**: Always know when using ghw vs regular gh
4. **Cross-platform**: pathlib, works on macOS/Linux/Windows

## Questions

**Why not just use GH_CONFIG_DIR manually?**
Easy to forget, easy to mess up. ghw adds validation and reminder.

**Why mise instead of direnv?**
Faster (<1ms vs 20-50ms), cleaner config, unified with your other tools.

**What if I delete a workspace folder?**
ghw will error immediately and tell you to recreate it.

**Can I use this outside my src folder?**
Yes, anywhere. Just add .mise.toml with the workspace you want.
