# Hangar Backend

FastAPI backend for the Hangar orchestration IDE.

## Architecture

The backend is a thin orchestration layer that shells out to CLI tools (`bd`, `openspec`, `git`, `claude`) and presents their JSON output through a REST API.

### Services (6)

| Service | CLI | Purpose |
|---------|-----|---------|
| `BeadsService` | `bd` | Task CRUD, dependency graph, status management |
| `OpenSpecService` | `openspec` | Change listing, artifact browsing |
| `ImportSyncService` | `bd` | Bridge between tasks.md and Beads |
| `SpecWizardService` | `claude`/`codex` | AI-generated spec artifacts |
| `AgentLauncherService` | — | Context-aware agent launch commands |
| `GitDiffService` | `git` | Commit history and diffs per task |

### Routers (6)

| Router | Prefix | Endpoints |
|--------|--------|-----------|
| Tasks | `/api/tasks` | list, ready, get, claim, close |
| Specs | `/api/specs` | list, get, artifacts |
| Sync | `/api/sync` | preview, import, sync, completion |
| Wizard | `/api/wizard` | create, generate, approve, state |
| Agents | `/api/agents` | list, launch |
| GitDiff | `/api/tasks/{id}/diff` | task diff |

### Dependency Injection

Services are DI singletons wired through `dependencies.py`. Each getter lazily creates the service and caches it. `set_project_path()` resets all singletons when the project root changes.

## Development

```bash
uv sync                          # Install dependencies
uv run hangar                    # Start the server (port 8000)
uv run pytest -v                 # Run all 190 tests
uv run pytest -m integration -v  # Run only integration tests
uv run pytest -m "not integration" -v  # Run only unit tests
```

## Testing

The test suite has two layers:

- **Unit tests** — Mock services via `app.dependency_overrides`. Fast, isolated, test router logic.
- **Integration tests** — Real DI chain, mock at `asyncio.create_subprocess_exec` level. Catch wiring bugs.

Test markers: `@pytest.mark.integration` for integration tests.
