From d16d4199225fd7c3401b029937d5a0c295266be6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 26 Feb 2026 19:11:47 +0000 Subject: [PATCH 1/4] Initial plan From 50f809b35725cdcf3e6495fc2b2b18eac042c798 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 26 Feb 2026 19:14:43 +0000 Subject: [PATCH 2/4] Add repository-level AI instruction files (AGENTS.md, copilot-instructions.md, CLAUDE.md) Co-authored-by: tomvothecoder <25624127+tomvothecoder@users.noreply.github.com> --- .claude/CLAUDE.md | 58 ++++++++++++++++ .github/copilot-instructions.md | 48 +++++++++++++ AGENTS.md | 117 ++++++++++++++++++++++++++++++++ 3 files changed, 223 insertions(+) create mode 100644 .claude/CLAUDE.md create mode 100644 .github/copilot-instructions.md create mode 100644 AGENTS.md diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md new file mode 100644 index 00000000..7b4ffd8a --- /dev/null +++ b/.claude/CLAUDE.md @@ -0,0 +1,58 @@ +# CLAUDE.md — Claude Code Instructions for xCDAT + + + +## Project + +xCDAT (Xarray Climate Data Analysis Tools) extends xarray for climate data +analysis on structured grids. Python ≥3.11. + +## Coding Rules + +- Format and lint with **Ruff** (config in `pyproject.toml`). Import sorting is + handled by Ruff (`ruff check --select I --fix`). +- Type-check with **MyPy** (`check_untyped_defs = true`). All public APIs must + have type annotations. +- Write **NumPy-style** docstrings with `Parameters`, `Returns`, and `Raises` + sections. +- Use absolute imports (e.g., `from xcdat.axis import get_dim_coords`). +- License: Apache-2.0 with LLVM exception. + +## Architecture + +- Dataset functionality uses **xarray accessors** (`@xr.register_dataset_accessor`): + `BoundsAccessor`, `SpatialAccessor`, `TemporalAccessor`, `RegridderAccessor`. +- Use **cf_xarray** for coordinate discovery — never hardcode dimension names. +- Shared helpers belong in `xcdat/utils.py`. Export new public symbols from + `xcdat/__init__.py`. + +## Testing + +- Use **pytest**. Tests live in `tests/test_.py`. +- Prefer `xarray.testing.assert_identical` / `assert_allclose` for comparisons. +- Construct expected results explicitly and compare against actual output. +- Run: `pytest tests/test_.py` (targeted) or `make test` (full suite). + +## Dependencies + +- Do not add new runtime dependencies without discussion. +- Core: xarray, numpy, cf_xarray, cftime, dask, pandas, scipy, netcdf4, pooch, + regionmask, sparse, python-dateutil. +- Regridding: xesmf, xgcm. + +## Workflow + +- Run `pre-commit run --all-files` before committing. +- Every PR must include tests for new or changed behavior. +- Keep changes minimal and focused. + +## Build Commands + +```bash +make install # install local build +make lint # ruff check + fix +make format # ruff format +make test # full test suite with coverage +pytest tests/test_.py # targeted tests +make docs # build Sphinx documentation +``` diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 00000000..1993a357 --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,48 @@ +# Copilot Instructions for xCDAT + + + + +## Project + +xCDAT (Xarray Climate Data Analysis Tools) extends xarray for climate data +analysis on structured grids. Python ≥3.11. + +## Coding Rules + +- Format and lint with **Ruff** (config in `pyproject.toml`). Import sorting is + handled by Ruff (`ruff check --select I --fix`). +- Type-check with **MyPy** (`check_untyped_defs = true`). All public APIs must + have type annotations. +- Write **NumPy-style** docstrings with `Parameters`, `Returns`, and `Raises` + sections. +- Use absolute imports (e.g., `from xcdat.axis import get_dim_coords`). +- License: Apache-2.0 with LLVM exception. + +## Architecture + +- Dataset functionality uses **xarray accessors** (`@xr.register_dataset_accessor`): + `BoundsAccessor`, `SpatialAccessor`, `TemporalAccessor`, `RegridderAccessor`. +- Use **cf_xarray** for coordinate discovery — never hardcode dimension names. +- Shared helpers belong in `xcdat/utils.py`. Export new public symbols from + `xcdat/__init__.py`. + +## Testing + +- Use **pytest**. Tests live in `tests/test_.py`. +- Prefer `xarray.testing.assert_identical` / `assert_allclose` for comparisons. +- Construct expected results explicitly and compare against actual output. +- Run: `pytest tests/test_.py` (targeted) or `make test` (full suite). + +## Dependencies + +- Do not add new runtime dependencies without discussion. +- Core: xarray, numpy, cf_xarray, cftime, dask, pandas, scipy, netcdf4, pooch, + regionmask, sparse, python-dateutil. +- Regridding: xesmf, xgcm. + +## Workflow + +- Run `pre-commit run --all-files` before committing. +- Every PR must include tests for new or changed behavior. +- Keep changes minimal and focused. diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 00000000..e2ac43c1 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,117 @@ +# AGENTS.md — AI Development Guidelines for xCDAT + +This file is the canonical, tool-agnostic source of AI development rules for the +[xCDAT](https://github.com/xCDAT/xcdat) project. Tool-specific files +(`.github/copilot-instructions.md`, `.claude/CLAUDE.md`) contain concise extracts +aligned with this document. + +## Project Overview + +xCDAT (Xarray Climate Data Analysis Tools) is a Python library that extends +[xarray](https://xarray.dev) for climate data analysis on structured grids. It +provides spatial/temporal averaging, regridding, bounds handling, and dataset +I/O with CF-convention support. The minimum supported Python version is 3.11. + +## Repository Layout + +``` +xcdat/ # Main package source + axis.py # Coordinate axis utilities + bounds.py # BoundsAccessor (xarray accessor) + dataset.py # Dataset I/O (open_dataset, open_mfdataset) + spatial.py # SpatialAccessor for spatial averaging + temporal.py # TemporalAccessor for temporal averaging + mask.py # Masking operations + regridder/ # Regridding subpackage (xESMF, xgcm, regrid2) + utils.py # Shared utility functions + _logger.py # Logger setup + tutorial.py # Sample data utilities +tests/ # Pytest test suite (test_*.py) +docs/ # Sphinx documentation +conda-env/ # Conda environment files +``` + +## Coding Standards + +- **Formatter / Linter**: [Ruff](https://docs.astral.sh/ruff/) — handles + formatting, linting, and import sorting. Configuration is in `pyproject.toml` + under `[tool.ruff]`. +- **Type Checking**: [MyPy](https://mypy-lang.org/) with `check_untyped_defs = true`. + All public APIs must include type annotations. Configuration is in `pyproject.toml` + under `[tool.mypy]`. +- **Docstrings**: Use **NumPy-style** docstrings for all public functions, classes, + and methods. Include `Parameters`, `Returns`, and `Raises` sections as applicable. +- **Imports**: Sort imports with Ruff (`ruff check --select I --fix`). Use absolute + imports within the package (e.g., `from xcdat.axis import get_dim_coords`). +- **Line Length**: No hard limit enforced (E501 is ignored), but aim for readability. +- **Pre-commit**: The project uses pre-commit hooks (`.pre-commit-config.yaml`) that + run Ruff and MyPy automatically on each commit. +- **License**: New contributions must be made under the Apache-2.0 with LLVM exception + license. + +## Architecture + +- **xarray Accessors**: `BoundsAccessor`, `SpatialAccessor`, `TemporalAccessor`, and + `RegridderAccessor` extend `xr.Dataset` via `@xr.register_dataset_accessor`. + Follow this pattern when adding new dataset-level functionality. +- **CF Conventions**: Use `cf_xarray` for coordinate discovery. Always reference axes + by CF standard names or axis attributes, not hardcoded dimension names. +- **Module Responsibility**: Each module has a single clear responsibility. Avoid + circular imports. Shared helpers go in `utils.py`. +- **Public API**: All public symbols are re-exported from `xcdat/__init__.py`. When + adding a new public function or class, add it to `__init__.py`. + +## Testing Conventions + +- **Framework**: [pytest](https://docs.pytest.org/) with `pytest-cov`. +- **File Naming**: Test files live in `tests/` and follow the pattern `test_.py`. +- **Assertions**: Prefer `xarray.testing.assert_identical` and + `xarray.testing.assert_allclose` for comparing xarray objects. +- **Fixtures**: Use pytest fixtures for reusable test data. Construct expected results + explicitly and compare against actual output. +- **Running Tests**: `pytest` (full suite) or `pytest tests/test_.py` (targeted). + Use `make test` for the full suite with coverage. +- **Markers**: `@pytest.mark.flaky` and `@pytest.mark.network` are available for + unstable or network-dependent tests. + +## Dependencies + +- **Core**: xarray (≥2024.03.0), numpy (≥2.0.0, <3.0.0), cf_xarray (≥0.10.7), + cftime, dask, pandas, scipy, netcdf4, pooch (≥1.8), regionmask, sparse, + python-dateutil. +- **Regridding**: xesmf (≥0.8.7), xgcm (≥0.9.0). +- **Dev**: ruff, mypy, pre-commit, types-python-dateutil. +- **Test**: pytest, pytest-cov. +- Do not add new runtime dependencies without discussion. Prefer leveraging existing + dependencies before introducing new ones. + +## Build & Development + +```bash +# Create dev environment +conda env create -f conda-env/dev.yml +conda activate xcdat_dev + +# Install local build +make install # or: python -m pip install . + +# Quality assurance +make lint # ruff check + fix +make format # ruff format +make pre-commit # run all pre-commit hooks + +# Testing +make test # full suite with coverage +pytest tests/test_.py # targeted tests + +# Documentation +make docs # build Sphinx HTML docs +``` + +## Workflow Rules + +- Always run `pre-commit run --all-files` before committing. +- Every PR should include tests for new or changed behavior. +- Do not modify unrelated code or tests. +- Keep changes minimal and focused on the issue being addressed. +- Use meaningful commit messages that summarize the change. From ce87cb48078c53cb3fbddabff6a27940189d8b2f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 26 Feb 2026 19:28:14 +0000 Subject: [PATCH 3/4] Regenerate AI instruction files: remove volatile info, use source-of-truth references Co-authored-by: tomvothecoder <25624127+tomvothecoder@users.noreply.github.com> --- .claude/CLAUDE.md | 13 +++++------ .github/copilot-instructions.md | 13 +++++------ AGENTS.md | 39 +++++++++++++++------------------ 3 files changed, 30 insertions(+), 35 deletions(-) diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md index 7b4ffd8a..a416e2cd 100644 --- a/.claude/CLAUDE.md +++ b/.claude/CLAUDE.md @@ -1,17 +1,18 @@ # CLAUDE.md — Claude Code Instructions for xCDAT - + ## Project xCDAT (Xarray Climate Data Analysis Tools) extends xarray for climate data -analysis on structured grids. Python ≥3.11. +analysis on structured grids. See `pyproject.toml` for the supported Python +version and dependency constraints. ## Coding Rules - Format and lint with **Ruff** (config in `pyproject.toml`). Import sorting is - handled by Ruff (`ruff check --select I --fix`). -- Type-check with **MyPy** (`check_untyped_defs = true`). All public APIs must + handled by Ruff. +- Type-check with **MyPy** (config in `pyproject.toml`). All public APIs must have type annotations. - Write **NumPy-style** docstrings with `Parameters`, `Returns`, and `Raises` sections. @@ -36,9 +37,7 @@ analysis on structured grids. Python ≥3.11. ## Dependencies - Do not add new runtime dependencies without discussion. -- Core: xarray, numpy, cf_xarray, cftime, dask, pandas, scipy, netcdf4, pooch, - regionmask, sparse, python-dateutil. -- Regridding: xesmf, xgcm. +- See `pyproject.toml` for the full dependency list and version constraints. ## Workflow diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 1993a357..e077aefc 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -1,18 +1,19 @@ # Copilot Instructions for xCDAT - + ## Project xCDAT (Xarray Climate Data Analysis Tools) extends xarray for climate data -analysis on structured grids. Python ≥3.11. +analysis on structured grids. See `pyproject.toml` for the supported Python +version and dependency constraints. ## Coding Rules - Format and lint with **Ruff** (config in `pyproject.toml`). Import sorting is - handled by Ruff (`ruff check --select I --fix`). -- Type-check with **MyPy** (`check_untyped_defs = true`). All public APIs must + handled by Ruff. +- Type-check with **MyPy** (config in `pyproject.toml`). All public APIs must have type annotations. - Write **NumPy-style** docstrings with `Parameters`, `Returns`, and `Raises` sections. @@ -37,9 +38,7 @@ analysis on structured grids. Python ≥3.11. ## Dependencies - Do not add new runtime dependencies without discussion. -- Core: xarray, numpy, cf_xarray, cftime, dask, pandas, scipy, netcdf4, pooch, - regionmask, sparse, python-dateutil. -- Regridding: xesmf, xgcm. +- See `pyproject.toml` for the full dependency list and version constraints. ## Workflow diff --git a/AGENTS.md b/AGENTS.md index e2ac43c1..2ab70371 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -10,7 +10,10 @@ aligned with this document. xCDAT (Xarray Climate Data Analysis Tools) is a Python library that extends [xarray](https://xarray.dev) for climate data analysis on structured grids. It provides spatial/temporal averaging, regridding, bounds handling, and dataset -I/O with CF-convention support. The minimum supported Python version is 3.11. +I/O with CF-convention support. + +See `pyproject.toml` for the minimum supported Python version and all dependency +constraints. ## Repository Layout @@ -33,19 +36,16 @@ conda-env/ # Conda environment files ## Coding Standards -- **Formatter / Linter**: [Ruff](https://docs.astral.sh/ruff/) — handles - formatting, linting, and import sorting. Configuration is in `pyproject.toml` - under `[tool.ruff]`. -- **Type Checking**: [MyPy](https://mypy-lang.org/) with `check_untyped_defs = true`. - All public APIs must include type annotations. Configuration is in `pyproject.toml` - under `[tool.mypy]`. +- **Formatter / Linter**: Ruff — handles formatting, linting, and import sorting. + See `pyproject.toml` under `[tool.ruff]` for configuration. +- **Type Checking**: MyPy — all public APIs must include type annotations. + See `pyproject.toml` under `[tool.mypy]` for configuration. - **Docstrings**: Use **NumPy-style** docstrings for all public functions, classes, and methods. Include `Parameters`, `Returns`, and `Raises` sections as applicable. -- **Imports**: Sort imports with Ruff (`ruff check --select I --fix`). Use absolute - imports within the package (e.g., `from xcdat.axis import get_dim_coords`). -- **Line Length**: No hard limit enforced (E501 is ignored), but aim for readability. -- **Pre-commit**: The project uses pre-commit hooks (`.pre-commit-config.yaml`) that - run Ruff and MyPy automatically on each commit. +- **Imports**: Use absolute imports within the package + (e.g., `from xcdat.axis import get_dim_coords`). Import sorting is handled by Ruff. +- **Pre-commit**: The project uses pre-commit hooks. See `.pre-commit-config.yaml` + for the configured checks (Ruff, MyPy, whitespace, etc.). - **License**: New contributions must be made under the Apache-2.0 with LLVM exception license. @@ -63,7 +63,8 @@ conda-env/ # Conda environment files ## Testing Conventions -- **Framework**: [pytest](https://docs.pytest.org/) with `pytest-cov`. +- **Framework**: pytest with pytest-cov. See `pyproject.toml` under + `[tool.pytest.ini_options]` for configuration. - **File Naming**: Test files live in `tests/` and follow the pattern `test_.py`. - **Assertions**: Prefer `xarray.testing.assert_identical` and `xarray.testing.assert_allclose` for comparing xarray objects. @@ -71,17 +72,13 @@ conda-env/ # Conda environment files explicitly and compare against actual output. - **Running Tests**: `pytest` (full suite) or `pytest tests/test_.py` (targeted). Use `make test` for the full suite with coverage. -- **Markers**: `@pytest.mark.flaky` and `@pytest.mark.network` are available for - unstable or network-dependent tests. ## Dependencies -- **Core**: xarray (≥2024.03.0), numpy (≥2.0.0, <3.0.0), cf_xarray (≥0.10.7), - cftime, dask, pandas, scipy, netcdf4, pooch (≥1.8), regionmask, sparse, - python-dateutil. -- **Regridding**: xesmf (≥0.8.7), xgcm (≥0.9.0). -- **Dev**: ruff, mypy, pre-commit, types-python-dateutil. -- **Test**: pytest, pytest-cov. +- See `pyproject.toml` under `[project.dependencies]` for runtime dependencies and + version constraints. +- See `pyproject.toml` under `[project.optional-dependencies]` for dev, test, and + docs dependencies. - Do not add new runtime dependencies without discussion. Prefer leveraging existing dependencies before introducing new ones. From da3669f391a406ca328da197c752f647642c5b47 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 4 Mar 2026 22:29:33 +0000 Subject: [PATCH 4/4] Refactor tool-specific files into thin adapters deferring to AGENTS.md Co-authored-by: tomvothecoder <25624127+tomvothecoder@users.noreply.github.com> --- .claude/CLAUDE.md | 53 +++++++-------------------------- .github/copilot-instructions.md | 52 ++++++++------------------------ 2 files changed, 23 insertions(+), 82 deletions(-) diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md index a416e2cd..6861a3fe 100644 --- a/.claude/CLAUDE.md +++ b/.claude/CLAUDE.md @@ -1,51 +1,20 @@ # CLAUDE.md — Claude Code Instructions for xCDAT - +## Canonical Reference -## Project +All coding standards, architecture constraints, testing conventions, and +dependency policies are defined in **`AGENTS.md`** at the repository root. +Apply those rules to all generated code and suggestions. -xCDAT (Xarray Climate Data Analysis Tools) extends xarray for climate data -analysis on structured grids. See `pyproject.toml` for the supported Python -version and dependency constraints. +## Claude-Specific Behavior -## Coding Rules +- Read `AGENTS.md` at the start of each session for full project context. +- Ground all suggestions in the actual repository structure and existing code. +- Do not invent files, modules, or configuration not present in the repository. +- When uncertain about project conventions, consult `AGENTS.md`, `pyproject.toml`, + or `.pre-commit-config.yaml`. -- Format and lint with **Ruff** (config in `pyproject.toml`). Import sorting is - handled by Ruff. -- Type-check with **MyPy** (config in `pyproject.toml`). All public APIs must - have type annotations. -- Write **NumPy-style** docstrings with `Parameters`, `Returns`, and `Raises` - sections. -- Use absolute imports (e.g., `from xcdat.axis import get_dim_coords`). -- License: Apache-2.0 with LLVM exception. - -## Architecture - -- Dataset functionality uses **xarray accessors** (`@xr.register_dataset_accessor`): - `BoundsAccessor`, `SpatialAccessor`, `TemporalAccessor`, `RegridderAccessor`. -- Use **cf_xarray** for coordinate discovery — never hardcode dimension names. -- Shared helpers belong in `xcdat/utils.py`. Export new public symbols from - `xcdat/__init__.py`. - -## Testing - -- Use **pytest**. Tests live in `tests/test_.py`. -- Prefer `xarray.testing.assert_identical` / `assert_allclose` for comparisons. -- Construct expected results explicitly and compare against actual output. -- Run: `pytest tests/test_.py` (targeted) or `make test` (full suite). - -## Dependencies - -- Do not add new runtime dependencies without discussion. -- See `pyproject.toml` for the full dependency list and version constraints. - -## Workflow - -- Run `pre-commit run --all-files` before committing. -- Every PR must include tests for new or changed behavior. -- Keep changes minimal and focused. - -## Build Commands +## Quick Reference — Build Commands ```bash make install # install local build diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index e077aefc..447914ac 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -1,47 +1,19 @@ # Copilot Instructions for xCDAT - -## Project +## Canonical Reference -xCDAT (Xarray Climate Data Analysis Tools) extends xarray for climate data -analysis on structured grids. See `pyproject.toml` for the supported Python -version and dependency constraints. +All coding standards, architecture constraints, testing conventions, and +dependency policies are defined in **`AGENTS.md`** at the repository root. +Apply those rules to every response in this workspace. -## Coding Rules +## Copilot-Specific Behavior -- Format and lint with **Ruff** (config in `pyproject.toml`). Import sorting is - handled by Ruff. -- Type-check with **MyPy** (config in `pyproject.toml`). All public APIs must - have type annotations. -- Write **NumPy-style** docstrings with `Parameters`, `Returns`, and `Raises` - sections. -- Use absolute imports (e.g., `from xcdat.axis import get_dim_coords`). -- License: Apache-2.0 with LLVM exception. - -## Architecture - -- Dataset functionality uses **xarray accessors** (`@xr.register_dataset_accessor`): - `BoundsAccessor`, `SpatialAccessor`, `TemporalAccessor`, `RegridderAccessor`. -- Use **cf_xarray** for coordinate discovery — never hardcode dimension names. -- Shared helpers belong in `xcdat/utils.py`. Export new public symbols from - `xcdat/__init__.py`. - -## Testing - -- Use **pytest**. Tests live in `tests/test_.py`. -- Prefer `xarray.testing.assert_identical` / `assert_allclose` for comparisons. -- Construct expected results explicitly and compare against actual output. -- Run: `pytest tests/test_.py` (targeted) or `make test` (full suite). - -## Dependencies - -- Do not add new runtime dependencies without discussion. -- See `pyproject.toml` for the full dependency list and version constraints. - -## Workflow - -- Run `pre-commit run --all-files` before committing. -- Every PR must include tests for new or changed behavior. -- Keep changes minimal and focused. +- Always ground suggestions in the actual repository structure and existing code. +- Do not hallucinate files, modules, or configuration that are not present in the + repository. +- Prefer patterns already established in the codebase over speculative alternatives. +- Do not generate code that violates the rules in `AGENTS.md`. +- When uncertain about project conventions, consult `AGENTS.md`, `pyproject.toml`, + or `.pre-commit-config.yaml` rather than guessing.