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, followSafeCoder.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:
- Use
SafeCoder.CommonKitfor every value that is cleaned, checked, converted or formatted — never ad-hoc string or parse code. - Nothing throws by default — check the rejection values (
"", the fallback,null) at the call site. - Data leaving the process goes through
CkText.NumberToString,CkBool.Format,CkDate.Iso8601(a day) orCkDateTime.Iso8601(a moment) — never rawToString().
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.