OCaml client library for Claude Code
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

codec: let open Json.Codec in cleanup across claude + bottler

Reduce Json.Codec. qualifier noise in codec-heavy bodies. Pattern:
each [let X : ... Json.codec = ...] body opens [Json.Codec] at the
top of its expression, so combinators ([Object.map], [string], [int],
[list], [bool], [enum], etc.) resolve unqualified.

Files cleaned:

- ocaml-claude/lib/{outgoing,options,client,model}.ml -- the
case_mem chains and Object.map pipelines now read like the
encodings-skill examples instead of being hidden behind the
Json.Codec. prefix.
- bottler/lib/config.ml -- six Object.map pipelines (dep_type,
head_dep, linux_mode, build, package, storage, tap, jsont) all
use the open. The package one needed explicit (p : package) and
: package annotations because Json.Codec.mem_map carries fields
named [name] / [enc] that would otherwise shadow the package
record's fields under the open.

The lesson for future cleanups: any record whose field names clash
with mem_map's fields ([name], [doc], [type'], [id], [dec_absent],
[enc], [enc_omit]) needs anchoring annotations on the constructor
function and on each [~enc] lambda. Most records in this repo
don't clash, but the [name]/[enc] case is common enough to call
out.

+55 -58
+6 -6
lib/client.ml
··· 31 31 type t = { matcher : string option; hook_callback_ids : string list } 32 32 33 33 let json : t Json.codec = 34 + let open Json.Codec in 34 35 let make matcher hook_callback_ids = { matcher; hook_callback_ids } in 35 - Json.Codec.Object.map ~kind:"HookMatcherWire" make 36 - |> Json.Codec.Object.opt_mem "matcher" Json.Codec.string ~enc:(fun r -> 37 - r.matcher) 38 - |> Json.Codec.Object.mem "hookCallbackIds" 39 - (Json.Codec.list Json.Codec.string) ~enc:(fun r -> r.hook_callback_ids) 40 - |> Json.Codec.Object.finish 36 + Object.map ~kind:"HookMatcherWire" make 37 + |> Object.opt_mem "matcher" string ~enc:(fun r -> r.matcher) 38 + |> Object.mem "hookCallbackIds" (list string) ~enc:(fun r -> 39 + r.hook_callback_ids) 40 + |> Object.finish 41 41 42 42 let encode matchers = 43 43 List.map
+2 -1
lib/model.ml
··· 45 45 | s -> `Custom s 46 46 47 47 let json : t Json.codec = 48 - Json.Codec.map ~kind:"Model" ~dec:of_string ~enc:to_string Json.Codec.string 48 + let open Json.Codec in 49 + map ~kind:"Model" ~dec:of_string ~enc:to_string string
+30 -35
lib/options.ml
··· 11 11 type setting_source = User | Project | Local 12 12 13 13 let setting_source_jsont : setting_source Json.codec = 14 - Json.Codec.enum [ ("user", User); ("project", Project); ("local", Local) ] 14 + let open Json.Codec in 15 + enum [ ("user", User); ("project", Project); ("local", Local) ] 15 16 16 17 type t = { 17 18 allowed_tools : string list; ··· 155 156 unknown; 156 157 } 157 158 in 158 - Json.Codec.Object.( 159 - map ~kind:"Options" make 160 - |> mem "allowedTools" 161 - (Json.Codec.list Json.Codec.string) 162 - ~enc:allowed_tools ~dec_absent:[] 163 - |> mem "disallowedTools" 164 - (Json.Codec.list Json.Codec.string) 165 - ~enc:disallowed_tools ~dec_absent:[] 166 - |> opt_mem "maxThinkingTokens" Json.Codec.int ~enc:max_thinking_tokens 167 - |> opt_mem "systemPrompt" Json.Codec.string ~enc:system_prompt 168 - |> opt_mem "appendSystemPrompt" Json.Codec.string 169 - ~enc:append_system_prompt 170 - |> opt_mem "permissionMode" Permissions.Mode.json ~enc:permission_mode 171 - |> opt_mem "model" Model.json ~enc:model 172 - |> mem "continueConversation" Json.Codec.bool ~enc:continue_conversation 173 - ~dec_absent:false 174 - |> opt_mem "resume" Json.Codec.string ~enc:resume 175 - |> opt_mem "maxTurns" Json.Codec.int ~enc:max_turns 176 - |> opt_mem "permissionPromptToolName" Json.Codec.string 177 - ~enc:permission_prompt_tool_name 178 - |> opt_mem "settings" Json.Codec.string ~enc:settings 179 - |> mem "addDirs" 180 - (Json.Codec.list Json.Codec.string) 181 - ~enc:add_dirs ~dec_absent:[] 182 - |> opt_mem "maxBudgetUsd" Json.Codec.number ~enc:max_budget_usd 183 - |> opt_mem "fallbackModel" Model.json ~enc:fallback_model 184 - |> opt_mem "settingSources" 185 - (Json.Codec.list setting_source_jsont) 186 - ~enc:setting_sources 187 - |> opt_mem "maxBufferSize" Json.Codec.int ~enc:max_buffer_size 188 - |> opt_mem "user" Json.Codec.string ~enc:user 189 - |> opt_mem "outputFormat" Structured_output.json ~enc:output_format 190 - |> keep_unknown Unknown.mems ~enc:unknown 191 - |> finish) 159 + let open Json.Codec in 160 + Object.map ~kind:"Options" make 161 + |> Object.mem "allowedTools" (list string) ~enc:allowed_tools ~dec_absent:[] 162 + |> Object.mem "disallowedTools" (list string) ~enc:disallowed_tools 163 + ~dec_absent:[] 164 + |> Object.opt_mem "maxThinkingTokens" int ~enc:max_thinking_tokens 165 + |> Object.opt_mem "systemPrompt" string ~enc:system_prompt 166 + |> Object.opt_mem "appendSystemPrompt" string ~enc:append_system_prompt 167 + |> Object.opt_mem "permissionMode" Permissions.Mode.json 168 + ~enc:permission_mode 169 + |> Object.opt_mem "model" Model.json ~enc:model 170 + |> Object.mem "continueConversation" bool ~enc:continue_conversation 171 + ~dec_absent:false 172 + |> Object.opt_mem "resume" string ~enc:resume 173 + |> Object.opt_mem "maxTurns" int ~enc:max_turns 174 + |> Object.opt_mem "permissionPromptToolName" string 175 + ~enc:permission_prompt_tool_name 176 + |> Object.opt_mem "settings" string ~enc:settings 177 + |> Object.mem "addDirs" (list string) ~enc:add_dirs ~dec_absent:[] 178 + |> Object.opt_mem "maxBudgetUsd" number ~enc:max_budget_usd 179 + |> Object.opt_mem "fallbackModel" Model.json ~enc:fallback_model 180 + |> Object.opt_mem "settingSources" (list setting_source_jsont) 181 + ~enc:setting_sources 182 + |> Object.opt_mem "maxBufferSize" int ~enc:max_buffer_size 183 + |> Object.opt_mem "user" string ~enc:user 184 + |> Object.opt_mem "outputFormat" Structured_output.json ~enc:output_format 185 + |> Object.keep_unknown Unknown.mems ~enc:unknown 186 + |> Object.finish 192 187 193 188 let pp ppf t = Json.pp_value json () ppf t 194 189 end
+17 -16
lib/outgoing.ml
··· 9 9 | Control_response of Control.control_response 10 10 11 11 let json : t Json.codec = 12 + let open Json.Codec in 12 13 let case_control_request = 13 - Json.Codec.Object.Case.map "control_request" Control.control_request_jsont 14 + Object.Case.map "control_request" Control.control_request_jsont 14 15 ~dec:(fun v -> Control_request v) 15 16 in 16 17 let case_control_response = 17 - Json.Codec.Object.Case.map "control_response" Control.control_response_jsont 18 + Object.Case.map "control_response" Control.control_response_jsont 18 19 ~dec:(fun v -> Control_response v) 19 20 in 20 21 let case_user = 21 - Json.Codec.Object.Case.map "user" Message.User.outgoing_jsont ~dec:(fun v -> 22 + Object.Case.map "user" Message.User.outgoing_jsont ~dec:(fun v -> 22 23 Message (Message.User v)) 23 24 in 24 25 let case_assistant = 25 - Json.Codec.Object.Case.map "assistant" Message.Assistant.json ~dec:(fun v -> 26 + Object.Case.map "assistant" Message.Assistant.json ~dec:(fun v -> 26 27 Message (Message.Assistant v)) 27 28 in 28 29 let case_system = 29 - Json.Codec.Object.Case.map "system" Message.System.json ~dec:(fun v -> 30 + Object.Case.map "system" Message.System.json ~dec:(fun v -> 30 31 Message (Message.System v)) 31 32 in 32 33 let case_result = 33 - Json.Codec.Object.Case.map "result" Message.Result.json ~dec:(fun v -> 34 + Object.Case.map "result" Message.Result.json ~dec:(fun v -> 34 35 Message (Message.Result v)) 35 36 in 36 37 let enc_case = function 37 - | Control_request v -> Json.Codec.Object.Case.value case_control_request v 38 - | Control_response v -> Json.Codec.Object.Case.value case_control_response v 38 + | Control_request v -> Object.Case.value case_control_request v 39 + | Control_response v -> Object.Case.value case_control_response v 39 40 | Message msg -> ( 40 41 match msg with 41 - | Message.User u -> Json.Codec.Object.Case.value case_user u 42 - | Message.Assistant a -> Json.Codec.Object.Case.value case_assistant a 43 - | Message.System s -> Json.Codec.Object.Case.value case_system s 44 - | Message.Result r -> Json.Codec.Object.Case.value case_result r) 42 + | Message.User u -> Object.Case.value case_user u 43 + | Message.Assistant a -> Object.Case.value case_assistant a 44 + | Message.System s -> Object.Case.value case_system s 45 + | Message.Result r -> Object.Case.value case_result r) 45 46 in 46 47 let cases = 47 - Json.Codec.Object.Case. 48 + Object.Case. 48 49 [ 49 50 make case_control_request; 50 51 make case_control_response; ··· 54 55 make case_result; 55 56 ] 56 57 in 57 - Json.Codec.Object.map ~kind:"Outgoing" Fun.id 58 - |> Json.Codec.Object.case_mem "type" Json.Codec.string ~enc:Fun.id ~enc_case 58 + Object.map ~kind:"Outgoing" Fun.id 59 + |> Object.case_mem "type" string ~enc:Fun.id ~enc_case 59 60 cases ~tag_to_string:Fun.id ~tag_compare:String.compare 60 - |> Json.Codec.Object.finish 61 + |> Object.finish 61 62 62 63 let pp ppf t = Json.pp_value json () ppf t 63 64