+72
-2
cli/README.md
+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
+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