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

Configure Feed

Select the types of activity you want to include in your feed.

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