Monorepo for wisp.place. A static site hosting service built on top of the AT Protocol. wisp.place
1<!DOCTYPE html> 2<html lang="en"> 3<head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 6 <title>Wisp CLI - Download</title> 7 <link href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/themes/prism.min.css" rel="stylesheet" /> 8 <link href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/themes/prism-tomorrow.min.css" rel="stylesheet" media="(prefers-color-scheme: dark)" /> 9 <style> 10 :root { 11 /* Light theme */ 12 --demo-bg: #eeeeee; 13 --demo-text: #1a1a1a; 14 --demo-text-secondary: #666; 15 --demo-border: #ddd; 16 --demo-input-bg: #fff; 17 --demo-button-bg: #0066cc; 18 --demo-button-text: #fff; 19 --demo-code-bg: #f5f5f5; 20 --demo-code-border: #e0e0e0; 21 --demo-hr: #e0e0e0; 22 } 23 24 /* Dark theme */ 25 @media (prefers-color-scheme: dark) { 26 :root { 27 --demo-bg: #1a1a1a; 28 --demo-text: #e0e0e0; 29 --demo-text-secondary: #999; 30 --demo-border: #444; 31 --demo-input-bg: #2a2a2a; 32 --demo-button-bg: #0066cc; 33 --demo-button-text: #fff; 34 --demo-code-bg: #2a2a2a; 35 --demo-code-border: #444; 36 --demo-hr: #444; 37 } 38 } 39 40 * { 41 margin: 0; 42 padding: 0; 43 box-sizing: border-box; 44 } 45 46 body { 47 margin: 0; 48 padding: 0; 49 background: var(--demo-bg); 50 color: var(--demo-text); 51 transition: background-color 200ms ease, color 200ms ease; 52 font-family: system-ui, sans-serif; 53 line-height: 1.6; 54 } 55 56 .container { 57 max-width: 860px; 58 margin: 40px auto; 59 padding: 0 20px; 60 min-height: 100vh; 61 } 62 63 h1 { 64 margin-top: 0; 65 color: var(--demo-text); 66 font-size: 2.5rem; 67 margin-bottom: 0.5rem; 68 } 69 70 .subtitle { 71 color: var(--demo-text-secondary); 72 font-size: 1.1rem; 73 margin-bottom: 2rem; 74 line-height: 1.4; 75 } 76 77 .description { 78 margin-bottom: 2rem; 79 line-height: 1.6; 80 color: var(--demo-text); 81 } 82 83 hr { 84 margin: 32px 0; 85 border: none; 86 border-top: 1px solid var(--demo-hr); 87 } 88 89 h2 { 90 color: var(--demo-text); 91 margin-bottom: 1rem; 92 margin-top: 2rem; 93 font-size: 1.5rem; 94 } 95 96 h3 { 97 color: var(--demo-text); 98 margin-bottom: 0.75rem; 99 margin-top: 1.5rem; 100 font-size: 1.2rem; 101 } 102 103 .downloads { 104 background: var(--demo-code-bg); 105 border: 1px solid var(--demo-code-border); 106 border-radius: 8px; 107 padding: 2rem; 108 margin-bottom: 2rem; 109 } 110 111 .downloads h2 { 112 margin-top: 0; 113 } 114 115 .download-link { 116 display: block; 117 background: var(--demo-button-bg); 118 color: var(--demo-button-text); 119 text-decoration: none; 120 padding: 12px 16px; 121 border-radius: 8px; 122 margin-bottom: 8px; 123 transition: opacity 0.2s; 124 font-family: 'Monaco', 'Menlo', 'Courier New', monospace; 125 font-size: 0.9rem; 126 } 127 128 .download-link:hover { 129 opacity: 0.85; 130 } 131 132 .platform { 133 font-weight: bold; 134 margin-right: 0.5rem; 135 } 136 137 .cicd-section { 138 margin-top: 2rem; 139 } 140 141 .cicd-section h2 { 142 margin-top: 0; 143 } 144 145 .cicd-section > p { 146 color: var(--demo-text-secondary); 147 margin-bottom: 1rem; 148 } 149 150 pre { 151 background: var(--demo-code-bg) !important; 152 border: 1px solid var(--demo-code-border); 153 padding: 1.5rem !important; 154 border-radius: 8px; 155 overflow-x: auto; 156 font-size: 0.85rem; 157 line-height: 1.5; 158 margin: 1rem 0; 159 } 160 161 pre code { 162 color: var(--demo-text); 163 background: none !important; 164 padding: 0 !important; 165 text-shadow: none !important; 166 } 167 168 code { 169 font-family: 'Monaco', 'Menlo', 'Courier New', monospace; 170 } 171 172 .note { 173 background: var(--demo-code-bg); 174 border-left: 4px solid var(--demo-button-bg); 175 border: 1px solid var(--demo-code-border); 176 border-left: 4px solid var(--demo-button-bg); 177 padding: 1rem; 178 margin-top: 1rem; 179 border-radius: 4px; 180 } 181 182 .note strong { 183 color: var(--demo-text); 184 } 185 186 .note code { 187 background: var(--demo-input-bg); 188 padding: 2px 6px; 189 border-radius: 4px; 190 border: 1px solid var(--demo-border); 191 } 192 193 a { 194 color: var(--demo-button-bg); 195 text-decoration: none; 196 } 197 198 a:hover { 199 text-decoration: underline; 200 } 201 202 .features { 203 margin: 2rem 0; 204 } 205 206 .features ul { 207 list-style: none; 208 padding-left: 0; 209 } 210 211 .features li { 212 padding: 0.5rem 0; 213 padding-left: 1.5rem; 214 position: relative; 215 line-height: 1.6; 216 } 217 218 .features li:before { 219 content: "✓"; 220 position: absolute; 221 left: 0; 222 color: var(--demo-button-bg); 223 font-weight: bold; 224 } 225 226 .footer { 227 margin-top: 3rem; 228 padding-top: 2rem; 229 border-top: 1px solid var(--demo-hr); 230 text-align: center; 231 color: var(--demo-text-secondary); 232 } 233 </style> 234</head> 235<body> 236 <div class="container"> 237 <h1>Wisp CLI <span style="font-size: 1.5rem; color: var(--demo-text-secondary);">v0.4.0</span></h1> 238 <p class="subtitle">Deploy static sites to the AT Protocol</p> 239 240 <div class="description"> 241 <p> 242 The Wisp CLI is a command-line tool for deploying static websites directly to your AT Protocol account. 243 Host your sites on <a href="https://wisp.place" target="_blank">wisp.place</a> with full ownership and control, 244 backed by the decentralized AT Protocol. 245 </p> 246 </div> 247 248 <div class="features"> 249 <h2>Features</h2> 250 <ul> 251 <li><strong>Deploy:</strong> Push static sites directly from your terminal</li> 252 <li><strong>Pull:</strong> Download sites from the PDS for development or backup</li> 253 <li><strong>Serve:</strong> Run a local server with real-time firehose updates</li> 254 <li>Authenticate with app password or OAuth</li> 255 </ul> 256 </div> 257 258 <div class="downloads"> 259 <h2>Download v0.4.0</h2> 260 <a href="https://sites.wisp.place/nekomimi.pet/wisp-cli-binaries/wisp-cli-aarch64-darwin" class="download-link" download> 261 <span class="platform">macOS (Apple Silicon):</span> wisp-cli-aarch64-darwin 262 </a> 263 <a href="https://sites.wisp.place/nekomimi.pet/wisp-cli-binaries/wisp-cli-aarch64-linux" class="download-link" download> 264 <span class="platform">Linux (ARM64):</span> wisp-cli-aarch64-linux 265 </a> 266 <a href="https://sites.wisp.place/nekomimi.pet/wisp-cli-binaries/wisp-cli-x86_64-linux" class="download-link" download> 267 <span class="platform">Linux (x86_64):</span> wisp-cli-x86_64-linux 268 </a> 269 <a href="https://sites.wisp.place/nekomimi.pet/wisp-cli-binaries/wisp-cli-x86_64-windows.exe" class="download-link" download> 270 <span class="platform">Windows (x86_64):</span> wisp-cli-x86_64-windows.exe 271 </a> 272 273 <h3 style="margin-top: 1.5rem; margin-bottom: 0.5rem;">SHA-1 Checksums</h3> 274 <pre style="font-size: 0.75rem; padding: 1rem;"><code class="language-bash">2b5c1d6d0e21f9d764dd66ef869bfcd348e8a111 wisp-cli-aarch64-darwin 27568d4a3831c07d2f32fdde8d3e809af1ab79e804e wisp-cli-aarch64-linux 27686e89f592b0ec53239c082f502cbe7a47ed8bbec wisp-cli-x86_64-linux 277227b735911ad260cff5af3ca3beefa4e1e3956a8 wisp-cli-x86_64-windows.exe</code></pre> 278 </div> 279 280 <div class="cicd-section"> 281 <h2>CI/CD Integration</h2> 282 <p>Deploy automatically on every push using <a href="https://tangledspindle.org" target="_blank">Tangled Spindle</a>:</p> 283 284 <pre><code class="language-yaml">when: 285 - event: ['push'] 286 branch: ['main'] 287 - event: ['manual'] 288 289engine: 'nixery' 290 291clone: 292 skip: false 293 depth: 1 294 submodules: false 295 296dependencies: 297 nixpkgs: 298 - nodejs 299 - coreutils 300 - curl 301 github:NixOS/nixpkgs/nixpkgs-unstable: 302 - bun 303 304environment: 305 SITE_PATH: 'dist' 306 SITE_NAME: 'my-site' 307 WISP_HANDLE: 'your-handle.bsky.social' 308 309steps: 310 - name: build site 311 command: | 312 export PATH="$HOME/.nix-profile/bin:$PATH" 313 314 # regenerate lockfile, https://github.com/npm/cli/pull/8184 makes rolldown not install 315 rm package-lock.json bun.lock 316 bun install @rolldown/binding-linux-arm64-gnu --save-optional 317 bun install 318 319 # run directly with bun because of shebang issues in nix 320 bun node_modules/.bin/vite build 321 322 - name: deploy to wisp 323 command: | 324 # Download Wisp CLI 325 curl https://sites.wisp.place/nekomimi.pet/wisp-cli-binaries/wisp-cli-x86_64-linux -o wisp-cli 326 chmod +x wisp-cli 327 328 # Deploy to Wisp 329 ./wisp-cli \ 330 "$WISP_HANDLE" \ 331 --path "$SITE_PATH" \ 332 --site "$SITE_NAME" \ 333 --password "$WISP_APP_PASSWORD"</code></pre> 334 335 <div class="note"> 336 <strong>Note:</strong> Set <code>WISP_APP_PASSWORD</code> as a secret in your Tangled Spindle repository settings. 337 Generate an app password from your AT Protocol account settings. 338 </div> 339 </div> 340 341 <div class="cicd-section"> 342 <h2>Basic Usage</h2> 343 344 <h3>Deploy a Site</h3> 345 <pre><code class="language-bash"># Download and make executable 346curl -O https://sites.wisp.place/nekomimi.pet/wisp-cli-binaries/wisp-cli-macos-arm64 347chmod +x wisp-cli-macos-arm64 348 349# Deploy your site 350./wisp-cli-macos-arm64 deploy your-handle.bsky.social \ 351 --path ./dist \ 352 --site my-site \ 353 354# Your site will be available at: 355# https://sites.wisp.place/your-handle/my-site</code></pre> 356 357 <h3>Pull a Site from PDS</h3> 358 <p style="color: var(--demo-text-secondary); margin-bottom: 0.5rem;">Download a site from the PDS to your local machine (uses OAuth authentication):</p> 359 <pre><code class="language-bash"># Pull a site to a specific directory 360wisp-cli pull your-handle.bsky.social \ 361 --site my-site \ 362 --output ./my-site 363 364# Pull to current directory 365wisp-cli pull your-handle.bsky.social \ 366 --site my-site 367</code></pre> 368 <h3>Serve a Site Locally with Real-Time Updates</h3> 369 <p style="color: var(--demo-text-secondary); margin-bottom: 0.5rem;">Run a local server that monitors the firehose for real-time updates (uses OAuth authentication):</p> 370 <pre><code class="language-bash"># Serve on http://localhost:8080 (default) 371wisp-cli serve your-handle.bsky.social \ 372 --site my-site 373 374# Serve on a custom port 375wisp-cli serve your-handle.bsky.social \ 376 --site my-site \ 377 --port 3000 378 379# Downloads site, serves it, and watches firehose for live updates! 380 381# Enable SPA mode (serve index.html for all routes) 382wisp-cli serve your-handle.bsky.social \ 383 --site my-site \ 384 --spa 385 386# Enable directory listing for paths without index files 387wisp-cli serve your-handle.bsky.social \ 388 --site my-site \ 389 --directory</code></pre> 390 </div> 391 392 <div class="footer"> 393 <p>Learn more at <a href="https://wisp.place">wisp.place</a></p> 394 </div> 395 </div> 396 <script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-core.min.js"></script> 397 <script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/plugins/autoloader/prism-autoloader.min.js"></script> 398 <script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-bash.min.js"></script> 399 <script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-yaml.min.js"></script> 400</body> 401</html>