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

6.4 KiB
Raw Permalink Blame History

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 → basedpyrightcompileall → 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/*.yamlAppSettings 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.