Skip to content

Commit bde41ea

Browse files
committed
ai(rules[AGENTS]) Add AGENTS.md
1 parent 67dc8f1 commit bde41ea

File tree

1 file changed

+333
-0
lines changed

1 file changed

+333
-0
lines changed

AGENTS.md

Lines changed: 333 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,333 @@
1+
# AGENTS.md
2+
3+
This file provides guidance to AI agents (including Claude Code, Cursor, and other LLM-powered tools) when working with code in this repository.
4+
5+
## CRITICAL REQUIREMENTS
6+
7+
### Test Success
8+
- ALL tests MUST pass for code to be considered complete and working
9+
- Never describe code as "working as expected" if there are ANY failing tests
10+
- Even if specific feature tests pass, failing tests elsewhere indicate broken functionality
11+
- Changes that break existing tests must be fixed before considering implementation complete
12+
- A successful implementation must pass linting, type checking, AND all existing tests
13+
14+
## Project Overview
15+
16+
libtmux is a typed Python library that provides an Object-Relational Mapping (ORM) wrapper for interacting programmatically with [tmux](https://github.com/tmux/tmux), a terminal multiplexer.
17+
18+
Key features:
19+
- Manage tmux servers, sessions, windows, and panes programmatically
20+
- Typed Python API with full type hints
21+
- Built on tmux's target and formats system
22+
- Powers [tmuxp](https://github.com/tmux-python/tmuxp), a tmux workspace manager
23+
- Provides pytest fixtures for testing with tmux
24+
25+
## Development Environment
26+
27+
This project uses:
28+
- Python 3.10+
29+
- [uv](https://github.com/astral-sh/uv) for dependency management
30+
- [ruff](https://github.com/astral-sh/ruff) for linting and formatting
31+
- [mypy](https://github.com/python/mypy) for type checking
32+
- [pytest](https://docs.pytest.org/) for testing
33+
- [pytest-watcher](https://github.com/olzhasar/pytest-watcher) for continuous testing
34+
35+
## Common Commands
36+
37+
### Setting Up Environment
38+
39+
```bash
40+
# Install dependencies
41+
uv pip install --editable .
42+
uv pip sync
43+
44+
# Install with development dependencies
45+
uv pip install --editable . -G dev
46+
```
47+
48+
### Running Tests
49+
50+
```bash
51+
# Run all tests
52+
make test
53+
# or directly with pytest
54+
uv run pytest
55+
56+
# Run a single test file
57+
uv run pytest tests/test_pane.py
58+
59+
# Run a specific test
60+
uv run pytest tests/test_pane.py::test_send_keys
61+
62+
# Run tests with test watcher
63+
make start
64+
# or
65+
uv run ptw .
66+
67+
# Run tests with doctests
68+
uv run ptw . --now --doctest-modules
69+
```
70+
71+
### Linting and Type Checking
72+
73+
```bash
74+
# Run ruff for linting
75+
make ruff
76+
# or directly
77+
uv run ruff check .
78+
79+
# Format code with ruff
80+
make ruff_format
81+
# or directly
82+
uv run ruff format .
83+
84+
# Run ruff linting with auto-fixes
85+
uv run ruff check . --fix --show-fixes
86+
87+
# Run mypy for type checking
88+
make mypy
89+
# or directly
90+
uv run mypy src tests
91+
92+
# Watch mode for linting (using entr)
93+
make watch_ruff
94+
make watch_mypy
95+
```
96+
97+
### Development Workflow
98+
99+
Follow this workflow for code changes (see `.cursor/rules/dev-loop.mdc`):
100+
101+
1. **Format First**: `uv run ruff format .`
102+
2. **Run Tests**: `uv run pytest`
103+
3. **Run Linting**: `uv run ruff check . --fix --show-fixes`
104+
4. **Check Types**: `uv run mypy`
105+
5. **Verify Tests Again**: `uv run pytest`
106+
107+
### Documentation
108+
109+
```bash
110+
# Build documentation
111+
make build_docs
112+
113+
# Start documentation server with auto-reload
114+
make start_docs
115+
116+
# Update documentation CSS/JS
117+
make design_docs
118+
```
119+
120+
## Code Architecture
121+
122+
libtmux follows an object-oriented design that mirrors tmux's hierarchy:
123+
124+
```
125+
Server (tmux server instance)
126+
└─ Session (tmux session)
127+
└─ Window (tmux window)
128+
└─ Pane (tmux pane)
129+
```
130+
131+
### Core Modules
132+
133+
1. **Server** (`src/libtmux/server.py`)
134+
- Represents a tmux server instance
135+
- Manages sessions
136+
- Executes tmux commands via `tmux()` method
137+
- Entry point for most libtmux interactions
138+
139+
2. **Session** (`src/libtmux/session.py`)
140+
- Represents a tmux session
141+
- Manages windows within the session
142+
- Provides session-level operations (attach, kill, rename, etc.)
143+
144+
3. **Window** (`src/libtmux/window.py`)
145+
- Represents a tmux window
146+
- Manages panes within the window
147+
- Provides window-level operations (split, rename, move, etc.)
148+
149+
4. **Pane** (`src/libtmux/pane.py`)
150+
- Represents a tmux pane (terminal instance)
151+
- Provides pane-level operations (send-keys, capture, resize, etc.)
152+
- Core unit for command execution and output capture
153+
154+
5. **Common** (`src/libtmux/common.py`)
155+
- Base classes and shared functionality
156+
- `TmuxRelationalObject` and `TmuxMappingObject` base classes
157+
- Format handling and command execution
158+
159+
6. **Formats** (`src/libtmux/formats.py`)
160+
- Tmux format string constants
161+
- Used for querying tmux state
162+
163+
7. **Neo** (`src/libtmux/neo.py`)
164+
- Modern query interface and dataclass-based objects
165+
- Alternative to traditional ORM-style objects
166+
167+
8. **pytest Plugin** (`src/libtmux/pytest_plugin.py`)
168+
- Provides fixtures for testing with tmux
169+
- Creates temporary tmux sessions/windows/panes
170+
171+
## Testing Strategy
172+
173+
libtmux uses pytest for testing with custom fixtures. The pytest plugin (`pytest_plugin.py`) defines fixtures for creating temporary tmux objects for testing. These include:
174+
175+
- `server`: A tmux server instance for testing
176+
- `session`: A tmux session for testing
177+
- `window`: A tmux window for testing
178+
- `pane`: A tmux pane for testing
179+
180+
These fixtures handle setup and teardown automatically, creating isolated test environments.
181+
182+
### Testing Guidelines
183+
184+
1. **Use existing fixtures over mocks** (see `.cursor/rules/dev-loop.mdc`)
185+
- Use fixtures from conftest.py instead of `monkeypatch` and `MagicMock` when available
186+
- For libtmux, use provided fixtures: `server`, `session`, `window`, and `pane`
187+
- Document in test docstrings why standard fixtures weren't used for exceptional cases
188+
189+
2. **Preferred pytest patterns**
190+
- Use `tmp_path` (pathlib.Path) fixture over Python's `tempfile`
191+
- Use `monkeypatch` fixture over `unittest.mock`
192+
193+
3. **Running tests continuously**
194+
- Use pytest-watcher during development: `uv run ptw .`
195+
- For doctests: `uv run ptw . --now --doctest-modules`
196+
197+
### Example Fixture Usage
198+
199+
```python
200+
def test_window_rename(window):
201+
"""Test renaming a window."""
202+
# window is already a Window instance with a live tmux window
203+
window.rename_window('new_name')
204+
assert window.window_name == 'new_name'
205+
```
206+
207+
## Coding Standards
208+
209+
For detailed coding standards, refer to `.cursor/rules/dev-loop.mdc`. Key highlights:
210+
211+
### Imports
212+
213+
- **Use namespace imports**: `import enum` instead of `from enum import Enum`
214+
- **For typing**, use `import typing as t` and access via namespace: `t.NamedTuple`, etc.
215+
- **Use `from __future__ import annotations`** at the top of all Python files
216+
217+
### Docstrings
218+
219+
Follow NumPy docstring style for all functions and methods (see `.cursor/rules/dev-loop.mdc`):
220+
221+
```python
222+
"""Short description of the function or class.
223+
224+
Detailed description using reStructuredText format.
225+
226+
Parameters
227+
----------
228+
param1 : type
229+
Description of param1
230+
param2 : type
231+
Description of param2
232+
233+
Returns
234+
-------
235+
type
236+
Description of return value
237+
"""
238+
```
239+
240+
### Doctest Guidelines
241+
242+
1. **Use narrative descriptions** for test sections rather than inline comments
243+
2. **Move complex examples** to dedicated test files at `tests/examples/<path_to_module>/test_<example>.py`
244+
3. **Keep doctests simple and focused** on demonstrating usage
245+
4. **Add blank lines between test sections** for improved readability
246+
247+
### Git Commit Standards
248+
249+
See `.cursor/rules/git-commits.mdc` for detailed commit message standards.
250+
251+
Format commit messages as:
252+
```
253+
Component/File(commit-type[Subcomponent/method]): Concise description
254+
255+
why: Explanation of necessity or impact.
256+
what:
257+
- Specific technical changes made
258+
- Focused on a single topic
259+
```
260+
261+
Common commit types:
262+
- **feat**: New features or enhancements
263+
- **fix**: Bug fixes
264+
- **refactor**: Code restructuring without functional change
265+
- **docs**: Documentation updates
266+
- **chore**: Maintenance (dependencies, tooling, config)
267+
- **test**: Test-related updates
268+
- **style**: Code style and formatting
269+
- **py(deps)**: Dependencies
270+
- **py(deps[dev])**: Dev Dependencies
271+
- **ai(rules[LLM type])**: AI Rule Updates
272+
273+
Example:
274+
```
275+
Pane(feat[send_keys]): Add support for literal flag
276+
277+
why: Enable sending literal characters without tmux interpretation
278+
what:
279+
- Add literal parameter to send_keys method
280+
- Update send_keys to pass -l flag when literal=True
281+
- Add tests for literal key sending
282+
```
283+
284+
## Debugging Tips
285+
286+
See `.cursor/rules/avoid-debug-loops.mdc` for detailed debugging guidance.
287+
288+
When stuck in debugging loops:
289+
290+
1. **Pause and acknowledge the loop**
291+
2. **Minimize to MVP**: Remove all debugging cruft and experimental code
292+
3. **Document the issue** comprehensively for a fresh approach
293+
4. **Format for portability** (using quadruple backticks)
294+
295+
## tmux-Specific Considerations
296+
297+
### tmux Command Execution
298+
299+
- All tmux commands go through the `cmd()` method on Server/Session/Window/Pane objects
300+
- Commands return a `CommandResult` object with `stdout` and `stderr`
301+
- Use tmux format strings to query object state (see `formats.py`)
302+
303+
### Format Strings
304+
305+
libtmux uses tmux's format system extensively:
306+
- Defined in `src/libtmux/formats.py`
307+
- Used to query session_id, window_id, pane_id, etc.
308+
- Format: `#{format_name}` (e.g., `#{session_id}`, `#{window_name}`)
309+
310+
### Object Refresh
311+
312+
- Objects can become stale if tmux state changes externally
313+
- Use refresh methods (e.g., `session.refresh()`) to update object state
314+
- Alternative: use `neo.py` query interface for fresh data
315+
316+
## References
317+
318+
- Documentation: https://libtmux.git-pull.com/
319+
- API Reference: https://libtmux.git-pull.com/api.html
320+
- Architecture: https://libtmux.git-pull.com/about.html
321+
- tmux man page: http://man.openbsd.org/OpenBSD-current/man1/tmux.1
322+
- tmuxp (workspace manager): https://tmuxp.git-pull.com/
323+
324+
## Cursor Rules Reference
325+
326+
This project uses Cursor rules (`.cursor/rules/*.mdc`) to provide context-specific guidance:
327+
328+
- **dev-loop.mdc**: Development workflow and QA process
329+
- **git-commits.mdc**: Git commit message standards
330+
- **avoid-debug-loops.mdc**: Debugging best practices
331+
- **notes-llms-txt.mdc**: LLM-optimized markdown format for notes
332+
333+
These rules are automatically applied based on file patterns and provide additional guidance to AI assistants.

0 commit comments

Comments
 (0)