commits
- scripts/publish-docs.zig: uses zat to publish README, roadmap, and
changelog as site.standard.document records
- .tangled/workflows/publish-docs.yml: triggers on v* tags
- build.zig: adds publish-docs executable target
requires ATPROTO_HANDLE and ATPROTO_PASSWORD secrets in repo settings.
馃 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The README links to docs/roadmap.md which works on GitHub/Tangled,
but when copied to site-out/docs/ context, the path became double-prefixed.
馃 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
could probably use threaded workers for trying both methods at the same time in the future.
documents new sync types, migration guide, and library overview.
馃 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
new enums from com.atproto.sync.subscribeRepos lexicon:
- CommitAction: create, update, delete
- EventKind: commit, sync, identity, account, info
- AccountStatus: takendown, suspended, deleted, etc.
these work with std.json automatic enum parsing, enabling
exhaustive switches instead of mem.eql string comparisons.
bumps version to 0.1.0 (new feature, backwards compatible).
馃 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
馃 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
https://github.com/ziglang/zig/issues/25021
馃 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
the stdlib deflate decompressor panics with "reached unreachable code"
on certain gzip responses when running on x86_64-linux. setting
Accept-Encoding: identity avoids triggering the decompressor.
馃 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
bsky.app -> did:plc:z72i7hdynmk6r22z27h6tvur
馃 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
using tangled CI now
馃 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
馃 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
uses official test vectors from bluesky-social/indigo:
- ES256K (secp256k1) signature verification
- ES256 (P-256) signature verification
- reject wrong key test
馃 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
adds:
- handle resolution via HTTP well-known
- fixes memory leak in DID resolver test
馃 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
馃 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
std.http.Client internals leak memory that std.testing.allocator catches.
wrap test in arena allocator to handle cleanup, matching pattern in
handle_resolver tests.
馃 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
resolves handles to DIDs using https://{handle}/.well-known/atproto-did
note: DNS TXT resolution (_atproto.{handle}) not implemented as zig std
doesn't provide TXT record lookup. HTTP method is the primary fallback
per atproto spec.
馃 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
馃 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- fix use-after-free in jwt payload parsing (dupe strings)
- fix crypto.sign.ecdsa path for zig 0.15
- fix test token to have correct 64-byte signature
- use arena allocator in extractAt tests to avoid leaks
馃 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
馃 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- jwt.zig: parse and verify ES256/ES256K tokens
- multibase.zig: base58btc decoding for DID document keys
- multicodec.zig: parse secp256k1/p256 key types from prefix
follows atproto.com/specs/xrpc service auth spec
馃 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- DidDocument: parse did documents from json
- DidResolver: resolve did:plc and did:web
- XrpcClient: call AT Protocol endpoints
- json helpers: navigate nested json with paths
馃 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Handle: domain-based identifiers (max 253 chars, 2+ segments, TLD rules)
- Nsid: namespaced identifiers (3+ segments, domain + name validation)
- Rkey: record keys (1-512 chars, restricted charset, no . or ..)
enhanced existing modules:
- Did: generic method support, spec-compliant charset validation
- AtUri: fragment/query rejection, proper path parsing
- Tid: first-char high bit check per atproto spec
all validation rules derived from atproto.com/specs and MarshalX/atproto
馃 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- add minimal README with install/usage
- tid: first char must have high bit 0x40 unset (only 2-7 allowed)
- add test for rejecting tids starting with a-z
ref: MarshalX/atproto string_formats.py
馃 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
internal APIs for TID, AtUri, and Did parsing.
- Tid: parse/generate timestamp identifiers (base32-sortable)
- AtUri: parse at://did/collection/rkey URIs
- Did: parse did:plc and did:web identifiers
all APIs start in internal module, promoted to root when stable.
馃 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- scripts/publish-docs.zig: uses zat to publish README, roadmap, and
changelog as site.standard.document records
- .tangled/workflows/publish-docs.yml: triggers on v* tags
- build.zig: adds publish-docs executable target
requires ATPROTO_HANDLE and ATPROTO_PASSWORD secrets in repo settings.
馃 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
new enums from com.atproto.sync.subscribeRepos lexicon:
- CommitAction: create, update, delete
- EventKind: commit, sync, identity, account, info
- AccountStatus: takendown, suspended, deleted, etc.
these work with std.json automatic enum parsing, enabling
exhaustive switches instead of mem.eql string comparisons.
bumps version to 0.1.0 (new feature, backwards compatible).
馃 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
the stdlib deflate decompressor panics with "reached unreachable code"
on certain gzip responses when running on x86_64-linux. setting
Accept-Encoding: identity avoids triggering the decompressor.
馃 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
resolves handles to DIDs using https://{handle}/.well-known/atproto-did
note: DNS TXT resolution (_atproto.{handle}) not implemented as zig std
doesn't provide TXT record lookup. HTTP method is the primary fallback
per atproto spec.
馃 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- fix use-after-free in jwt payload parsing (dupe strings)
- fix crypto.sign.ecdsa path for zig 0.15
- fix test token to have correct 64-byte signature
- use arena allocator in extractAt tests to avoid leaks
馃 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- jwt.zig: parse and verify ES256/ES256K tokens
- multibase.zig: base58btc decoding for DID document keys
- multicodec.zig: parse secp256k1/p256 key types from prefix
follows atproto.com/specs/xrpc service auth spec
馃 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Handle: domain-based identifiers (max 253 chars, 2+ segments, TLD rules)
- Nsid: namespaced identifiers (3+ segments, domain + name validation)
- Rkey: record keys (1-512 chars, restricted charset, no . or ..)
enhanced existing modules:
- Did: generic method support, spec-compliant charset validation
- AtUri: fragment/query rejection, proper path parsing
- Tid: first-char high bit check per atproto spec
all validation rules derived from atproto.com/specs and MarshalX/atproto
馃 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- add minimal README with install/usage
- tid: first char must have high bit 0x40 unset (only 2-7 allowed)
- add test for rejecting tids starting with a-z
ref: MarshalX/atproto string_formats.py
馃 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
internal APIs for TID, AtUri, and Did parsing.
- Tid: parse/generate timestamp identifiers (base32-sortable)
- AtUri: parse at://did/collection/rkey URIs
- Did: parse did:plc and did:web identifiers
all APIs start in internal module, promoted to root when stable.
馃 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>