···11# Agent Guidelines for ATP Monorepo
2233## Build & Test Commands
44+45- Run all tests: `deno test -P`
56- Run single test file: `deno test -P path/to/file_test.ts`
67- Run specific test: `deno test -P --filter "test name" path/to/file_test.ts`
···910- Check code: `deno check`
10111112## Code Style
1313+1214- **NO COMMENTS** unless explicitly requested
1313-- Use JSDoc only for exported types/functions with `@prop`, `@param`, `@returns` tags
1414-- Test files: `*_test.ts` pattern (e.g., `car_test.ts`), use Deno.test(), imports from `@std/assert`
1515-- Types: Explicit types for function parameters/returns, prefer `interface` over `type` for objects
1616-- Error handling: Use custom error classes extending base errors, include `ErrorOptions` with `cause`
1717-- Imports: Use JSR/npm imports from deno.json, absolute imports (e.g., `@atp/crypto`, `@std/assert`)
1818-- Naming: camelCase for vars/functions, PascalCase for classes/types, UPPER_CASE for constants
1515+- Use JSDoc only for exported types/functions with `@prop`, `@param`, `@returns`
1616+ tags
1717+- Test files: `*_test.ts` pattern (e.g., `car_test.ts`), use Deno.test(),
1818+ imports from `@std/assert`
1919+- Types: Explicit types for function parameters/returns, prefer `interface` over
2020+ `type` for objects
2121+- Error handling: Use custom error classes extending base errors, include
2222+ `ErrorOptions` with `cause`
2323+- Imports: Use JSR/npm imports from deno.json, absolute imports (e.g.,
2424+ `@atp/crypto`, `@std/assert`)
2525+- Naming: camelCase for vars/functions, PascalCase for classes/types, UPPER_CASE
2626+ for constants
1927- Exports: Use `export` directly, re-export from `mod.ts` for public API
2028- Async: Prefer async/await over promises, use AsyncGenerator for streams
2129- Formatting: 2 spaces indent, semicolons, trailing commas, 80 char soft limit
+40-13
README.md
···6677## Overview
8899-This monorepo provides modular, standards-based TypeScript implementations of core AT Protocol components, based on the @atproto NPM packages.
99+This monorepo provides modular, standards-based TypeScript implementations of
1010+core AT Protocol components, based on the @atproto NPM packages.
10111111-Each package is designed to work across JavaScript runtimes (Deno, Node.js, Bun, Cloudflare Workers) and can be used independently or together.
1212+Each package is designed to work across JavaScript runtimes (Deno, Node.js, Bun,
1313+Cloudflare Workers) and can be used independently or together.
12141315## Packages
14161517### [@atp/xrpc-server](./xrpc-server)
1616-Hono-based XRPC server implementation with lexicon validation, authentication, rate limiting, and WebSocket streaming support. Works across JavaScript runtimes with comprehensive error handling and type safety.
1818+1919+Hono-based XRPC server implementation with lexicon validation, authentication,
2020+rate limiting, and WebSocket streaming support. Works across JavaScript runtimes
2121+with comprehensive error handling and type safety.
17221823### [@atp/xrpc](./xrpc)
1919-XRPC client library for calling AT Protocol services with lexicon schema validation.
20242525+XRPC client library for calling AT Protocol services with lexicon schema
2626+validation.
21272228### [@atp/sync](./sync)
2323-Tools for syncing data from AT Protocol, including firehose (relay) subscriptions with authentication and filtering.
2929+3030+Tools for syncing data from AT Protocol, including firehose (relay)
3131+subscriptions with authentication and filtering.
24322533### [@atp/lex-cli](./lex-cli)
2626-Command-line tool for generating documentation, servers, and clients from AT Protocol lexicon files.
3434+3535+Command-line tool for generating documentation, servers, and clients from AT
3636+Protocol lexicon files.
27372838### [@atp/crypto](./crypto)
2929-Cryptographic primitives for AT Protocol supporting P-256 and K-256 (secp256k1) elliptic curves. Includes key generation, signing, verification, DID key serialization, and hashing utilities.
3939+4040+Cryptographic primitives for AT Protocol supporting P-256 and K-256 (secp256k1)
4141+elliptic curves. Includes key generation, signing, verification, DID key
4242+serialization, and hashing utilities.
30433144### [@atp/identity](./identity)
3232-Decentralized identity resolution for DIDs and handles. Resolves handles to DIDs, DIDs to DID documents, and provides caching and verification methods.
4545+4646+Decentralized identity resolution for DIDs and handles. Resolves handles to
4747+DIDs, DIDs to DID documents, and provides caching and verification methods.
33483449### [@atp/lexicon](./lexicon)
3535-Validation utilities for AT Protocol lexicons. Validates records, XRPC parameters, inputs, and outputs against lexicon schemas.
5050+5151+Validation utilities for AT Protocol lexicons. Validates records, XRPC
5252+parameters, inputs, and outputs against lexicon schemas.
36533754### [@atp/repo](./repo)
3838-Repository utilities including the Merkle Search Tree (MST) implementation. Handles signed key/value stores with CBOR-encoded data records, CAR files, and repo synchronization.
5555+5656+Repository utilities including the Merkle Search Tree (MST) implementation.
5757+Handles signed key/value stores with CBOR-encoded data records, CAR files, and
5858+repo synchronization.
39594060### [@atp/syntax](./syntax)
4141-Validation and parsing for AT Protocol string formats including DIDs, handles, NSIDs, AT URIs, TIDs, record keys, and datetimes.
6161+6262+Validation and parsing for AT Protocol string formats including DIDs, handles,
6363+NSIDs, AT URIs, TIDs, record keys, and datetimes.
42644365### [@atp/common](./common)
4444-Shared utilities for server-oriented applications, including IPLD handling, streams, async helpers, obfuscation, retry logic, and TID generation.
6666+6767+Shared utilities for server-oriented applications, including IPLD handling,
6868+streams, async helpers, obfuscation, retry logic, and TID generation.
45694670### [@atp/bytes](./bytes)
4747-Simple `Uint8Array` utilities including allocation, comparison, concatenation, string conversion (with multibase encoding support), and XOR operations. Based on the uint8arrays npm package.
7171+7272+Simple `Uint8Array` utilities including allocation, comparison, concatenation,
7373+string conversion (with multibase encoding support), and XOR operations. Based
7474+on the uint8arrays npm package.
48754976## Installation
5077
+5
identity/did/atproto-data.ts
···1717 getPdsEndpoint as getPds,
1818};
19192020+/** Resolve a did to its `did:key` signing key, stringified */
2021export const getKey = (doc: DidDocument): string | undefined => {
2122 const key = getSigningKey(doc);
2223 if (!key) return undefined;
2324 return getDidKeyFromMultibase(key);
2425};
25262727+/** Extract and format a `did:key` signing key from multibase */
2628export const getDidKeyFromMultibase = (key: {
2729 type: string;
2830 publicKeyMultibase: string;
···4042 return didKey;
4143};
42444545+/** Parse an atproto document ("did doc") to its atproto data*/
4346export const parseToAtprotoDocument = (
4447 doc: DidDocument,
4548): Partial<AtprotoData> => {
···5255 };
5356};
54575858+/** Authenticate and verify the existance of an atproto Did Document */
5559export const ensureAtpDocument = (doc: DidDocument): AtprotoData => {
5660 const { did, signingKey, handle, pds } = parseToAtprotoDocument(doc);
5761 if (!did) {
···6973 return { did, signingKey, handle, pds };
7074};
71757676+/** Parse a `did:key` signing key from a Did Document */
7277export const ensureAtprotoKey = (doc: DidDocument): string => {
7378 const { signingKey } = parseToAtprotoDocument(doc);
7479 if (!signingKey) {
+4
identity/did/base-resolver.ts
···1313} from "../types.ts";
1414import * as atprotoData from "./atproto-data.ts";
15151616+/**
1717+ * Core functionality of did and handle resolution and validation,
1818+ * including cache handling.
1919+ */
1620export abstract class BaseResolver {
1721 constructor(public cache?: DidCache) {}
1822
+4
identity/did/did-resolver.ts
···77import { DidPlcResolver } from "./plc-resolver.ts";
88import { DidWebResolver } from "./web-resolver.ts";
991010+/**
1111+ * Did Resolver class combining DidPlcResolver and DidWebResolver,
1212+ * resolves did:plc and did:web dids with optional caching.
1313+ */
1014export class DidResolver extends BaseResolver {
1115 methods: Record<string, BaseResolver>;
1216
+5
identity/did/memory-cache.ts
···11import { DAY, HOUR } from "@atp/common";
22import type { CacheResult, DidCache, DidDocument } from "../types.ts";
3344+/**
55+ * Value stored in cache for a DID doc
66+ * @prop doc - DID Document object
77+ * @prop updatedAt - Last time DID doc cached was updated
88+ */
49type CacheVal = {
510 doc: DidDocument;
611 updatedAt: number;
+5
identity/did/plc-resolver.ts
···22import { BaseResolver } from "./base-resolver.ts";
33import { timed } from "./util.ts";
4455+/**
66+ * Did resolver for resolving DIDs to atproto
77+ * data, specifically `did:plc` DIDs.
88+ * Can optionally cache resolved DID docs.
99+ */
510export class DidPlcResolver extends BaseResolver {
611 constructor(
712 public plcUrl: string,
+1
identity/did/util.ts
···11+/** A timed function to abort after a certain amount of time */
12export async function timed<F extends (signal: AbortSignal) => unknown>(
23 ms: number,
34 fn: F,
+5
identity/did/web-resolver.ts
···99/** Path to the DID document on a `did:web` DID. */
1010export const DOC_PATH = "/.well-known/did.json";
11111212+/**
1313+ * Did resolver for resolving DIDs to atproto
1414+ * data, specifically `did:web` DIDs.
1515+ * Can optionally cache resolved DID docs.
1616+ */
1217export class DidWebResolver extends BaseResolver {
1318 constructor(
1419 public timeout: number,
+2-1
identity/id-resolver.ts
···33import type { IdentityResolverOpts } from "./types.ts";
4455/**
66- * Combines Handle and DID resolvers into a single identity resolver class.
66+ * A single identity resolver class combining Did resolver and Handle resolver.
77+ * Can resolve handles and dids to atproto data with an optional cache.
78 */
89export class IdResolver {
910 public handle: HandleResolver;
+4
identity/types.ts
···6969 expired: boolean;
7070};
71717272+/**
7373+ * An optional configured cache for caching resolved
7474+ * did documents and getting the cached did docs.
7575+ */
7276export interface DidCache {
7377 cacheDid(
7478 did: string,