Imported from tsortwehttam/begat (
AGENTS.md). Install upstream withnpx skills add tsortwehttam/begat. Copyright stays with the author.
Instructions
See @README.md
General
- Write simple, minimal, modular code that is strongly typed and:
- DRY: If you repeat code in multiple places, extract it into a reusable function.
- YAGNI: But make abstractions only when you actually need it in more than one place.
- Use short variable names in clean, tight, well-organized stanzas
- Don't add comments unless critical; code should be self-descriptive
- If you add a comment, it should explain why the code is needed, not what it does
- Prefer pure functions with explicit inputs and outputs
- Prefer early return over conditional
- Array properties should default to empty arrays, not
null - Prefer libraries' own types over writing your own
- Don't add console.logs - unless temporarily for debugging
- But leave existing console.logs/info untouched
- Never include backward compat code (unless instructed)
- When researching APIs and docs, use latest content (it is 2026)
- If you're unsure about something, ask!
- Make shared constants
UPPER_CASE - For functions, prefer camel case verbs (
calcTimeAt(x), nottimeAt(x)) - For variables and object properties, prefer concise single words (
elapsed, notelapsedTime) - Fix problems the right way (robust), not hacky
- For functional units that don't require I/O or significant setup/teardown, add unit tests
- Write tests in
test/*.test.ts
- Write tests in
- Warn me if you notice security vulnerabilities, flaws
- Always double check that we aren't exposing secret keys or env vars to the client
JavaScript & TypeScript
- Avoid mjs whenever possible
- Use yarn (not npm)
- After logical changes, package upgrades, or refactors, run typecheck and unit tests
- Never use the
anytype - For command line tools and arg parsing, always use yargs
- Prefer function declaration style (
function getFoo() {...}) - Don't add try/catch blocks
- Rely on strong typing rather than throwing
- Be liberal in what we accept
- Don't use
optional?:types function arguments or object properties - Don't use default exports (unless necessary)
- Make Zod schemas PascalCase, like
FooSchema - See
lib/*for pre-existing utility/helpers files - When naming files with shared code, use
FooUtils.tsfor i/o stuff,BarHelpers.ts- e.g.
MathHelpers.ts,WebsocketUtils.ts, etc.
- e.g.
Try to Enforce Shared Contracts
Before you implement a function that feels "generic", check if an implementation already exists. For example, if you're making a change to due with pricing, you should scan to see what utility code already exists for managing pricing, billing, etc. Then, after any set of changes, go back over your work to seek out and eliminate duplicate code, streamline logic, reduce footprint, and prevent the divergence of features that should mutually depend on the same types. Keep a single source of truth for shared try your best to consolidate code and avoid repetition.
Always look for runtime invariants (shared constants, policies, validations, subroutines) and find ways to share across modules to avoid code drift. For example, suppose we are writing an LLM prompt with a desired output shape which we then pass to a function. The naive (bad) way to do this would be to write literal JSON in the prompt, a one off function to validate its shape, and then a separate type signature for the function. The smart (good) way would be to write a single Zod schema, use that for the prompt's JSON, for validating the output, and as the type signature of the function.
Consider whether the solution is LESS code
Can we improve the system by consolidating, simplifying, reducing, or even deleting code, pathways, modules, etc? Oftentimes simplifying unlocks an elegant fix or improvement that adding modules would not. Consider this.