+4
-4
apps/main-app/public/editor/tabs/CLITab.tsx
+4
-4
apps/main-app/public/editor/tabs/CLITab.tsx
···
71
71
</a>
72
72
<div className="text-xs text-muted-foreground">
73
73
<span className="font-mono">
74
-
SHA-1: 9281454860f2eb07b39b80f7a9cc8e9bdcff491b
74
+
SHA-1: 2b5c1d6d0e21f9d764dd66ef869bfcd348e8a111
75
75
</span>
76
76
</div>
77
77
</div>
···
87
87
</a>
88
88
<div className="text-xs text-muted-foreground">
89
89
<span className="font-mono">
90
-
SHA-1: d460863150c4c162b7e7e3801a67746da3aaf9d9
90
+
SHA-1: 68d4a3831c07d2f32fdde8d3e809af1ab79e804e
91
91
</span>
92
92
</div>
93
93
</div>
···
103
103
</a>
104
104
<div className="text-xs text-muted-foreground">
105
105
<span className="font-mono">
106
-
SHA-1: 94968abed20422df826b78c38cb506dd4b1b5885
106
+
SHA-1: 86e89f592b0ec53239c082f502cbe7a47ed8bbec
107
107
</span>
108
108
</div>
109
109
</div>
···
119
119
</a>
120
120
<div className="text-xs text-muted-foreground">
121
121
<span className="font-mono">
122
-
SHA-1: 45293e47da38b97ef35258a08cb2682eee64a659
122
+
SHA-1: 227b735911ad260cff5af3ca3beefa4e1e3956a8
123
123
</span>
124
124
</div>
125
125
</div>
+401
binaries/index.html
+401
binaries/index.html
···
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.2.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
275
+
68d4a3831c07d2f32fdde8d3e809af1ab79e804e wisp-cli-aarch64-linux
276
+
86e89f592b0ec53239c082f502cbe7a47ed8bbec wisp-cli-x86_64-linux
277
+
227b735911ad260cff5af3ca3beefa4e1e3956a8 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
+
289
+
engine: 'nixery'
290
+
291
+
clone:
292
+
skip: false
293
+
depth: 1
294
+
submodules: false
295
+
296
+
dependencies:
297
+
nixpkgs:
298
+
- nodejs
299
+
- coreutils
300
+
- curl
301
+
github:NixOS/nixpkgs/nixpkgs-unstable:
302
+
- bun
303
+
304
+
environment:
305
+
SITE_PATH: 'dist'
306
+
SITE_NAME: 'my-site'
307
+
WISP_HANDLE: 'your-handle.bsky.social'
308
+
309
+
steps:
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
346
+
curl -O https://sites.wisp.place/nekomimi.pet/wisp-cli-binaries/wisp-cli-macos-arm64
347
+
chmod +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
360
+
wisp-cli pull your-handle.bsky.social \
361
+
--site my-site \
362
+
--output ./my-site
363
+
364
+
# Pull to current directory
365
+
wisp-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)
371
+
wisp-cli serve your-handle.bsky.social \
372
+
--site my-site
373
+
374
+
# Serve on a custom port
375
+
wisp-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)
382
+
wisp-cli serve your-handle.bsky.social \
383
+
--site my-site \
384
+
--spa
385
+
386
+
# Enable directory listing for paths without index files
387
+
wisp-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>
binaries/wisp-cli-aarch64-darwin
binaries/wisp-cli-aarch64-darwin
This is a binary file and will not be displayed.
binaries/wisp-cli-aarch64-linux
binaries/wisp-cli-aarch64-linux
This is a binary file and will not be displayed.
binaries/wisp-cli-x86_64-linux
binaries/wisp-cli-x86_64-linux
This is a binary file and will not be displayed.
binaries/wisp-cli-x86_64-windows.exe
binaries/wisp-cli-x86_64-windows.exe
This is a binary file and will not be displayed.
+16
-4
docs/src/content/docs/cli.md
+16
-4
docs/src/content/docs/cli.md
···
48
48
<h3 style="margin-top: 1.5rem; margin-bottom: 0.5rem;">SHA-1 Checksums</h3>
49
49
50
50
<pre style="font-size: 0.75rem; padding: 1rem;" class="language-bash" tabindex="0"><code class="language-bash">
51
-
9281454860f2eb07b39b80f7a9cc8e9bdcff491b wisp-cli-aarch64-darwin
51
+
2b5c1d6d0e21f9d764dd66ef869bfcd348e8a111 wisp-cli-aarch64-darwin
52
52
53
-
d460863150c4c162b7e7e3801a67746da3aaf9d9 wisp-cli-aarch64-linux
53
+
68d4a3831c07d2f32fdde8d3e809af1ab79e804e wisp-cli-aarch64-linux
54
54
55
-
94968abed20422df826b78c38cb506dd4b1b5885 wisp-cli-x86_64-linux
55
+
86e89f592b0ec53239c082f502cbe7a47ed8bbec wisp-cli-x86_64-linux
56
56
57
-
45293e47da38b97ef35258a08cb2682eee64a659 wisp-cli-x86_64-windows.exe
57
+
227b735911ad260cff5af3ca3beefa4e1e3956a8 wisp-cli-x86_64-windows.exe
58
58
</code></pre>
59
59
60
60
</div>
···
161
161
wisp-cli serve your-handle.bsky.social \
162
162
--site my-site \
163
163
--port 3000
164
+
165
+
# Enable SPA mode (serve index.html for all routes)
166
+
wisp-cli serve your-handle.bsky.social \
167
+
--site my-site \
168
+
--spa
169
+
170
+
# Enable directory listing for paths without index files
171
+
wisp-cli serve your-handle.bsky.social \
172
+
--site my-site \
173
+
--directory
164
174
```
165
175
166
176
Downloads site, serves it, and watches firehose for live updates!
···
249
259
-s, --site <SITE> Site name to serve
250
260
-o, --output <OUTPUT> Site files directory [default: .]
251
261
-p, --port <PORT> Port to serve on [default: 8080]
262
+
--spa Enable SPA mode (serve index.html for all routes)
263
+
--directory Enable directory listing mode for paths without index files
252
264
-h, --help Print help
253
265
```
254
266