Files
guide/AGENTS.md
2025-11-22 00:54:31 +00:00

92 lines
6.4 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Repository Guidelines (Agent-Facing)
## What This Project Is
- Guided demo platform built on FastAPI + Playwright to showcase browser automations and GraphQL-backed data flows.
- Entry point: `src/guide/app/main.py`; CLI runner: `python -m guide` (respects `HOST`/`PORT`).
- Personas and host targets are data-driven via YAML, not hardcoded.
- App state wiring happens in `create_app()`: loads settings, builds `PersonaStore`, `ActionRegistry`, and `BrowserClient`, then stashes them on `app.state` for dependency injection.
## Code & Module Layout
- Source root: `src/guide/app/`
- `actions/` — FastAPI-triggered demo actions; keep them thin, declarative, and side-effect scoped.
- `auth/` — pluggable MFA/auth helpers; avoid coupling to specific IdPs.
- `browser/``BrowserClient` and Playwright wrappers; centralize navigation, timeouts, and tracing.
- `core/` — settings, logging, dependency wiring; `AppSettings` drives runtime config and reads YAML/env merges.
- `errors/``GuideError` hierarchy; routes standardize error responses.
- `raindrop/` — GraphQL client + operations; isolate schemas/operations from business logic.
- `strings/` — selectors, labels, copy, GraphQL strings; no inline literals in actions.
- `models/` — domain/persona models; prefer pydantic v2 models with explicit types.
- `utils/` — shared helpers; keep <300 LoC and avoid circular deps.
- Config files: `config/hosts.yaml`, `config/personas.yaml` describe targets/personas; never embed secrets. ENV overrides: `RAINDROP_DEMO_BROWSER_HOSTS_JSON` and `RAINDROP_DEMO_PERSONAS_JSON` accept JSON arrays of objects matching the YAML shape.
## Development Workflow
- Install deps: `pip install -e .`
- Type check: `basedpyright src`
- Sanity compile: `python -m compileall src/guide`
- Run API (dev): `python -m guide`
- Preferred loop: edit → `basedpyright``compileall` → manual smoke via CLI or hitting local `/docs`.
- API surface (2025-11-22):
- `GET /healthz` liveness.
- `GET /actions` list action metadata.
- `POST /actions/{id}/execute` run an action; yields `ActionEnvelope` with correlation_id.
- `GET /config/browser-hosts` current default + host map.
## Coding Conventions
- Python 3.12+, Pydantic v2, pydantic-settings.
- Use PEP 604 unions (`str | None`), built-in generics (`list[str]`, `dict[str, JSONValue]`).
- Ban `Any` and `# type: ignore`; add type guards instead.
- Actions/constants: use `ClassVar[str]` for IDs/descriptions.
- Keep modules small (<300 LoC); split by domain (e.g., `actions/intake/basic.py`).
- Strings/queries belong in `strings/`; selectors should be reusable and labeled.
- `strings.service` enforces domain names; missing keys raise immediately, so keep selectors/texts in sync with UI.
## Error Handling & Logging
- Raise `GuideError` subclasses; let routers translate to consistent HTTP responses.
- Log via `core/logging` (structured, levelled). Include persona/action ids and host targets in logs for traceability.
- For browser flows, prefer Playwright traces over ad-hoc prints; disable tracing only intentionally.
- `BrowserClient.open_page` resolves host by ID → CDP attach (reuses existing Raindrop page) or launches headless chromium/firefox/webkit; always close context/browser on exit.
- CDP mode requires `host` + `port` in `hosts.yaml`; errors surface as `BrowserConnectionError` with host_id detail.
## Browser Automation Notes
- Route all CDP calls through `BrowserClient`; configure timeouts/retries there, not per action.
- Keep selectors in `strings/`; avoid brittle text selectors—prefer data-testid / aria labels when available.
- When mocking Playwright in tests, isolate side effects and avoid real network/CDP hits.
- Current MFA flow uses `DummyMfaCodeProvider` which raises `NotImplementedError`; real runs need a provider implementation or override before executing login/ensure_persona.
## GraphQL & Data Layer
- `raindrop/graphql.py` houses the client; operations live in `raindrop/operations`. Keep queries/mutations versioned and colocated with types in `strings/`.
- Validate responses with pydantic models; surface schema mismatches as `GuideError`.
- Never bake URLs/tokens—pull from `AppSettings` and YAML/env overrides.
- HTTP transport via `httpx.AsyncClient` (10s timeout); GraphQL errors bubble as `GraphQLTransportError` or `GraphQLOperationError` with returned `errors` payload in `details`.
## Configuration & Secrets
- Runtime configuration flows: env vars → `config/*.yaml``AppSettings` defaults.
- Do not commit credentials; use env overrides for tokens/hosts.
- MFA providers are pluggable; keep provider-specific wiring behind interfaces.
- Default env prefix: `RAINDROP_DEMO_` (see `AppSettings.model_config`).
## Testing Expectations
- Minimum: `basedpyright src` and `python -m compileall src/guide` before publishing.
- Add unit tests under `tests/` alongside code; mock Playwright/GraphQL; avoid real external calls.
- Prefer deterministic fixtures; document any required env vars in test module docstrings.
- Action pipeline happy-path: request → resolve persona + browser host → `BrowserClient.open_page` → optional `ensure_persona` → action.run → `ActionEnvelope` with correlation_id from `ActionContext`.
## Git & PR Hygiene
- Commits: scoped and descriptive (e.g., `feat: add auth login action`, `chore: tighten typing`).
- PRs should state changes, commands run, and any config additions (`hosts.yaml`, `personas.yaml`).
- Link related issues; include screenshots/log snippets when UI or API behavior changes.
## Performance & Footprint
- Keep browser sessions short-lived; close contexts to avoid leaking handles.
- Cache expensive GraphQL lookups when safe; prefer per-request timeouts over global sleeps.
- Avoid widening dependencies; stick to project pins unless justified.
- Close Playwright contexts/browser handles promptly (client already wraps in contextmanager; keep action code lean to avoid dangling pages).
## Quick Start Checklist (new agents)
- [ ] Create/verify `config/hosts.yaml` and `config/personas.yaml` match your target env.
- [ ] Run `pip install -e .`
- [ ] Run `basedpyright src` and `python -m compileall src/guide`.
- [ ] Start API: `python -m guide` and open `/docs` to smoke basic actions.
- [ ] Review `strings/` for selectors relevant to your feature before writing new actions.
- [ ] If executing auth flows, supply a working `MfaCodeProvider` (current dummy raises) or stub the login call in demos/tests.