Skip to content

Commit ffecc27

Browse files
authored
Add AGENTS.md (#6337)
* Add AGENTS.md Get some sanity when developing with Claude, Cursor, and friends. * Add AI-assisted PR section * align code coverage fail under for CONTRIBUTING.md * suggests from farhan
1 parent 4e7b239 commit ffecc27

3 files changed

Lines changed: 134 additions & 4 deletions

File tree

AGENTS.md

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
# Coding Agent Guidelines
2+
3+
Reflex: Python web **framework** compiling to React. Monorepo using uv workspace — main package in `reflex/`, sub-packages in `packages/`, docs site in `docs/`.
4+
5+
## Workflow
6+
7+
1. **Plan first.** Ensure the task is well-defined before writing code. If unclear, work with the user to flesh out details. No sloppy/spaghetti code — every feature/fix must be clearly understood first.
8+
2. **Bugfixes:** write a regression test that fails before writing the fix.
9+
3. **After implementation:** act as an adversarial reviewer. Scrutinize the diff against all rules in this file. Call out numbered issues, then wait for the user to request followup changes.
10+
11+
## Commands
12+
13+
Use `uv` for everything — never bare `python` or `python3`.
14+
15+
```
16+
uv sync # install deps
17+
uv run pytest tests/units --cov --no-cov-on-fail --cov-report= # unit tests (>=72% coverage)
18+
uv run pytest tests/integration # integration tests (slow)
19+
uv run ruff check . # lint
20+
uv run ruff format . # format
21+
uv run pyright reflex tests # type check
22+
uv run python scripts/make_pyi.py # regenerate .pyi stubs
23+
uv run pre-commit run --all-files # all pre-commit hooks
24+
```
25+
26+
## Layout
27+
28+
```
29+
reflex/ # main framework package (app, state, compiler, components, utils, istate)
30+
packages/ # workspace sub-packages (reflex-base, reflex-components-*, reflex-docgen, reflex-ui)
31+
tests/units/ # unit tests, mirrors source tree
32+
tests/integration/ # Selenium integration tests (run in dev+prod modes)
33+
tests_playwright/ # Playwright integration tests (preferred for new tests)
34+
tests/benchmarks/ # performance benchmarks
35+
docs/ # documentation site (separate workspace member)
36+
```
37+
38+
## Code style
39+
40+
- Concise, robust code. Reflex is a framework used in many ways — handle edge cases without unnecessary complexity.
41+
- Performance matters. Avoid suboptimal patterns (e.g. iterating a dict to find a value by identity). Suggest restructuring data/APIs if an operation can't be done efficiently.
42+
- Don't add expensive workarounds (e.g. `isinstance` checks) to paper over type-level problems — fix the root cause instead.
43+
- Don't repeat validation or be over-defensive; trust data that was already validated upstream.
44+
- Think in CPU cycles: avoid unnecessary data copies, redundant allocations, and gratuitous indirection.
45+
- Extract duplicated code into parameterized helpers.
46+
- No block comments (`# --- Section ---`, `# ============`). Plain inline comments only.
47+
- Be cautious creating new public APIs — they must be documented and supported long-term.
48+
- Google-style docstrings on all functions: one-line summary, optional detail sentence(s), then Args/Returns (or Yields)/Raises.
49+
50+
## Testing
51+
52+
- Write comprehensive tests for new/changed features; extend existing test files where possible.
53+
- Test functions at module level, not wrapped in classes.
54+
- **Unit tests:** `tests/units/`, run with `uv run pytest tests/units`.
55+
- unit tests should primarily cover a single module, and should be named accordingly, including subdirectories (e.g. `tests/units/istate/test_manager.py` for `reflex/istate/manager.py`). For subpackages, also include the corresponding path below `src/` (e.g. `tests/units/reflex_base/event/test_context.py` for `packages/reflex-base/src/reflex_base/event/context.py`).
56+
- **Integration tests:** prefer Playwright (`tests/integration/tests_playwright/`). Integration tests are slow — extend existing test apps rather than creating new ones for trivial functionality. Multiple test cases sharing one app is fine.
57+
58+
### Integration test patterns
59+
60+
Apps as factory functions, run via `AppHarness`:
61+
62+
```python
63+
def SomeApp():
64+
import reflex as rx
65+
class State(rx.State):
66+
value: str = ""
67+
def index():
68+
return rx.box(rx.text(State.value))
69+
app = rx.App()
70+
app.add_page(index)
71+
72+
@pytest.fixture(scope="module")
73+
def some_app(tmp_path_factory) -> Generator[AppHarness, None, None]:
74+
with AppHarness.create(root=tmp_path_factory.mktemp("some_app"), app_source=SomeApp) as harness:
75+
yield harness
76+
```
77+
78+
Playwright tests use the `page` fixture and navigate to `harness.frontend_url`. Utilities in `tests/integration/utils.py` (polling, event ordering, storage).
79+
80+
## .pyi stubs
81+
82+
When adding/modifying components: `uv run python scripts/make_pyi.py`. Commit `pyi_hashes.json` (not `.pyi` files). If the diff removes many modules, run `uv sync`, delete `.pyi_generator_last_run`, and regenerate.
83+
84+
## Breaking changes and deprecation
85+
86+
Reflex has downstream users — don't break them. Provide a fallback path during deprecation.
87+
88+
**Runtime warning** via `console.deprecate()`:
89+
```python
90+
from reflex_base.utils import console
91+
console.deprecate(
92+
feature_name="OldFeature",
93+
reason="Use NewFeature instead.",
94+
deprecation_version="<next dot version of latest git tag>",
95+
removal_version="1.0",
96+
)
97+
```
98+
Set `deprecation_version` to the next dot version of the latest tag (`git fetch --tags` if needed, e.g. tag `v0.7.3` -> `"0.7.4"`). Set `removal_version` to next major unless directed otherwise.
99+
100+
**Type-level deprecation** for deprecated methods/overloads using `typing_extensions.deprecated`, always inside a `TYPE_CHECKING` guard to avoid double warnings:
101+
```python
102+
from __future__ import annotations
103+
from typing import TYPE_CHECKING
104+
if TYPE_CHECKING:
105+
from typing_extensions import deprecated
106+
@deprecated("Use new_method() instead")
107+
def old_method(self) -> str: ...
108+
```
109+
110+
## Checklist
111+
112+
Before submitting:
113+
1. Tests pass with adequate coverage
114+
2. `uv run ruff check .` and `uv run ruff format .` clean
115+
3. `uv run pyright reflex tests` passes
116+
4. `pyi_hashes.json` updated if components changed
117+
5. Documentation updated if user-facing behavior changed
118+
6. Deprecation warnings added if breaking changes introduced

CLAUDE.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
AGENTS.md

CONTRIBUTING.md

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,18 +65,17 @@ Once you solve a current issue or improvement to Reflex, you can make a PR, and
6565
Before submitting, a pull request, ensure the following steps are taken and test passing.
6666

6767
In your `reflex` directory run make sure all the unit tests are still passing using the following command.
68-
This will fail if code coverage is below 70%.
68+
This will fail if code coverage is below 72%.
6969

7070
```bash
7171
uv run pytest tests/units --cov --no-cov-on-fail --cov-report=
7272
```
7373

74-
Next make sure all the following tests pass. This ensures that every new change has proper documentation and type checking.
74+
Next make sure all the following tests pass. This ensures that every new change has proper type checking.
7575

7676
```bash
7777
uv run ruff check .
7878
uv run pyright reflex tests
79-
find reflex tests -name "*.py" -not -path reflex/reflex.py | xargs uv run darglint
8079
```
8180

8281
Finally, run `ruff` to format your code.
@@ -85,14 +84,26 @@ Finally, run `ruff` to format your code.
8584
uv run ruff format .
8685
```
8786

88-
Consider installing git pre-commit hooks so Ruff, Pyright, Darglint and `make_pyi` will run automatically before each commit.
87+
Consider installing git pre-commit hooks so Ruff, Pyright, and `make_pyi` will run automatically before each commit.
8988

9089
```bash
9190
uv run pre-commit install
9291
```
9392

9493
That's it you can now submit your PR. Thanks for contributing to Reflex!
9594

95+
## 🤖 AI-Assisted PRs
96+
97+
We welcome AI-assisted contributions, but they must meet the same quality bar as any other PR.
98+
99+
- **A human developer must be responsible for the PR contents and review process.** Bot account PRs are subject to prejudicial closure.
100+
- Ensure pre-commit hooks and unit tests pass before submitting.
101+
- Review the patch locally with an "adversarial" prompt before opening the PR.
102+
- Apply fixes for reasonable feedback from Greptile and/or Copilot review bots.
103+
- Resolve or dismiss irrelevant bot feedback with a brief explanation.
104+
- All added/changed lines MUST have unit or integration test coverage with _real_ assertions. No untested code, no bogus test code.
105+
- PRs with merge conflicts or failing tests will not be reviewed or merged. The maintainers do not spend time on PRs that are not in a ready state. If you need attention on a PR that is not ready, mention the maintainers in a comment.
106+
96107
## Editing Templates
97108

98109
To edit the templates in Reflex you can do so in two way.

0 commit comments

Comments
 (0)