Agent rules for the pyRevit repository.
See docs/repo-organization.md.
pyRevit is a Rapid Application Development (RAD) environment for Autodesk Revit. It lets users write automation tools in Python (IronPython 2.7.12 default, CPython 3.12.3, or IronPython 3.4.2), C#, or VB.NET. The project also ships a CLI utility for deployment and a telemetry server for usage tracking.
See docs/architecture.md (also links to docs/extensions.md).
- Revit 2021–2024: .NET Framework 4.8.
- Revit 2025–2026: .NET 8.0 /.NET 10
- Revit 2027+: .NET 10.0
- Python: IronPython 2.7.12 (default), CPython 3.12.3, IronPython 3.4.2.
- C#: .NET Framework 4.8, .NET 8.0, or .NET 10.0, depending on Revit version — see Supported Revit versions.
- Go: pyRevit autocomplete application (
dev/pyRevitLabs/pyRevitCLIAutoComplete). - Build tools: .NET 10, ModularPipelines, Visual Studio 2022, MSBuild, Inno Setup.
The build is driven by the C# ModularPipelines project under build/. To verify a change builds, run from build/:
# Default unsigned local build (Channel=none)
dotnet run -c Release -- ci
# Debug build (attach the Visual Studio debugger to revit.exe)
dotnet run -c Debug -- ciThe wip/release channel stamping (Build__Channel env var) and the other pipeline modes (pack, sign, publish, winget, notify) are CI-owned — don't invoke them locally. See build/README.md for details.
- Developer Docs (Notion)
- Technical docs source:
docs/(mkdocs). Reference API is generated from source docstrings.
Build and validate before finishing doc changes:
mkdocs build --strict # Build docs, fail on warnings
pipenv run check-docstrings # Lint docstrings with ruffTo test in Revit:
pyrevit clones add dev <path-to-repo>
pyrevit attach dev default --installeddevelopbranch: active development — branch from here, PR back into it.masterbranch: release material only.docsbranch: documentation website, published by CI — don't push to it directly.
- Branch from
develop. - Initialize submodules:
git submodule update --init --recursive(also after switching branches). - Install dependencies:
pipenv install --dev. - Install the pre-commit hooks:
pipenv run pre-commit install(orpipenv run install-hooks). - Build:
cd build && dotnet run -c Debug -- ci && cd ... - Test in Revit by attaching the clone — see Testing.
Pipfile— Python dependencies (requires Python 3.14).pyRevitfile— Engine definitions and deployment profiles..pre-commit-config.yaml— commit-timeruff format(Python) anddotnet format(C#) hooks; see Code style..editorconfig— the C# formatting conventionsdotnet formatenforces.
- Python: Google docstring convention.
ruff formatruns automatically on commit via a pre-commit hook for any staged Python file in the repo, except paths excluded by the hook (notablysite-packages/,pyrevitlib/rpw/, anddev/modules/); it will reformat and fail the commit for review if it changes anything — install it once withpipenv run pre-commit install. Also runpipenv run ruff check --fix <path>to lint before finishing; that part isn't hook-enforced. - C#: matches each area's existing brace convention (see
.editorconfig: same-line/K&R everywhere except thepyRevitAssemblyBuilder/pyRevitExtensionParser/pyRevitExtensionParserTestertrio underdev/pyRevitLoader/, which use Allman).dotnet formatruns automatically on commit via the same pre-commit hook for any staged.csfile (vendoreddev/modules/excluded) and will reformat and fail the commit for review if it changes anything.
Don't write inline comments. Ever. Code must be self-explanatory — if it isn't, improve names or extract a well-named function instead of explaining it in a comment. Keep pre-existing comments unless they're clearly outdated.
Exceptions:
- Pragmas required by tooling or the language:
# noqa,# type: ignore,# pylint: disable=…,# coding: utf-8, shebang lines, encoding markers, license headers. TODO/FIXME/XXXwith an owner and ticket reference.
Principle: document information that is expensive to rediscover from code. Do not document information that is obvious from the name, types, or one line of code. Sparse, high-value docstrings beat padded ones — duplicated information goes stale and misleads the next refactor.
Code tells the agent how. Docstrings tell it what, why, and what must remain true.
Information lives in the narrowest scope that carries it:
| Scope | Carries |
|---|---|
AGENTS.md |
Conventions, commands every agent needs |
| Module docstring | Why this subsystem exists; its boundaries |
| Class docstring | Responsibilities, lifecycle, invariants |
| Function / method docstring | Contract, side effects, exceptions, non-obvious constraints |
| Inline comment | Pragmas and TODO/FIXME/XXX only — see Commenting guidelines |
When applicable, capture:
- Purpose — what abstraction or business operation this represents.
- Contract — inputs, outputs, important guarantees.
- Side effects — DB writes, network calls, filesystem changes, emitted events.
- Exceptions — especially domain-specific ones and what they mean here.
- Invariants — conditions that must remain true after refactoring.
- Non-obvious constraints — ordering, idempotency, thread safety, transaction boundaries, compatibility requirements.
- Architectural role — how this symbol relates to the rest of the system (e.g. "Payment providers must not modify subscriptions directly").
Mark dangerous-to-break constraints explicitly with Google-style sections: Important:, Note:, Warning:, Invariant:. Treat them as red lines for the next editor.
- Restating the signature, name, or types.
- Narrating the implementation (
"""Loop through items and add item.price to total."""). - Padding trivial functions — if behaviour is obvious from the code, omit the docstring entirely.
- Python: Google-style docstrings on public symbols (non-underscored).
- C#: XML
///doc comments on public classes and methods.<summary>carries purpose;<param>/<returns>/<exception>cover non-obvious details only. - Private (underscored Python,
private/internalC#) members are exempt.
When behaviour changes, update the docstring / XML doc in the same change.