+31
-11
stack/bushel/bin/bushel_common.ml
+31
-11
stack/bushel/bin/bushel_common.ml
······
+16
-19
stack/bushel/bin/bushel_faces.ml
+16
-19
stack/bushel/bin/bushel_faces.ml
·········-) $ Bushel_common.base_dir $ Bushel_common.output_dir ~default:"." $ Bushel_common.handle_opt $-Bushel_common.url_term ~default:"https://photos.recoil.org" ~doc:"Base URL of the Immich instance")+) $ Bushel_common.base_dir $ Bushel_common.output_dir ~default:"." $ Bushel_common.handle_opt $ immiche_profile_term)let info = Cmd.info "faces" ~doc:"Retrieve face thumbnails for Bushel contacts from Immich" in
+158
-181
stack/bushel/bin/bushel_links.ml
+158
-181
stack/bushel/bin/bushel_links.ml
······-let upload_to_karakeep ~sw ~env base_url api_key_opt links_file tag max_concurrent delay_seconds limit verbose =+let upload_to_karakeep ~sw ~env base_url profile links_file tag max_concurrent delay_seconds limit verbose =-(batch_num + 1) batch_successes (List.length batch) new_total (new_total + (List.length links_to_upload - new_total));+(batch_num + 1) batch_successes (List.length batch) new_total (new_total + (List.length links_to_upload - new_total));······-Cmd.v info Term.(const update_from_bushel $ base_dir_arg $ links_file_arg $ include_domains_arg $ exclude_domains_arg)+Cmd.v info Term.(const update_from_bushel $ base_dir_arg $ links_file_arg $ include_domains_arg $ exclude_domains_arg)-Cmd.v info Term.(const (fun base_url api_key_opt links_file tag max_concurrent delay_seconds limit verbose ->-upload_to_karakeep ~sw ~env base_url api_key_opt links_file tag max_concurrent delay_seconds limit verbose)-$ base_url_arg $ api_key_arg $ links_file_arg $ tag_arg $ concurrent_arg $ delay_arg $ limit_arg $ verbose_arg)+Cmd.v info Term.(const (fun base_url profile links_file tag max_concurrent delay_seconds limit verbose ->+upload_to_karakeep ~sw ~env:eio_env base_url profile links_file tag max_concurrent delay_seconds limit verbose)+$ base_url_arg $ profile_term $ links_file_arg $ tag_arg $ concurrent_arg $ delay_arg $ limit_arg $ verbose_arg)
+63
-56
stack/bushel/bin/bushel_main.ml
+63
-56
stack/bushel/bin/bushel_main.ml
······
+25
-23
stack/bushel/bin/bushel_search.ml
+25
-23
stack/bushel/bin/bushel_search.ml
······-Printf.eprintf "Error: API key is required. Use --api-key, set TYPESENSE_API_KEY environment variable, or create .typesense-key file.\n";···
+1
-1
stack/bushel/bin/dune
+1
-1
stack/bushel/bin/dune
+2
stack/bushel/bushel.opam
+2
stack/bushel/bushel.opam
+2
stack/bushel/dune-project
+2
stack/bushel/dune-project
+1
-1
stack/cacheio/bin/dune
+1
-1
stack/cacheio/bin/dune
+136
stack/eiocmd/README.md
+136
stack/eiocmd/README.md
···+Eiocmd provides a convenient wrapper for building command-line applications with [Eio](https://github.com/ocaml-multicore/eio). It handles common setup tasks and provides a clean interface for building CLIs with minimal boilerplate.
+39
stack/eiocmd/dune-project
+39
stack/eiocmd/dune-project
···+"Eiocmd provides a convenient wrapper for building command-line applications with Eio. It handles common setup tasks including: random number generator initialization, logging configuration (logs/fmt), CLI argument parsing (cmdliner), and optional integration with xdge (XDG directories) and keyeio (API key management).")
+39
stack/eiocmd/eiocmd.opam
+39
stack/eiocmd/eiocmd.opam
···+"Eiocmd provides a convenient wrapper for building command-line applications with Eio. It handles common setup tasks including: random number generator initialization, logging configuration (logs/fmt), CLI argument parsing (cmdliner), and optional integration with xdge (XDG directories) and keyeio (API key management)."
+3
stack/eiocmd/example/dune
+3
stack/eiocmd/example/dune
+34
stack/eiocmd/example/eiocmd_example.ml
+34
stack/eiocmd/example/eiocmd_example.ml
···
+4
stack/eiocmd/lib/dune
+4
stack/eiocmd/lib/dune
+62
stack/eiocmd/lib/eiocmd.ml
+62
stack/eiocmd/lib/eiocmd.ml
···
+24
stack/eiocmd/lib/eiocmd.mli
+24
stack/eiocmd/lib/eiocmd.mli
···
+5
-2
stack/karakeepe/dune-project
+5
-2
stack/karakeepe/dune-project
···-(description "An Eio-based OCaml client library for the Karakeep bookmark management service API")+(description "An Eio-based OCaml client library for the Karakeep bookmark management service API, with a command-line interface")···
+4
-1
stack/karakeepe/karakeepe.opam
+4
-1
stack/karakeepe/karakeepe.opam
···+"An Eio-based OCaml client library for the Karakeep bookmark management service API, with a command-line interface"···
+1
-1
stack/keyeio/CLAUDE.md
+1
-1
stack/keyeio/CLAUDE.md
···
+17
-20
stack/keyeio/README.md
+17
-20
stack/keyeio/README.md
············
+1
-1
stack/keyeio/dune-project
+1
-1
stack/keyeio/dune-project
+31
-8
stack/keyeio/example/keyeio_example.ml
+31
-8
stack/keyeio/example/keyeio_example.ml
············Fmt.pr "Authorization: Bearer %s@." (String.sub api_key 0 (min 8 (String.length api_key)) ^ "...");······
+1
-1
stack/keyeio/keyeio.opam
+1
-1
stack/keyeio/keyeio.opam
+1
-1
stack/keyeio/lib/dune
+1
-1
stack/keyeio/lib/dune
+174
-47
stack/keyeio/lib/keyeio.ml
+174
-47
stack/keyeio/lib/keyeio.ml
···+(fun tbl (k, v) -> Toml.Types.Table.add (Toml.Types.Table.Key.of_string k) (Toml.Types.TString v) tbl)···+(Invalid_key_file (Printf.sprintf "Service file '%s.toml' contains no valid profile tables" service))| exn -> Error (`Msg (Printf.sprintf "Error loading service: %s" (Printexc.to_string exn))))·········+Arg.(value & opt (some string) default_val & info [ flag_name ] ~docv:(String.uppercase_ascii key) ~doc)···
+114
-31
stack/keyeio/lib/keyeio.mli
+114
-31
stack/keyeio/lib/keyeio.mli
·································+(** [create_term ~app_name ~fs ~service ~default_data ()] creates a Cmdliner term for creating keyfiles.
+35
-44
stack/keyeio/test/keyeio.t
+35
-44
stack/keyeio/test/keyeio.t
··················
+2
-2
stack/requests/lib/requests.ml
+2
-2
stack/requests/lib/requests.ml
······
+8
-8
stack/river/bin/river_cli.ml
+8
-8
stack/river/bin/river_cli.ml
···-let xdg_term = Xdge.Cmd.term "river" fs ~config:false ~data:false ~cache:false ~runtime:false () in···-let xdg_term = Xdge.Cmd.term "river" fs ~config:false ~data:false ~cache:false ~runtime:false () in···-let xdg_term = Xdge.Cmd.term "river" fs ~config:false ~data:false ~cache:false ~runtime:false () in···-let xdg_term = Xdge.Cmd.term "river" fs ~config:false ~data:false ~cache:false ~runtime:false () in···-let xdg_term = Xdge.Cmd.term "river" fs ~config:false ~data:false ~cache:false ~runtime:false () in···-let xdg_term = Xdge.Cmd.term "river" fs ~config:false ~data:false ~cache:false ~runtime:false () in···-let xdg_term = Xdge.Cmd.term "river" fs ~config:false ~data:false ~cache:false ~runtime:false () in···-let xdg_term = Xdge.Cmd.term "river" fs ~config:false ~data:false ~cache:false ~runtime:false () in
stack/toru/.gitignore
toru/.gitignore
stack/toru/.gitignore
toru/.gitignore
stack/toru/CLAUDE.md
toru/CLAUDE.md
stack/toru/CLAUDE.md
toru/CLAUDE.md
stack/toru/README.md
toru/README.md
stack/toru/README.md
toru/README.md
stack/toru/TODO.md
toru/TODO.md
stack/toru/TODO.md
toru/TODO.md
stack/toru/bin/dune
toru/bin/dune
stack/toru/bin/dune
toru/bin/dune
stack/toru/bin/tessera_loader.ml
toru/bin/tessera_loader.ml
stack/toru/bin/tessera_loader.ml
toru/bin/tessera_loader.ml
stack/toru/bin/toru_cache.ml
toru/bin/toru_cache.ml
stack/toru/bin/toru_cache.ml
toru/bin/toru_cache.ml
stack/toru/bin/toru_cli.ml
toru/bin/toru_cli.ml
stack/toru/bin/toru_cli.ml
toru/bin/toru_cli.ml
stack/toru/bin/toru_main.ml
toru/bin/toru_main.ml
stack/toru/bin/toru_main.ml
toru/bin/toru_main.ml
stack/toru/bin/toru_make_registry.ml
toru/bin/toru_make_registry.ml
stack/toru/bin/toru_make_registry.ml
toru/bin/toru_make_registry.ml
stack/toru/bin/toru_make_registry_simple.ml
toru/bin/toru_make_registry_simple.ml
stack/toru/bin/toru_make_registry_simple.ml
toru/bin/toru_make_registry_simple.ml
stack/toru/dune-project
toru/dune-project
stack/toru/dune-project
toru/dune-project
stack/toru/lib/toru/cache.ml
toru/lib/toru/cache.ml
stack/toru/lib/toru/cache.ml
toru/lib/toru/cache.ml
stack/toru/lib/toru/cache.mli
toru/lib/toru/cache.mli
stack/toru/lib/toru/cache.mli
toru/lib/toru/cache.mli
stack/toru/lib/toru/cmd.ml
toru/lib/toru/cmd.ml
stack/toru/lib/toru/cmd.ml
toru/lib/toru/cmd.ml
stack/toru/lib/toru/downloader.ml
toru/lib/toru/downloader.ml
stack/toru/lib/toru/downloader.ml
toru/lib/toru/downloader.ml
stack/toru/lib/toru/downloader.mli
toru/lib/toru/downloader.mli
stack/toru/lib/toru/downloader.mli
toru/lib/toru/downloader.mli
stack/toru/lib/toru/dune
toru/lib/toru/dune
stack/toru/lib/toru/dune
toru/lib/toru/dune
stack/toru/lib/toru/hash.ml
toru/lib/toru/hash.ml
stack/toru/lib/toru/hash.ml
toru/lib/toru/hash.ml
stack/toru/lib/toru/hash.mli
toru/lib/toru/hash.mli
stack/toru/lib/toru/hash.mli
toru/lib/toru/hash.mli
stack/toru/lib/toru/logging.ml
toru/lib/toru/logging.ml
stack/toru/lib/toru/logging.ml
toru/lib/toru/logging.ml
stack/toru/lib/toru/logging.mli
toru/lib/toru/logging.mli
stack/toru/lib/toru/logging.mli
toru/lib/toru/logging.mli
stack/toru/lib/toru/make_registry.ml
toru/lib/toru/make_registry.ml
stack/toru/lib/toru/make_registry.ml
toru/lib/toru/make_registry.ml
stack/toru/lib/toru/make_registry.mli
toru/lib/toru/make_registry.mli
stack/toru/lib/toru/make_registry.mli
toru/lib/toru/make_registry.mli
stack/toru/lib/toru/processors.ml
toru/lib/toru/processors.ml
stack/toru/lib/toru/processors.ml
toru/lib/toru/processors.ml
stack/toru/lib/toru/processors.mli
toru/lib/toru/processors.mli
stack/toru/lib/toru/processors.mli
toru/lib/toru/processors.mli
stack/toru/lib/toru/registry.ml
toru/lib/toru/registry.ml
stack/toru/lib/toru/registry.ml
toru/lib/toru/registry.ml
stack/toru/lib/toru/registry.mli
toru/lib/toru/registry.mli
stack/toru/lib/toru/registry.mli
toru/lib/toru/registry.mli
stack/toru/lib/toru/toru.ml
toru/lib/toru/toru.ml
stack/toru/lib/toru/toru.ml
toru/lib/toru/toru.ml
stack/toru/lib/toru/toru.mli
toru/lib/toru/toru.mli
stack/toru/lib/toru/toru.mli
toru/lib/toru/toru.mli
+15
-6
stack/xdge/lib/xdge.ml
+15
-6
stack/xdge/lib/xdge.ml
··················-let runtime_dir = make_dir_arg ~enabled:runtime "runtime" "RUNTIME_DIR" "XDG_RUNTIME_DIR" None in+let runtime_dir = make_dir_arg ~enabled:(has_dir `Runtime) "runtime" "RUNTIME_DIR" "XDG_RUNTIME_DIR" None in
+25
-19
stack/xdge/lib/xdge.mli
+25
-19
stack/xdge/lib/xdge.mli
···@see <https://specifications.freedesktop.org/basedir-spec/latest/> XDG Base Directory Specification *)······
+17
-8
stack/zulip/lib/zulip/lib/client.ml
+17
-8
stack/zulip/lib/zulip/lib/client.ml
······
+3
-1
stack/zulip/lib/zulip/lib/client.mli
+3
-1
stack/zulip/lib/zulip/lib/client.mli
···+@param content_type Optional Content-Type header (default: application/x-www-form-urlencoded for POST/PUT, none for GET/DELETE) *)
+62
-3
stack/zulip/lib/zulip/lib/messages.ml
+62
-3
stack/zulip/lib/zulip/lib/messages.ml
···(match narrow with Some n -> List.mapi (fun i s -> ("narrow[" ^ string_of_int i ^ "]", s)) n | None -> []) in+Buffer.add_string body ("Content-Disposition: form-data; name=\"file\"; filename=\"" ^ basename ^ "\"\r\n");+| _ -> Error (Zulip_types.create_error ~code:(Zulip_types.Other "upload_error") ~msg:"Failed to parse upload response" ()))
+41
-1
stack/zulip/lib/zulip/lib/messages.mli
+41
-1
stack/zulip/lib/zulip/lib/messages.mli
···+val add_reaction : Client.t -> message_id:int -> emoji_name:string -> (unit, Zulip_types.zerror) result+val remove_reaction : Client.t -> message_id:int -> emoji_name:string -> (unit, Zulip_types.zerror) result