Skip to content

Using it with AI tools

If an AI assistant helps you write code — GitHub Copilot, Claude Code, Cursor, or any coding agent — one extra step makes it use CommonKit properly. Without that step, assistants do what they always do: sprinkle Trim(), Replace(), regex and int.Parse all over your features, and your codebase drifts right back to the ad-hoc cleaning this library exists to end.

The fix is simple: the library ships with its own instruction file, and you point your AI tool at it.

The file that does the work: AGENTS.md

Next to the library's source lives SafeCoder.CommonKit/AGENTS.md — a compact reference written for AI tools. It holds the whole contract (nothing throws, the rejection values, the OrNull family), a quick-start, one dense section per class, and the gotchas an assistant would otherwise re-learn the hard way. It is updated in the same commit as every library change, so it is never stale.

Whatever tool you use, the goal is always the same: get AGENTS.md into the AI's context before it writes code that touches data.

GitHub Copilot

Copilot reads .github/copilot-instructions.md from the root of your repository and applies it to every request. Create the file (or add to it) with the pointer and the one non-negotiable rule:

**Read `SafeCoder.CommonKit/AGENTS.md` before generating any code that touches data.**

- Always use SafeCoder.CommonKit to clean, validate, convert or format a value
  (text, emails, phones, numbers, booleans, money, dates, UUIDs, IPs, URLs,
  files, payloads). Never write ad-hoc Trim()/Replace()/regex/Parse code in a feature.
- CommonKit never throws by default: string methods answer "" on rejection,
  converters answer the fallback, the OrNull family answers null (OrNull methods
  never throw and take no throwIfInvalid at all).
- Write outbound values with CkText.NumberToString / CkBool.Format /
  CkDate.Iso8601 (a day) or CkDateTime.Iso8601 (a moment) — never raw ToString().
- Call style: two or more arguments, all named, one per line; a single argument
  is passed positionally.

Claude Code

Claude Code reads CLAUDE.md from your repository root at the start of every session. Add a short section that makes the library the default path for data:

## Data handling
Always use the `SafeCoder.CommonKit` library to clean, validate, convert and format
values — never ad-hoc Trim()/Replace()/regex/Parse code. The full reference for
every class, the contract, and the gotchas is `SafeCoder.CommonKit/AGENTS.md`; read
it before writing code that touches data. If a helper is missing, add it to the
library (with tests) instead of inlining the logic in a feature.

Cursor and other agents

Many agent tools — Cursor, Codex-style CLIs, and most newer agents — automatically read a file named AGENTS.md at the repository root. Two easy options:

  • Point at the library's copy. Add one line to your root AGENTS.md (create the file if you don't have one): "For any code that touches data, follow SafeCoder.CommonKit/AGENTS.md."
  • Paste it into the rules box. Cursor's Rules, a system prompt, a custom instruction field — the library's AGENTS.md fits in any of them.

The throw switch

Generated code often forgets to check a rejection value — the empty string, the fallback, the sentinel. While an agent is building an app on this source, flip CkSettings.DefaultThrowIfInvalid to true: every rejected value then surfaces at once as an exception carrying the input and the reason, and the agent sees the bad data instead of a quiet fallback three tables later. Back to false to ship.

If you can only say three things

Some tools give you one small instruction box. Make it these three lines:

  1. Use SafeCoder.CommonKit for every value that is cleaned, checked, converted or formatted — never ad-hoc string or parse code.
  2. Nothing throws by default — check the rejection values ("", the fallback, null) at the call site.
  3. Data leaving the process goes through CkText.NumberToString, CkBool.Format, CkDate.Iso8601 (a day) or CkDateTime.Iso8601 (a moment) — never raw ToString().

Why this matters more than it looks

An AI assistant writes the code you let it write. Left alone, it produces perfectly plausible email.Trim().ToLower() lines that crash on null and let junk through — and it does so a hundred times, one feature at a time. With AGENTS.md in its context, the same assistant writes CkEmail.Address(email) instead, and every rule on How it works comes along for free.