(** Configuration of the opam hooks (the three wrapper fields in [~/.opam/config]). Changes are applied with the user's own [opam option], never by writing the config file directly, so the file always matches the opam version that owns it. *) val fields : exe:string -> (string * string * string) list (** The wrapper fields, the command to append to each, and a substring identifying our command if already present. The per-package hooks are plain coreutils ([mkdir]/[touch]/[rm]) so they work without odd installed; only the post-session worker invokes the binary at [exe]. *) val print : exe:string -> unit (** Print the [opam option] invocations that {!apply} would run. *) val apply : exe:string -> (unit, [ `Msg of string ]) result (** Run them, skipping any field that already mentions [exe]. *)