The type-first spec step was labelled "Blue", which collides with the Red-Green-Blue convention where blue means the refactor phase (and our loop already has an explicit Refactor step). Rename phase 1 to Type and describe the loop as type -> red -> green -> refactor. Tie the discipline to its established name: Type-Driven Development (Edwin Brady), quoting the Idris framing -- treat the type as the plan, let the compiler/type-checker drive you to a program that satisfies it. Section heading becomes "Testing discipline (type-driven)"; update the AGENTS.md pointer + anchor. Add "idris" to the cspell dictionary. De-duplicate: CONTRIBUTING.md no longer re-lists the banned directives (@ts-ignore, as casts, ...); it links to AGENTS.md "Never do", the single home for that rule, so the lists can't drift.
44 lines
4.0 KiB
Markdown
44 lines
4.0 KiB
Markdown
# AGENTS.md
|
|
|
|
Machine entry point for AI coding agents working in this repo. The authoritative
|
|
guidance for humans lives in [CONTRIBUTING.md](./CONTRIBUTING.md) and
|
|
[README.md](./README.md); this file only points at it and states the stable
|
|
first-action facts. Do not restate evolving prose here — it will drift.
|
|
|
|
## First action
|
|
|
|
- Project: F#-style pattern matching for TypeScript/ESM. Node `>=26` (pinned via `.node-version`), ESM-only (no CommonJS shim).
|
|
- **While iterating:** `npm run test` (`check:tsc` + the unit suite) for fast feedback on the files you changed.
|
|
- **Definition of done — run this before you call the work finished:** `npm run verify`. If all green, commit. If red, look at the output, fix the root cause, and re-run.
|
|
- **On commit:** write a good message (see [CONTRIBUTING.md § Commit messages](./CONTRIBUTING.md#commit-messages)). Lefthook's pre-commit hook already runs the fast, offline, staged-file checks — don't run them by hand. If the hook fails on style, `npm run fix`, restage, recommit.
|
|
- **`npm run maintain` is NOT part of the feature loop.** Its scans are advisory, never a gate; run them only on an explicit maintenance / update-deps branch.
|
|
|
|
```sh
|
|
npm run test # while iterating (fast feedback)
|
|
npm run verify # definition of done: whole-project correctness, one shot
|
|
```
|
|
|
|
## Never do
|
|
|
|
Don't silence the type system to force a green run. As an agent these are forbidden:
|
|
|
|
- `// @ts-nocheck`, `// @ts-ignore`, `// @ts-expect-error`
|
|
- `// oxlint-disable` / `// oxlint-disable-next-line`
|
|
- `as` casts used to push an expression through (type-aware oxlint already flags unsafe assertions)
|
|
|
|
Fix the root cause with the type system instead — narrowing, generics, `satisfies`, conditional / mapped types, utility types (`NonNullable`, `Exclude`, …). TypeScript can express it; that's the intended tool. The `oxlint-disable`-location rule in [CONTRIBUTING.md § Rules the tools don't enforce](./CONTRIBUTING.md#rules-the-tools-dont-enforce) is a **human** last-resort convention (so a reviewer can spot a deliberate suppression) — it is not permission for you to add one. If the types genuinely cannot express something, stop and surface the conflict (commit message / MR) rather than suppress it.
|
|
|
|
The same applies to the checks themselves: **never `git commit --no-verify`** (or otherwise skip a pre-commit / pre-push hook). The checks are fast and offline, so a redundant run is fine — bypassing a hook to get green is the identical anti-pattern. If a commit already skipped a hook, redo it through one: `git reset --soft HEAD~1 && git commit -C <skipped-sha>`.
|
|
|
|
Never start a long-lived / blocking process such as `npm run watch`. It runs until a human stops it with Ctrl-C, so in an agent turn it hangs forever and floods the context with continuous output. Reach for a one-shot command instead — `npm run test` (or `npm run check`) — to get feedback.
|
|
|
|
## Read these
|
|
|
|
- [CONTRIBUTING.md § Rules the tools don't enforce](./CONTRIBUTING.md#rules-the-tools-dont-enforce) — the constraints the linters don't catch; CI/review bounce these. **The most important section.**
|
|
- [CONTRIBUTING.md § Testing discipline (type-driven)](./CONTRIBUTING.md#testing-discipline-type-driven) — write the `expectTypeOf` (type) before the `assert` (red); the types are the feature.
|
|
- [CONTRIBUTING.md § Script prefix convention](./CONTRIBUTING.md#script-prefix-convention) — adding an `npm run` script? reuse an existing prefix or it doesn't belong.
|
|
- [CONTRIBUTING.md § Commit messages](./CONTRIBUTING.md#commit-messages) — gitmoji + imperative + 50/72.
|
|
- [CONTRIBUTING.md § Feedback tiers](./CONTRIBUTING.md#feedback-tiers) — what runs when and at what cost (`watch` / pre-commit / pre-push / `check` / `verify` / `fix` / `maintain` / CI).
|
|
- [README.md § Tooling decisions](./README.md#tooling-decisions) — the rationale behind each tool choice; read before changing tooling.
|
|
- [package.json `#scripts`](./package.json) — the source of truth for every command (the `LEFTHOOK_FILES` convention scopes them to staged files vs. the whole project).
|