ActivityPub in OCaml using jsont/eio/requests

Add project metadata for opam release

Prepare the package for publication to aoah-opam-repo with proper
metadata including license, authors, homepage, and CI configuration.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

+185 -6
+17 -1
.gitignore
··· 1 - _build 1 + # OCaml build artifacts 2 + _build/ 3 + *.install 4 + *.merlin 5 + 6 + # Third-party sources (fetch locally with opam source) 7 + third_party/ 8 + 9 + # Editor and OS files 10 + .DS_Store 11 + *.swp 12 + *~ 13 + .vscode/ 14 + .idea/ 15 + 16 + # Opam local switch 17 + _opam/
+1
.ocamlformat
··· 1 + version=0.28.1
+53
.tangled/workflows/build.yml
··· 1 + when: 2 + - event: ["push", "pull_request"] 3 + branch: ["main"] 4 + 5 + engine: nixery 6 + 7 + dependencies: 8 + nixpkgs: 9 + - shell 10 + - stdenv 11 + - findutils 12 + - binutils 13 + - libunwind 14 + - ncurses 15 + - opam 16 + - git 17 + - gawk 18 + - gnupatch 19 + - gnum4 20 + - gnumake 21 + - gnutar 22 + - gnused 23 + - gnugrep 24 + - diffutils 25 + - gzip 26 + - bzip2 27 + - gcc 28 + - ocaml 29 + - pkg-config 30 + 31 + steps: 32 + - name: opam 33 + command: | 34 + opam init --disable-sandboxing -a -y 35 + - name: repo 36 + command: | 37 + opam repo add aoah https://tangled.org/anil.recoil.org/aoah-opam-repo.git 38 + - name: switch 39 + command: | 40 + opam install . --confirm-level=unsafe-yes --deps-only 41 + - name: build 42 + command: | 43 + opam exec -- dune build 44 + - name: switch-test 45 + command: | 46 + opam install . --confirm-level=unsafe-yes --deps-only --with-test 47 + - name: test 48 + command: | 49 + opam exec -- dune runtest --verbose 50 + - name: doc 51 + command: | 52 + opam install -y odoc 53 + opam exec -- dune build @doc
+15
LICENSE.md
··· 1 + ISC License 2 + 3 + Copyright (c) 2025 Anil Madhavapeddy <anil@recoil.org> 4 + 5 + Permission to use, copy, modify, and distribute this software for any 6 + purpose with or without fee is hereby granted, provided that the above 7 + copyright notice and this permission notice appear in all copies. 8 + 9 + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+72
README.md
··· 1 + # apubt - ActivityPub Client Library for OCaml 2 + 3 + An ActivityPub/ActivityStreams protocol implementation for OCaml using Eio for concurrent I/O. Provides typed representations of actors, activities, and objects with bidirectional JSON codecs. 4 + 5 + ## Key Features 6 + 7 + - **Type-safe ActivityPub**: Full OCaml types for actors, activities, objects, and collections 8 + - **JSON codecs**: Bidirectional encoding/decoding using jsont 9 + - **Eio-based HTTP**: Direct-style concurrent I/O with connection pooling 10 + - **HTTP Signatures**: RFC 9421 message signatures for authenticated federation 11 + - **Webfinger**: Actor discovery via RFC 7033 12 + - **NodeInfo**: Server metadata discovery 13 + 14 + ## Usage 15 + 16 + ```ocaml 17 + open Eio.Std 18 + 19 + let () = Eio_main.run @@ fun env -> 20 + Switch.run @@ fun sw -> 21 + 22 + (* Create an ActivityPub client *) 23 + let client = Apubt.create ~sw env in 24 + 25 + (* Discover an actor via Webfinger *) 26 + let actor = Apubt.Actor.lookup client "user@example.com" in 27 + Printf.printf "Found: %s\n" 28 + (Option.value ~default:"<none>" (Apubt.Proto.Actor.name actor)); 29 + 30 + (* Fetch their outbox *) 31 + let outbox = Apubt.Actor.outbox client actor in 32 + List.iter (fun activity -> 33 + Printf.printf "Activity: %s\n" 34 + (Apubt.Proto.Activity_type.to_string (Apubt.Proto.Activity.type_ activity)) 35 + ) (Option.value ~default:[] (Apubt.Proto.Collection.items outbox)) 36 + ``` 37 + 38 + ### With HTTP Signatures 39 + 40 + ```ocaml 41 + (* Configure signing for authenticated requests *) 42 + let signing = Apubt.Signing.from_pem_exn 43 + ~key_id:"https://example.com/users/alice#main-key" 44 + ~pem:private_key_pem 45 + () in 46 + let client = Apubt.create ~sw ~signing env in 47 + 48 + (* Post a public note *) 49 + let _activity = Apubt.Outbox.public_note client 50 + ~actor:my_actor 51 + ~content:"<p>Hello from OCaml!</p>" 52 + () 53 + ``` 54 + 55 + ## Installation 56 + 57 + ``` 58 + opam install apubt 59 + ``` 60 + 61 + ## Documentation 62 + 63 + API documentation is available via: 64 + 65 + ``` 66 + opam install apubt 67 + odig doc apubt 68 + ``` 69 + 70 + ## License 71 + 72 + ISC
+10 -2
apubt.opam
··· 2 2 opam-version: "2.0" 3 3 synopsis: "ActivityPub client library for OCaml with Eio" 4 4 description: 5 - "ActivityPub/ActivityStreams protocol implementation with jsont codecs and Eio-based HTTP client" 5 + "ActivityPub/ActivityStreams protocol implementation for OCaml. Provides typed representations of ActivityPub actors, activities, and objects with bidirectional JSON codecs using jsont. Includes an Eio-based HTTP client for federation with HTTP signature support." 6 + maintainer: ["Anil Madhavapeddy <anil@recoil.org>"] 7 + authors: ["Anil Madhavapeddy"] 8 + license: "ISC" 9 + homepage: "https://tangled.org/@anil.recoil.org/ocaml-apubt" 10 + bug-reports: "https://tangled.org/@anil.recoil.org/ocaml-apubt/issues" 6 11 depends: [ 7 - "dune" {>= "3.0"} 12 + "dune" {>= "3.20"} 8 13 "ocaml" {>= "5.1.0"} 9 14 "jsont" {>= "0.2.0"} 10 15 "jsont-bytesrw" ··· 14 19 "cmdliner" {>= "1.2.0"} 15 20 "logs" {>= "0.7.0"} 16 21 "fmt" {>= "0.9.0"} 22 + "ptime" 23 + "x509" 17 24 "odoc" {with-doc} 18 25 ] 19 26 build: [ ··· 30 37 "@doc" {with-doc} 31 38 ] 32 39 ] 40 + x-maintenance-intent: ["(latest)"]
+17 -3
dune-project
··· 1 - (lang dune 3.0) 1 + (lang dune 3.20) 2 2 (name apubt) 3 3 4 4 (generate_opam_files true) 5 5 6 + (license ISC) 7 + (authors "Anil Madhavapeddy") 8 + (homepage "https://tangled.org/@anil.recoil.org/ocaml-apubt") 9 + (maintainers "Anil Madhavapeddy <anil@recoil.org>") 10 + (bug_reports "https://tangled.org/@anil.recoil.org/ocaml-apubt/issues") 11 + (maintenance_intent "(latest)") 12 + 6 13 (package 7 14 (name apubt) 8 15 (synopsis "ActivityPub client library for OCaml with Eio") 9 - (description "ActivityPub/ActivityStreams protocol implementation with jsont codecs and Eio-based HTTP client") 16 + (description 17 + "ActivityPub/ActivityStreams protocol implementation for OCaml. \ 18 + Provides typed representations of ActivityPub actors, activities, \ 19 + and objects with bidirectional JSON codecs using jsont. Includes \ 20 + an Eio-based HTTP client for federation with HTTP signature support.") 10 21 (depends 11 22 (ocaml (>= 5.1.0)) 12 23 (jsont (>= 0.2.0)) ··· 16 27 (requests (>= 0.1.0)) 17 28 (cmdliner (>= 1.2.0)) 18 29 (logs (>= 0.7.0)) 19 - (fmt (>= 0.9.0)))) 30 + (fmt (>= 0.9.0)) 31 + ptime 32 + x509 33 + (odoc :with-doc)))