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

update serve and pull to use --path to be consisten

Changed files
+87 -18
cli
+72 -2
cli/README.md
··· 32 32 33 33 ## Usage 34 34 35 + ### Commands 36 + 37 + The CLI supports three main commands: 38 + - **deploy**: Upload a site to your PDS (default command) 39 + - **pull**: Download a site from a PDS to a local directory 40 + - **serve**: Serve a site locally with real-time firehose updates 41 + 35 42 ### Basic Deployment 36 43 37 44 Deploy the current directory: 38 45 39 46 ```bash 40 - wisp-cli nekomimi.ppet --path . --site my-site 47 + wisp-cli nekomimi.pet --path . --site my-site 41 48 ``` 42 49 43 50 Deploy a specific directory: ··· 46 53 wisp-cli alice.bsky.social --path ./dist/ --site my-site 47 54 ``` 48 55 56 + Or use the explicit `deploy` subcommand: 57 + 58 + ```bash 59 + wisp-cli deploy alice.bsky.social --path ./dist/ --site my-site 60 + ``` 61 + 62 + ### Pull a Site 63 + 64 + Download a site from a PDS to a local directory: 65 + 66 + ```bash 67 + wisp-cli pull alice.bsky.social --site my-site --path ./downloaded-site 68 + ``` 69 + 70 + This will download all files from the site to the specified directory. 71 + 72 + ### Serve a Site Locally 73 + 74 + Serve a site locally with real-time updates from the firehose: 75 + 76 + ```bash 77 + wisp-cli serve alice.bsky.social --site my-site --path ./site --port 8080 78 + ``` 79 + 80 + This will: 81 + 1. Download the site to the specified path 82 + 2. Start a local server on the specified port (default: 8080) 83 + 3. Watch the firehose for updates and automatically reload files when changed 84 + 49 85 ### Authentication Methods 50 86 51 87 #### OAuth (Recommended) ··· 79 115 80 116 ## Command-Line Options 81 117 118 + ### Deploy Command 119 + 82 120 ``` 83 - wisp-cli [OPTIONS] <INPUT> 121 + wisp-cli [deploy] [OPTIONS] <INPUT> 84 122 85 123 Arguments: 86 124 <INPUT> Handle (e.g., alice.bsky.social), DID, or PDS URL ··· 90 128 -s, --site <SITE> Site name (defaults to directory name) 91 129 --store <STORE> Path to auth store file (only used with OAuth) [default: /tmp/wisp-oauth-session.json] 92 130 --password <PASSWORD> App Password for authentication (alternative to OAuth) 131 + --directory Enable directory listing mode for paths without index files 132 + --spa Enable SPA mode (serve index.html for all routes) 133 + -y, --yes Skip confirmation prompts (automatically accept warnings) 93 134 -h, --help Print help 94 135 -V, --version Print version 136 + ``` 137 + 138 + ### Pull Command 139 + 140 + ``` 141 + wisp-cli pull [OPTIONS] --site <SITE> <INPUT> 142 + 143 + Arguments: 144 + <INPUT> Handle (e.g., alice.bsky.social) or DID 145 + 146 + Options: 147 + -s, --site <SITE> Site name (record key) 148 + -p, --path <PATH> Output directory for the downloaded site [default: .] 149 + -h, --help Print help 150 + ``` 151 + 152 + ### Serve Command 153 + 154 + ``` 155 + wisp-cli serve [OPTIONS] --site <SITE> <INPUT> 156 + 157 + Arguments: 158 + <INPUT> Handle (e.g., alice.bsky.social) or DID 159 + 160 + Options: 161 + -s, --site <SITE> Site name (record key) 162 + -p, --path <PATH> Output directory for the site files [default: .] 163 + -P, --port <PORT> Port to serve on [default: 8080] 164 + -h, --help Print help 95 165 ``` 96 166 97 167 ## How It Works
+15 -16
cli/src/main.rs
··· 41 41 struct Args { 42 42 #[command(subcommand)] 43 43 command: Option<Commands>, 44 - 44 + 45 45 // Deploy arguments (when no subcommand is specified) 46 46 /// Handle (e.g., alice.bsky.social), DID, or PDS URL 47 - #[arg(global = true, conflicts_with = "command")] 48 47 input: Option<CowStr<'static>>, 49 48 50 49 /// Path to the directory containing your static site 51 - #[arg(short, long, global = true, conflicts_with = "command")] 50 + #[arg(short, long)] 52 51 path: Option<PathBuf>, 53 52 54 53 /// Site name (defaults to directory name) 55 - #[arg(short, long, global = true, conflicts_with = "command")] 54 + #[arg(short, long)] 56 55 site: Option<String>, 57 56 58 57 /// Path to auth store file 59 - #[arg(long, global = true, conflicts_with = "command")] 58 + #[arg(long)] 60 59 store: Option<String>, 61 60 62 61 /// App Password for authentication 63 - #[arg(long, global = true, conflicts_with = "command")] 62 + #[arg(long)] 64 63 password: Option<CowStr<'static>>, 65 64 66 65 /// Enable directory listing mode for paths without index files 67 - #[arg(long, global = true, conflicts_with = "command")] 66 + #[arg(long)] 68 67 directory: bool, 69 68 70 69 /// Enable SPA mode (serve index.html for all routes) 71 - #[arg(long, global = true, conflicts_with = "command")] 70 + #[arg(long)] 72 71 spa: bool, 73 72 74 73 /// Skip confirmation prompts (automatically accept warnings) 75 - #[arg(short = 'y', long, global = true, conflicts_with = "command")] 74 + #[arg(short = 'y', long)] 76 75 yes: bool, 77 76 } 78 77 ··· 122 121 123 122 /// Output directory for the downloaded site 124 123 #[arg(short, long, default_value = ".")] 125 - output: PathBuf, 124 + path: PathBuf, 126 125 }, 127 126 /// Serve a site locally with real-time firehose updates 128 127 Serve { ··· 135 134 136 135 /// Output directory for the site files 137 136 #[arg(short, long, default_value = ".")] 138 - output: PathBuf, 137 + path: PathBuf, 139 138 140 139 /// Port to serve on 141 - #[arg(short, long, default_value = "8080")] 140 + #[arg(short = 'P', long, default_value = "8080")] 142 141 port: u16, 143 142 }, 144 143 } ··· 156 155 run_with_oauth(input, store, path, site, directory, spa, yes).await 157 156 } 158 157 } 159 - Some(Commands::Pull { input, site, output }) => { 160 - pull::pull_site(input, CowStr::from(site), output).await 158 + Some(Commands::Pull { input, site, path }) => { 159 + pull::pull_site(input, CowStr::from(site), path).await 161 160 } 162 - Some(Commands::Serve { input, site, output, port }) => { 163 - serve::serve_site(input, CowStr::from(site), output, port).await 161 + Some(Commands::Serve { input, site, path, port }) => { 162 + serve::serve_site(input, CowStr::from(site), path, port).await 164 163 } 165 164 None => { 166 165 // Legacy mode: if input is provided, assume deploy command