|
| 1 | +# Repository guidance |
| 2 | + |
| 3 | +## Development and verification |
| 4 | + |
| 5 | +- Python minimum is 3.13; CI tests 3.13 and 3.14 on Linux/macOS. Use `uv`; |
| 6 | + `uv sync --extra telemetry` includes the optional dependencies exercised in CI. |
| 7 | +- Run checks from the repo root, in CI order: |
| 8 | + ```sh |
| 9 | + uv run ruff check |
| 10 | + uv run ruff format --check |
| 11 | + uv run python -m pytest |
| 12 | + ``` |
| 13 | +- Focused test: `uv run python -m pytest tests/test_agent_builder.py`; append |
| 14 | + `::test_read_only_mode_denies_writes` to run one case. |
| 15 | +- CLI startup requires `fd`, `rg`, and `rtk` on PATH. Debian's `fd-find` installs |
| 16 | + `fdfind`, so expose it as `fd`. Search tests skip without their binaries; |
| 17 | + CI supplies an RTK pass-through shim, not real compaction coverage. |
| 18 | +- `.pre-commit-config.yaml` runs Ruff checks and formatting on commit, the full |
| 19 | + pytest suite on pre-push. The formatting hook modifies files. |
| 20 | + |
| 21 | +## Runtime boundaries |
| 22 | + |
| 23 | +- `src/lecode/cli.py` dispatches interactive, headless, loop, and chain modes. |
| 24 | + They share `agent/builder.py:build_runtime()` for wiring and |
| 25 | + `agent/runner.py:AgentRunner` for the model/tool loop. Keep builder wiring |
| 26 | + network-free; interactive catalog/MCP startup is deferred until chat opens. |
| 27 | +- Route tool execution through `agent/tools/base.py:ToolRegistry.dispatch_result()`: |
| 28 | + it validates arguments and enforces permissions/approval. Auto-approval never |
| 29 | + overrides Deny; hooks and agent overlays can only narrow permissions. |
| 30 | +- TUI changes must preserve normal terminal scrollback, not an alternate-screen UI. |
| 31 | + `tui/feed.py` keeps live tokens in the layout and flushes completed text to |
| 32 | + scrollback; partial-line printing through `patch_stdout` can erase streaming output. |
| 33 | + Check `tests/test_tui_feed.py`, `tests/test_tui_app.py`, and |
| 34 | + `tests/test_tui_streaming_pty.py` for rendering changes. |
| 35 | +- `session/storage.py` stores append-only JSONL. Replay through `load_for_model()` |
| 36 | + so compaction, clear events, and undo tombstones apply. Keep lock sidecars on |
| 37 | + release: unlinking them allows competing processes to lock different inodes. |
| 38 | + |
| 39 | +## Isolation and sources of truth |
| 40 | + |
| 41 | +- `config/loader.py:load_config()` creates defaults and rewrites migrated config. |
| 42 | + Tests constructing runtimes/config/session stores should isolate |
| 43 | + `LECODE_CONFIG_DIR`, `LECODE_SKILLS_DIR`, and project cwd under `tmp_path`. |
| 44 | + The shared `tool_ctx` fixture is not autouse and isolates only the config directory. |
| 45 | +- Reuse `tests/fakes.py` for providers/catalogs. MCP tests launch mock subprocesses |
| 46 | + and localhost servers; disable auto servers as in `tests/test_mcp.py:mcp_config` |
| 47 | + to avoid ambient credentials activating Exa. Keep the SSE shutdown reset in |
| 48 | + `tests/conftest.py`; it prevents order-dependent failures across server tests. |
| 49 | +- `docs/build-plan.md` is historical, not the current spec: permissions now have |
| 50 | + two modes, config is TOML-only, and the catalog is live with an empty fallback. |
| 51 | + For config or hook changes, consult `docs/configuration.md` or `docs/hooks.md` |
| 52 | + and reconcile with the implementation. |
| 53 | +- Releases use conventional commits and release-please, with wheel/sdist attached |
| 54 | + to GitHub Releases, not PyPI. `.github/workflows/release.yml` separately re-locks |
| 55 | + `uv.lock` after release-please bumps `pyproject.toml`. |
0 commit comments