a web app for declaring if an atproto account is automated + package for the lexicon
jsr.io/@voyager/autonomy-lexicon
atprotocol
lexicon
1# CLAUDE.md
2
3This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
5## Project Overview
6
7This is an ATProtocol lexicon project for declaring automation and AI usage on Bluesky. It has three main components:
8
91. **Lexicon Definition** - The `studio.voyager.account.autonomy` schema in `lexicon/autonomy-declaration.json`
102. **JSR Package** - Published as `@voyager/autonomy-lexicon` for TypeScript consumers
113. **Web Client** - A single-page form for users to submit autonomy declarations to their PDS
12
13## Key Architecture Concepts
14
15### Lexicon Ownership and Publishing
16
17The 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.
18
19Schema publishing workflow:
201. Lexicon changes are made in `lexicon/autonomy-declaration.json`
212. The schema is published to ATProtocol via `com.atproto.repo.putRecord` with:
22 - Collection: `com.atproto.lexicon.schema`
23 - Rkey: `studio.voyager.account.autonomy`
24 - Record type: `com.atproto.lexicon.schema`
253. DNS TXT record at `_lexicon.account.voyager.studio` points to the publisher's DID
26
27### Record Key: `literal:self`
28
29The 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.
30
31### Client-Side Record Creation
32
33The web client (`client/app.js`) allows any Bluesky user to create their own autonomy declaration:
34- Uses `BskyAgent` from `@atproto/api`
35- Authenticates with user's handle + app password
36- Creates record in collection `studio.voyager.account.autonomy` on their own PDS
37- Only `createdAt` field is required; all others are optional
38
39## Common Commands
40
41**Run web form locally:**
42```bash
43deno task dev
44# Serves client on http://localhost:8000
45```
46
47**Publish package to JSR:**
48```bash
49deno publish --dry-run # Preview
50deno publish # Publish
51```
52
53**Publish schema (voyager.studio owner only):**
54```bash
55# Set VOYAGER_PASSWORD in .env first
56deno task publish:lexicon
57```
58
59## Important Implementation Details
60
61### Environment Variables
62- The publish script uses `--env` flag to auto-load `.env` file
63- Only requires `VOYAGER_PASSWORD` (voyager.studio app password)
64- No username needed - hardcoded to `voyager.studio`
65
66### Lexicon Structure
67- All fields except `createdAt` are optional
68- `automationLevel` has known values: human, assisted, collaborative, automated
69- `responsibleParty` is a nested object with optional fields
70- `externalServices` is an array (max 20 items, 200 chars each)
71
72### Client Form Processing
73- External services are entered one per line in a textarea
74- Responsible party object is only included if at least one field is filled
75- Empty optional fields are omitted from the record (not sent as null/empty)