# Prauto — Autonomous PR Worker

Prauto is a cron-driven bash worker that monitors GitHub issues labeled `prauto:ready`, invokes Claude Code CLI to analyze and implement changes, and submits pull requests.

See `spec/AI_PRAUTO.md` for the full specification (heartbeat cycle, label lifecycle, phase state machine, security model, prompt templates).

## Prerequisites

- `claude` CLI installed and authenticated
- `gh` CLI installed and authenticated (PAT with Issues, PRs, Contents permissions)
- `git` configured for the repository
- `jq` for JSON processing

## Setup

1. Copy the instance config template:

   ```bash
   cp .prauto/config.local.env.example .prauto/config.local.env
   ```

2. Edit `.prauto/config.local.env` with your worker identity, Claude model, and secrets.

3. Sync GitHub labels (once):

   ```bash
   npx github-label-sync --access-token "$(gh auth token)" --labels .github/labels.yml <owner>/<repo>
   ```

4. Schedule the heartbeat. Choose one of the options below:

   **Option A — `cron` (Linux / CI)**

   ```bash
   # Run heartbeat every 30 minutes, Mon-Fri 9:00-18:00 KST
   */30 9-18 * * 1-5 cd /path/to/dataspoke-baseline && .prauto/heartbeat.sh >> .prauto/state/heartbeat_cron.log 2>&1
   ```

   **Option B — `launchd` (macOS)**

   On macOS, cron jobs cannot access the Keychain that can be useful to use claude code without `ANTHROPIC_API_KEY` set. in this case, launchd can be used instead of cron. create launchd setting file (e.g. `~/Library/LaunchAgents/com.dataspoke.prauto.heartbeat.plist`) and load it. Note that when using launchd, PATH must include directories for **all** required CLIs (`claude`, `gh`, `git`, `jq`).

   ```bash
   vi ~/Library/LaunchAgents/com.dataspoke.prauto.heartbeat.plist                                # edit
   launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.dataspoke.prauto.heartbeat.plist  # load
   launchctl bootout gui/$(id -u)/com.dataspoke.prauto.heartbeat                                 # unload
   launchctl kickstart gui/$(id -u)/com.dataspoke.prauto.heartbeat                               # run now
   ```

## Optional: Dedicated GitHub Bot Account

Running prauto under a separate GitHub account (e.g., `youraccount-prauto`) keeps bot activity visually distinct from human commits and PR comments. This is optional — prauto works fine with the repo owner's credentials.

### 1. Invite the bot account as a collaborator

From the repo owner account, go to:

```
https://github.com/youraccount/yourrepo/settings/access
```

Search for the bot account and send the invitation. For personal repositories, collaborators receive Write access by default (no role selector is shown). For organization repositories, select the **Write** role.

### 2. Accept the invitation

Log in as the bot account and accept the collaborator invitation at `https://github.com/notifications`.

### 3. Create a classic PAT from the bot account

Go to `https://github.com/settings/tokens/new` (logged in as the bot account) and check the **`repo`** scope.

> **Why classic PAT, not fine-grained?**
> Fine-grained PATs require the Resource owner to be the token creator or one of their organizations. Another personal account (the repo owner) cannot appear as a Resource owner, so fine-grained PATs cannot be scoped to a repo owned by a different personal account.

### 4. Set the token in `config.local.env`

```bash
GH_TOKEN="ghp_xxxxxxxxxxxx"
```

All GitHub API operations (issue labels, comments, PR creation) will then run as the bot account. Git commit identity remains whatever is set in `PRAUTO_GIT_AUTHOR_NAME` / `PRAUTO_GIT_AUTHOR_EMAIL`.

## Manual Run

```bash
cd /path/to/dataspoke-baseline
.prauto/heartbeat.sh
```

## Troubleshooting

- **Lock issues**: Check `.prauto/state/heartbeat.lock` — if the PID is stale, delete the file.
- **Job stuck**: Check heartbeat log and GitHub labels (`prauto:wip`, `prauto:review`) to determine the current phase.
- **Logs**: Check `.prauto/state/heartbeat.log` for cron output.
- **Session history**: Check `.prauto/state/sessions/` for Claude session outputs.
