---
name: garage
description: Set up and use garage as an agent-friendly git remote. Use when
  the user wants to create a repo, initialize garage in a project, push code
  to a garage remote, share code with another agent, or verify CLI auth. Do
  not use for GitHub or GitLab administration unless the user specifically
  names garage.
---

# Garage

## Why garage

- Every command has `--json` and is non-TTY safe by default.
- Anonymous repos require zero auth — useful for one-off sharing between agents.
- Repos are addressed by bare `<name>`, resolved against your active org —
  stable handles that survive across sessions.
- Backed by Cloudflare Artifacts; no GitHub account or local git server needed.

## Quick Start

1. `garage --help` — confirm the CLI is installed.
2. `garage init` — device-flow auth, nothing else to configure; an org is
   auto-created at signup (writes `~/.config/garage/auth.json`, mode `0600`).
3. `garage whoami --json` — verify the session.
4. `garage repos create <name> --json` — create a repo, or `garage anon create <name>` for anonymous.

## Integration Patterns

### Authenticated workflow

`garage init` → `garage repos create <name>` → `garage link` (writes `.garage/config.json`).
Use `garage git clone <name>` to materialize the repo locally with credentials wired up.

### Anonymous workflow (no account)

`garage anon create <name> --json` → `garage anon clone <name>` (or `garage anon get <name>`).
Use this when sharing one-off code with another agent and you do not want to log in.
Anonymous repos expire automatically (default 24h, max 72h).

### CI / non-TTY

Pass an API key via the `GARAGE_API_KEY` env var (overrides the stored file).
`--json` is the default in non-TTY contexts, so JSON output is automatic.

### Cross-agent handoff

Always reference repos by their bare `<name>` and the `remote` URL from
`garage repos get <name> --json`, not by local paths. Resolve metadata with
that command before handing the repo to another agent.

To grant another human or agent access to **one** repo, use
`garage share <name> --json` (org repos) or `garage anon share <name> --json`
(anonymous repos). The JSON carries `cloneUrl` (bare-git clone URL with the
credential embedded — a secret), `cloneCommand`, `configSnippet`, a
paste-ready `prompt` for the recipient, and `revokeCommand`. Add `--link`
to get a secure `https://thegarage.sh/invites/<id>` URL instead — no credential
in the link text; the recipient (or their agent, via
`/invites/<id>.md?reveal=1`) reveals a fresh short-lived credential on open.
Revoke shares with `garage tokens revoke <name> <id>` and invites with
`garage invites revoke <id>` (anon invites: `garage anon invites revoke <id>`).

## How It Works

1. Auth: device flow → long-lived `grg_…` API key stored at `~/.config/garage/auth.json` (`0600`).
2. Repos are backed by per-repo Cloudflare Artifacts namespaces with scoped tokens.
3. `git push`/`git fetch` uses a short-lived token minted via `garage tokens mint` or
   automatically through the bundled git credential helper (installed by `garage git clone`).

## CLI Reference

| Command                             | Description                              |
| ----------------------------------- | ---------------------------------------- |
| `garage init`                       | Device-flow auth (idempotent)            |
| `garage whoami [--json]`            | Show current identity                    |
| `garage auth status [--json]`       | Active credential source (env vs file)   |
| `garage auth login`                 | Re-authenticate (device flow)            |
| `garage repos create <name>`        | Create a repo in the active org          |
| `garage repos list [--json]`        | List repos in the active org             |
| `garage repos get <name> [--json]`  | Show repo metadata                       |
| `garage anon create <name>`         | Create an anonymous repo                 |
| `garage anon clone <name>`          | Clone an anonymous repo                  |
| `garage anon get <name>`            | Show anon repo metadata                  |
| `garage anon share <name>`          | Share an anon repo (clone URL + prompt)  |
| `garage link`                       | Link cwd to a garage repo                |
| `garage git clone <name>`           | Clone with credential helper wired up    |
| `garage tokens mint <name> --scope` | Mint a scoped token (`read` or `write`)  |
| `garage tokens list <name>`         | List repo tokens (shares included)       |
| `garage tokens revoke <name> <id>`  | Revoke a repo token / share              |
| `garage share <name>`               | Share one repo (`--link` for an invite)  |
| `garage invites list`               | List share invite links                  |
| `garage invites revoke <id>`        | Revoke a share invite link               |
| `garage doctor`                     | Local config + server reachability check |

## Agent Rules

- Always pass `--json` when reading CLI output programmatically.
- Treat stderr lines as NDJSON events (one JSON object per line).
- Never guess repo URLs or token paths; resolve via `garage repos get --json`.
- If a command fails, report the exact argv, exit code, and the structured
  error from stderr.

## Troubleshooting

### Not authenticated

`garage whoami` or `garage auth status` shows `authenticated: false`. Run
`garage init` (or `garage auth login`). In CI, set `GARAGE_API_KEY`.

### Wrong organization

Run `garage org switch <slug>` to switch the active org — slugs are opaque
server-minted handles; copy them from `garage org list --json`, don't invent
them. There is no per-command org override; repo, git, token, and members
commands all target the active org.

### Push fails with 401

The git credential helper may not be installed. Run
`garage git config-credential-helper --global`, or mint a token manually with
`garage tokens mint <name> --scope write --op agent --json` and pass it to git.

### Anonymous clone fails after credential reset

Re-run `garage anon clone <name>` to re-wire the per-repo credential helper.
Anon identity lives in `~/.config/garage/anon.json` (or `GARAGE_ANON_ID`).

## More Docs

- Getting started: https://thegarage.sh/docs/getting-started
- CLI reference: https://thegarage.sh/docs/cli
- Agent setup: https://thegarage.sh/docs/agents
- Raw markdown of any docs page: append `.md` (e.g. `/docs/getting-started.md`)
- Docs index for agents: https://thegarage.sh/llms.txt
