Monorepo for wisp.place. A static site hosting service built on top of the AT Protocol. wisp.place
1import { 2 Card, 3 CardContent, 4 CardDescription, 5 CardHeader, 6 CardTitle 7} from '@public/components/ui/card' 8import { Badge } from '@public/components/ui/badge' 9import { ExternalLink } from 'lucide-react' 10import { CodeBlock } from '@public/components/ui/code-block' 11 12export function CLITab() { 13 return ( 14 <div className="space-y-4 min-h-[400px]"> 15 <Card> 16 <CardHeader> 17 <div className="flex items-center gap-2 mb-2"> 18 <CardTitle>Wisp CLI Tool</CardTitle> 19 <Badge variant="secondary" className="text-xs">v0.2.0</Badge> 20 <Badge variant="outline" className="text-xs">Alpha</Badge> 21 </div> 22 <CardDescription> 23 Deploy static sites directly from your terminal 24 </CardDescription> 25 </CardHeader> 26 <CardContent className="space-y-6"> 27 <div className="prose prose-sm max-w-none dark:prose-invert"> 28 <p className="text-sm text-muted-foreground"> 29 The Wisp CLI is a command-line tool for deploying static websites directly to your AT Protocol account. 30 Authenticate with app password or OAuth and deploy from CI/CD pipelines. 31 </p> 32 </div> 33 34 <div className="space-y-3"> 35 <h3 className="text-sm font-semibold">Features</h3> 36 <ul className="text-sm text-muted-foreground space-y-2 list-disc list-inside"> 37 <li><strong>Deploy:</strong> Push static sites directly from your terminal</li> 38 <li><strong>Pull:</strong> Download sites from the PDS for development or backup</li> 39 <li><strong>Serve:</strong> Run a local server with real-time firehose updates</li> 40 </ul> 41 </div> 42 43 <div className="space-y-3"> 44 <h3 className="text-sm font-semibold">Download v0.2.0</h3> 45 <div className="grid gap-2"> 46 <div className="p-3 bg-muted/50 hover:bg-muted rounded-lg transition-colors border border-border"> 47 <a 48 href="https://sites.wisp.place/nekomimi.pet/wisp-cli-binaries/wisp-cli-aarch64-darwin" 49 target="_blank" 50 rel="noopener noreferrer" 51 className="flex items-center justify-between mb-2" 52 > 53 <span className="font-mono text-sm">macOS (Apple Silicon)</span> 54 <ExternalLink className="w-4 h-4 text-muted-foreground" /> 55 </a> 56 <div className="text-xs text-muted-foreground"> 57 <span className="font-mono">SHA-1: a8c27ea41c5e2672bfecb3476ece1c801741d759</span> 58 </div> 59 </div> 60 <div className="p-3 bg-muted/50 hover:bg-muted rounded-lg transition-colors border border-border"> 61 <a 62 href="https://sites.wisp.place/nekomimi.pet/wisp-cli-binaries/wisp-cli-aarch64-linux" 63 target="_blank" 64 rel="noopener noreferrer" 65 className="flex items-center justify-between mb-2" 66 > 67 <span className="font-mono text-sm">Linux (ARM64)</span> 68 <ExternalLink className="w-4 h-4 text-muted-foreground" /> 69 </a> 70 <div className="text-xs text-muted-foreground"> 71 <span className="font-mono">SHA-1: fd7ee689c7600fc953179ea755b0357c8481a622</span> 72 </div> 73 </div> 74 <div className="p-3 bg-muted/50 hover:bg-muted rounded-lg transition-colors border border-border"> 75 <a 76 href="https://sites.wisp.place/nekomimi.pet/wisp-cli-binaries/wisp-cli-x86_64-linux" 77 target="_blank" 78 rel="noopener noreferrer" 79 className="flex items-center justify-between mb-2" 80 > 81 <span className="font-mono text-sm">Linux (x86_64)</span> 82 <ExternalLink className="w-4 h-4 text-muted-foreground" /> 83 </a> 84 <div className="text-xs text-muted-foreground"> 85 <span className="font-mono">SHA-1: 8bca6992559e19e1d29ab3d2fcc6d09b28e5a485</span> 86 </div> 87 </div> 88 <div className="p-3 bg-muted/50 hover:bg-muted rounded-lg transition-colors border border-border"> 89 <a 90 href="https://sites.wisp.place/nekomimi.pet/wisp-cli-binaries/wisp-cli-x86_64-windows.exe" 91 target="_blank" 92 rel="noopener noreferrer" 93 className="flex items-center justify-between mb-2" 94 > 95 <span className="font-mono text-sm">Windows (x86_64)</span> 96 <ExternalLink className="w-4 h-4 text-muted-foreground" /> 97 </a> 98 <div className="text-xs text-muted-foreground"> 99 <span className="font-mono">SHA-1: 90ea3987a06597fa6c42e1df9009e9758e92dd54</span> 100 </div> 101 </div> 102 </div> 103 </div> 104 105 <div className="space-y-3"> 106 <h3 className="text-sm font-semibold">Deploy a Site</h3> 107 <CodeBlock 108 code={`# Download and make executable 109curl -O https://sites.wisp.place/nekomimi.pet/wisp-cli-binaries/wisp-cli-aarch64-darwin 110chmod +x wisp-cli-aarch64-darwin 111 112# Deploy your site 113./wisp-cli-aarch64-darwin deploy your-handle.bsky.social \\ 114 --path ./dist \\ 115 --site my-site \\ 116 --password your-app-password 117 118# Your site will be available at: 119# https://sites.wisp.place/your-handle/my-site`} 120 language="bash" 121 /> 122 </div> 123 124 <div className="space-y-3"> 125 <h3 className="text-sm font-semibold">Pull a Site from PDS</h3> 126 <p className="text-xs text-muted-foreground"> 127 Download a site from the PDS to your local machine (uses OAuth authentication): 128 </p> 129 <CodeBlock 130 code={`# Pull a site to a specific directory 131wisp-cli pull your-handle.bsky.social \\ 132 --site my-site \\ 133 --output ./my-site 134 135# Pull to current directory 136wisp-cli pull your-handle.bsky.social \\ 137 --site my-site 138 139# Opens browser for OAuth authentication on first run`} 140 language="bash" 141 /> 142 </div> 143 144 <div className="space-y-3"> 145 <h3 className="text-sm font-semibold">Serve a Site Locally with Real-Time Updates</h3> 146 <p className="text-xs text-muted-foreground"> 147 Run a local server that monitors the firehose for real-time updates (uses OAuth authentication): 148 </p> 149 <CodeBlock 150 code={`# Serve on http://localhost:8080 (default) 151wisp-cli serve your-handle.bsky.social \\ 152 --site my-site 153 154# Serve on a custom port 155wisp-cli serve your-handle.bsky.social \\ 156 --site my-site \\ 157 --port 3000 158 159# Downloads site, serves it, and watches firehose for live updates!`} 160 language="bash" 161 /> 162 </div> 163 164 <div className="space-y-3"> 165 <h3 className="text-sm font-semibold">CI/CD with Tangled Spindle</h3> 166 <p className="text-xs text-muted-foreground"> 167 Deploy automatically on every push using{' '} 168 <a 169 href="https://blog.tangled.org/ci" 170 target="_blank" 171 rel="noopener noreferrer" 172 className="text-accent hover:underline" 173 > 174 Tangled Spindle 175 </a> 176 </p> 177 178 <div className="space-y-4"> 179 <div> 180 <h4 className="text-xs font-semibold mb-2 flex items-center gap-2"> 181 <span>Example 1: Simple Asset Publishing</span> 182 <Badge variant="secondary" className="text-xs">Copy Files</Badge> 183 </h4> 184 <CodeBlock 185 code={`when: 186 - event: ['push'] 187 branch: ['main'] 188 - event: ['manual'] 189 190engine: 'nixery' 191 192clone: 193 skip: false 194 depth: 1 195 196dependencies: 197 nixpkgs: 198 - coreutils 199 - curl 200 201environment: 202 SITE_PATH: '.' # Copy entire repo 203 SITE_NAME: 'myWebbedSite' 204 WISP_HANDLE: 'your-handle.bsky.social' 205 206steps: 207 - name: deploy assets to wisp 208 command: | 209 # Download Wisp CLI 210 curl https://sites.wisp.place/nekomimi.pet/wisp-cli-binaries/wisp-cli-x86_64-linux -o wisp-cli 211 chmod +x wisp-cli 212 213 # Deploy to Wisp 214 ./wisp-cli deploy \\ 215 "$WISP_HANDLE" \\ 216 --path "$SITE_PATH" \\ 217 --site "$SITE_NAME" \\ 218 --password "$WISP_APP_PASSWORD" 219 220 # Output 221 #Deployed site 'myWebbedSite': at://did:plc:ttdrpj45ibqunmfhdsb4zdwq/place.wisp.fs/myWebbedSite 222 #Available at: https://sites.wisp.place/did:plc:ttdrpj45ibqunmfhdsb4zdwq/myWebbedSite 223 `} 224 language="yaml" 225 /> 226 </div> 227 228 <div> 229 <h4 className="text-xs font-semibold mb-2 flex items-center gap-2"> 230 <span>Example 2: React/Vite Build & Deploy</span> 231 <Badge variant="secondary" className="text-xs">Full Build</Badge> 232 </h4> 233 <CodeBlock 234 code={`when: 235 - event: ['push'] 236 branch: ['main'] 237 - event: ['manual'] 238 239engine: 'nixery' 240 241clone: 242 skip: false 243 depth: 1 244 submodules: false 245 246dependencies: 247 nixpkgs: 248 - nodejs 249 - coreutils 250 - curl 251 github:NixOS/nixpkgs/nixpkgs-unstable: 252 - bun 253 254environment: 255 SITE_PATH: 'dist' 256 SITE_NAME: 'my-react-site' 257 WISP_HANDLE: 'your-handle.bsky.social' 258 259steps: 260 - name: build site 261 command: | 262 # necessary to ensure bun is in PATH 263 export PATH="$HOME/.nix-profile/bin:$PATH" 264 265 bun install --frozen-lockfile 266 267 # build with vite, run directly to get around env issues 268 bun node_modules/.bin/vite build 269 270 - name: deploy to wisp 271 command: | 272 # Download Wisp CLI 273 curl https://sites.wisp.place/nekomimi.pet/wisp-cli-binaries/wisp-cli-x86_64-linux -o wisp-cli 274 chmod +x wisp-cli 275 276 # Deploy to Wisp 277 ./wisp-cli deploy \\ 278 "$WISP_HANDLE" \\ 279 --path "$SITE_PATH" \\ 280 --site "$SITE_NAME" \\ 281 --password "$WISP_APP_PASSWORD"`} 282 language="yaml" 283 /> 284 </div> 285 </div> 286 287 <div className="p-3 bg-muted/30 rounded-lg border-l-4 border-accent"> 288 <p className="text-xs text-muted-foreground"> 289 <strong className="text-foreground">Note:</strong> Set <code className="px-1.5 py-0.5 bg-background rounded text-xs">WISP_APP_PASSWORD</code> as a secret in your Tangled Spindle repository settings. 290 Generate an app password from your AT Protocol account settings. 291 </p> 292 </div> 293 </div> 294 295 <div className="space-y-3"> 296 <h3 className="text-sm font-semibold">Learn More</h3> 297 <div className="grid gap-2"> 298 <a 299 href="https://tangled.org/@nekomimi.pet/wisp.place-monorepo/tree/main/cli" 300 target="_blank" 301 rel="noopener noreferrer" 302 className="flex items-center justify-between p-3 bg-muted/50 hover:bg-muted rounded-lg transition-colors border border-border" 303 > 304 <span className="text-sm">Source Code</span> 305 <ExternalLink className="w-4 h-4 text-muted-foreground" /> 306 </a> 307 <a 308 href="https://blog.tangled.org/ci" 309 target="_blank" 310 rel="noopener noreferrer" 311 className="flex items-center justify-between p-3 bg-muted/50 hover:bg-muted rounded-lg transition-colors border border-border" 312 > 313 <span className="text-sm">Tangled Spindle CI/CD</span> 314 <ExternalLink className="w-4 h-4 text-muted-foreground" /> 315 </a> 316 </div> 317 </div> 318 </CardContent> 319 </Card> 320 </div> 321 ) 322}