{"id":49351148,"url":"https://github.com/arrow7000/atproto-fsharp","last_synced_at":"2026-04-27T10:00:55.407Z","repository":{"id":340870100,"uuid":"1167960300","full_name":"Arrow7000/atproto-fsharp","owner":"Arrow7000","description":"Idiomatic F# library for the AT Protocol (atproto/Bluesky)","archived":false,"fork":false,"pushed_at":"2026-03-25T13:02:52.000Z","size":982,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-26T13:31:23.255Z","etag":null,"topics":["atproto","atproto-client","bluesky","bluesky-client","dotnet","fsharp"],"latest_commit_sha":null,"homepage":"https://arrow7000.github.io/atproto-fsharp/","language":"F#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Arrow7000.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-02-26T21:44:53.000Z","updated_at":"2026-03-25T13:03:04.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/Arrow7000/atproto-fsharp","commit_stats":null,"previous_names":["arrow7000/atproto-fsharp"],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/Arrow7000/atproto-fsharp","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Arrow7000%2Fatproto-fsharp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Arrow7000%2Fatproto-fsharp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Arrow7000%2Fatproto-fsharp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Arrow7000%2Fatproto-fsharp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Arrow7000","download_url":"https://codeload.github.com/Arrow7000/atproto-fsharp/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Arrow7000%2Fatproto-fsharp/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32331305,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-26T23:26:28.701Z","status":"online","status_checked_at":"2026-04-27T02:00:06.769Z","response_time":128,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["atproto","atproto-client","bluesky","bluesky-client","dotnet","fsharp"],"created_at":"2026-04-27T10:00:30.266Z","updated_at":"2026-04-27T10:00:55.359Z","avatar_url":"https://github.com/Arrow7000.png","language":"F#","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003c!-- @format --\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://raw.githubusercontent.com/Arrow7000/atproto-fsharp/main/docs/assets/header.svg\" alt=\"FSharp.ATProto\" width=\"400\"/\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://www.nuget.org/packages/FSharp.ATProto.Bluesky\"\u003e\u003cimg src=\"https://img.shields.io/nuget/v/FSharp.ATProto.Bluesky\" alt=\"NuGet\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/Arrow7000/atproto-fsharp/actions/workflows/ci.yml\"\u003e\u003cimg src=\"https://github.com/Arrow7000/atproto-fsharp/actions/workflows/ci.yml/badge.svg\" alt=\"CI\"\u003e\u003c/a\u003e\n  \u003cimg src=\"https://img.shields.io/badge/.NET-10.0-512BD4?logo=dotnet\" alt=\".NET 10\"\u003e\n  \u003cimg src=\"https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/Arrow7000/b4926c04f5a0cf1326acd6be7fab8ef3/raw/test-count.json\" alt=\"Tests\"\u003e\n  \u003ca href=\"https://github.com/Arrow7000/atproto-fsharp/blob/main/LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/badge/license-MIT-blue\" alt=\"License: MIT\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  A native F# library for \u003ca href=\"https://bsky.app\"\u003eBluesky\u003c/a\u003e and the \u003ca href=\"https://atproto.com\"\u003eAT Protocol\u003c/a\u003e.\n  \u003cbr/\u003e\n  Built from the ground up in F#. No C# wrappers. Functional-first.\n\u003c/p\u003e\n\n---\n\n## Install\n\n```bash\ndotnet add package FSharp.ATProto.Bluesky\n```\n\n## Quick Example\n\n```fsharp\nopen FSharp.ATProto.Bluesky\n\ntaskResult {\n    let! agent = Bluesky.login \"https://bsky.social\" \"my-handle.bsky.social\" \"app-password\"\n    let! post = Bluesky.post agent \"Hello from F#! 🦋\"\n    let! like = Bluesky.like agent post // PostRef -\u003e LikeRef (the compiler prevents mix-ups)\n    let! reply = Bluesky.replyTo agent \"Nice thread!\" post // thread root resolved automatically\n    let! _ = Bluesky.undo agent like // generic undo — works on any ref type\n    return reply\n}\n// : Task\u003cResult\u003cPostRef, XrpcError\u003e\u003e — no exceptions, ever\n```\n\n## Design\n\n- **If it compiles, it's correct** -- distinct types for every domain concept (`PostRef`, `LikeRef`, `FollowRef`, `BlockRef`...) mean the compiler catches your mistakes.\n- **The library handles protocol complexity** -- thread roots, rich text facets, chat proxy headers -- all resolved automatically.\n- **Results, not exceptions** -- every public function returns `Result`. No `failwith`, no try/catch.\n- **Rich domain types** -- `PostRef`, `Profile`, `FeedItem`, `ConvoSummary`, `Page\u003c'T\u003e`, and more. Plus convenience functions for search, bookmarks, muting, notifications, and moderation.\n- **Generated from the spec** -- 324 Lexicon schemas compiled to F# types + 237 typed XRPC endpoint wrappers.\n\n## Getting Started\n\nSee the [Quickstart](https://arrow7000.github.io/atproto-fsharp/quickstart) to get up and running in 5 minutes.\n\n## Features\n\n- **Posts** -- create, reply, quote, delete, with automatic rich text detection ([guide](https://arrow7000.github.io/atproto-fsharp/guides/posts))\n- **Rich text** -- mentions, links, and hashtags detected and resolved automatically ([guide](https://arrow7000.github.io/atproto-fsharp/guides/rich-text))\n- **Images** -- upload and attach with typed `ImageMime` and alt text ([guide](https://arrow7000.github.io/atproto-fsharp/guides/media))\n- **Social graph** -- follow, block, like, repost, mute, with typed refs and generic undo ([guide](https://arrow7000.github.io/atproto-fsharp/guides/social))\n- **Feeds** -- timeline, author feed, actor likes, bookmarks ([guide](https://arrow7000.github.io/atproto-fsharp/guides/feeds))\n- **Profiles** -- get, search, typeahead, batch fetch, upsert ([guide](https://arrow7000.github.io/atproto-fsharp/guides/profiles))\n- **Chat / DMs** -- conversations, messages, reactions, with automatic proxy headers ([guide](https://arrow7000.github.io/atproto-fsharp/guides/chat))\n- **Notifications** -- fetch, count unread, mark seen ([guide](https://arrow7000.github.io/atproto-fsharp/guides/notifications))\n- **Moderation** -- report content, mute threads, mod lists, and a full moderation engine ([guide](https://arrow7000.github.io/atproto-fsharp/guides/moderation))\n- **Identity** -- DID resolution, handle verification, PDS discovery ([guide](https://arrow7000.github.io/atproto-fsharp/guides/identity))\n- **Lists** -- create and manage lists and starter packs ([guide](https://arrow7000.github.io/atproto-fsharp/guides/lists))\n- **Preferences** -- saved feeds, muted words, content filtering ([guide](https://arrow7000.github.io/atproto-fsharp/guides/preferences))\n- **Streaming** -- real-time events via Jetstream and Firehose ([guide](https://arrow7000.github.io/atproto-fsharp/guides/streaming))\n- **Video** -- upload and post video content ([guide](https://arrow7000.github.io/atproto-fsharp/guides/media))\n- **Pagination** -- lazy `IAsyncEnumerable` paginators for timeline, followers, notifications ([guide](https://arrow7000.github.io/atproto-fsharp/guides/pagination))\n- **OAuth** -- OAuth 2.0 client with DPoP/PKCE, plus authorization server ([guide](https://arrow7000.github.io/atproto-fsharp/guides/oauth))\n- **Server-side** -- feed generator framework, XRPC server, service auth\n- **Full XRPC access** -- all 237 Bluesky endpoints available as typed wrappers ([guide](https://arrow7000.github.io/atproto-fsharp/guides/raw-xrpc))\n\n## Documentation\n\nFull docs at [arrow7000.github.io/atproto-fsharp](https://arrow7000.github.io/atproto-fsharp/).\n\n- [Quickstart](https://arrow7000.github.io/atproto-fsharp/quickstart) -- zero to first post\n- [Build a Bot](https://arrow7000.github.io/atproto-fsharp/guides/build-a-bot) -- end-to-end tutorial\n- [Concepts](https://arrow7000.github.io/atproto-fsharp/concepts) -- AT Protocol terms explained (DID, Handle, AT-URI, PDS, Lexicon)\n\n\n## Building \u0026 Testing\n\nRequires [.NET 10 SDK](https://dotnet.microsoft.com/download).\n\n```bash\ndotnet build \u0026\u0026 dotnet test\n```\n\n2,623 tests across 14 projects.\n\n## AI Transparency\n\nThis project was built with heavy use of AI coding assistants, mostly Claude Opus 4.6.\n\nTo ensure correctness the project validates against ground truth at every layer:\n\n- **Syntax parsing** -- [tested](tests/FSharp.ATProto.Syntax.Tests/) against the official [AT Protocol interop test vectors](https://github.com/bluesky-social/atproto-interop-tests) (valid and invalid inputs for DIDs, Handles, NSIDs, TIDs, AT-URIs, and more)\n- **CBOR \u0026 CID** -- [tested](tests/FSharp.ATProto.DRISL.Tests/InteropTests.fs) against the interop data-model fixtures (known JSON -\u003e CBOR -\u003e CID round-trips), plus [property-based tests](tests/FSharp.ATProto.DRISL.Tests/PropertyTests.fs) for encoding invariants\n- **Lexicon schemas** -- all 324 real lexicon files from the [official atproto repo](https://github.com/bluesky-social/atproto/tree/main/lexicons) are [parsed and validated](tests/FSharp.ATProto.Lexicon.Tests/RealLexiconTests.fs); the code generator is tested against them\n- **Rich text** -- [property-based tests](tests/FSharp.ATProto.Bluesky.Tests/RichTextTests.fs) verify byte-range correctness and facet ordering\n- **XRPC / Bluesky** -- [tested](tests/FSharp.ATProto.Bluesky.Tests/) via mock HTTP handlers that verify request construction, multi-step orchestration (e.g. thread root resolution), error handling, and domain type mapping (note: the mocks don't validate against real Bluesky API responses -- that contract is covered by the generated types matching the lexicon schemas above)\n\nAll told, 2,623 tests across 14 projects, with zero reliance on manual testing or live API calls.\n\nDocumentation guides are written as [literate F# scripts](https://fsprojects.github.io/FSharp.Formatting/literate.html) (`.fsx` files) -- every code snippet is compiler-checked during the docs build, so examples can never drift out of sync with the library.\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farrow7000%2Fatproto-fsharp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Farrow7000%2Fatproto-fsharp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farrow7000%2Fatproto-fsharp/lists"}