effect-ts
Imported from paulrberg/agent-skills/skills/effect-ts.
Install
npx skills add https://github.com/PaulRBerg/agent-skills/tree/main/skills/effect-ts
claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install paulrberg-agent-skills@llmmart
git clone https://github.com/PaulRBerg/agent-skills.git
The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole paulrberg/agent-skills collection as a plugin from our marketplace. Git is the plain clone.
Skill manifest
Effect 3
Apply Effect 3 semantics from project-local architecture, the narrowest relevant reference, and source matching the target's installed packages.
Workflow
Do not activate this workflow merely because a file imports effect. For nontrivial Effect work:
- Resolve the target package or workspace and its exact installed
effectand relevant@effect/*versions. Ifeffectis not 3.x, stop because this skill does not apply. - Inspect neighboring services, layers, errors, schemas, runtime boundaries, and tests. Local conventions decide organization; installed package evidence decides API facts.
- Read
references/critical-rules.md, then only the task-specific references below. - Verify every uncertain import, signature, or behavior against the package installation visible to the target workspace before editing.
- Implement the smallest pattern consistent with the project and run the narrowest test or typecheck covering the changed semantics.
Evidence Order
Use the target workspace's manifest and lockfile to identify versions. Prefer, in order:
- the installed package's
src/, README, tests, and changelog; - its emitted declarations when source is not shipped;
- the matching official package artifact or source tag.
Do not install or update dependencies solely to obtain documentation. Do not trust an unrelated checkout or a source branch that does not match the target's installed version. If exact behavior cannot be verified, stop rather than guessing.
Reference Router
| Task | Reference |
|---|---|
Services, Layers, tags, Effect.fn |
references/services-layers.md |
| Config providers and secrets | references/config.md |
| Schema, JSON Schema, encoded errors/models | references/schema-jsonschema.md |
@effect/vitest, clocks, fibers, retries |
references/testing.md |
| resources, scheduling, refs, concurrency | references/runtime.md |
| streams and backpressure | references/streams.md |
| pattern matching and tagged unions | references/pattern-matching.md |
@effect/ai |
references/ai.md |
@effect/sql |
references/sql.md |
Next.js / @prb/effect-next |
references/next-js.md |
| Effect Atom | references/effect-atom.md |
Option at nullable boundaries |
references/option-null.md |
For platform/RPC APIs, collection utilities, deprecations, or constructor lookup, inspect the installed package source directly instead of loading a local API inventory.
Boundaries
- Keep pure helpers, constants, and path manipulation pure unless an Effect boundary provides a concrete dependency, testability, resource-safety, or error-model benefit.
- Preserve existing domain facades and service/runtime boundaries unless the user requested redesign.
- Prefer typed failures and scoped resources at IO boundaries; choose Schema-backed errors/models only when encoding or boundary validation is needed.
- Do not broaden environment requirements merely to replace a small platform call.
For changes, completion requires code consistent with local Effect architecture, selected references and installed
source where needed, and the narrowest test/typecheck that exercises the changed semantics. Read-only work requires
evidence for the reported conclusion. Finish with ### ⚡ Effect — ✅ change complete after verified edits or
### ⚡ Effect — 🔎 reviewed, no files written for read-only work, one sentence naming the boundary or pattern used,
and ### 🧪 Verification with exact scoped commands/results. If required validation is incomplete, use
### ⚡ Effect — ⛔ blocked instead. Add ### ⚠️ Limitation only for non-blocking caveats. Never decorate typed
errors, Schema messages, logs, tests, generated JSON/API responses, or command output.
Files (agent-skills)
-
agents
-
openai.yaml 42 B
policy: allow_implicit_invocation: true
-
-
references
-
ai.md 1.3 KB
# Effect AI Use installed `@effect/ai` and provider package source for exact model, request, and response configuration. Keep tool contracts Schema-driven so parameters and structured output are validated at runtime. ## Tool Parameters Omit `parameters` for a no-argument tool or use `Tool.EmptyParams` when the closed empty-object contract must be explicit. `Tool.EmptyParams` is a record whose values are `Schema.Never`; do not replace it with a loose record. Use `Tool.Parameters<T>`, `Tool.ParametersEncoded<T>`, and `Tool.ParametersSchema<T>` rather than reconstructing a tool's types manually. Use `setParameters` when deriving a tool with another parameter schema. ## OpenAI Structured Output The OpenAI language-model configuration supports `strict?: boolean` and enables strict schema handling by default. Set `strict: false` only when the selected model or a required schema construct cannot satisfy strict structured-output requirements. The provider consumes this option while preparing tools; do not forward it as an unrelated top-level request field. Prompt-cache retention accepts `"in_memory"` or `"24h"`; spell the in-memory value with an underscore. Before adding a provider workaround for request or response behavior, inspect the installed provider source and changelog so application code does not duplicate a fixed package concern. -
config.md 1.1 KB
# Config and Secrets Use Effect `Config` at application boundaries so missing or invalid configuration remains typed. Keep configuration descriptions declarative and provide alternate `ConfigProvider`s at the runtime or test boundary. ```ts import { Config } from "effect"; const AppConfig = Config.all({ host: Config.string("HOST").pipe(Config.withDefault("localhost")), port: Config.number("PORT"), apiKey: Config.redacted("API_KEY"), }); ``` - Use `Config.redacted` for credentials and tokens. Call `Redacted.value` only at the narrow boundary that passes the secret to a client; never interpolate the value into logs or errors. - Use `Config.nested` for stable prefixes instead of repeating environment-variable names. - Validate constrained values in the Config description so startup fails before partially constructing the application. - For tests, provide a map-backed or custom `ConfigProvider` through `Layer.setConfigProvider`; do not mutate process environment globally when a provider expresses the dependency. - Do not turn constants or request data into Config merely because they are values. Config owns deployment-time input. -
critical-rules.md 2.7 KB
# Critical Effect 3 Rules Read this before changing nontrivial Effect code. These rules protect semantics that ordinary TypeScript intuition often gets wrong; use the installed package source for exact combinator signatures. ## Effect Failures Are Not Thrown Exceptions An Effect failure yielded inside `Effect.gen` is represented in the Effect error channel. An ordinary `try/catch` around `yield*` does not recover it. ```ts // Wrong: the catch block does not handle an Effect failure. Effect.gen(function* () { try { return yield* program; } catch { return fallback; } }); ``` Use `Effect.catchTag`, `Effect.catchTags`, `Effect.catchAll`, or `Effect.exit` according to whether the caller should recover, map, or inspect the failure. Wrap foreign throwing code with `Effect.try` or `Effect.tryPromise` at the boundary where it enters Effect. ## Preserve Typed Failures Model expected failures with tagged domain types rather than the global `Error` class. Use `Schema.TaggedError` when the failure crosses an encoding, persistence, API, or documentation boundary; use `Data.TaggedError` for internal-only failures. Do not use `as any`, `as never`, double assertions, or widened `Error` channels to make an Effect typecheck. Fix the service, error, or environment type that produced the mismatch. A narrow assertion at a poorly typed external boundary needs a documented reason. ## Keep Defects Out of Expected Error Mapping `Cause` contains expected failures, defects, and interruption. Use `Effect.mapError` or tagged recovery for expected failures. Use `catchAllCause` only at a deliberate runtime, reporting, or supervision boundary where handling the whole cause is the requirement. Do not silently convert a required audit, billing, persistence, authorization, or notification effect to `Effect.void`. Propagate or translate its expected failure. Fallback values are appropriate only when the product semantics make the operation optional. ## Keep Pure Work Pure Do not wrap safe array transformations, constants, path manipulation, or other deterministic pure work in `Effect.try`. Use `Effect.sync` for synchronous observable effects and `Effect.try` only for code that can throw. ## Make Generator Termination Explicit Use `return yield*` for failures and interruption inside conditional generator branches. The runtime stops on the failed yield either way, but the explicit return preserves control-flow clarity and avoids misleading unreachable code. ```ts Effect.gen(function* () { if (!isAuthorized) { return yield* Effect.fail("Unauthorized"); } return yield* performAction; }); ``` For absence modeling, follow [option-null.md](option-null.md) and normalize once at the system boundary. -
effect-atom.md 1.6 KB
# Effect Atom Effect Atom separates core atoms from framework bindings. Verify APIs against the installed packages: - core constructors, Registry, Result, RPC, and HTTP integrations: `@effect-atom/atom/*`; - React hooks and Registry provider: `@effect-atom/atom-react`. ```ts import * as Atom from "@effect-atom/atom/Atom"; import * as Result from "@effect-atom/atom/Result"; import { RegistryProvider, useAtomSet, useAtomValue } from "@effect-atom/atom-react"; ``` ## Atom Semantics - `Atom.make(value)` creates writable state; `Atom.make(get => value)` creates derived state. - An Effect or Stream passed to `Atom.make` produces a `Result`, not the raw success value. - Use `Atom.family` for stable parameterized atoms and `Atom.keepAlive` only when state must outlive component mounts. - Use `Atom.runtime(layer)` when atoms need an Effect runtime with services. - `Atom.fn` creates a writable Effect/Stream function. Its handler receives the written argument and atom context. - Use `get.addFinalizer` or a scoped Effect for listeners and resources owned by an atom. ## React Boundaries Use `useAtomValue` to read and `useAtomSet` to write. For Effect-backed mutation atoms, select `mode: "promiseExit"` when the caller must branch on typed success or failure; do not throw away the `Exit` merely to mimic an untyped async callback. Render `Result` states explicitly, including initial/waiting and failure. Use suspense hooks only when the surrounding React boundary is designed to suspend or surface failures. Inspect `AtomRpc`, `AtomHttpApi`, and hydration modules only when the task uses them; do not load their APIs for ordinary state work. -
next-js.md 2 KB
# Effect 3 and Next.js Use this reference only for projects using `@prb/effect-next`. Inspect the installed package README and declarations before relying on an API because the package is experimental. ## Choose the Boundary Helper - Route handlers: build a named handler with `Next.make(name, layer)` from `@prb/effect-next/handlers`, then expose methods with `Route.build`. - Server actions: provide the application Layer at the action boundary, then use `runServerAction` or `runServerActionOrThrow` from `@prb/effect-next/action` according to the caller's error contract. - Request data: call the Effects exported as `Headers()`, `Cookies()`, and `DraftMode()`; they are not service tags. - Navigation: yield the package navigation helpers so redirects, rewrites, and not-found behavior remain in the Effect control flow. ## Pick the Cache by Lifetime - `reactCache(effectFn)` from `@prb/effect-next/react-cache` deduplicates work within one React request. It rejects Effects requiring `Scope`; move resource acquisition into a Layer. The root export's `reactCache(effect, runtime)` is a different Promise-returning helper. - `cachedEffect` and `cachedEffectWithKey` implement cross-request cache-aside behavior with an explicit store, TTL, optional stale-while-revalidate window, Schema, and failure policy. - Cache-control helpers build browser/CDN headers. Set visibility explicitly and keep browser, generic CDN, and Vercel CDN policies distinct. Reading Headers or Cookies opts the route into dynamic rendering. Keep those reads out of layouts or components that must remain static or CDN-cacheable. ## Middleware and Telemetry Compose middleware through the route builder and package middleware tags/layers; do not hand-roll a parallel handler pipeline. Use the telemetry adapter Layer only when an application supplies the backend. Bound sampling and redact high-cardinality or sensitive values on high-volume routes. Use the package testing kit for its documented Exit and runtime helpers, but preserve the host project's Vitest and `@effect/vitest` conventions. -
option-null.md 897 B
# Option and Nullable Boundaries Use `Option<A>` for meaningful absence inside Effect domain logic. Use `A | null` or `A | undefined` only when the external contract requires it, such as JSON, React state, browser storage, or a third-party API. Normalize once: - incoming nullable value: `Option.fromNullable` at the boundary; - outgoing JSON or React value: `Option.getOrNull` or `Option.getOrUndefined` at the boundary; - optional Schema domain field: `Schema.optionalWith(schema, { as: "Option" })`; - explicitly nullable encoded field: `Schema.NullOr(schema)`. Do not repeatedly wrap an `Option` with `Option.fromNullable`; flatten nested options when separate operations each introduce meaningful absence. Database repositories may return `Option<A>` when no row is normal, then translate `Option.none` to a tagged domain error at the service boundary when the caller requires existence. -
pattern-matching.md 835 B
# Pattern Matching Use `Match` when tagged-union branching should be exhaustive or when a multi-case error handler would otherwise become a chain of nested conditionals. ```ts const renderError = Match.type<AppError>().pipe( Match.tag("ValidationError", (error) => error.message), Match.tag("NetworkError", () => "Connection failed"), Match.exhaustive, ); ``` Use `Match.value` for one local value and `Match.type` when defining a reusable matcher. Prefer `Match.exhaustive` when every variant must be handled; use `Match.orElse` only when the fallback is a real domain case. For a `Data.taggedEnum`, prefer its `$match` helper when generic variant payloads or recursive unions would otherwise require assertions. Verify constructor and matcher signatures against the installed `Data` source before changing a generic union. -
runtime.md 1.3 KB
# Runtime, Resources, and Concurrency ## Resource Lifetimes Acquire resources with `Effect.acquireRelease` or `Effect.acquireUseRelease` and run them in a Scope. Put long-lived clients and background processes in `Layer.scoped`; keep the Layer's Scope owned by the application runtime. Every forked fiber needs an owner and a completion policy: join it, interrupt it, or place it in a Scope that closes. Do not create fire-and-forget fibers whose failures and finalizers become invisible. ## Time and Scheduling Use Effect `Clock`, `Duration`, and `Schedule` instead of ambient time and ad hoc timer loops. Duration inputs accept human-readable strings; preserve the project's established representation rather than normalizing for style alone. Choose retry schedules from failure semantics: retry only transient failures, bound attempts or elapsed time, and keep non-retryable domain failures outside the retry predicate. ## Coordination Primitives - `Ref` owns mutable state accessed by Effects. - `Deferred` is a one-shot synchronization or result handoff. - `SubscriptionRef` owns state plus a stream of changes; construct it with the safe `make` API. Do not reach for unsafe constructors merely to avoid yielding an Effect. For concurrency-sensitive behavior, test the coordination point explicitly rather than assuming a forked fiber has already run. -
schema-jsonschema.md 1.9 KB
# Schema and JSON Schema Use Schema to decode untrusted input once at an IO boundary, then pass validated domain values internally. Prefer the Effect-returning decoder inside Effect code so parse failures stay typed. ```ts import { Schema } from "effect"; const UserId = Schema.NonEmptyTrimmedString.pipe(Schema.brand("UserId")); class User extends Schema.Class<User>("app/User")({ id: UserId, email: Schema.NonEmptyTrimmedString, }) {} const decodeUser = Schema.decodeUnknown(User); ``` ## Model the Domain Precisely - Prefer `Schema.Class` for named entities and API models that need construction, encoding, annotations, or structural equality. - Brand identifiers and constrained primitives instead of weakening them to `Schema.String` or `Schema.Number`. - Use `Schema.TaggedError` for errors that cross encoded boundaries; use `Data.TaggedError` for internal-only errors. - Reuse decoders and encoders at module scope rather than rebuilding them for each request. ## Encode Absence Intentionally - `Schema.optionalWith(schema, { as: "Option" })` is appropriate when absence belongs to the decoded domain model. - `Schema.NullOr(schema)` is appropriate when the encoded contract uses `null`. - Exact optional fields reject unexpected keys when the boundary requires a closed shape. - Avoid `*FromSelf` schemas for JSON contracts unless the input is intentionally already decoded. See [option-null.md](option-null.md) for the project boundary rule. ## JSON Schema Consumers For a closed no-parameter object, use `Schema.Record({ key: Schema.String, value: Schema.Never })` or a library's named equivalent such as `Tool.EmptyParams`. Do not replace it with a loose record. When generating JSON Schema directly, verify `JSONSchema.fromAST` options against the installed source. If generation fails, inspect unsupported AST nodes and missing annotations before weakening the domain schema. -
services-layers.md 2.3 KB
# Services and Layers Use this reference when defining services, choosing Layer boundaries, or composing generator-based business logic. Inspect neighboring services first; preserve the project's established tag and layer style when it is type-safe. ## Choose the Service Shape Deliberately - Use `Context.Tag` when the service interface and its implementations should remain separate. - Use `Effect.Service` when a default implementation and dependency Layer belong with the service declaration. - Use `Context.Reference` for a context value with a safe default, such as a feature flag or policy value. - Use `Effect.provideService` for request-local values such as actor, tenant, locale, or request identifier; do not build a Layer for data that changes per request. ```ts class UserRepository extends Context.Tag("app/UserRepository")< UserRepository, { readonly findById: (id: string) => Effect.Effect<string, never, never> } >() {} ``` Keep stable service identifiers globally unique within the application or package. ## Put Acquisition in the Layer Choose the constructor by lifecycle: - `Layer.succeed` for a ready, pure value; - `Layer.effect` for effectful construction without cleanup; - `Layer.scoped` for acquisition that registers finalizers; - `Layer.unwrapEffect` when an Effect decides which Layer to build. Do not hide effectful or resourceful construction inside `Layer.succeed`. Provide the completed application Layer at a runtime boundary; avoid scattering `Effect.provide` through domain methods unless the local architecture deliberately encapsulates a private dependency. Layers memoize by object identity within a composition. Reuse one Layer value to share an instance. A factory call already creates a distinct Layer; use `Layer.fresh` only when deliberately escaping memoization of the same Layer object. ## Use `Effect.fn` for Reusable Effectful Functions Prefer `Effect.fn("qualifiedName")` for reusable generator functions that benefit from named traces and better stack information. Keep a raw `Effect.gen` for one-off program composition. ```ts const findUser = Effect.fn("UserRepository.findUser")(function* (id: string) { const repository = yield* UserRepository; return yield* repository.findById(id); }); ``` Keep service methods domain-oriented. Avoid exporting one accessor wrapper per method when callers can yield the service directly. -
sql.md 1.1 KB
# Effect SQL Use the installed `@effect/sql` package source for exact driver and helper signatures. Keep SQL at repository boundaries and return domain values rather than unchecked row shapes. ## Decode Rows Prefer `SqlSchema.findOne`, `SqlSchema.findAll`, or `SqlSchema.single` when their cardinality matches the query. A raw SQL type parameter describes a row but does not validate database output. Use precise schemas for identifiers, literals, decimals, and encoded values. Keep absence as `Option<A>` when no row is normal; translate it to a tagged domain error when the service contract requires existence. ## Preserve Repository and Transaction Boundaries Repository services may expose domain errors while retaining driver and decode causes for diagnostics. Map expected SQL or decode failures with `Effect.mapError`; do not map defects through `catchAllCause` in ordinary repository code. Use the client's transaction API for writes that must commit atomically. Include audit, outbox, or ledger writes in the same transaction only when the product invariant requires one commit boundary. -
streams.md 1.2 KB
# Streams and Backpressure Streams are lazy and may be infinite. Before consuming one, determine its termination, backpressure, error, and resource semantics. ## Bound Consumption Never collect a stream that may be infinite without a bound. Use `Stream.take`, `Stream.takeUntil`, a domain termination condition, or an Effect timeout. Prefer `runForEach`, `runFold`, or another incremental consumer when the whole result does not need to be retained. ## Preserve Backpressure and Chunking Streams are pull-based; avoid converting them to eager arrays merely for familiar collection APIs. Use `mapEffect` or `flatMap` when a transformation is effectful, and choose concurrency explicitly. Batch with `grouped` or `groupedWithin` only when the downstream system benefits from the chosen size or time window. ## Own Resources and Failures Use `Stream.acquireRelease`, `Stream.scoped`, or `Stream.ensuring` for resources and cleanup. A consuming Scope must outlive the stream. Recovery with `catchTag`, `catchAll`, or `retry` must preserve the intended domain semantics; do not turn a required failure into an empty stream. Tests must bound streams, advance `TestClock` for scheduled producers, and interrupt or scope background consumers. -
testing.md 1.7 KB
# Testing Effect 3 with Vitest Use `@effect/vitest` for Effect programs. Keep assertions inside the returned Effect and run only the tests covering the changed behavior. ## Choose the Test Runtime - `it.effect` provides Effect's test environment, including `TestClock`. - `it.live` uses live runtime services. - `it.scoped` combines the test environment with a Scope. - `it.scopedLive` combines live services with a Scope. - `layer(...)` shares one Layer across a test block; use nested `it.layer(...)` when a subgroup needs another Layer. Use regular `it` for pure synchronous tests. Do not call `Effect.runPromise`, `runSync`, or another runtime launcher inside an Effect test; that escapes the test runtime and can silently replace test services. ## Advance Virtual Time Deliberately Under `it.effect`, time does not advance until the test calls `TestClock.adjust` or `TestClock.setTime`. Fork the effect that sleeps, retries, polls, or repeats, then advance enough time for the whole schedule and join the fiber. Use `it.live` only when wall-clock behavior is genuinely under test. Production Effect code should read time through `Clock` or `DateTime`, not `Date.now`, so tests can control it. ## Prove Fiber Startup Before Opening Gates Forking schedules a fiber; it does not prove that the fiber reached the intended coordination point. For overlap, deduplication, or sharing tests, have the worker complete a `started` Deferred immediately before awaiting a separate gate. Await `started` before opening the gate. ## Bound and Release Bound infinite streams and polling loops. Join or interrupt every fiber. Use scoped tests when code allocates scoped resources, and let Layer/test scopes own finalizers instead of launching detached runtimes.
-
-
SKILL.md 4.5 KB
--- compatibility: Requires a project using current stable Effect 3 packages; verify exact APIs against the target's installed package source. name: effect-ts description: Use for nontrivial Effect 3 work including services/layers, typed errors, Schema/JSONSchema, Config, runtime/concurrency, @effect/vitest, @effect/ai, @effect/sql, Effect Atom, or @prb/effect-next. --- # Effect 3 Apply Effect 3 semantics from project-local architecture, the narrowest relevant reference, and source matching the target's installed packages. ## Workflow Do not activate this workflow merely because a file imports `effect`. For nontrivial Effect work: 1. Resolve the target package or workspace and its exact installed `effect` and relevant `@effect/*` versions. If `effect` is not 3.x, stop because this skill does not apply. 2. Inspect neighboring services, layers, errors, schemas, runtime boundaries, and tests. Local conventions decide organization; installed package evidence decides API facts. 3. Read `references/critical-rules.md`, then only the task-specific references below. 4. Verify every uncertain import, signature, or behavior against the package installation visible to the target workspace before editing. 5. Implement the smallest pattern consistent with the project and run the narrowest test or typecheck covering the changed semantics. ## Evidence Order Use the target workspace's manifest and lockfile to identify versions. Prefer, in order: 1. the installed package's `src/`, README, tests, and changelog; 2. its emitted declarations when source is not shipped; 3. the matching official package artifact or source tag. Do not install or update dependencies solely to obtain documentation. Do not trust an unrelated checkout or a source branch that does not match the target's installed version. If exact behavior cannot be verified, stop rather than guessing. ## Reference Router | Task | Reference | | ------------------------------------------ | --------------------------------- | | Services, Layers, tags, `Effect.fn` | `references/services-layers.md` | | Config providers and secrets | `references/config.md` | | Schema, JSON Schema, encoded errors/models | `references/schema-jsonschema.md` | | `@effect/vitest`, clocks, fibers, retries | `references/testing.md` | | resources, scheduling, refs, concurrency | `references/runtime.md` | | streams and backpressure | `references/streams.md` | | pattern matching and tagged unions | `references/pattern-matching.md` | | `@effect/ai` | `references/ai.md` | | `@effect/sql` | `references/sql.md` | | Next.js / `@prb/effect-next` | `references/next-js.md` | | Effect Atom | `references/effect-atom.md` | | `Option` at nullable boundaries | `references/option-null.md` | For platform/RPC APIs, collection utilities, deprecations, or constructor lookup, inspect the installed package source directly instead of loading a local API inventory. ## Boundaries - Keep pure helpers, constants, and path manipulation pure unless an Effect boundary provides a concrete dependency, testability, resource-safety, or error-model benefit. - Preserve existing domain facades and service/runtime boundaries unless the user requested redesign. - Prefer typed failures and scoped resources at IO boundaries; choose Schema-backed errors/models only when encoding or boundary validation is needed. - Do not broaden environment requirements merely to replace a small platform call. For changes, completion requires code consistent with local Effect architecture, selected references and installed source where needed, and the narrowest test/typecheck that exercises the changed semantics. Read-only work requires evidence for the reported conclusion. Finish with `### ⚡ Effect — ✅ change complete` after verified edits or `### ⚡ Effect — 🔎 reviewed, no files written` for read-only work, one sentence naming the boundary or pattern used, and `### 🧪 Verification` with exact scoped commands/results. If required validation is incomplete, use `### ⚡ Effect — ⛔ blocked` instead. Add `### ⚠️ Limitation` only for non-blocking caveats. Never decorate typed errors, Schema messages, logs, tests, generated JSON/API responses, or command output.
Comments (0)
Sign in to join the conversation.
Reviews (0)
No reviews yet.
No comments yet.