diff --git a/AGENTS.md b/AGENTS.md deleted file mode 100644 index 93fad2a..0000000 --- a/AGENTS.md +++ /dev/null @@ -1,236 +0,0 @@ -# AGENTS.md - Development Guidelines for Newton - -## Overview - -Newton is a Python/Gtk3 desktop application (code editor) using PyGObject. The project follows specific conventions documented below. - ---- - -## Build, Lint, and Test Commands - -### Running the Application - -```bash -# Activate virtual environment and run -source .venv/bin/activate -python -m src -``` - -### Type Checking (Pyright) - -The project uses pyright for static type checking. Configuration is in `pyrightconfig.json`: - -```bash -# Run pyright (ensure venv is activated) -pyright src/ - -# Or via Python module -python -m pyright src/ -``` - -**pyrightconfig.json settings:** -- `venvPath`: "." -- `venv`: ".venv" -- Reports: unused variables, unused imports, duplicate imports - -### No Test Framework - -**There are currently no tests in this codebase.** If tests are added: -- Use pytest as the testing framework -- Test files should be in a `tests/` directory -- Run a single test: `pytest tests/test_file.py::test_function_name` - ---- - -## Code Style Guidelines - -### Import Organization - -Imports must be organized with blank lines between groups (in this exact order): - -```python -# Python imports -import os -import logging - -# Lib imports -import gi -gi.require_version('Gtk', '3.0') - -from gi.repository import Gtk -from gi.repository import GLib - -# Application imports -from libs.dto.states import SourceViewStates -from .mixins.source_view_dnd_mixin import SourceViewDnDMixin -``` - -### Type Hints - -- Use type hints for all function parameters and return types -- Use Python's built-in types (`list[str]`, `dict[str, int]`) not typing module aliases -- Example: `def message_to(self, name: str, event: BaseEvent):` - -### Naming Conventions - -| Element | Convention | Example | -|---------|------------|---------| -| Classes | PascalCase | `ControllerBase`, `SourceView` | -| Methods/Variables | snake_case | `set_controller_context`, `_cut_buffer` | -| Private methods | Leading underscore | `_setup_styles`, `_subscribe_to_events` | -| Constants | UPPER_SNAKE_CASE | `LOG_LEVEL`, `DEFAULT_ZOOM` | -| Exception classes | PascalCase ending in Exception | `ControllerBaseException` | - -### Class Structure - -```python -class MyClass(Singleton, EmitDispatcher): - def __init__(self): - super(MyClass, self).__init__() - - self.controller_context: ControllerContext = None - self._private_var = None - - def public_method(self, param: str) -> None: - ... - - def _private_method(self) -> None: - ... -``` - -### Placeholder Methods - -Use ellipsis `...` for unimplemented methods or abstract-like methods: - -```python -def _subscribe_to_events(self): - ... -``` - -### Dataclasses for DTOs/Events - -Use `@dataclass` for data transfer objects and events: - -```python -from dataclasses import dataclass, field - -@dataclass -class TextInsertedEvent(CodeEvent): - location: Gtk.TextIter = None - text: str = "" - length: int = 0 -``` - -### Error Handling - -- Custom exceptions should end with `Exception` -- Use `raise ValueError("message")` for validation errors -- Let exceptions propagate for unexpected errors - -### Singleton Pattern - -Classes requiring singleton behavior should inherit from `Singleton`: - -```python -from libs.singleton import Singleton - -class MySingleton(Singleton): - ... -``` - -### GTK/Widget Conventions - -- Call `_setup_styles()`, `_setup_signals()`, `_subscribe_to_events()`, `_load_widgets()` in `__init__` -- Use `self.connect("signal-name", self._handler)` for GTK signals -- Private GTK attributes use underscore prefix: `self._cut_temp_timeout_id` - -### Code Formatting - -- Use spaces around operators: `x = value`, not `x=value` -- Align assignments with spaces for related variables: - ```python - self.state = state - self._cut_temp_timeout_id = None - ``` -- Maximum line length: Let pyright/editor handle warnings (typically 80-120 chars) - -### No Comments - -DO NOT add comments to code unless explicitly required. Write self-documenting code. - ---- - -## Project Structure - -``` -Newton/ -├── src/ -│ ├── app.py # Main application entry -│ ├── __main__.py # Module entry point -│ ├── __builtins__.py # Built-in definitions -│ ├── core/ # Core UI components -│ │ ├── containers/ # Layout containers -│ │ ├── controllers/ # Controllers -│ │ └── widgets/ # GTK widgets -│ ├── libs/ # Core libraries -│ │ ├── controllers/ # Controller infrastructure -│ │ ├── db/ # Database (SQLModel) -│ │ ├── dto/ # Data transfer objects -│ │ ├── mixins/ # Mixin classes -│ │ └── settings/ # Settings management -│ └── plugins/ # Plugin system -├── plugins/ # Plugin implementations -├── user_config/ # User configuration files -├── requirements.txt # Python dependencies -└── pyrightconfig.json # Pyright configuration -``` - ---- - -## Key Libraries Used - -- **PyGObject** (GTK3) - GUI framework -- **sqlmodel** - Database (SQLAlchemy + Pydantic) -- **setproctitle** - Process title management -- **pyxdg** - XDG desktop file parsing - ---- - -## Common Patterns - -### Creating a New Controller - -```python -from libs.controllers.controller_base import ControllerBase -from libs.controllers.controller_context import ControllerContext - -class MyController(ControllerBase): - def __init__(self): - super().__init__() - self.controller_context = None - - def _controller_message(self, event: BaseEvent): - # Handle events - pass -``` - -### Creating a New Event/DTO - -```python -from dataclasses import dataclass -from libs.dto.code.code_event import CodeEvent - -@dataclass -class MyEvent(CodeEvent): - field1: str = "" - field2: int = 0 -``` - -### Connecting to Events - -```python -from libs.event_system import EventSystem - -event_system = EventSystem() -event_system.subscribe("event_name", self.my_handler) -```