This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
pnpm install- Install dependenciespnpm run build- Lint and compile TypeScriptpnpm run compile- Compile TypeScript onlypnpm run test- Run linting, type tests, and coverage testspnpm run test:unit- Run unit tests onlypnpm run test:cover- Run unit tests with coveragepnpm run test:tsd- Run TypeScript definition testspnpm run lint- Run ESLintpnpm run ci- Full CI pipeline (lint, compile, type tests, coverage)
Run a single test:
pnpm run test:unit -- --grep "test name pattern"-
Expression Evaluator (
src/lib/evaluator.ts): Evaluates boolean expressions against a contextevaluate()- Returns boolean resultevaluateWithReason()- Returns{result, reason}where reason is the minimal expression that caused the result. Forand/or, reason is always wrapped in array form (e.g.,{or: [reason]})validate()- Validates expression structure against a full context
-
Rule Engine (
src/lib/engine.ts): Evaluates rules with conditions and consequences- Rules have a condition (expression) and consequence (message + custom payload)
- Can also use rule functions that combine condition checking and consequence in one
The type system uses ts-toolbelt for advanced type manipulation. Generic parameters follow this pattern:
<Context, FunctionsTable, Ignore, CustomRunOptions>- Context: The object being evaluated against
- FunctionsTable: Custom functions available in expressions
- Ignore: Types to exclude from path extraction (e.g.,
Moment) to avoid TypeScript exhaustion - CustomRunOptions: User-defined options passed to functions
Key types in src/types/:
Expression- Union type of all valid expression forms (and/or/not/property comparisons/functions)ValidationContext- Context with all optional properties required (for validation)EvaluationResult- Result ofevaluateWithReason()with boolean and minimal expression
Logical: and, or, not
Comparison: eq, neq, gt, gte, lt, lte, between, inq, nin, regexp, regexpi, exists
Right-hand side can be: literal value, {ref: "path"} to reference context, or math operation {op, lhs, rhs}.
- 4-space indentation, single quotes, semicolons required
- Lines ~120 characters max
- 100% code coverage required
- Type tests use TSD in
src/test/types/ - Linting via ESLint (flat config in
eslint.config.mjs) - Testing via Vitest
Supports Node.js ^20, ^22, or ^24
- CI runs on Ubuntu, macOS, and Windows
- Tests run across all supported Node.js versions
- Primary checks (Snyk, coverage, type tests) run on Ubuntu + Node 24
- Avoid shell-specific glob patterns in npm scripts (let tools handle glob expansion internally)
- Use forward slashes in paths within config files (ESLint, TypeScript handle this cross-platform)