Monorepo for wisp.place. A static site hosting service built on top of the AT Protocol.

symlink claude.md to agents.md

+144 -143
+143
agents.md
··· 1 + The project is wisp.place. It is a static site hoster built on top of the AT Protocol. The overall basis of the project is that users upload site assets to their PDS as blobs, and creates a manifest record listing every blob as well as site name. The hosting service then catches events relating to the site (create, read, upload, delete) and handles them appropriately. 2 + 3 + The lexicons look like this: 4 + ```typescript 5 + //place.wisp.fs 6 + interface Main { 7 + $type: 'place.wisp.fs' 8 + site: string 9 + root: Directory 10 + fileCount?: number 11 + createdAt: string 12 + } 13 + 14 + interface File { 15 + $type?: 'place.wisp.fs#file' 16 + type: 'file' 17 + blob: BlobRef 18 + encoding?: 'gzip' 19 + mimeType?: string 20 + base64?: boolean 21 + } 22 + 23 + interface Directory { 24 + $type?: 'place.wisp.fs#directory' 25 + type: 'directory' 26 + entries: Entry[] 27 + } 28 + 29 + interface Entry { 30 + $type?: 'place.wisp.fs#entry' 31 + name: string 32 + node: $Typed<File> | $Typed<Directory> | $Typed<Subfs> | { $type: string } 33 + } 34 + 35 + interface Subfs { 36 + $type?: 'place.wisp.fs#subfs' 37 + type: 'subfs' 38 + subject: string // AT-URI pointing to a place.wisp.subfs record 39 + flat?: boolean 40 + } 41 + 42 + //place.wisp.subfs 43 + interface Main { 44 + $type: 'place.wisp.subfs' 45 + root: Directory 46 + fileCount?: number 47 + createdAt: string 48 + } 49 + 50 + interface File { 51 + $type?: 'place.wisp.subfs#file' 52 + type: 'file' 53 + blob: BlobRef 54 + encoding?: 'gzip' 55 + mimeType?: string 56 + base64?: boolean 57 + } 58 + 59 + interface Directory { 60 + $type?: 'place.wisp.subfs#directory' 61 + type: 'directory' 62 + entries: Entry[] 63 + } 64 + 65 + interface Entry { 66 + $type?: 'place.wisp.subfs#entry' 67 + name: string 68 + node: $Typed<File> | $Typed<Directory> | $Typed<Subfs> | { $type: string } 69 + } 70 + 71 + interface Subfs { 72 + $type?: 'place.wisp.subfs#subfs' 73 + type: 'subfs' 74 + subject: string // AT-URI pointing to another place.wisp.subfs record 75 + } 76 + 77 + //place.wisp.settings 78 + interface Main { 79 + $type: 'place.wisp.settings' 80 + directoryListing: boolean 81 + spaMode?: string 82 + custom404?: string 83 + indexFiles?: string[] 84 + cleanUrls: boolean 85 + headers?: CustomHeader[] 86 + } 87 + 88 + interface CustomHeader { 89 + $type?: 'place.wisp.settings#customHeader' 90 + name: string 91 + value: string 92 + path?: string // Optional glob pattern 93 + } 94 + ``` 95 + 96 + The main differences between place.wisp.fs and place.wisp.subfs: 97 + - place.wisp.fs has a required site field 98 + - place.wisp.fs#subfs has an optional flat field that place.wisp.subfs#subfs doesn't have 99 + 100 + The project is a monorepo. The package handler it uses for the typescript side is Bun. For the Rust cli, it is cargo. 101 + 102 + ### Typescript Bun Workspace Layout 103 + 104 + Bun workspaces: `packages/@wisp/*`, `apps/main-app`, `apps/hosting-service` 105 + 106 + There are two typescript apps 107 + **`apps/main-app`** - Main backend (Bun + Elysia) 108 + 109 + - OAuth authentication and session management 110 + - Site CRUD operations via PDS 111 + - Custom domain management 112 + - Admin database view in /admin 113 + - React frontend in public/ 114 + 115 + **`apps/hosting-service`** - CDN static file server (Node + Hono) 116 + 117 + - Watches AT Protocol firehose for `place.wisp.fs` record changes 118 + - Downloads and caches site files to disk 119 + - Serves sites at `https://sites.wisp.place/{did}/{site-name}` and custom domains 120 + - Handles redirects (`_redirects` file support) and routing logic 121 + - Backfill mode for syncing existing sites 122 + 123 + ### Shared Packages (`packages/@wisp/*`) 124 + 125 + - **`lexicons`** - AT Protocol lexicons (`place.wisp.fs`, `place.wisp.subfs`, `place.wisp.settings`) with 126 + generated TypeScript types 127 + - **`fs-utils`** - Filesystem tree building, manifest creation, subfs splitting logic 128 + - **`atproto-utils`** - AT Protocol helpers (blob upload, record operations, CID handling) 129 + - **`database`** - PostgreSQL schema and queries 130 + - **`constants`** - Shared constants (limits, file patterns, default settings) 131 + - **`observability`** - OpenTelemetry instrumentation 132 + - **`safe-fetch`** - Wrapped fetch with timeout/retry logic 133 + 134 + ### CLI 135 + 136 + **`cli/`** - Rust CLI using Jacquard (AT Protocol library) 137 + - Direct PDS uploads without interacting with main-app 138 + - Can also do the same firehose watching, caching, and serving hosting-service does, just without domain management 139 + 140 + ### Other Directories 141 + 142 + - **`docs/`** - Astro documentation site 143 + - **`binaries/`** - Compiled CLI binaries for distribution
+1 -143
claude.md
··· 1 - The project is wisp.place. It is a static site hoster built on top of the AT Protocol. The overall basis of the project is that users upload site assets to their PDS as blobs, and creates a manifest record listing every blob as well as site name. The hosting service then catches events relating to the site (create, read, upload, delete) and handles them appropriately. 2 - 3 - The lexicons look like this: 4 - ```typescript 5 - //place.wisp.fs 6 - interface Main { 7 - $type: 'place.wisp.fs' 8 - site: string 9 - root: Directory 10 - fileCount?: number 11 - createdAt: string 12 - } 13 - 14 - interface File { 15 - $type?: 'place.wisp.fs#file' 16 - type: 'file' 17 - blob: BlobRef 18 - encoding?: 'gzip' 19 - mimeType?: string 20 - base64?: boolean 21 - } 22 - 23 - interface Directory { 24 - $type?: 'place.wisp.fs#directory' 25 - type: 'directory' 26 - entries: Entry[] 27 - } 28 - 29 - interface Entry { 30 - $type?: 'place.wisp.fs#entry' 31 - name: string 32 - node: $Typed<File> | $Typed<Directory> | $Typed<Subfs> | { $type: string } 33 - } 34 - 35 - interface Subfs { 36 - $type?: 'place.wisp.fs#subfs' 37 - type: 'subfs' 38 - subject: string // AT-URI pointing to a place.wisp.subfs record 39 - flat?: boolean 40 - } 41 - 42 - //place.wisp.subfs 43 - interface Main { 44 - $type: 'place.wisp.subfs' 45 - root: Directory 46 - fileCount?: number 47 - createdAt: string 48 - } 49 - 50 - interface File { 51 - $type?: 'place.wisp.subfs#file' 52 - type: 'file' 53 - blob: BlobRef 54 - encoding?: 'gzip' 55 - mimeType?: string 56 - base64?: boolean 57 - } 58 - 59 - interface Directory { 60 - $type?: 'place.wisp.subfs#directory' 61 - type: 'directory' 62 - entries: Entry[] 63 - } 64 - 65 - interface Entry { 66 - $type?: 'place.wisp.subfs#entry' 67 - name: string 68 - node: $Typed<File> | $Typed<Directory> | $Typed<Subfs> | { $type: string } 69 - } 70 - 71 - interface Subfs { 72 - $type?: 'place.wisp.subfs#subfs' 73 - type: 'subfs' 74 - subject: string // AT-URI pointing to another place.wisp.subfs record 75 - } 76 - 77 - //place.wisp.settings 78 - interface Main { 79 - $type: 'place.wisp.settings' 80 - directoryListing: boolean 81 - spaMode?: string 82 - custom404?: string 83 - indexFiles?: string[] 84 - cleanUrls: boolean 85 - headers?: CustomHeader[] 86 - } 87 - 88 - interface CustomHeader { 89 - $type?: 'place.wisp.settings#customHeader' 90 - name: string 91 - value: string 92 - path?: string // Optional glob pattern 93 - } 94 - ``` 95 - 96 - The main differences between place.wisp.fs and place.wisp.subfs: 97 - - place.wisp.fs has a required site field 98 - - place.wisp.fs#subfs has an optional flat field that place.wisp.subfs#subfs doesn't have 99 - 100 - The project is a monorepo. The package handler it uses for the typescript side is Bun. For the Rust cli, it is cargo. 101 - 102 - ### Typescript Bun Workspace Layout 103 - 104 - Bun workspaces: `packages/@wisp/*`, `apps/main-app`, `apps/hosting-service` 105 - 106 - There are two typescript apps 107 - **`apps/main-app`** - Main backend (Bun + Elysia) 108 - 109 - - OAuth authentication and session management 110 - - Site CRUD operations via PDS 111 - - Custom domain management 112 - - Admin database view in /admin 113 - - React frontend in public/ 114 - 115 - **`apps/hosting-service`** - CDN static file server (Node + Hono) 116 - 117 - - Watches AT Protocol firehose for `place.wisp.fs` record changes 118 - - Downloads and caches site files to disk 119 - - Serves sites at `https://sites.wisp.place/{did}/{site-name}` and custom domains 120 - - Handles redirects (`_redirects` file support) and routing logic 121 - - Backfill mode for syncing existing sites 122 - 123 - ### Shared Packages (`packages/@wisp/*`) 124 - 125 - - **`lexicons`** - AT Protocol lexicons (`place.wisp.fs`, `place.wisp.subfs`, `place.wisp.settings`) with 126 - generated TypeScript types 127 - - **`fs-utils`** - Filesystem tree building, manifest creation, subfs splitting logic 128 - - **`atproto-utils`** - AT Protocol helpers (blob upload, record operations, CID handling) 129 - - **`database`** - PostgreSQL schema and queries 130 - - **`constants`** - Shared constants (limits, file patterns, default settings) 131 - - **`observability`** - OpenTelemetry instrumentation 132 - - **`safe-fetch`** - Wrapped fetch with timeout/retry logic 133 - 134 - ### CLI 135 - 136 - **`cli/`** - Rust CLI using Jacquard (AT Protocol library) 137 - - Direct PDS uploads without interacting with main-app 138 - - Can also do the same firehose watching, caching, and serving hosting-service does, just without domain management 139 - 140 - ### Other Directories 141 - 142 - - **`docs/`** - Astro documentation site 143 - - **`binaries/`** - Compiled CLI binaries for distribution 1 + agents.md