NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
pub.dev · #3662 most downloaded on pub.dev
The most famous and powerful Dart/Flutter library for AT Protocol.
Last release 2 months ago
09 Aug 2026
Release timing varies
gaps range from 8 days to 3 months
Nearly every release is documented
notes for 60 of the last 60 stable releases
Nothing withdrawn
no release was ever pulled
4 years old
136 releases · first in 2023
One column per quarter.
feat: added Firehose, a durable com.atproto.sync.subscribeRepos consumer. It connects, hands each decoded message to a handler, reconnects with expone
Firehose, a durable com.atproto.sync.subscribeRepos consumer. It connects, hands each decoded message to a handler, reconnects with exponential backoff and jitter when the relay drops the connection, and — the part that was missing — persists how far it got so a restart resumes instead of skipping to the live edge. subscribeReposAsMessages is unchanged; Firehose is a layer on top of it, not a replacement.CursorStore (with an InMemoryCursorStore default), the injection point for durable cursor storage, matching the OAuthStateStore / OAuthSessionStore / DPoPNonceCache pattern. delete() is part of the interface because a relay answers a cursor that is ahead of its own stream with FutureCursor on every reconnect: without a way to discard the cursor, a consumer that has read past its relay never recovers.Firehose takes a handler rather than exposing a Stream. A stream can only report when a message was delivered, never when the consumer finished with it, so advancing the cursor on delivery would lose everything in flight when a process dies — the exact loss a persisted cursor exists to prevent. The completion of the handler's future is the only evidence a message was handled, so delivery is at-least-once and handlers should be idempotent.flushEveryEvents, default 100; flushEveryInterval, default 5s) because the full-network firehose runs at hundreds to thousands of events per second and a write per message would put the store on the hot path. The replay window after a crash is bounded by those same settings, and a flush is forced before every reconnect and on stop().#info OutdatedCursor is surfaced through onError as FirehoseOutdatedCursorException instead of passing silently. It means the relay no longer holds the requested cursor and resumed from the oldest event it does hold, so events have already been lost — without the signal the caller has no way to notice the gap.fix: ATProto.fromOAuthSession passes its timeout through to the OAuthSessionManager it builds, so a hung restore or refresh is bounded by the timeout
ATProto.fromOAuthSession passes its timeout through to the OAuthSessionManager it builds, so a hung restore or refresh is bounded by the timeout the caller asked for instead of running unbounded.feat: added com.atproto.server.describeServer.output.blobUploadLimit
com.atproto.server.describeServer.output.blobUploadLimitchore: bump atproto_core to ^2.4.0, picking up the decodeCar CAR-header validation, the true 5xx status code on RetryContext, the stale-401 refresh sh
atproto_core to ^2.4.0, picking up the decodeCar CAR-header validation, the true 5xx status code on RetryContext, the stale-401 refresh short-circuit and ServiceContext.withAdditionalHeaders.feat: added ATProto.actorDid, surfacing ServiceContext.actorDid so callers can ask which actor a client is authenticated as without branching on the a
ATProto.actorDid, surfacing ServiceContext.actorDid so callers can ask which actor a client is authenticated as without branching on the auth kind. Named actorDid rather than repo, which is already the com.atproto.repo.* service on this class.fromOAuth now records that one shared OAuthSessionManager is what makes several clients share a session, and fromOAuthSession that it mints a fresh manager per call. Two managers restored from one OAuthSession do not merely fail to share: because a rotating refresh token is only honoured once, they revoke each other, surfacing OAuthSessionRevokedException from a session that was valid.atproto_core to ^2.3.0.chore: widen atproto_core to ^2.2.0 and xrpc to ^1.1.3.
atproto_core to ^2.2.0 and xrpc to ^1.1.3.feat: added ATProto.onSessionUpdated, surfacing ServiceContext.onSessionUpdated so callers can re-persist credentials rotated by an automatic refresh.
ATProto.onSessionUpdated, surfacing ServiceContext.onSessionUpdated so callers can re-persist credentials rotated by an automatic refresh. Without it an app that persists the session it constructed the client with ends up storing a spent refresh token, since refresh tokens are single-use.atproto_core to ^2.1.0.feat: added ATProto.ctx, exposing the ServiceContext that backs every service. A wrapping client can now drive its own services from the same context
ATProto.ctx, exposing the ServiceContext that backs every service. A wrapping client can now drive its own services from the same context instead of constructing a second one, which is required for correct session refresh because refresh tokens are single-use.docs: documented OAuth authentication in the README — ATProto.fromOAuth(OAuthSessionManager), ATProto.fromOAuthSession(session, {oauthClient}), and th
ATProto.fromOAuth(OAuthSessionManager), ATProto.fromOAuthSession(session, {oauthClient}), and the renamed oAuthSessionManager getter.atproto.sync.subscribeReposAsMessages() API, keeping the raw subscribeRepos() + SyncSubscribeReposAdaptor path as the advanced alternative.retryConfig accepts any RetryStrategy, with RetryStrategy/RetryContext/RetryReason re-exported from core.dart.atproto_core to ^2.0.1 and xrpc to ^1.1.2.feat!: ATProto.fromOAuth(OAuthSessionManager). fromOAuthSession(session, {oauthClient}) now wraps a manager (pass oauthClient for auto-refresh); the o
ATProto.fromOAuth(OAuthSessionManager). fromOAuthSession(session, {oauthClient}) now wraps a manager (pass oauthClient for auto-refresh); the oAuthSession getter is replaced by oAuthSessionManager.Subscription, SyncServiceImpl, and WebSocketChannelFactory so subscription/sync return types are usable without a direct atproto_core/xrpc dependency.email/emailConfirmed/emailAuthFactor.retryConfig parameter now accepts any RetryStrategy, not only RetryConfig, so callers can fully customize backoff and which failures retry. RetryStrategy/RetryContext/RetryReason are re-exported. By default a procedure (POST) is no longer retried after an ambiguous failure the server may already have applied (see atproto_core).feat: added atproto.sync.subscribeReposAsMessages(), a Firehose subscription that yields already-decoded, typed USyncSubscribeReposMessages (CBOR/CAR-
atproto.sync.subscribeReposAsMessages(), a Firehose subscription that yields already-decoded, typed USyncSubscribeReposMessages (CBOR/CAR-decoded blocks, normalized ops/commit/prevData CID links) instead of raw Uint8List frames. The existing subscribeRepos() (raw bytes) is unchanged, and a frame that fails to decode surfaces as a stream error without terminating the subscription.package:atproto/firehose.dart now re-exports the com.atproto.sync.subscribeRepos message types, so a single import provides the adaptors, the typed USyncSubscribeReposMessage, and its isCommit/commit accessors.feat: automatic access-token refresh in ATProto.fromSession (wired through com.atproto.server.refreshSession); atproto.session reflects the new creden
ATProto.fromSession (wired through com.atproto.server.refreshSession); atproto.session reflects the new credentials. fromOAuthSession is untouched, and all new parameters are optional (non-breaking).ref int-list heuristic in cid_links that allowed any network user to crash every Firehose consumer by publishing a record containing "ref": [1,2,3] (A-3).#commit prevData/prev CID links are now converted, so sync v1.1 commits no longer degrade to unknown (A-1).#sync frame blocks are decoded into a typed Sync event (account migration/recovery) (A-2).op == -1, e.g. FutureCursor/ConsumerTooSlow) now surface as a typed FirehoseErrorException, and text frames raise a typed FirehoseFrameException instead of a TypeError (A-8/A-10).protocol is now forwarded in create/refresh/deleteSession (A-7).lex_gen ($type injection, UTC datetime, required+nullable serialization).convertCidLinks no-op (and its call in the firehose adaptor) — CID links and byte strings are already normalized by decodeCar in atproto_core.lex_gen — a string field with both knownValues and a default is now non-nullable and carries its spec default instead of reporting null: com.atproto.label.defs#labelValueDefinition.defaultSetting (warn) and com.atproto.admin.getInviteCodes.sort (recent). The corresponding hasX/hasNotX getters were removed (G-18).atproto_core to ^1.3.0.chore: bump atproto_core to ^1.2.2.
atproto_core to ^1.2.2.feat: added com.germnetwork.declaration record.
com.germnetwork.declaration record.- core: generated code.
- core: generated code.
fix: optional jwt scope and auth identity.
- chore: Sync Lexicon Data. - (#2173) - (#2175) - (#2177) - fix: Codegen errors.
- chore: Sync Lexicon Data.
FIX: Fixed type compatibility issues with AtUri parameters
IMPROVEMENT: Enhanced union type classes with sealed class implementation
sealed classes instead of abstract classesfeat: Added Admin and Lexicon services to ATProto
com.atproto.admin.* endpointscom.atproto.lexicon.* endpointsMIGRATION: Updated to use the consolidated at_primitives package for all AT Protocol primitive types.
at_primitives package for all AT Protocol primitive types.at_primitives.feat: Version bump to v1.1.0 to reflect enhanced AT Protocol capabilities
com.atproto.temp.dereferenceScope endpointchore: Update source files automatically
com.atproto.temp.dereferenceScope endpoint for temporary scope dereferencing operationsBREAKING CHANGE: Enhanced lexicon known values naming with proper camelCase convention
reasonAppeal → toolsOzoneReportDefsReasonAppeal)chore: Sync Lexicon Data. (#2105, #2107)
fix: Drop universal_io for WASM compatibility.
universal_io for WASM compatibility.chore: fix WARNING: The annotation 'JsonSerializable.new' can only be used on classes..
WARNING: The annotation 'JsonSerializable.new' can only be used on classes..Add service functions. Endpoints can be easily called as functions like comAtprotoIdentityResolveDid
comAtprotoIdentityResolveDidServiceContext from core library.chore: Removed outdated processes.
@JsonSerializable(includeIfNull: false) for lex gen objects.get, list, create, put and delete operations for each record.chore: Update source files automatically. (##2081)
Fix SDK constraint to '">=3.8.0 <4.0.0"'.
Improved firehose conversion process. Use SyncSubscribeReposAdaptor to convert byte data from subscribeRepos.
SyncSubscribeReposAdaptor to convert byte data from subscribeRepos.$unknown cannot override a known field. (#2068)Nothing published for this version
Bump SDK constraint to '^3.8.0'.
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
- Bump xrpc.
xrpc.- Expose JwtExtension.
JwtExtension.Retry if a DPoP nonce error occurs during the execution of OAuthClient.refresh.
OAuthClient.refresh.restoreOAuthSession function.Add .fromOAuthSession constructor on ATProto.
atproto_oauth package..fromOAuthSession constructor on ATProto.AuthToken to Jwt.
scope from enum to Stringsubject to subexpiresAt to expissuedAt to iatSession
accessToken to accessTokenJwtrefreshToken to refreshTokenJwtAdd service parameter on ATProto.get and ATProto.post.
atproto_core.service parameter on ATProto.get and ATProto.post. (#1783)exp and lxm parameters on ServerService.getServiceAuth.Fixed a bug that prevented RepoService.deleteRecord from working.
RepoService.deleteRecord from working.- Bump atproto_core.
atproto_core.Expose .atprotoPdsEndpoint from as an extension of Session. You can get specific pds endpoint based on did document.
.atprotoPdsEndpoint from as an extension of Session. You can get specific pds endpoint based on did document.Expose .accessToken and .refreshToken as an extension from Session.
.accessToken and .refreshToken as an extension from Session.Change the type .collection property from String to NSID on AtUri. You need to do .collection.toString() when you want a string of collection.
.collection property from String to NSID on AtUri. You need to do .collection.toString() when you want a string of collection. (#1551)package:bluesky/atproto.dart => atproto featurespackage:bluesky/core.dart => core featuresThe service is automatically resolved from the DID Document of the given Session.
service is automatically resolved from the DID Document of the given Session. (#1543)
Session is passed, the default bsky.social is used.service, it always respects the value of the user's service.bsky.social as default.Fixed a bug that prevented toJson on freezed objects from atproto_core.
atproto_core.Add .active and .status properties on Session and CurrentSession objects.
.active and .status properties on Session and CurrentSession objects. (#1516)BlobConverter, Blob, BlobRef from atproto package to atproto_core..active and .status properties on Repo object. (#1517).getRepoStatus method on SyncService. (#1517)SubscribedRepoCommit -> CommitSubscribedRepoIdentity -> IdentitySubscribedRepoHandle -> HandleSubscribedRepoMigrate -> MigrateSubscribedRepoTombstone -> TombstoneSubscribedRepoInfo -> InfoAccount -> CreateAccountOutputaccount event on SyncService.subscribeRepos. (#1517)Nothing published for this version
Nothing published for this version
Nothing published for this version
Your coding agent can read these notes before it upgrades. Set up the MCP server →