npx claudepluginhub avsm/ocaml-claude-marketplace --plugin ocaml-devThis skill uses the workspace's default tool permissions.
**Effects for control flow, exceptions for errors.**
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Searches prompts.chat for AI prompt templates by keyword or category, retrieves by ID with variable handling, and improves prompts via AI. Use for discovering or enhancing prompts.
Checks Next.js compilation errors using a running Turbopack dev server after code edits. Fixes actionable issues before reporting complete. Replaces `next build`.
Effects for control flow, exceptions for errors.
| Concern | Mechanism | Example |
|---|---|---|
| Suspension (wait for data) | Effects | perform Block, perform Yield |
| Error (EOF, malformed) | Exceptions | raise End_of_file, Invalid_argument |
Effects should be handled at the source level, not in protocol parsers:
Application
↓
Protocol parser (Binary.Reader, Cbor, etc.)
↓ raises exceptions on EOF/error
bytesrw (effect-agnostic)
↓ just calls pull function
Source (Eio flow, affect fd, Unix fd)
↓ performs effects for suspension
Effect handler (Eio scheduler, affect runtime)
Effects are internal to the scheduler. User code looks synchronous:
(* Reading blocks via internal effects *)
let data = Eio.Flow.read flow buf
Explicit effects for fiber scheduling:
type _ Effect.t +=
| Block : 'a block -> 'a Effect.t (* suspension *)
| Await : await -> unit Effect.t (* wait on fibers *)
| Yield : unit Effect.t (* cooperative yield *)
(* Block has callbacks for scheduler integration *)
type 'a block = {
block : handle -> unit; (* register blocked fiber *)
cancel : handle -> bool; (* handle cancellation *)
return : handle -> 'a (* extract result *)
}
Effect-agnostic streaming. The pull function you provide can perform any effects:
(* bytesrw just calls your function *)
let reader = Bytesrw.Bytes.Reader.make my_pull_fn
(* If my_pull_fn performs Eio effects, they propagate *)
(* If my_pull_fn performs affect Block, they propagate *)
(* bytesrw doesn't care - it just calls the function *)
Wire effect-performing sources to effect-agnostic libraries:
(* With Eio *)
let reader = Bytesrw_eio.bytes_reader_of_flow flow in
let r = Binary.Reader.of_reader reader in
parse r (* Eio effects happen in pull function *)
(* With affect *)
let pull () =
let buf = Bytes.create 4096 in
perform (Block { block; cancel; return = fun _ ->
Slice.make buf ~first:0 ~length:n })
in
let reader = Bytesrw.Bytes.Reader.make pull in
parse (Binary.Reader.of_reader reader)
Slice.eod from bytesrw means final EOF - no more data will ever come.
Don't: Define Await effect in protocol parsers
(* WRONG - parser shouldn't know about suspension *)
let get_byte t =
if no_data then perform Await; ...
Do: Let the source handle suspension
(* RIGHT - parser just reads, source handles waiting *)
let get_byte t =
match pull_next_slice t with (* may perform effects *)
| Some slice -> ...
| None -> raise End_of_file (* true EOF *)