# Toga - Agent Development Guide For additional context about technologies to be used, project structure, shell commands, and other important information, read the current plan This file tells autonomous coding agents (and human contributors using agent tools) how to be productive in this repository without breaking it. It is operational guidance; the binding rules live in `.specify/memory/constitution.md` and the contribution docs under `docs/en/how-to/contribute/`. When this file disagrees with either, the constitution wins. ## What Toga is Toga is a Python-native, OS-native GUI toolkit published under BSD-3-Clause as part of the BeeWare suite. A single `toga-core` API is rendered by a platform-specific backend so that one Python codebase produces native apps on macOS, Windows, Linux, iOS, Android, Web, and terminal. ## Repository layout | Path | What it contains | | --- | --- | | `core/` | `toga-core` — the public API and shared widget contracts. | | `travertino/` | Style and layout engine used by `core`. | | `dummy/` | Reference headless backend; MUST implement the full core API so core tests can run without a GUI. | | `cocoa/` | macOS backend. | | `gtk/` | Linux/GTK backend (GTK3 stable, GTK4 experimental). | | `winforms/` | Windows backend. | | `iOS/` | iOS backend. | | `android/` | Android backend. | | `textual/` | Terminal backend. | | `web/` | Web backend. | | `qt/` | Linux/Qt backend. | | `positron/` | Briefcase plugin for generating apps where the UI has been defined with web tools. Similar to Electron, but using Python for the web server | | `testbed/` | Briefcase app used to validate backend behaviour on a real platform. | | `docs/en/` | User and contributor documentation (MkDocs, `mkdocs.en.yml`). | | `changes/` | Towncrier fragments (`..md`) — one per user-visible change. | | `examples/`, `demo/` | Standalone sample apps. | | `.specify/` | SpecKit workflow assets (constitution, templates, extensions). | Do not create new top-level directories without a clear constitutional reason; extend existing ones. ## Non-negotiables (from the constitution) 1. **Backend parity.** A new `toga-core` API MUST have a concrete implementation plan for every production backend. The Dummy backend MUST always implement the full surface. 2. **Native behaviour.** Production backends MUST delegate to the native toolkit. No emulated/custom-drawn widgets without documented justification. 3. **Comprehensive tests (NON-NEGOTIABLE).** 100% line coverage for `core` and `travertino`. Backend changes MUST be exercised via `testbed/`. Bug fixes MUST include a regression test that fails before the fix. 4. **Documented change.** Every user-visible change MUST include a `changes/..md` fragment and updated docs. Breaking changes require a deprecation release. 5. **Contributor accountability.** The submitter owns the diff, regardless of AI assistance. Follow the BeeWare Code of Conduct and AI Policy. Any PR failing one of these is rejected, not waived. ## Toolchain - **Python**: 3.11–3.15 (see `core/pyproject.toml` classifiers). - **Task runner**: `tox` (with `tox-uv`). Install the dev tooling via `uv pip install --group dev` at the repo root, or let `tox` bootstrap. - **Lint/format**: `ruff` (check + format), `codespell`, `rumdl` (Markdown), configured in root `pyproject.toml`. - **Pre-commit**: `pre-commit run --all-files` — MUST pass before PR. - **Packaging / testbed driver**: `briefcase`. - **Release notes**: `towncrier` (config in root `pyproject.toml`). - **Docs**: MkDocs; built with the `docs` dependency group. Do not replace or bypass these tools. Add new dependencies only with a clear need and a compatible license (BSD-3-Clause friendly). ## Canonical commands Run from the repository root unless noted. ```console # Everything pre-commit checks (ruff, format, codespell, rumdl, etc.) pre-commit run --all-files # Core + Travertino test suites with coverage (MUST be 100%) tox -m test # Just core tox -m test-core # Just Travertino tox -m test-trav # A single test file against core tox -e py-cov -- core/tests/path/to/test_file.py # A single test file against Travertino tox -e py-trav -- travertino/tests/path/to/test_file.py # Towncrier draft (preview assembled release notes) tox -e towncrier-check # Docs lint tox -e docs-lint ``` ### Testbed (backend validation) The core suite uses the Dummy backend. Real backend behaviour is validated through the testbed app. Install only the backend under test in your virtualenv, then: ```console # Desktop (from testbed/) briefcase dev --app testbed --test # GTK variants (Linux) briefcase dev --app testbed --test TOGA_GTK=4 TOGA_GTKLIB=None briefcase dev --app testbed --test TOGA_GTK=4 TOGA_GTKLIB=Adw briefcase dev --app testbed --test # Qt (Linux) briefcase dev --app testbed-qt --test # Textual (Linux) briefcase dev --app testbed-textual --test # Mobile (requires the relevant SDK/toolchain) briefcase run android --app testbed --test briefcase run iOS --app testbed --test # macOS host only # Subset with slow mode for visual inspection briefcase dev --app testbed --test -- tests/widgets/test_button.py --slow ``` **Do not touch the keyboard/mouse while the testbed is running** — it drives input programmatically and will desync. ## Change notes Every user-visible PR needs a file in `changes/`: ```text changes/..md ``` `` MUST be one of: `feature`, `bugfix`, `removal`, `doc`, `misc`. Content is one or more sentences of past-tense prose describing the user-visible change. `misc` entries are hidden from release notes and appropriate for purely internal changes. Do not edit `docs/en/about/releases.md` directly; towncrier assembles it at release time. ## Coding conventions - Follow the Toga code style guide linked from `CONTRIBUTING.md`. Ruff enforces most of it; do not disable rules locally. - Keep public API surface minimal and documented. New public names MUST appear in reference docs under `docs/en/reference/api/`. - Type hints: use them on public API; keep them consistent with the `.pyi` stub (`core/src/toga/__init__.pyi`) when applicable. That stub is excluded from Ruff — hand-edit it carefully. - `# pragma: no cover` is reserved for the cases already whitelisted in `tool.coverage.coverage_conditional_plugin.rules`. Do not introduce new ones to work around missing tests. - `filterwarnings = ["error"]` is set for pytest; warnings in tests are failures. Either fix the root cause or add a scoped, commented `pytest.warns(...)` / `filterwarnings` mark. - `isort` config in root `pyproject.toml` lists the first-party backend packages; add new packages there if you create one. ## Documentation expectations - Every new public API, widget, or behavioural change MUST update `docs/en/` in the same PR. - Tutorials live under `docs/en/tutorial/`, how-tos under `docs/en/how-to/`, reference under `docs/en/reference/`, topic explanations under `docs/en/topics/`. - Build-time doc linting runs through `tox -e docs-lint`; fix anything it reports. - Markdown files in this project (including `AGENTS.md`, `docs/en/`, and `changes/` fragments) must **not** use hard line breaks to enforce an 80-character column limit. Each paragraph or list item must be written as a single unbroken line, regardless of its length. Let the reader's editor or renderer handle wrapping. This rule applies to all prose. Code blocks, directory trees, and other pre-formatted blocks are exempt — keep those readable within their own constraints. When writing or editing any `.md` file, do not insert newlines mid-sentence or mid-paragraph to stay within 80 columns. - Follow the BeeWare documentation style guide (linked from `CONTRIBUTING.md`). ## Pull-request workflow 1. Branch off `main` with a descriptive name. Do not push to `main`. 2. Make the smallest change that addresses one issue. Avoid scope creep; file a separate issue/PR for drive-by refactors. 3. Before opening the PR, run locally: - `pre-commit run --all-files` - `tox -m test` (expect 100% coverage) - Testbed on any backend the change affects 4. Include in the PR: - A `changes/..md` fragment - Docs updates when user-visible - A description naming the issue closed and the backends exercised 5. CI MUST be green. Reviewers confirm the five constitutional principles; failures are fixed, not waived. 6. Default merge strategy is squash; the squash message is what users will read, so make it describe the user-visible change. ## Agent-specific rules Agents operating in this repo MUST: - Load `.specify/memory/constitution.md` before any change that affects public API, backends, test coverage, or release tooling. - Prefer editing existing files over creating new ones. Never proactively create new top-level files or directories. - Keep the ` ... ` block at the top of this file intact; SpecKit commands inject plan context there. - Never add `# pragma: no cover`, `# noqa`, or disable Ruff/codespell rules inline to pass CI; diagnose and fix the underlying issue. - Never commit secrets, API keys, `.env` files, or contributor PII. - Never rewrite Git history on `main` or force-push shared branches. - When uncertain about backend parity or API shape, open an issue or discussion before implementing; Toga favours design-first for anything non-trivial (see `docs/en/how-to/contribute/how/propose-feature.md`). - Disclose AI assistance in the PR description where it is material to review, per the BeeWare AI Policy. ## Where to look next - `CONTRIBUTING.md` — entry point for all contributors. - `.specify/memory/constitution.md` — binding project principles. - `docs/en/how-to/contribute/` — style guides, PR process, review guide, scope-creep guide, AI policy. - `docs/en/reference/platforms/` — per-backend requirements and status. - Toga documentation site: - BeeWare community and Code of Conduct: