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 skills/pauljphilp/effectpatterns/effect-patterns-value-handlingnpx skills add PaulJPhilp/EffectPatterns --skill effect-patterns-value-handlinggit clone --depth 1 https://github.com/PaulJPhilp/EffectPatternsWhat 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.00027 | $0.04604 |
| Opus 5 | $0.00014 | $0.02302 |
| Sonnet 5 | $0.00005 | $0.00921 |
| Haiku 4.5 | $0.00003 | $0.00460 |
Grade A, and why
effect-patterns-value-handling 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 2d ago.
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 — 677 lines — stays where its author put it; the contents beside it link to each section on GitHub.
Effect-TS Patterns: Value Handling
This skill provides 2 curated Effect-TS patterns for value handling. Use this skill when working on tasks related to:
- value handling
- Best practices in Effect-TS applications
- Real-world patterns and solutions
🟡 Intermediate Patterns
Optional Pattern 1: Handling None and Some Values
Rule: Use Option to represent values that may not exist, replacing null/undefined with type-safe Option that forces explicit handling.
Good Example:
This example demonstrates Option handling patterns.
import { Effect, Option } from "effect";
interface User {
id: string;
name: string;
email: string;
}
interface Profile {
bio: string;
website?: string;
location?: string;
}
const program = Effect.gen(function* () {
console.log(
`\n[OPTION HANDLING] None/Some values and pattern matching\n`
);
// Example 1: Creating Options
console.log(`[1] Creating Option values:\n`);
const someValue: Option.Option<string> = Option.some("data");
const noneValue: Option.Option<string> = Option.none();
const displayOption = <T,>(opt: Option.Option<T>, label: string) =>
Effect.gen(function* () {
if (Option.isSome(opt)) {
yield* Effect.log(`${label}: Some(${opt.value})`);
} else {
yield* Effect.log(`${label}: None`);
}
});
yield* displayOption(someValue, "someValue");
yield* displayOption(noneValue, "noneValue");
// Example 2: Creating from nullable values
console.log(`\n[2] Converting nullable to Option:\n`);
const possiblyNull = (shouldExist: boolean): string | null =>
shouldExist ? "found" : null;
const toOption = (value: string | null | undefined): Option.Option<string> =>
value ? Option.some(value) : Option.none();
const opt1 = toOption(possiblyNull(true));
const opt2 = toOption(possiblyNull(false));
yield* displayOption(opt1, "toOption(found)");
yield* displayOption(opt2, "toOption(null)");
// Example 3: Pattern matching on Option
console.log(`\n[3] Pattern matching with match():\n`);
const userId: Option.Option<string> = Option.some("user-123");
const message = Option.match(userId, {
onSome: (id) => `User ID: ${id}`,
onNone: () => "No user found",
});
yield* Effect.log(`[MATCH] ${message}`);
const emptyUserId: Option.Option<string> = Option.none();
const emptyMessage = Option.match(emptyUserId, {
onSome: (id) => `User ID: ${id}`,
onNone: () => "No user found",
});
yield* Effect.log(`[MATCH] ${emptyMessage}\n`);
// Example 4: Transforming with map
console.log(`[4] Transforming values with map():\n`);
const userCount: Option.Option<number> = Option.some(42);
const doubled = Option.map(userCount, (count) => count * 2);
yield* displayOption(doubled, "doubled");
// Chaining maps
const email: Option.Option<string> = Option.some("[email protected]");
const domain = Option.map(email, (e) =>
e.split("@")[1] ?? "unknown"
);
yield* displayOption(domain, "email domain");
// Example 5: Chaining with flatMap
console.log(`\n[5] Chaining operations with flatMap():\n`);
const findUser = (id: string): Option.Option<User> =>
id === "user-1"
? Option.some({ id, name: "Alice", email: "[email protected]" })
: Option.none();
const getProfile = (userId: string): Option.Option<Profile> =>
userId === "user-1"
? Option.some({ bio: "Developer", website: "alice.dev" })
: Option.none();
const userId2 = Option.some("user-1");
// Chained operations: userId -> user -> profile
const profileChain = Option.flatMap(userId2, (id) =>
Option.flatMap(findUser(id), (user) =>
getProfile(user.id)
)
);
const profileResult = Option.match(profileChain, {
onSome: (profile) => `Bio: ${profile.bio}, Website: ${profile.website}`,
onNone: () => "No profile found",
});
yield* Effect.log(`[CHAIN] ${profileResult}\n`);
// Example 6: Fallback values with getOrElse
console.log(`[6] Default values with getOrElse():\n`);
const optionalStatus: Option.Option<string> = Option.none();
const status = Option.getOrElse(optionalStatus, () => "unknown");
yield* Effect.log(`[DEFAULT] Status: ${status}`);
// Real value
const knownStatus: Option.Option<string> = Option.some("active");
const realStatus = Option.getOrElse(knownStatus, () => "unknown");
yield* Effect.log(`[VALUE] Status: ${realStatus}\n`);
// Example 7: Filter with predicate
console.log(`[7] Filtering with conditions:\n`);
const ageOption: Option.Option<number> = Option.some(25);
const isAdult = Option.filter(ageOption, (age) => age >= 18);
yield* displayOption(isAdult, "Adult check (25)");
const ageOption2: Option.Option<number> = Option.some(15);
const isAdult2 = Option.filter(ageOption2, (age) => age >= 18);
yield* displayOption(isAdult2, "Adult check (15)");
// Example 8: Multiple Options (all present?)
console.log(`\n[8] Combining multiple Options:\n`);
const firstName: Option.Option<string> = Option.some("John");
const lastName: Option.Option<string> = Option.some("Doe");
const middleName: Option.Option<string> = Option.none();
// All three present?
const allPresent = Option.all([firstName, lastName, middleName]);
yield* displayOption(allPresent, "All present");
// Just two
const twoPresent = Option.all([firstName, lastName]);
yield* displayOption(twoPresent, "Two present");
// Example 9: Converting Option to Error
console.log(`\n[9] Converting Option to Result/Error:\n`);
const optionalConfig: Option.Option<{ apiKey: string }> = Option.none();
const configOrError = Option.match(optionalConfig, {
onSome: (config) => config,
onNone: () => {
throw new Error("Configuration not found");
},
});
// In real code, would catch error
const result = Option.match(optionalConfig, {
onSome: (config) => ({ success: true, value: config }),
onNone: () => ({ success: false, error: "config-not-found" }),
});
yield* Effect.log(`[CONVERT] ${JSON.stringify(result)}\n`);
// Example 10: Option in business logic
console.log(`[10] Practical: Optional user settings:\n`);
const userSettings: Option.Option<{
theme: string;
notifications: boolean;
}> = Option.some({
theme: "dark",
notifications: true,
});
const getTheme = Option.map(userSettings, (s) => s.theme);
const theme = Option.getOrElse(getTheme, () => "light"); // Default
yield* Effect.log(`[SETTING] Theme: ${theme}`);
// No settings
const noSettings: Option.Option<{ theme: string; notifications: boolean }> =
Option.none();
const noTheme = Option.map(noSettings, (s) => s.theme);
const defaultTheme = Option.getOrElse(noTheme, () => "light");
yield* Effect.log(`[DEFAULT] Theme: ${defaultTheme}`);
});
Effect.runPromise(program);
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.
- 2d ago First seen · 677 lines · 27 tokens per session scan A 45d6400aa82b
effect-patterns-value-handling is a skill published in the GitHub repository PaulJPhilp/EffectPatterns (795 stars, last pushed 2mo ago), licensed MIT. It adds 27 tokens to every session and 4,604 once invoked, about $0.0001 per session on Opus 5. 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 skills, from other repositories
effect-best-practices
Enforces Effect-TS patterns for services, errors, layers, and atoms. Use when writing code with Effect.Service, Schema.TaggedError, Layer composition, or effect-atom React components.
effect-http-api
Build typed HTTP APIs with Effect's HttpApi — endpoints with schemas, handlers, security middleware, OpenAPI docs, derived clients, and handler unit tests. Use when building HTTP servers, REST APIs, or typed HTTP clients with Effect v4.
effect-rpc-cluster
Build typed RPC endpoints and cluster-distributed entities, singletons, cron jobs, and durable workflows with Effect's RPC and Cluster modules (Rpc/RpcGroup/RpcServer/RpcClient, Entity/Sharding/Singleton, Node/Bun bundles). Use when building RPC services or distributed/clustered Effect systems.
effect-error-handling
Implement typed error handling in Effect v4 using Schema.TaggedErrorClass, catchTag/catchTags, catchReason/catchReasons, Cause, ErrorReporter, and recovery patterns. Use this skill when working with Effect error channels, handling expected failures, or designing error recovery strategies.
effect-http-server
Build HTTP servers with effect/unstable/http — HttpRouter routes and middleware, HttpServerRequest schema decoding, HttpServerResponse constructors, multipart uploads, websocket upgrades, static files, NodeHttpServer/BunHttpServer layers, and in-memory web handlers. Use when serving raw HTTP routes, reading request…
effect-fiber
Fork, supervise, and interrupt Effect fibers with Effect.forkChild/forkScoped/forkIn/forkDetach, Fiber join/await/interrupt, uninterruptible regions, and the FiberHandle/FiberMap/FiberSet supervision collections. Use when running background work, cancelling or restarting tasks, implementing latest-wins or keyed…