# Hey Hey CLI

## Development

From this directory:

```bash
pnpm dev
```

This runs the local API server flow from source (`tsx src/index.tsx`).
By default (`heyhey` with no command), the CLI starts the local server and waits until `Ctrl+C`.

Other useful dev scripts:

- `pnpm dev:build` - TypeScript watch build to `dist/`
- `pnpm dev:run` - run the CLI directly from source

## Register `heyhey` command

From this directory:

```bash
pnpm run register
```

This builds `dist/` and globally links the package so `heyhey` is available in your shell.

## Verify

```bash
heyhey --help
```

Example invocation:

```bash
heyhey
```

Provider credential refresh:

```bash
heyhey credential refresh --provider codex --account default
```

## Agent Auth Mode

Agent runs can authenticate in two ways:

- Stored credential mode: if a credential exists for the selected provider/account, Hey Hey binds it and injects auth env vars for the provider CLI.
- Native CLI auth mode: if no stored credential exists, Hey Hey launches the provider CLI without injected auth tokens so the CLI uses its own signed-in state (for example OAuth/login done directly in `codex` or `claude`).
- Codex invocation compatibility: Hey Hey uses `codex exec --full-auto --json ...` (and `codex exec resume --full-auto --json ...`) so orchestrated runs avoid interactive approval gates while staying sandboxed.
- Credential refresh command: use `heyhey credential refresh --provider <claude|codex> [--account <accountId>]` to store/replace provider API keys used by agent runs.

## Agent Invocation Recovery Config

The CLI reads agent invocation recovery settings from:

- `HEYHEY_AGENT_INVOCATION_CONFIG_PATH` (explicit file path), or
- `HEYHEY_CONFIG_DIR/agent-invocation.json`, or
- default config location:
  - macOS: `~/Library/Application Support/heyhey/agent-invocation.json`
  - Linux: `~/.config/heyhey/agent-invocation.json`
  - Windows: `%APPDATA%\\heyhey\\agent-invocation.json`

Example:

```json
{
  "agentInvocation": {
    "errorVerbosity": "compact",
    "model": "claude-sonnet-4-6",
    "reasoningEffort": "medium",
    "retryPolicies": {
      "claude": {
        "maxAttempts": 4,
        "initialDelayMs": 300,
        "maxDelayMs": 5000,
        "multiplier": 2,
        "jitterRatio": 0.2
      },
      "codex": {
        "maxAttempts": 3,
        "initialDelayMs": 250
      }
    }
  }
}
```

- `model` — default Claude model ID (e.g. `claude-opus-4-6`, `claude-sonnet-4-6`, `claude-haiku-4-5-20251001`). Overridden per-run via the `model` field on `LocalCreateRunRequest`.
- `reasoningEffort` — default reasoning effort (`low`, `medium`, `high`). Overridden per-run via `reasoningEffort` on `LocalCreateRunRequest`.

## Cross-Service Review Workspace Flow

The local runtime now supports preparing a multi-repository review workspace for cross-service code review runs.

API integration points:

- `POST /api/local/system/review-workspace`
  - Request body:
    - `sessionId` (string, required)
    - `repositories` (non-empty array)
      - `serviceId` (string, required)
      - `serviceName` (string, required)
      - `repositoryPath` (string, required)
  - Response body:
    - `workspaceRoot`
    - `workspaceLayout` (`"symlink_tree"`)
    - `allowedRepositoryRoots`
    - `links` (service-to-symlink mapping)

Runtime behavior:

1. The UI creates a coding session for cross-service review, then calls `/api/local/system/review-workspace`.
2. The local server validates repository targets, canonicalizes roots, and creates a per-session symlink-tree workspace.
3. The prepared workspace response is used to launch `/api/local/runs` with `scope.mode="cross_service_review"`, `workspaceRoot`, and `allowedRepositoryRoots`.
4. Run creation/recovery persists `scope` on the local run record.
5. Runner execution resolves working directory from run scope:
   - default runs execute in the mapped service repository
   - cross-service review runs execute in the prepared symlink-tree `workspaceRoot`
6. Prompt reference validation enforces that resolved references stay within the run's allowed repository roots.

## Unregister

From this directory:

```bash
pnpm run unregister
```
