# src/core

Internal pure engine: no Pi imports and no public API. It trusts input already filtered by the tool layer and does not re-validate it. Core's report references are type-only and erased at runtime.

## Modules

- `hash.ts` computes position-dependent line checksums (line number + content → `LINE#HASH`). `lines.ts` handles splitting, line-ending detection, and physical line counts. `text.ts` does strict and lossy UTF-8 decoding and decides which text cannot be written.
- `apply.ts` `applyEdits` validates a whole batch of `Edit` ops (see `types.ts`) against a single snapshot: anchor checks, overlap and conflict detection, and shifted-anchor recovery (`AnchorRecovery`: local `shiftRadius` search, then full file). It returns new text or structured anchor failures, throws `OVERLAPPING_EDITS` for an overlap, and never touches the filesystem.
- `regex.ts` builds JavaScript regexes on the LF view (`regexSource`, `buildRegex`) for both grep and replace; neither engine imports the other. `checkRegexArguments` is their shared entry check: it reports flags V8 rejects and compiles regex-mode patterns.
- `replace.ts` is replace's engine: literal and JavaScript-regex matching on the LF view, separator restoration, and overlap rejection. `replace-schema.ts` defines the tool's replacement schema and the engine's result schema, with their derived types.
- `search.ts` evaluates native JavaScript queries on the LF view and returns bounded physical rows; `search-schema.ts` defines its result.
- `search-analysis.ts` parses patterns with regexpp (V8 has already accepted them at tool entry), decides smart case, and derives the literals every match must contain; `case-fold.ts` supplies JavaScript's case equivalence; `character-set.ts` owns character-class sets and shared AST surrogate-pair decoding for both candidate strategies.
- `errors.ts` holds the classified `HashlineError`, typed by code so its facts and `next` alternative must match the code's schema, and errno classification.
- `ranges.ts` provides overlap detection for both engines and range merging for failure neighborhoods.

## Constraints

- Own interval algebra, bounded membership caching, and explicit class-string enumeration in `character-set.ts`; derive Unicode properties, `v` sets, and case closure from the running V8 rather than separate Unicode tables. Intersections may enumerate either string operand, subtractions only the left, and unions require every operand. Unknown string properties remain widened.
- Derive one necessary file condition in `search-analysis.ts`: an AND keeps its most selective side, because extra rg passes cost more than they save. Preserve every OR alternative, retain necessary prefixes or suffixes when expansion is too large, and cut literals where bytes can differ from the LF view. Unknown constructs widen candidates, never narrow them.
