a web app for declaring if an atproto account is automated + package for the lexicon jsr.io/@voyager/autonomy-lexicon
atprotocol lexicon

CLAUDE.md#

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Project Overview#

This is an ATProtocol lexicon project for declaring automation and AI usage on Bluesky. It has three main components:

  1. Lexicon Definition - The studio.voyager.account.autonomy schema in lexicon/autonomy-declaration.json
  2. JSR Package - Published as @voyager/autonomy-lexicon for TypeScript consumers
  3. Web Client - A single-page form for users to submit autonomy declarations to their PDS

Key Architecture Concepts#

Lexicon Ownership and Publishing#

The lexicon ID is studio.voyager.account.autonomy, which means it must be published from the voyager.studio account. The publishing script (scripts/publish_lexicon.ts) is hardcoded to use voyager.studio as the publisher handle - this is not configurable.

Schema publishing workflow:

  1. Lexicon changes are made in lexicon/autonomy-declaration.json
  2. The schema is published to ATProtocol via com.atproto.repo.putRecord with:
    • Collection: com.atproto.lexicon.schema
    • Rkey: studio.voyager.account.autonomy
    • Record type: com.atproto.lexicon.schema
  3. DNS TXT record at _lexicon.account.voyager.studio points to the publisher's DID

Record Key: literal:self#

The lexicon uses "key": "literal:self", meaning each account can only have one autonomy declaration record (not a collection). When users submit via the web form, it creates/updates their single declaration record.

Client-Side Record Creation#

The web client (client/app.js) allows any Bluesky user to create their own autonomy declaration:

  • Uses BskyAgent from @atproto/api
  • Authenticates with user's handle + app password
  • Creates record in collection studio.voyager.account.autonomy on their own PDS
  • Only createdAt field is required; all others are optional

Common Commands#

Run web form locally:

deno task dev
# Serves client on http://localhost:8000

Publish package to JSR:

deno publish --dry-run  # Preview
deno publish            # Publish

Publish schema (voyager.studio owner only):

# Set VOYAGER_PASSWORD in .env first
deno task publish:lexicon

Important Implementation Details#

Environment Variables#

  • The publish script uses --env flag to auto-load .env file
  • Only requires VOYAGER_PASSWORD (voyager.studio app password)
  • No username needed - hardcoded to voyager.studio

Lexicon Structure#

  • All fields except createdAt are optional
  • automationLevel has known values: human, assisted, collaborative, automated
  • responsibleParty is a nested object with optional fields
  • externalServices is an array (max 20 items, 200 chars each)

Client Form Processing#

  • External services are entered one per line in a textarea
  • Responsible party object is only included if at least one field is filled
  • Empty optional fields are omitted from the record (not sent as null/empty)