based on a small sample set, a repo summary
0
AT_report_small.md
edited
1# AT Protocol Ecosystem Repository Analysis
2
3*Generated 2026-08-12 (rev. 2) · Reference document for future LLM sessions*
4
5## 1. Methodology
6
7**Discovery.** Seed sources: the [psingletary.com Tangled profile](https://tangled.org/psingletary.com?tab=repos), [exosphere.site/airglow](https://tangled.org/exosphere.site/airglow), [rrcobb/atprotozoa](https://github.com/rrcobb/atprotozoa), plus [nekomimi.pet/wisp.place-monorepo](https://tangled.org/nekomimi.pet/wisp.place-monorepo) (added rev. 2 — it is the source of the wisp.place hosting platform used by several repos in this set). Crawl rule: analysis stopped inside each repo once found; external sites referenced by repos were noted but not visited.
8
9**Access limitations (fields marked "unknown").** Tangled's web UI rendered READMEs and file trees but not raw `package.json` contents, so exact direct-dependency lists are unknown for `zodiac`, `altifier`, `verifier`, `airglow`, `ATProtocol-Playground`, and `wisp.place-monorepo`. `atprotozoa` was analyzed from its full file tree and README. Language attribution uses labels displayed on the Tangled repo listing plus observed file types.
10
11## 2. Repository Inventory
12
13### airglow — [tangled.org/exosphere.site/airglow](https://tangled.org/exosphere.site/airglow)
14"Automations for the AT Protocol — listen to events, filter them, and trigger actions like webhook deliveries or PDS record creation"; connects to Jetstream, works like "IFTTT or Zapier, but the trigger side is always 'something happened on the AT Protocol.'"
15- **Language:** TypeScript (primary)
16- **Framework/tooling:** Bun runtime + Vite
17- **Hosting:** self-hosted (env-var config: `DATABASE_PATH` for SQLite, `JETSTREAM_URL`, NSID allow/blocklists)
18- **Deployment:** manual self-host; CI unknown
19- **AT Proto specifics:** Jetstream consumer; custom lexicons in `lexicons/` managed with [goat](https://github.com/bluesky-social/indigo/tree/main/cmd/goat); exact npm deps unknown
20
21### wisp.place-monorepo — [tangled.org/nekomimi.pet/wisp.place-monorepo](https://tangled.org/nekomimi.pet/wisp.place-monorepo)
22The platform behind wisp.place: hosts static sites *inside* an AT Protocol repository — the PDS is the source of truth (signed manifests + file blobs), and a hosting microservice watches the firehose to cache and serve sites via `*.wisp.place` subdomains or custom domains with CDN distribution.
23- **Languages:** TypeScript (primary — backend + frontend), Rust (secondary — CLI)
24- **Frameworks:** Elysia (main backend), Hono (hosting microservice), React 19 (frontend)
25- **Structure (one inventory entry, monorepo):** `apps/main-app` (OAuth, site management, custom domains, React UI), `apps/hosting-service` (serves cached sites), `cli/` (Rust: PDS uploads, firehose updates), `packages/` (shared internals)
26- **Hosting:** self-hosted service (it *is* the delivery platform); end-user deploys via `wispctl` / `npm create wisp`
27- **Deployment:** CLI-driven uploads to the PDS; no CI/CD configs observed — unknown
28- **AT Proto specifics:** ATProto OAuth; custom lexicons; PDS blobs as site storage; firehose consumer; [Jacquard](https://tangled.org/@nonbinary.computer/jacquard) (Rust ATProto library) in the CLI; supports `.wispignore` and `_redirects`
29
30### atprotozoa — [github.com/rrcobb/atprotozoa](https://github.com/rrcobb/atprotozoa)
31"A monorepo of ~200 tiny atproto experiments" — many small sites, each its own Cloudflare Worker at `<name>.bisks.net`, deployed on commit; many built by the `@buildthis.bisks.net` Bluesky bot ("tag it with an idea and it builds the site").
32- **Language:** TypeScript (per-site `src/index.ts` Workers) + vanilla JavaScript front-ends
33- **Framework:** none — hand-rolled static HTML + copied vanilla-JS libs; explicit "copy-don't-abstract" rule
34- **Hosting:** Cloudflare Workers (`wrangler.toml` per site; `apex/` front-door Worker for gallery + handle verification)
35- **Deployment:** GitHub Actions deploy-on-commit (`.github/workflows/deploy.yml`, `buildthis.yml`); pnpm workspaces
36- **AT Proto specifics:** hand-rolled per-site libs — `lib/oauth.js` + `lib/oauth-jwt.js` + `public/client-metadata.json` (ATProto OAuth), `lib/atproto.js`, `lib/car.js` (CAR parsing), `lib/identity.js`, `lib/handle-typeahead.js`; OG image generation via `og-gen.mjs` (+ `@resvg`); repo-wide `audit/` health-check scripts
37
38### altifier — [tangled.org/psingletary.com/altifier](https://tangled.org/psingletary.com/altifier)
39"Scans the image posts (`app.bsky.feed.post` records with `app.bsky.embed.images`) in your PDS, identifies images missing alt text, generates descriptions via AI, and lets you apply them by recreating your posts."
40- **Language:** JavaScript · **Framework:** React ("fully static React SPA")
41- **Hosting/deploy:** wisp.place via `wispctl deploy`, Tangled Sites (deploy dir `/build`), or any static host
42- **Deps:** ATProto OAuth (`src/contexts/AuthContext.js` + `public/client-metadata.json`); Google Gemini 2.5 Flash; full `package.json` unknown
43
44### verifier — [tangled.org/psingletary.com/verifier](https://tangled.org/psingletary.com/verifier)
45"A lightweight tool for creating and managing Bluesky verification records (`app.bsky.graph.verification`) on an account's PDS."
46- **Language:** JavaScript · **Framework:** React, fully static SPA
47- **Hosting/deploy:** static host (same pattern as altifier); deps/CI unknown
48
49### zodiac — [tangled.org/psingletary.com/zodiac](https://tangled.org/psingletary.com/zodiac)
50"Private astrology compatibility website… no accounts, no tracking, no data storage" — ATProto-adjacent (hosted via ATProto-native infra).
51- **Language:** TypeScript · **Framework:** Next.js 16 (App Router) + Tailwind CSS v4, "fully static — zero server routes… deployable to any static host (Tangled, wisp, Vercel, S3, etc.)"
52- **Deploy/CI:** manual static deploy; no CI configs found; deps unknown
53
54### daily-bsky-hype-vid — [tangled.org/psingletary.com/daily-bsky-hype-vid](https://tangled.org/psingletary.com/daily-bsky-hype-vid)
55"A daily, AI-produced hype video of your Bluesky mutuals' last 24 hours" — Claude Code fetches mutuals' posts, composes a soundtrack, renders a <60s vertical video.
56- **Language:** Python (numpy, scipy, Pillow, ffmpeg; Claude Code)
57- **AT Proto access:** raw public Bluesky AppView API, no auth, no SDK (`fetch_bsky.py`)
58- **Hosting/deploy:** none — local, manual run
59
60### ATProtocol-Playground — [tangled.org/psingletary.com/ATProtocol-Playground](https://tangled.org/psingletary.com/ATProtocol-Playground)
61"Scripts for fooling around with ATProto and BSky.app"; dirs: `docs/`, `js/`, `sample/`, `tests/`; no manifest or CI files visible.
62- **Language:** Python (primary), some JS · **Hosting/deploy/deps:** unknown/none
63
64### ptharbor — [tangled.org/psingletary.com/ptharbor](https://tangled.org/psingletary.com/ptharbor)
65Migration of a small-business site (Point Harbor Signs) from Weebly to the AT Protocol stack: wisp.place hosting, Protobase.at managed PDS, Tangled git, Marque.at registrar — "a repeatable blueprint for migrating small businesses off Facebook/Instagram/WordPress/Wix to AT Protocol."
66- **Language:** HTML · **Framework:** none (static port)
67- **Hosting:** wisp.place (PDS-based static hosting); did:web identity files (`did-web/`, did.json at ptharbor.net)
68- **Deployment:** manual scripts (`scripts/` for key generation, deploy)
69
70## 3. Ranked: Programming Languages (primary, one per repo; n=9)
71
72| Rank | Language | Count | Repos |
73|---|---|---|---|
74| 1 | TypeScript | 4 | airglow, atprotozoa, zodiac, wisp.place-monorepo |
75| 2 (tie) | JavaScript | 2 | altifier, verifier |
76| 2 (tie) | Python | 2 | daily-bsky-hype-vid, ATProtocol-Playground |
77| 4 | HTML | 1 | ptharbor |
78
79*Notable secondary: Rust (wisp.place CLI).*
80
81## 4. Ranked: Website Delivery Platforms
82
83| Rank | Platform | Count | Repos |
84|---|---|---|---|
85| 1 | PDS-based / ATProto-native static hosting (wisp.place, Tangled Sites) | 4 | altifier, verifier, zodiac, ptharbor |
86| 2 | Self-hosted service | 2 | airglow, wisp.place-monorepo |
87| 3 | Cloudflare Workers | 1 | atprotozoa (~200 sites, one repo) |
88| — | N/A (local tools) | 2 | daily-bsky-hype-vid, ATProtocol-Playground |
89
90## 5. Ranked: Deployment Processes
91
92| Rank | Process | Count | Repos |
93|---|---|---|---|
94| 1 | Manual static deploy (`wispctl` / Tangled Sites / copy build dir) | 4 | altifier, verifier, zodiac, ptharbor |
95| 2 | Manual self-host (env vars / CLI) | 2 | airglow, wisp.place-monorepo |
96| 3 | CI/CD deploy-on-commit (GitHub Actions + wrangler) | 1 | atprotozoa |
97| — | None / run locally | 2 | daily-bsky-hype-vid, ATProtocol-Playground |
98
99*Note: Tangled offers native CI/CD via [Spindle workflows](https://docs.tangled.org/spindles) (`.tangled/workflows` YAML, push/PR/manual triggers), but **zero** repos in this set were observed using it. See §8.2.*
100
101## 6. Ranked: Libraries (observed evidence only; most manifests unreadable — see Methodology)
102
103**AT Protocol–specific:**
104
105| Rank | Library/approach | Count | Evidence |
106|---|---|---|---|
107| 1 (tie) | Hand-rolled vanilla JS against XRPC/AppView (no SDK) | 2 | atprotozoa file tree; daily-bsky-hype-vid README |
108| 1 (tie) | Firehose/Jetstream consumers | 2 | airglow (Jetstream); wisp.place hosting-service (firehose) |
109| 1 (tie) | Custom lexicons | 2 | airglow `lexicons/`; wisp.place-monorepo |
110| 4 (tie) | goat (lexicon management, bluesky-social/indigo) | 1 | airglow |
111| 4 (tie) | Jacquard (Rust ATProto library) | 1 | wisp.place CLI |
112| — | `@atproto/api` / atcute | 0 confirmed | manifests unknown for TS/React apps — likely but unverified |
113
114**General:**
115
116| Rank | Library/tool | Count | Repos |
117|---|---|---|---|
118| 1 | React | 3 | altifier, verifier, wisp.place-monorepo (React 19) |
119| 2 (tie) | Next.js + Tailwind v4 | 1 | zodiac |
120| 2 (tie) | Bun + Vite + SQLite | 1 | airglow |
121| 2 (tie) | Elysia + Hono | 1 | wisp.place-monorepo |
122| 2 (tie) | pnpm workspaces + wrangler + @resvg | 1 | atprotozoa |
123| 2 (tie) | numpy/scipy/Pillow/ffmpeg + Claude Code | 1 | daily-bsky-hype-vid |
124| 2 (tie) | Google Gemini 2.5 Flash | 1 | altifier |
125
126## 7. Aggregate Summary of AT Protocol Tools
127
128**Categories observed:** (a) **PDS record tooling** — altifier, verifier: static browser apps reading/writing records directly in the user's PDS; (b) **event/automation infrastructure** — airglow (Jetstream → actions); (c) **hosting infrastructure** — wisp.place: the PDS itself as a static-site origin, firehose-invalidated CDN cache in front; (d) **micro-app factories** — atprotozoa's bot pipeline (mention → LLM builds site → deploy-on-commit → Worker); (e) **migration/identity tooling** — ptharbor (did:web + managed PDS + wisp); (f) **AppView-scraping content generators**; (g) **learning playgrounds**.
129
130**Architectural patterns:**
1311. **Static-first, serverless-second.** Dominant shape: fully static SPA doing ATProto OAuth in-browser, talking directly to the user's PDS — no backend. Backends, where present, are a tiny Worker or a single Bun/TypeScript process with SQLite.
1322. **PDS as infrastructure primitive.** wisp.place stores entire websites as PDS blobs with signed manifests; Tangled stores git and CI records (`sh.tangled.*` lexicons) in PDSes. The PDS is becoming the deployment target, not just the social-data store.
1333. **ATProto-native supply chain.** Code on Tangled, hosting on wisp.place, identity via did:web/did:plc, managed PDS (Protobase.at) — a full stack that never touches traditional PaaS.
1344. **SDK avoidance in small projects.** Copied single-file vanilla libs (OAuth, CAR parsing, identity resolution) or raw AppView calls instead of `@atproto/api`; atprotozoa codifies this as "copy, not extract." Infrastructure projects, by contrast, adopt real libraries (Jacquard).
1355. **LLM-in-the-loop development.** buildthis bot, Claude Code pipelines, `.hermes/plans/` agent-planned implementations.
1366. **Repeated OAuth boilerplate:** every app re-ships `client-metadata.json` pinned to its domain, `oauth.js`/`oauth-jwt.js`, handle typeahead.
137
138## 8. Recommendations: Tools That Need to Be Built
139
140Stack suggestions follow the rankings: **TypeScript, static-first, wisp.place/Tangled or Cloudflare Workers hosting, vendorable vanilla-JS libs, Bun + SQLite for services.**
141
1421. **`create-atproto-app` scaffolding CLI (the "project factory").** Problem: every app hand-assembles OAuth metadata, typeahead, deploy config. Stack: TypeScript CLI (Bun), templates for static SPA + optional Worker; emits `client-metadata.json`, `wrangler.toml`/wisp config, vendored single-file libs — and a `.tangled/workflows/deploy.yml` (see §8.2). *(Directly serves the project-factory goal.)*
143
1442. **Spindle adoption kit + hosted runners.** *(Revised after evaluating [Tangled Spindle docs](https://docs.tangled.org/spindles).)* The earlier claim "Tangled lacks native CI/CD" is **no longer true**: Spindle workflows live in `.tangled/workflows` (YAML), trigger on `push`/`pull_request`/`manual` with branch/tag globs, run on Docker (nixery) or microVM engines, support repo secrets, and the docs include a working deploy-to-Cloudflare-Workers example and PDS artifact publishing. **The real gap is adoption and infrastructure:** (a) none of the four manually-deployed Tangled repos in this set use Spindle; (b) Spindle is a self-hosted Go runner service listening on Jetstream — most individual developers won't run one. What to build: ready-made workflow templates (especially **deploy-to-wisp.place via `wispctl`**, which doesn't exist as a documented example), and/or a community/hosted spindle offering so repos get CI without operating runner hosts. Stack: YAML templates + Go (spindle is Go) or a managed nixery-engine host.
145
1463. **Vendorable ATProto micro-library set.** Problem: the "copy-don't-abstract" culture exists because `@atproto/api` is heavy for static SPAs; copied `oauth.js`/`car.js`/`identity.js` files drift and duplicate bugs across ~200 sites. Build audited, zero-dependency single-file ES modules (OAuth+DPoP, CAR reader, DID/handle resolution) designed to be copied. Stack: TypeScript → standalone ESM.
147
1484. **Non-destructive PDS record editor.** *(Expanded.)* The problem in depth: altifier's only way to fix alt text is **delete-and-recreate** the post. Because the new record gets a new rkey, its at-uri changes, so every like, repost, reply, and quote — all of which point at the old at-uri (as a `strongRef` of uri + CID) — is orphaned. The user must choose between accessibility and their engagement history. What's missing is a general-purpose tool built around the safer primitives the protocol already has: `com.atproto.repo.putRecord` overwrites a record **in place**, preserving the rkey and at-uri (replies and likes keep resolving; only the CID changes); `com.atproto.repo.applyWrites` batches creates/updates/deletes atomically; `com.atproto.sync.getRepo` exports a full CAR backup before any mutation. Feature set: browse any collection in your PDS (not just `app.bsky.*`), edit records as validated JSON against their lexicon, show a **dry-run diff** of every proposed write, warn when an edit would change semantics AppViews index (e.g. `createdAt`), automatic pre-mutation CAR snapshot with one-click restore, and bulk find-and-replace across a collection. No tool in the analyzed set — or widely in the ecosystem — combines editing with backup/diff/undo safety rails; existing repo browsers are read-only, and writing tools (altifier, verifier) are single-purpose. Stack: static React/TypeScript SPA, ATProto OAuth, CAR parsing lib (§8.3), hosted on wisp.place.
149
1505. **Managed multi-tenant Jetstream automation.** Problem: airglow is self-host-only. A hosted or one-click-deploy version (Workers + Durable Objects, or Bun+SQLite image) would open ATProto automations to non-operators.
151
1526. **Small-business migration toolkit.** Problem: ptharbor proves the demand but is a manual one-off. Automate: site scrape → static port → wisp.place deploy → did:web generation → managed-PDS provisioning checklist. Stack: TypeScript CLI + template repo on Tangled. *(See companion doc `Migration_Toolkit_research.md`.)*
153
1547. **Fleet health dashboard for micro-sites.** Problem: atprotozoa needed bespoke `audit/` scripts. A reusable uptime/OAuth-metadata/handle-verification monitor for many small ATProto sites doesn't exist in this set. Stack: scheduled Worker + static dashboard.
155
1568. **OG-image service for ATProto apps.** Problem: nearly every atprotozoa site bundles fonts + a per-site `og-gen.mjs`. A shared Worker rendering OG cards from URL params would delete hundreds of copies. Stack: Cloudflare Worker + resvg-wasm.
157
158---
159
160*Caveat: Tangled's web UI does not expose raw manifests, so the library ranking (§6) remains the weakest section — `@atproto/api`/atcute usage in the TS/React apps is plausible but unverified.*