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

Configure Feed

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

rebase

+198 -148
+1 -1
apps/main-app/public/editor/tabs/CLITab.tsx
··· 216 216 217 217 engine: 'nixery' 218 218 dependencies: 219 - nixpkgs: [nodejs, coreutils, curl] 219 + nixpkgs: [nodejs, coreutils, curl, glibc] 220 220 github:NixOS/nixpkgs/nixpkgs-unstable: [bun] 221 221 222 222 environment:
+197 -147
docs/src/content/docs/cli.md
··· 1 1 --- 2 - title: Wisp CLI 2 + title: Wisp CLI v1.0.0 3 3 description: Command-line tool for deploying static sites to the AT Protocol 4 4 --- 5 5 6 - `wispctl` deploys static sites to your AT Protocol account from the terminal. Supports incremental updates, OAuth and app password auth, and a local dev server with live firehose updates. 7 - 8 - ## Installation 6 + **Deploy static sites to the AT Protocol** 9 7 10 - ```bash 11 - npm install -g wispctl 12 - ``` 13 - 14 - Then use `wispctl` anywhere: 8 + The Wisp CLI is a command-line tool for deploying static websites directly to your AT Protocol account. Host your sites on wisp.place with full ownership and control, backed by the decentralized AT Protocol. 15 9 16 - ```bash 17 - wispctl deploy your-handle.bsky.social --path ./dist --site my-site 18 - ``` 10 + ## Features 19 11 20 - ## Quick Deploy 12 + - **Deploy**: Push static sites directly from your terminal 13 + - **Pull**: Download sites from the PDS for development or backup 14 + - **Serve**: Run a local server with real-time firehose updates 15 + - **Authenticate** with app password or OAuth 16 + - **Incremental updates**: Only upload changed files 21 17 22 - No install needed — use `npm create wisp` to deploy directly: 23 - 24 - ```bash 25 - npm create wisp your-handle.bsky.social --path ./dist --site my-site 26 - ``` 27 - 28 - Or with `npx`: 29 - 30 - ```bash 31 - npx wispctl deploy your-handle.bsky.social --path ./dist --site my-site 32 - ``` 33 - 34 - ## Deploying a Site 35 - 36 - ```bash 37 - wispctl deploy your-handle.bsky.social --path ./dist --site my-site 38 - ``` 39 - 40 - Your site will be at `https://sites.wisp.place/your-handle/my-site`. 41 - 42 - The CLI tracks files by content hash (CID), so subsequent deploys only upload what actually changed. First deploy uploads everything; after that, deploys complete in seconds when only a few files differ. 18 + ## Downloads 43 19 44 - ## Authentication 20 + <div class="downloads"> 45 21 46 - OAuth is the default — it opens your browser and saves a session to `/tmp/wisp-oauth-session.json`. For CI/CD or headless environments, use an app password instead: 22 + <h2>Download v1.0.0</h2> 47 23 48 - ```bash 49 - wispctl deploy your-handle.bsky.social \ 50 - --path ./dist \ 51 - --site my-site \ 52 - --password YOUR_APP_PASSWORD 53 - ``` 24 + <a href="https://sites.wisp.place/nekomimi.pet/wisp-cli-binaries/wisp-cli-aarch64-darwin" class="download-link" download=""> 54 25 55 - Generate app passwords from your AT Protocol account settings. Don't use your main password. 26 + <span class="platform">macOS (Apple Silicon):</span> wisp-cli-aarch64-darwin 56 27 57 - ## Domain Management 28 + </a> 58 29 59 - ```bash 60 - # Claim a wisp.place subdomain 61 - wispctl domain claim-subdomain your-handle.bsky.social --subdomain alice 30 + <a href="https://sites.wisp.place/nekomimi.pet/wisp-cli-binaries/wisp-cli-x86_64-darwin" class="download-link" download=""> 62 31 63 - # Claim a custom domain 64 - wispctl domain claim your-handle.bsky.social --domain example.com 32 + <span class="platform">macOS (Intel):</span> wisp-cli-x86_64-darwin 65 33 66 - # Check domain status 67 - wispctl domain status your-handle.bsky.social --domain example.com 34 + </a> 68 35 69 - # Attach a site to a domain 70 - wispctl domain add-site your-handle.bsky.social --domain example.com --site mysite 36 + <a href="https://sites.wisp.place/nekomimi.pet/wisp-cli-binaries/wisp-cli-aarch64-linux" class="download-link" download=""> 71 37 72 - # Delete a domain or site 73 - wispctl domain delete your-handle.bsky.social --domain example.com 74 - wispctl site delete your-handle.bsky.social --site mysite 75 - ``` 38 + <span class="platform">Linux (ARM64):</span> wisp-cli-aarch64-linux 76 39 77 - ```bash 78 - wispctl list domains your-handle.bsky.social 79 - wispctl list sites your-handle.bsky.social 80 - ``` 40 + </a> 81 41 82 - ## Pulling a Site 42 + <a href="https://sites.wisp.place/nekomimi.pet/wisp-cli-binaries/wisp-cli-x86_64-linux" class="download-link" download=""> 83 43 84 - Download a site from the PDS to your local machine: 44 + <span class="platform">Linux (x86_64):</span> wisp-cli-x86_64-linux 85 45 86 - ```bash 87 - wispctl pull your-handle.bsky.social --site my-site --path ./my-site 88 - ``` 46 + </a> 89 47 90 - ## Local Dev Server 48 + <h3 style="margin-top: 1.5rem; margin-bottom: 0.5rem;">SHA-256 Checksums</h3> 91 49 92 - Serve a site locally with real-time updates from the firehose: 50 + <pre style="font-size: 0.75rem; padding: 1rem;" class="language-bash" tabindex="0"><code class="language-bash"> 51 + 06544b3a3e27a4b8d7b3a46a39fb7205cf90b3061e19fe533b090facd604f375 wisp-cli-aarch64-darwin 52 + 9ec523e3ceef927b37adc52d449dcd9e13ea84fa49b0b77f0d5932c94cfe262e wisp-cli-x86_64-darwin 53 + 42a262668e13dce36173a4096cdc2b22358b805cf192335f84534c7f695d395b wisp-cli-aarch64-linux 54 + 589ee59f3959ddfbc12fea38d2bcb91701f1362f560ae6fd506bebea3150e2cc wisp-cli-x86_64-linux 55 + </code></pre> 93 56 94 - ```bash 95 - wispctl serve your-handle.bsky.social --site my-site 96 - wispctl serve your-handle.bsky.social --site my-site --port 3000 97 - wispctl serve your-handle.bsky.social --site my-site --spa # serve index.html for all routes 98 - wispctl serve your-handle.bsky.social --site my-site --directory # directory listing 99 - ``` 57 + </div> 100 58 101 - ## CI/CD 59 + ## CI/CD Integration 102 60 103 61 Deploy automatically on every push using Tangled Spindle: 104 62 ··· 112 70 113 71 dependencies: 114 72 nixpkgs: 73 + - nodejs 115 74 - coreutils 116 75 - curl 117 76 - glibc ··· 127 86 - name: build site 128 87 command: | 129 88 export PATH="$HOME/.nix-profile/bin:$PATH" 89 + 90 + # you may need to regenerate the lockfile due to nixery being weird 91 + # rm package-lock.json bun.lock 130 92 bun install 93 + 131 94 bun run build 132 95 133 96 - name: deploy to wisp 134 97 command: | 135 - curl -fsSL https://sites.wisp.place/nekomimi.pet/wisp-cli-binaries/wisp-cli-x86_64-linux -o wispctl 136 - chmod +x wispctl 137 - ./wispctl deploy \ 98 + # Download Wisp CLI 99 + curl https://sites.wisp.place/nekomimi.pet/wisp-cli-binaries/wisp-cli-x86_64-linux -o wisp-cli 100 + chmod +x wisp-cli 101 + 102 + # Deploy to Wisp 103 + ./wisp-cli \ 138 104 "$WISP_HANDLE" \ 139 105 --path "$SITE_PATH" \ 140 106 --site "$SITE_NAME" \ 141 107 --password "$WISP_APP_PASSWORD" 142 108 ``` 143 109 144 - Set `WISP_APP_PASSWORD` as a secret in your Tangled Spindle repository settings. 110 + **Note:** Set `WISP_APP_PASSWORD` as a secret in your Tangled Spindle repository settings. Generate an app password from your AT Protocol account settings. 145 111 146 - ## File Processing 112 + ## Basic Usage 147 113 148 - Files are gzip-compressed at level 9 and uploaded as `application/octet-stream` blobs with the original MIME type stored in the manifest. They may also be base64-encoded to bypass content sniffing on legacy reference PDS. The hosting service handles decompression transparently. 114 + ### Deploy a Site 149 115 150 - Common build artifacts like `.git`, `node_modules`, and `.env` are excluded automatically. Customize this with a [`.wispignore` file](/file-filtering). 116 + ```bash 117 + # Download and make executable 118 + curl -O https://sites.wisp.place/nekomimi.pet/wisp-cli-binaries/wisp-cli-aarch64-darwin 119 + chmod +x wisp-cli-aarch64-darwin 151 120 152 - ## Limits 121 + # Deploy your site 122 + ./wisp-cli-aarch64-darwin deploy your-handle.bsky.social \ 123 + --path ./dist \ 124 + --site my-site 125 + ``` 153 126 154 - - Max file size: 100 MB (after compression) 155 - - Max total size: 300 MB per site 156 - - Max files: 1,000 per site 157 - - Site name: alphanumeric, hyphens, underscores (AT Protocol rkey format) 127 + Your site will be available at: `https://sites.wisp.place/your-handle/my-site` 128 + 129 + ### Domain Management 130 + 131 + ```bash 132 + # Claim a custom domain 133 + ./wisp-cli domain claim your-handle.bsky.social --domain example.com 134 + 135 + # Claim a subdomain 136 + ./wisp-cli domain claim-subdomain your-handle.bsky.social --subdomain alice 158 137 159 - ## Command Reference 138 + # Check domain status 139 + ./wisp-cli domain status your-handle.bsky.social --domain example.com 160 140 161 - ### deploy 141 + # Attach a site to a domain 142 + ./wisp-cli domain add-site your-handle.bsky.social --domain example.com --site mysite 162 143 144 + # Delete a domain or site 145 + ./wisp-cli domain delete your-handle.bsky.social --domain example.com 146 + ./wisp-cli site delete your-handle.bsky.social --site mysite 163 147 ``` 164 - wispctl deploy [OPTIONS] <INPUT> 165 148 166 - Arguments: 167 - <INPUT> Handle (e.g., alice.bsky.social), DID, or PDS URL 149 + ### List Domains & Sites 168 150 169 - Options: 170 - -p, --path <PATH> Path to site directory [default: .] 171 - -s, --site <SITE> Site name (defaults to directory name) 172 - --store <STORE> OAuth session file [default: /tmp/wisp-oauth-session.json] 173 - --password <PASSWORD> App password 151 + ```bash 152 + ./wisp-cli list domains your-handle.bsky.social 153 + ./wisp-cli list sites your-handle.bsky.social 174 154 ``` 175 155 176 - ### pull 156 + ### Options 157 + 158 + Use an alternate proxy service DID: 177 159 160 + ```bash 161 + ./wisp-cli list domains your-handle.bsky.social --service did:web:example.com 178 162 ``` 179 - wispctl pull [OPTIONS] --site <SITE> <INPUT> 180 163 181 - Arguments: 182 - <INPUT> Handle or DID 164 + ### Pull a Site from PDS 183 165 184 - Options: 185 - -s, --site <SITE> Site name to download 186 - -p, --path <PATH> Output directory [default: .] 166 + Download a site from the PDS to your local machine: 167 + 168 + ```bash 169 + # Pull a site to a specific directory 170 + wisp-cli pull your-handle.bsky.social \ 171 + --site my-site \ 172 + --path ./my-site 173 + 174 + # Pull to current directory 175 + wisp-cli pull your-handle.bsky.social \ 176 + --site my-site 187 177 ``` 188 178 189 - ### serve 179 + ### Serve a Site Locally with Real-Time Updates 180 + 181 + Run a local server that monitors the firehose for real-time updates: 182 + 183 + ```bash 184 + # Serve on http://localhost:8080 (default) 185 + wisp-cli serve your-handle.bsky.social \ 186 + --site my-site 190 187 188 + # Serve on a custom port 189 + wisp-cli serve your-handle.bsky.social \ 190 + --site my-site \ 191 + --port 3000 192 + 193 + # Enable SPA mode (serve index.html for all routes) 194 + wisp-cli serve your-handle.bsky.social \ 195 + --site my-site \ 196 + --spa 197 + 198 + # Enable directory listing for paths without index files 199 + wisp-cli serve your-handle.bsky.social \ 200 + --site my-site \ 201 + --directory 191 202 ``` 192 - wispctl serve [OPTIONS] --site <SITE> <INPUT> 193 203 194 - Arguments: 195 - <INPUT> Handle or DID 204 + Downloads site, serves it, and watches firehose for live updates! 196 205 197 - Options: 198 - -s, --site <SITE> Site name 199 - -p, --path <PATH> Site files directory [default: .] 200 - -P, --port <PORT> Port [default: 8080] 201 - --spa Serve index.html for all routes 202 - --directory Directory listing for paths without index files 206 + ## Authentication 207 + 208 + ### OAuth (Recommended) 209 + 210 + The CLI uses OAuth by default, opening your browser for secure authentication: 211 + 212 + ```bash 213 + wisp-cli deploy your-handle.bsky.social --path ./dist --site my-site 203 214 ``` 204 215 205 - ## Binary Downloads 216 + This creates a session stored locally (default: `/tmp/wisp-oauth-session.json`). 206 217 207 - Pre-built binaries are available if you can't use npm. 218 + ### App Password 208 219 209 - <div class="downloads"> 220 + For headless environments or CI/CD, use an app password: 210 221 211 - <h2>Download v1.0.0</h2> 222 + ```bash 223 + wisp-cli deploy your-handle.bsky.social \ 224 + --path ./dist \ 225 + --site my-site \ 226 + --password YOUR_APP_PASSWORD 227 + ``` 212 228 213 - <a href="https://sites.wisp.place/nekomimi.pet/wisp-cli-binaries/wisp-cli-aarch64-darwin" class="download-link" download=""> 229 + **Generate app passwords** from your AT Protocol account settings. 214 230 215 - <span class="platform">macOS (Apple Silicon):</span> wisp-cli-aarch64-darwin 231 + ## File Processing 216 232 217 - </a> 233 + The CLI handles all file processing automatically to ensure reliable storage and delivery. Files are compressed with gzip at level 9 for optimal size reduction, then base64 encoded to bypass PDS content sniffing restrictions. Everything is uploaded as `application/octet-stream` blobs while preserving the original MIME type as metadata. When serving your site, the hosting service automatically decompresses non-HTML/CSS/JS files, ensuring your content is delivered correctly to visitors. 218 234 219 - <a href="https://sites.wisp.place/nekomimi.pet/wisp-cli-binaries/wisp-cli-x86_64-darwin" class="download-link" download=""> 235 + **File Filtering**: The CLI automatically excludes common files like `.git`, `node_modules`, `.env`, and other development artifacts. Customize this with a [`.wispignore` file](/file-filtering). 220 236 221 - <span class="platform">macOS (Intel):</span> wisp-cli-x86_64-darwin 237 + ## Incremental Updates 222 238 223 - </a> 239 + The CLI tracks file changes using CID-based content addressing to minimize upload times and bandwidth usage. On your first deploy, all files are uploaded to establish the initial site. For subsequent deploys, the CLI compares content-addressed CIDs to detect which files have actually changed, uploading only those that differ from the previous version. This makes fast iterations possible even for large sites, with deploys completing in seconds when only a few files have changed. 224 240 225 - <a href="https://sites.wisp.place/nekomimi.pet/wisp-cli-binaries/wisp-cli-aarch64-linux" class="download-link" download=""> 241 + ## Limits 226 242 227 - <span class="platform">Linux (ARM64):</span> wisp-cli-aarch64-linux 243 + - **Max file size**: 100MB per file (after compression) 244 + - **Max total size**: 300MB per site 245 + - **Max files**: 1000 files per site 246 + - **Site name**: Must follow AT Protocol rkey format (alphanumeric, hyphens, underscores) 228 247 229 - </a> 248 + ## Command Reference 230 249 231 - <a href="https://sites.wisp.place/nekomimi.pet/wisp-cli-binaries/wisp-cli-x86_64-linux" class="download-link" download=""> 250 + ### Deploy Command 232 251 233 - <span class="platform">Linux (x86_64):</span> wisp-cli-x86_64-linux 252 + ```bash 253 + wisp-cli deploy [OPTIONS] <INPUT> 234 254 235 - </a> 255 + Arguments: 256 + <INPUT> Handle (e.g., alice.bsky.social), DID, or PDS URL 236 257 237 - <h3 style="margin-top: 1.5rem; margin-bottom: 0.5rem;">SHA-256 Checksums</h3> 258 + Options: 259 + -p, --path <PATH> Path to site directory [default: .] 260 + -s, --site <SITE> Site name (defaults to directory name) 261 + --store <STORE> OAuth session file path [default: /tmp/wisp-oauth-session.json] 262 + --password <PASSWORD> App password for authentication 263 + -h, --help Print help 264 + ``` 238 265 239 - <pre style="font-size: 0.75rem; padding: 1rem;" class="language-bash" tabindex="0"><code class="language-bash"> 240 - 06544b3a3e27a4b8d7b3a46a39fb7205cf90b3061e19fe533b090facd604f375 wisp-cli-aarch64-darwin 241 - 9ec523e3ceef927b37adc52d449dcd9e13ea84fa49b0b77f0d5932c94cfe262e wisp-cli-x86_64-darwin 242 - 42a262668e13dce36173a4096cdc2b22358b805cf192335f84534c7f695d395b wisp-cli-aarch64-linux 243 - 589ee59f3959ddfbc12fea38d2bcb91701f1362f560ae6fd506bebea3150e2cc wisp-cli-x86_64-linux 244 - </code></pre> 266 + ### Pull Command 245 267 246 - </div> 268 + ```bash 269 + wisp-cli pull [OPTIONS] --site <SITE> <INPUT> 247 270 248 - ## Building from Source 271 + Arguments: 272 + <INPUT> Handle or DID 249 273 250 - The CLI is written in TypeScript and supports both Node.js and Bun runtimes. Run directly with Bun during development, or build a Node.js-compatible bundle for distribution. 274 + Options: 275 + -s, --site <SITE> Site name to download 276 + -p, --path <PATH> Output directory [default: .] 277 + -h, --help Print help 278 + ``` 279 + 280 + ### Serve Command 281 + 282 + ```bash 283 + wisp-cli serve [OPTIONS] --site <SITE> <INPUT> 284 + 285 + Arguments: 286 + <INPUT> Handle or DID 287 + 288 + Options: 289 + -s, --site <SITE> Site name to serve 290 + -p, --path <PATH> Site files directory [default: .] 291 + -P, --port <PORT> Port to serve on [default: 8080] 292 + --spa Enable SPA mode (serve index.html for all routes) 293 + --directory Enable directory listing mode for paths without index files 294 + -h, --help Print help 295 + ``` 296 + 297 + ## Development 298 + 299 + The CLI is written in Rust using the Jacquard AT Protocol library. To build from source: 251 300 252 301 ```bash 253 302 git clone https://tangled.org/@nekomimi.pet/wisp.place-monorepo 254 303 cd cli 255 - bun install 304 + cargo build --release 305 + ``` 306 + 307 + Built binaries are available in `target/release/`. 256 308 257 - # Run directly with Bun 258 - bun run index.ts 309 + ## Related 259 310 260 - # Build a Node.js bundle (outputs to dist/) 261 - bun run build 262 - node dist/index.js 263 - ``` 311 + - [place.wisp.fs](/lexicons/place-wisp-fs) - Site manifest lexicon 312 + - [place.wisp.subfs](/lexicons/place-wisp-subfs) - Subtree records for large sites 313 + - [AT Protocol](https://atproto.com) - The decentralized protocol powering Wisp