Skip to content

Commit 21aabb2

Browse files
committed
Add AGENT.md and Skills
Signed-off-by: Will Killian <william.killian@outlook.com>
1 parent 1e432e9 commit 21aabb2

15 files changed

Lines changed: 435 additions & 0 deletions

File tree

.cursor/skills

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../skills

AGENT.md

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# Agent guide — Course Constraint Scheduler
2+
3+
This file orients coding agents to the repository: how to build, test, and change the right places without guesswork.
4+
5+
## What this project is
6+
7+
Python **3.12+** package **`course-constraint-scheduler`**: a **Z3**-backed constraint solver for academic schedules, with **Pydantic** configuration, **CLI** (`scheduler`), **FastAPI** server (`scheduler-server`), and **Fern**-hosted docs.
8+
9+
- **Source**: `src/scheduler/` (import name `scheduler`)
10+
- **Tests**: `tests/` (`pytest`, coverage gate in `pyproject.toml`)
11+
- **User-facing docs site**: `fern/` (MDX + generated OpenAPI / schema / Python reference)
12+
13+
Human-oriented detail lives in [CONTRIBUTING.md](CONTRIBUTING.md) and [README.md](README.md).
14+
15+
## Commands agents should use
16+
17+
Prefer **`uv`** (lockfile: `uv.lock`). From repo root:
18+
19+
| Goal | Command |
20+
|------|---------|
21+
| Install deps + editable package | `uv sync` |
22+
| Tests (with coverage gate) | `uv run pytest` |
23+
| Lint | `uv run ruff check .` |
24+
| Format | `uv run ruff format .` |
25+
| Typecheck (matches hooks) | `uv run ty check . --ignore unresolved-import` |
26+
| Full pre-commit suite (matches CI) | `uv run prek run --all-files` |
27+
| Regenerate OpenAPI for Fern | `uv run python scripts/export_openapi.py` |
28+
| Regenerate config JSON Schema asset | `uv run python scripts/export_config_schema.py` |
29+
| Regenerate Python API MDX | `uv run python scripts/gen_python_api_mdx.py` |
30+
31+
CLI help: `uv run python -m scheduler.main --help`, `uv run python -m scheduler.server --help`.
32+
33+
## Layout (short)
34+
35+
```
36+
src/scheduler/ # Package: config, scheduler (Z3), server, models, writers, CLI
37+
tests/ # pytest; @pytest.mark.slow for heavy cases
38+
scripts/ # export_openapi, export_config_schema, gen_python_api_mdx
39+
fern/ # docs site; openapi.json and some assets are generated — do not hand-edit
40+
skills/ # task playbooks (SKILL.md per subfolder) for assistants and contributors
41+
.github/workflows/ # linting (prek + pytest), docs, publish
42+
```
43+
44+
## Conventions that trip people up
45+
46+
1. **`Course` naming**: `scheduler.config` uses `Course` as a **course-id string** type in JSON config. `scheduler.models` defines a **`Course` class** (credits, meetings, etc.). `CourseInstance.course` is the model; use **`.course.course_id`** for the config-style id. (See README “Note on naming”.)
47+
2. **Generated artifacts**: After changing **`server.py`** or API-facing models, refresh **`fern/openapi.json`**. After **`CombinedConfig`** / config models change, refresh **`fern/docs/assets/combined-config.schema.json`**. After public **docstrings** change, refresh **`fern/docs/pages/python/reference.mdx`** — see CONTRIBUTING.
48+
3. **Style**: **Ruff** is authoritative (`pyproject.toml`: line length **120**, `py312`). CONTRIBUTING’s “88 / Black” note is outdated relative to the repo config — follow **`pyproject.toml`**.
49+
50+
## Skills
51+
52+
Reusable, task-specific instructions live under **`skills/`** — one directory per topic, each with a **`SKILL.md`** (YAML frontmatter + body). See **[skills/README.md](skills/README.md)** for an index. Read the skill that matches the task (docs, tests, API, solver, CI) before large changes.
53+
54+
**Cursor:** **`.cursor/skills`** is a symlink to **`skills/`** so the editor can load project skills from the canonical tree without duplicating files.
55+
56+
## PR / commits
57+
58+
Use **Conventional Commits** (`feat:`, `fix:`, `docs:`, …). Before opening a PR: tests green, `prek` (or equivalent ruff + ty) clean, docs/regenerated artifacts updated when APIs or config schema change.

skills/README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Agent skills
2+
3+
This directory holds **task-focused playbooks** for anyone (or any automated assistant) working on the repository. Each subfolder is one skill; open **`SKILL.md`** inside it for the full instructions. Files use YAML frontmatter (`name`, `description`) so tools that ingest skills can discover them consistently.
4+
5+
| Skill | Use when |
6+
|-------|----------|
7+
| [sched-cli-main](sched-cli-main/SKILL.md) | CLI (`main.py`, Click, `--format`, output) |
8+
| [sched-domain-z3-config](sched-domain-z3-config/SKILL.md) | Solver, Z3, config vs models, time slots |
9+
| [sched-fastapi-server](sched-fastapi-server/SKILL.md) | REST API, `server.py`, OpenAPI |
10+
| [sched-fern-openapi-docs](sched-fern-openapi-docs/SKILL.md) | Fern site, regenerating openapi/schema/MDX |
11+
| [sched-github-ci](sched-github-ci/SKILL.md) | GitHub Actions, CI failures |
12+
| [sched-json-types](sched-json-types/SKILL.md) | `json_types.py`, wire shapes |
13+
| [sched-maintain-scripts](sched-maintain-scripts/SKILL.md) | `scripts/*.py` exporters |
14+
| [sched-output-writers](sched-output-writers/SKILL.md) | JSON/CSV writers |
15+
| [sched-pr-conventional-commits](sched-pr-conventional-commits/SKILL.md) | Commits, PR checklist |
16+
| [sched-ruff-ty-prek](sched-ruff-ty-prek/SKILL.md) | Lint, format, typecheck, prek |
17+
| [sched-testing-pytest](sched-testing-pytest/SKILL.md) | pytest, coverage, markers |
18+
| [sched-uv-workflow](sched-uv-workflow/SKILL.md) | `uv sync`, local env, `uv run` |
19+
20+
Orientation for the whole repo: **[AGENT.md](../AGENT.md)**.

skills/sched-cli-main/SKILL.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
---
2+
name: sched-cli-main
3+
description: >-
4+
Changes the scheduler command-line interface in main.py (Click), arguments,
5+
output paths, and format options. Use when adding CLI flags or adjusting how
6+
schedules are printed or written to disk.
7+
---
8+
9+
# CLI (`scheduler`)
10+
11+
## Entry
12+
13+
- **`src/scheduler/main.py`****`scheduler`** console script (`scheduler.main:main`).
14+
15+
## Typical flow
16+
17+
- Load config (Pydantic / file helpers from **`config`**).
18+
- Construct **`Scheduler`**, iterate models, write via **`writers`** (`json` / `csv`).
19+
20+
## Checklist
21+
22+
- Keep **`--help`** accurate; Click option names stable when possible.
23+
- If default output or formats change, update **README**, **Fern** pages, and **tests**.
24+
- Large or slow paths: consider documenting use of **`pytest` markers** for integration tests.
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
---
2+
name: sched-domain-z3-config
3+
description: >-
4+
Implements or debugs scheduling logic, Z3 constraints, and JSON configuration
5+
for the course constraint scheduler. Use when working in scheduler.py,
6+
config models, time slots, or solver behavior.
7+
---
8+
9+
# Domain: Z3, config, models
10+
11+
## Core files
12+
13+
- **`scheduler.py`**: Z3 problem construction, solving, optimization flags.
14+
- **`config.py`**: Pydantic models, validation, loading (`CombinedConfig`, etc.).
15+
- **`time_slot_generator.py`**: Time slot generation utilities.
16+
- **`models/`**: Runtime schedule representations (`CourseInstance`, `TimeSlot`, …).
17+
18+
## Naming trap: `Course`
19+
20+
- **`scheduler.config`**: `Course` (and related types) align with **JSON config** — often **course id strings** and config-shaped structures.
21+
- **`scheduler.models`**: **`Course`** is a **class** (credits, meetings, …). Instances in schedules use **`CourseInstance`**; the config id is **`course_instance.course.course_id`**.
22+
23+
When touching types or docs, preserve this distinction to avoid breaking configs or the public API.
24+
25+
## Config workflow
26+
27+
- Representative sample: **`example.json`**; smaller fixtures under **`tests/fixtures/`**.
28+
- After schema-affecting config changes, regenerate **`fern/docs/assets/combined-config.schema.json`** (see [sched-fern-openapi-docs](../sched-fern-openapi-docs/SKILL.md)).
29+
30+
## Z3
31+
32+
- Prefer clear, testable encodings; watch performance on large inputs.
33+
- Respect existing **caching** patterns; do not remove `@cache` on hot paths without analysis (Ruff **B019** is suppressed on intentional method caches).
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
---
2+
name: sched-fastapi-server
3+
description: >-
4+
Changes or reviews the FastAPI REST server, routes, and HTTP behavior for the
5+
scheduler. Use when editing server.py, async job flow, or API contracts.
6+
---
7+
8+
# FastAPI server
9+
10+
## Entry
11+
12+
- **Module**: `src/scheduler/server.py`
13+
- **Console script**: `scheduler-server``scheduler.server:main`
14+
15+
Run locally with `uv run python -m scheduler.server` (plus host/port flags from `--help`).
16+
17+
## Contracts
18+
19+
- Keep request/response models consistent with **OpenAPI** consumers.
20+
- After **route**, **model**, or **status code** changes, regenerate **`fern/openapi.json`**:
21+
22+
```bash
23+
uv run python scripts/export_openapi.py
24+
```
25+
26+
## Integration tests
27+
28+
- Use **`httpx`** (dev dependency) for async client tests where appropriate; see existing patterns in `tests/`.
29+
30+
## Documentation
31+
32+
- User-facing API narrative lives under **`fern/docs/pages/`**; machine-readable spec is **`fern/openapi.json`**.
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
---
2+
name: sched-fern-openapi-docs
3+
description: >-
4+
Maintains Fern documentation, OpenAPI, JSON Schema assets, and Python API
5+
reference MDX for this project. Use when changing FastAPI routes, public
6+
docstrings, Pydantic config models, or user-facing docs under fern/docs.
7+
---
8+
9+
# Fern docs and generated files
10+
11+
## Do not hand-edit
12+
13+
- **`fern/openapi.json`** — generated from FastAPI.
14+
- **`fern/docs/assets/combined-config.schema.json`** — generated from config models.
15+
- **`fern/docs/pages/python/reference.mdx`** — generated from docstrings (see script).
16+
17+
## Regenerate after changes
18+
19+
| Change | Command |
20+
|--------|---------|
21+
| `server.py`, API models, routes | `uv run python scripts/export_openapi.py` |
22+
| `CombinedConfig` / config schema | `uv run python scripts/export_config_schema.py` |
23+
| Public API docstrings | `uv run python scripts/gen_python_api_mdx.py` |
24+
25+
## Authoring
26+
27+
- **Guides / prose**: `fern/docs/pages/` (MDX), navigation in `fern/docs.yml`.
28+
- **Site config**: `fern/fern.config.json`, `fern/generators.yml`.
29+
30+
## Local preview
31+
32+
After regenerating as needed: install Fern CLI (`npm install -g fern-api`), then `fern docs dev` from the `fern/` directory (see CONTRIBUTING).
33+
34+
## CI
35+
36+
Docs deployment is in `.github/workflows/docs.yml` — keep generated artifacts committed when CI or publishers expect them.

skills/sched-github-ci/SKILL.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
---
2+
name: sched-github-ci
3+
description: >-
4+
Interprets or updates GitHub Actions workflows for linting, tests, docs, and
5+
publishing. Use when CI fails, when adding checks, or when aligning local
6+
commands with automation.
7+
---
8+
9+
# GitHub Actions
10+
11+
## Workflows
12+
13+
- **`.github/workflows/linting.yml`**: `uv sync --locked --group dev`, then `uv run prek run --all-files` and `uv run pytest`.
14+
- **`.github/workflows/docs.yml`**: Fern docs build/deploy (see file for triggers and secrets).
15+
- **`.github/workflows/publish.yml`**: Package publish pipeline.
16+
17+
## Aligning locally
18+
19+
If CI fails, reproduce with the same **locked** install:
20+
21+
```bash
22+
uv sync --locked --group dev
23+
uv run prek run --all-files
24+
uv run pytest
25+
```
26+
27+
## Dependabot
28+
29+
- **`.github/dependabot.yml`** schedules dependency updates; bump workflows if action major versions change.

skills/sched-json-types/SKILL.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
---
2+
name: sched-json-types
3+
description: >-
4+
Maintains TypedDict and JSON-shaped type definitions for API and config
5+
payloads. Use when editing json_types.py or aligning wire formats with
6+
Pydantic models and OpenAPI.
7+
---
8+
9+
# JSON types (`json_types.py`)
10+
11+
## Role
12+
13+
- Central place for **JSON structure typing** used across parsing, API, and docs.
14+
- Keep **`TypedDict`** / aliases aligned with **Pydantic** models in **`config.py`** and FastAPI schemas.
15+
16+
## Practices
17+
18+
- Prefer **one source of truth**: when possible, derive or mirror shapes from Pydantic rather than duplicating divergent definitions.
19+
- After changes that affect the HTTP API surface, regenerate **`fern/openapi.json`**.
20+
- Run **ty** and **tests** — JSON typing mistakes often show up as runtime validation errors in tests.
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
---
2+
name: sched-maintain-scripts
3+
description: >-
4+
Maintains or extends repository scripts under scripts/ for OpenAPI export,
5+
JSON Schema export, and Python API MDX generation. Use when changing export
6+
pipelines or adding codegen steps for documentation.
7+
---
8+
9+
# scripts/
10+
11+
| Script | Role |
12+
|--------|------|
13+
| `export_openapi.py` | Refresh **`fern/openapi.json`** from the FastAPI app |
14+
| `export_config_schema.py` | Refresh **`fern/docs/assets/combined-config.schema.json`** |
15+
| `gen_python_api_mdx.py` | Refresh **`fern/docs/pages/python/reference.mdx`** from docstrings |
16+
17+
Run with:
18+
19+
```bash
20+
uv run python scripts/<script>.py
21+
```
22+
23+
When editing these scripts:
24+
25+
- Keep output paths stable unless **`fern/docs.yml`** / publishers are updated too.
26+
- Prefer deterministic ordering in generated JSON/MDX when possible to reduce noisy diffs.

0 commit comments

Comments
 (0)