Getting it into your agent
One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.
npx agentmods add rules/davis7dotsh/river/neverthrowgit clone --depth 1 https://github.com/davis7dotsh/riverWhat it costs to keep this loaded
Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.
| Model | Per session | Once invoked |
|---|---|---|
| Fable 5 | $0.00000 | $0.01727 |
| Opus 5 | $0.00000 | $0.00864 |
| Sonnet 5 | $0.00000 | $0.00345 |
| Haiku 4.5 | $0.00000 | $0.00173 |
Grade A, and why
neverthrow scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured yesterday.
A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.
Nothing flagged
None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.
How it starts
The opening of the file, as written. The whole thing — 199 lines — stays where its author put it; the contents beside it link to each section on GitHub.
neverthrow — Condensed API (Core surface, minimal examples)
Top‑Level Exports
- ok, err, Ok, Err, Result, ResultAsync
- okAsync, errAsync
- fromThrowable, fromAsyncThrowable, fromPromise, fromSafePromise, safeTry
Core Concepts
- Result<T, E>: synchronous success/error container
- ResultAsync<T, E>: async version resolving to Result<T, E>
- Combinators never execute callbacks on the non-matching variant (short-circuit)
- Prefer map/andThen over try/catch; mapErr/orElse to standardize and recover errors
Result<T, E>
Constructors
ok<T, E = never>(value: T): Ok<T, E>
err<T = never, E = unknown>(error: E): Err<T, E>
Introspection
isOk(): boolean
isErr(): boolean
Transformations
map<U>(fn: (value: T) => U): Result<U, E>
mapErr<F>(fn: (error: E) => F): Result<T, F>
unwrapOr(defaultValue: T): T
match<A, B = A>(okFn: (v: T) => A, errFn: (e: E) => B): A | B
Control flow / chaining
andThen<U, F>(fn: (value: T) => Result<U, F>): Result<U, E | F>
asyncAndThen<U, F>(fn: (value: T) => ResultAsync<U, F>): ResultAsync<U, E | F>
asyncMap<U>(fn: (value: T) => Promise<U>): ResultAsync<U, E>
orElse<U, A>(fn: (error: E) => Result<U, A>): Result<U | T, A>
Side‑effect helpers
andTee(cb: (value: T) => unknown): Result<T, E> // pass-through side effects on Ok
orTee(cb: (error: E) => unknown): Result<T, E> // pass-through side effects on Err
andThrough<F>(cb: (value: T) => Result<unknown, F>): Result<T, E | F>
asyncAndThrough<F>(cb: (value: T) => ResultAsync<unknown, F>): ResultAsync<T, E | F>
Statics on Result
Result.fromThrowable<A, E>(fn: (...args: any[]) => A, mapError?: (u: unknown) => E): (...args: any[]) => Result<A, E>
Result.combine<T, E>(list: Result<T, E>[]): Result<T[], E>
Result.combine<T1, T2, E1, E2>(tuple: [Result<T1, E1>, Result<T2, E2>]): Result<[T1, T2], E1 | E2>
Result.combineWithAllErrors<T, E>(list: Result<T, E>[]): Result<T[], E[]>
ResultAsync<T, E>
Constructors
okAsync<T, E = never>(value: T): ResultAsync<T, E>
errAsync<T = never, E = unknown>(error: E): ResultAsync<T, E>
Introspection (via awaiting or .then): resolves to Result<T, E>
Transformations
map<U>(fn: (value: T) => U | Promise<U>): ResultAsync<U, E>
mapErr<F>(fn: (error: E) => F | Promise<F>): ResultAsync<T, F>
unwrapOr(defaultValue: T): Promise<T>
match<A, B = A>(okFn: (v: T) => A, errFn: (e: E) => B): Promise<A | B>
Control flow / chaining
andThen<U, F>(fn: (value: T) => Result<U, F> | ResultAsync<U, F>): ResultAsync<U, E | F>
orElse<U, A>(fn: (error: E) => Result<U, A> | ResultAsync<U, A>): ResultAsync<U | T, A>
Side‑effect helpers
andTee(cb: (value: T) => unknown): ResultAsync<T, E>
orTee(cb: (error: E) => unknown): ResultAsync<T, E>
andThrough<F>(cb: (value: T) => Result<unknown, F> | ResultAsync<unknown, F>): ResultAsync<T, E | F>
Statics on ResultAsync
ResultAsync.fromThrowable<A, E>(fn: (...args: any[]) => Promise<A>, mapError?: (u: unknown) => E): (...args: any[]) => ResultAsync<A, E>
ResultAsync.fromPromise<A, E>(p: PromiseLike<A>, mapError: (u: unknown) => E): ResultAsync<A, E>
ResultAsync.fromSafePromise<A, E = never>(p: PromiseLike<A>): ResultAsync<A, E>
ResultAsync.combine<T, E>(list: ResultAsync<T, E>[]): ResultAsync<T[], E>
ResultAsync.combineWithAllErrors<T, E>(list: ResultAsync<T, E>[]): ResultAsync<T[], E[]>
Utilities
fromThrowable / fromAsyncThrowable
- Wrap throwy sync/async functions into functions returning Result / ResultAsync
- Always provide mapError to normalize unknown to a typed E when possible
fromPromise / fromSafePromise
- fromPromise: wrap an existing promise, map rejection reason (unknown) to typed E
- fromSafePromise: same but assumes it won’t throw; no error handler; be certain
safeTry
- Write linear code over multiple Result/ResultAsync operations without manual unwrap
- Generator-based; yield* short-circuits on Err; returns Ok on success
const result = safeTry<number, string>(function* () {
const a = yield* mayFail1();
const b = yield* mayFail2();
return ok(a + b);
});
What this file has done since we first saw it
Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.
- yesterday First seen · 199 lines · 1,727 tokens per session scan A de0456f2cdcb
neverthrow is a cursor rule published in the GitHub repository davis7dotsh/river (227 stars, last pushed 5mo ago), licensed MIT. It costs nothing until one of its globs matches a file; then it loads 1,727 tokens. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-08-30.
Other cursor rules, from other repositories
svelte
You are an expert in Svelte 5, SvelteKit, TypeScript, and modern web development.
testing
Comprehensive Testing Best Practices for Svelte 5 + vitest-browser-svelte.
cursorrules
Comprehensive Testing Best Practices for Svelte 5 + vitest-browser-svelte.
upgrade-tests
// ✅ CORRECT: Upgrade package pattern await using ctx = testReactResource(appRouter, { server: { // server configuration }, client(opts) { return { links: [ httpLink({ url: opts.httpUrl, // client configuration }), ], }; }, }).
react-query-tests
// ✅ CORRECT: Legacy React Query pattern const ctx = konn() .beforeEach(() => createAppRouter()) .afterEach((ctx) => ctx?.close?.()) .done().
tanstack-react-query-tests
// ✅ CORRECT: Use await using for automatic cleanup await using ctx = testReactResource(appRouter, { server: { // server configuration }, client(opts) { return { links: [ httpLink({ url: opts.httpUrl, // client configuration }), ], }; }, }).