html-golive 0.4.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- html_golive-0.4.1/LICENSE +21 -0
- html_golive-0.4.1/PKG-INFO +324 -0
- html_golive-0.4.1/README.md +293 -0
- html_golive-0.4.1/golive/__init__.py +3 -0
- html_golive-0.4.1/golive/backends/__init__.py +1 -0
- html_golive-0.4.1/golive/backends/auth/__init__.py +1 -0
- html_golive-0.4.1/golive/backends/auth/base.py +17 -0
- html_golive-0.4.1/golive/backends/auth/none.py +12 -0
- html_golive-0.4.1/golive/backends/auth/oauth.py +330 -0
- html_golive-0.4.1/golive/backends/auth/presets.py +84 -0
- html_golive-0.4.1/golive/backends/auth/token.py +49 -0
- html_golive-0.4.1/golive/backends/data/__init__.py +5 -0
- html_golive-0.4.1/golive/backends/data/supabase.py +151 -0
- html_golive-0.4.1/golive/backends/factory.py +51 -0
- html_golive-0.4.1/golive/backends/images/__init__.py +15 -0
- html_golive-0.4.1/golive/backends/images/base.py +34 -0
- html_golive-0.4.1/golive/backends/images/command.py +139 -0
- html_golive-0.4.1/golive/backends/images/s3.py +88 -0
- html_golive-0.4.1/golive/backends/postgrest.py +138 -0
- html_golive-0.4.1/golive/backends/registry/__init__.py +1 -0
- html_golive-0.4.1/golive/backends/registry/sqlite_store.py +202 -0
- html_golive-0.4.1/golive/backends/registry/supabase_store.py +184 -0
- html_golive-0.4.1/golive/backends/storage/__init__.py +1 -0
- html_golive-0.4.1/golive/backends/storage/local.py +103 -0
- html_golive-0.4.1/golive/backends/storage/s3.py +195 -0
- html_golive-0.4.1/golive/backends/storage/supabase_store.py +242 -0
- html_golive-0.4.1/golive/cli.py +791 -0
- html_golive-0.4.1/golive/config.py +490 -0
- html_golive-0.4.1/golive/core/__init__.py +1 -0
- html_golive-0.4.1/golive/core/audit_log.py +277 -0
- html_golive-0.4.1/golive/core/bundle.py +945 -0
- html_golive-0.4.1/golive/core/cdn_localizer.py +222 -0
- html_golive-0.4.1/golive/core/clone_analyzer.py +562 -0
- html_golive-0.4.1/golive/core/clone_fetcher.py +920 -0
- html_golive-0.4.1/golive/core/clone_patcher.py +543 -0
- html_golive-0.4.1/golive/core/clone_site.py +315 -0
- html_golive-0.4.1/golive/core/code_safety_checker.py +364 -0
- html_golive-0.4.1/golive/core/css_style_enhancer.py +659 -0
- html_golive-0.4.1/golive/core/data_role_tagger.py +456 -0
- html_golive-0.4.1/golive/core/http_client.py +82 -0
- html_golive-0.4.1/golive/core/keymap_rules.py +143 -0
- html_golive-0.4.1/golive/core/migrate_check.py +189 -0
- html_golive-0.4.1/golive/core/paths.py +71 -0
- html_golive-0.4.1/golive/core/preview_server.py +780 -0
- html_golive-0.4.1/golive/core/publish_utils.py +189 -0
- html_golive-0.4.1/golive/core/slug_checker.py +150 -0
- html_golive-0.4.1/golive/inject/__init__.py +29 -0
- html_golive-0.4.1/golive/inject/_escape.py +72 -0
- html_golive-0.4.1/golive/inject/editor.py +434 -0
- html_golive-0.4.1/golive/inject/supabase_api.py +309 -0
- html_golive-0.4.1/golive/inject/template_api.py +431 -0
- html_golive-0.4.1/golive/inject/watermark.py +239 -0
- html_golive-0.4.1/golive/resources/css_styles/apple.css +184 -0
- html_golive-0.4.1/golive/resources/css_styles/bloomberg.css +208 -0
- html_golive-0.4.1/golive/resources/css_styles/carbon.css +145 -0
- html_golive-0.4.1/golive/resources/css_styles/cowork.css +184 -0
- html_golive-0.4.1/golive/resources/css_styles/cyberpunk.css +269 -0
- html_golive-0.4.1/golive/resources/css_styles/dreamy.css +143 -0
- html_golive-0.4.1/golive/resources/css_styles/earthy.css +143 -0
- html_golive-0.4.1/golive/resources/css_styles/fresh.css +143 -0
- html_golive-0.4.1/golive/resources/css_styles/glass.css +157 -0
- html_golive-0.4.1/golive/resources/css_styles/ink.css +308 -0
- html_golive-0.4.1/golive/resources/css_styles/macaron.css +143 -0
- html_golive-0.4.1/golive/resources/css_styles/minimal.css +197 -0
- html_golive-0.4.1/golive/resources/css_styles/morandi.css +142 -0
- html_golive-0.4.1/golive/resources/css_styles/newspaper.css +317 -0
- html_golive-0.4.1/golive/resources/css_styles/palace.css +345 -0
- html_golive-0.4.1/golive/resources/css_styles/steampunk.css +215 -0
- html_golive-0.4.1/golive/resources/css_styles/vivid.css +152 -0
- html_golive-0.4.1/golive/resources/css_styles/xhs-fun.css +209 -0
- html_golive-0.4.1/golive/resources/css_styles/xhs.css +183 -0
- html_golive-0.4.1/golive/security/__init__.py +1 -0
- html_golive-0.4.1/golive/security/ai_review.py +252 -0
- html_golive-0.4.1/golive/security/rules.yaml +94 -0
- html_golive-0.4.1/golive/security/scanner.py +328 -0
- html_golive-0.4.1/golive/server/__init__.py +1 -0
- html_golive-0.4.1/golive/server/app.py +395 -0
- html_golive-0.4.1/golive/server/editor_api.py +166 -0
- html_golive-0.4.1/html_golive.egg-info/PKG-INFO +324 -0
- html_golive-0.4.1/html_golive.egg-info/SOURCES.txt +97 -0
- html_golive-0.4.1/html_golive.egg-info/dependency_links.txt +1 -0
- html_golive-0.4.1/html_golive.egg-info/entry_points.txt +2 -0
- html_golive-0.4.1/html_golive.egg-info/requires.txt +9 -0
- html_golive-0.4.1/html_golive.egg-info/top_level.txt +1 -0
- html_golive-0.4.1/pyproject.toml +48 -0
- html_golive-0.4.1/setup.cfg +4 -0
- html_golive-0.4.1/tests/test_ai_review.py +211 -0
- html_golive-0.4.1/tests/test_backends_supabase.py +137 -0
- html_golive-0.4.1/tests/test_config.py +193 -0
- html_golive-0.4.1/tests/test_editor.py +310 -0
- html_golive-0.4.1/tests/test_inject.py +240 -0
- html_golive-0.4.1/tests/test_m2_warn_fixes.py +143 -0
- html_golive-0.4.1/tests/test_migrate_check.py +81 -0
- html_golive-0.4.1/tests/test_oauth.py +331 -0
- html_golive-0.4.1/tests/test_oidc_presets.py +93 -0
- html_golive-0.4.1/tests/test_smoke.py +153 -0
- html_golive-0.4.1/tests/test_v040_followups.py +80 -0
- html_golive-0.4.1/tests/test_v041_hardening.py +99 -0
- html_golive-0.4.1/tests/test_watermark.py +145 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Songhonglei
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: html-golive
|
|
3
|
+
Version: 0.4.1
|
|
4
|
+
Summary: Self-hosted one-command HTML deployment — Vercel-lite for your intranet.
|
|
5
|
+
Author: Songhonglei
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/Songhonglei/html-golive
|
|
8
|
+
Project-URL: Issues, https://github.com/Songhonglei/html-golive/issues
|
|
9
|
+
Keywords: html,deploy,static-site,self-hosted,intranet
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Environment :: Console
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Topic :: Internet :: WWW/HTTP :: Site Management
|
|
20
|
+
Requires-Python: >=3.9
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
License-File: LICENSE
|
|
23
|
+
Requires-Dist: requests>=2.25
|
|
24
|
+
Requires-Dist: beautifulsoup4>=4.9
|
|
25
|
+
Requires-Dist: pyyaml>=5.4
|
|
26
|
+
Provides-Extra: image
|
|
27
|
+
Requires-Dist: Pillow>=9.0; extra == "image"
|
|
28
|
+
Provides-Extra: s3
|
|
29
|
+
Requires-Dist: boto3>=1.26; extra == "s3"
|
|
30
|
+
Dynamic: license-file
|
|
31
|
+
|
|
32
|
+
# html-golive
|
|
33
|
+
|
|
34
|
+
> **Self-hosted one-command HTML deployment — Vercel-lite for your intranet.**
|
|
35
|
+
|
|
36
|
+
Turn any HTML file, project folder or zip archive into a shareable URL on
|
|
37
|
+
your own machine, NAS, VPS or intranet server.
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
pip install git+https://github.com/Songhonglei/html-golive.git
|
|
41
|
+
|
|
42
|
+
golive publish report.html --name "Q3 Report" --slug q3
|
|
43
|
+
# ✅ Published → http://localhost:8787/q3
|
|
44
|
+
|
|
45
|
+
golive serve
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
**Zero config to start** — local storage + SQLite + built-in server.
|
|
49
|
+
**Grows with you** — swap in Supabase or any S3-compatible backend
|
|
50
|
+
(MinIO / Tencent COS / Aliyun OSS / Volcengine TOS) with one yaml file.
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## Table of contents
|
|
55
|
+
|
|
56
|
+
- [Why html-golive](#why-html-golive)
|
|
57
|
+
- [Quickstart](#quickstart)
|
|
58
|
+
- [Features](#features)
|
|
59
|
+
- [Architecture](#architecture)
|
|
60
|
+
- [Configuration](#configuration)
|
|
61
|
+
- [Data layer](#data-layer-give-static-pages-a-database)
|
|
62
|
+
- [Security scanning](#security-scanning)
|
|
63
|
+
- [Docker](#docker)
|
|
64
|
+
- [Roadmap](#roadmap)
|
|
65
|
+
|
|
66
|
+
> 📖 **Full user manual**: [docs/manual.md](docs/manual.md) — every feature,
|
|
67
|
+
> organised by task (publishing, editor, access control, data, security,
|
|
68
|
+
> identity, migration, FAQ).
|
|
69
|
+
|
|
70
|
+
## Why html-golive
|
|
71
|
+
|
|
72
|
+
- **One command, one URL.** No build step, no server code, no cloud
|
|
73
|
+
account. `golive publish` → share the link.
|
|
74
|
+
- **Everything becomes a single file.** Folders and zips are bundled —
|
|
75
|
+
CSS/JS inlined, images compressed and embedded (or uploaded through
|
|
76
|
+
your own image host).
|
|
77
|
+
- **Static pages, real data.** Publish a plain HTML file that reads and
|
|
78
|
+
writes a real database via `window.TemplateAPI` /
|
|
79
|
+
`window.SupabaseAPI` — no backend code required.
|
|
80
|
+
- **Own your stack.** Runs entirely on your infrastructure. No outbound
|
|
81
|
+
calls at publish/serve time ([details](#network-behavior)).
|
|
82
|
+
- **Production habits built in.** Slug collision checks, 10-snapshot
|
|
83
|
+
rollback, credential/PII scanning on every publish, audit log.
|
|
84
|
+
|
|
85
|
+
## Quickstart
|
|
86
|
+
|
|
87
|
+
### 1 · Install
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
# from GitHub (PyPI release coming soon)
|
|
91
|
+
pip install git+https://github.com/Songhonglei/html-golive.git
|
|
92
|
+
|
|
93
|
+
# extras once installed from source checkout:
|
|
94
|
+
# pip install '.[image]' # + image compression (Pillow)
|
|
95
|
+
# pip install '.[s3]' # + S3-compatible backends (boto3)
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### 2 · Publish
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
golive publish index.html --name Demo --slug demo
|
|
102
|
+
golive publish ./my-project/ --slug app # folder → bundled single HTML
|
|
103
|
+
golive publish site.zip # zip / tar.gz work too
|
|
104
|
+
golive publish page.html --style apple # apply one of 19 CSS styles
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### 3 · Serve
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
golive serve --port 8787
|
|
111
|
+
# → http://<your-host>:8787/demo
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Everyday commands
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
golive list # all published sites
|
|
118
|
+
golive publish new.html --update demo # overwrite update
|
|
119
|
+
golive rollback demo --dry-run # inspect snapshots, then --yes
|
|
120
|
+
golive preview draft.html # live preview + style panel
|
|
121
|
+
golive clone https://example.com --save-only # snapshot a public page
|
|
122
|
+
golive styles # list the 19 CSS styles
|
|
123
|
+
golive doctor # environment health check
|
|
124
|
+
|
|
125
|
+
# v0.3 — online editing & watermark
|
|
126
|
+
golive publish page.html --enable-editor --owner you@example.com
|
|
127
|
+
golive maintainer add demo teammate@example.com
|
|
128
|
+
golive publish page.html --watermark "CONFIDENTIAL"
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### Online editing (v0.3)
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
export GOLIVE_EDITOR_TOKEN=$(openssl rand -hex 16)
|
|
135
|
+
golive publish report.html --slug q3 --enable-editor --owner you@example.com
|
|
136
|
+
golive serve
|
|
137
|
+
# open http://localhost:8787/q3?editor_token=<token>&editor_user=you@example.com
|
|
138
|
+
# click ✏️ → edit text inline → 💾 save (snapshot taken automatically)
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Saves go through the same security scanner as publishes, are limited to
|
|
142
|
+
the site owner + maintainers, and every overwrite is preceded by a
|
|
143
|
+
rollback snapshot. With `auth.provider: oidc` the editor accepts the
|
|
144
|
+
login session instead of the token+header pair.
|
|
145
|
+
|
|
146
|
+
## Features
|
|
147
|
+
|
|
148
|
+
**Publishing & content**
|
|
149
|
+
- Single HTML / directory / zip / tar.gz publishing with asset bundling
|
|
150
|
+
- 19 built-in CSS beautification styles (`--style`, custom font CDN via
|
|
151
|
+
`GOLIVE_FONT_CDN_BASE`)
|
|
152
|
+
- Image compression (`--compress`) and pluggable image upload
|
|
153
|
+
(`GOLIVE_UPLOADER_CMD` command template, or native S3 uploader)
|
|
154
|
+
- Website cloning (`golive clone <url>`) with static snapshot mode
|
|
155
|
+
|
|
156
|
+
**Operations**
|
|
157
|
+
- Short slugs with reserved-word and collision checks
|
|
158
|
+
- Rollback with 10 snapshots per site
|
|
159
|
+
- Built-in static server with JSON API and health endpoint
|
|
160
|
+
- Live preview with hot reload and style-switch panel
|
|
161
|
+
- `golive doctor` environment diagnostics, audit log
|
|
162
|
+
|
|
163
|
+
**Data & backends** *(v0.2)*
|
|
164
|
+
- `window.TemplateAPI` / `window.SupabaseAPI` injection — static pages
|
|
165
|
+
get a real database with zero backend code
|
|
166
|
+
- Storage / registry / data backends: local + SQLite (default),
|
|
167
|
+
Supabase (one project covers all three), S3-compatible object storage
|
|
168
|
+
- `golive migrate-check` — port pages from other golive deployments
|
|
169
|
+
- Docker Compose deployment (+ optional MinIO profile)
|
|
170
|
+
|
|
171
|
+
**Editing, identity & watermarking** *(v0.3)*
|
|
172
|
+
- In-browser inline editor (`publish --enable-editor`): contenteditable
|
|
173
|
+
text editing with a save API that re-runs the full security pipeline,
|
|
174
|
+
snapshots before every overwrite, and enforces owner/maintainer ACLs
|
|
175
|
+
(`golive maintainer add/remove/list`)
|
|
176
|
+
- Page watermarking (`--watermark [text]`): canvas-tiled identity
|
|
177
|
+
watermark — OIDC user, static text, or page meta tag; optional
|
|
178
|
+
view-report webhook; `GOLIVE_WATERMARK_OFF=1` kill switch
|
|
179
|
+
- Generic **OIDC login** (`auth.provider: oidc`): Google / Keycloak /
|
|
180
|
+
Authentik / any discovery-document IdP; PKCE + signed session cookies;
|
|
181
|
+
sessions accepted by the management and editor APIs
|
|
182
|
+
- Optional **LLM security review** of weak scan hits via any
|
|
183
|
+
OpenAI-compatible endpoint (`security.llm.*`), with a conservative
|
|
184
|
+
degrade path and a `strict_mode` gate
|
|
185
|
+
|
|
186
|
+
**Safety**
|
|
187
|
+
- Credential / PII scanning on every publish (YAML-extensible rules)
|
|
188
|
+
- Path-traversal-hardened server and archive extraction
|
|
189
|
+
- Token-protected management API (`GOLIVE_TOKEN`)
|
|
190
|
+
|
|
191
|
+
## Architecture
|
|
192
|
+
|
|
193
|
+
```
|
|
194
|
+
┌────────────── golive core (pure logic) ───────────────────┐
|
|
195
|
+
│ bundle / image compress / CSS styles / clone / preview / │
|
|
196
|
+
│ security scanner / slug checker │
|
|
197
|
+
└──────┬──────────────────┬──────────────────┬──────────────┘
|
|
198
|
+
StorageBackend RegistryBackend DataBackend
|
|
199
|
+
site HTML/assets site metadata TemplateAPI/SupabaseAPI
|
|
200
|
+
│ │ │
|
|
201
|
+
local-fs / s3 / SQLite / supabase supabase (PostgREST)
|
|
202
|
+
supabase storage
|
|
203
|
+
│
|
|
204
|
+
AuthProvider: none (default) / token (GOLIVE_TOKEN) / oidc (generic OIDC)
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
All data lives under `GOLIVE_HOME` (default `~/.golive/`):
|
|
208
|
+
|
|
209
|
+
```
|
|
210
|
+
~/.golive/
|
|
211
|
+
├── sites/<site_id>/index.html published content
|
|
212
|
+
├── backups/<site_id>/ rollback snapshots (max 10)
|
|
213
|
+
├── registry.db SQLite registry
|
|
214
|
+
├── logs/ audit log
|
|
215
|
+
└── cache/ style backups etc.
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
## Configuration
|
|
219
|
+
|
|
220
|
+
Everything works with zero config. Two layers of knobs, **env always
|
|
221
|
+
wins over yaml**:
|
|
222
|
+
|
|
223
|
+
### golive.yaml (backend selection)
|
|
224
|
+
|
|
225
|
+
Lookup order: `--config <path>` → `$GOLIVE_CONFIG` → `./golive.yaml` →
|
|
226
|
+
`$GOLIVE_HOME/golive.yaml`. Full annotated example:
|
|
227
|
+
[golive.example.yaml](golive.example.yaml) · backend combinations:
|
|
228
|
+
[docs/backends.md](docs/backends.md)
|
|
229
|
+
|
|
230
|
+
### Environment variables
|
|
231
|
+
|
|
232
|
+
| Variable | Purpose |
|
|
233
|
+
|---|---|
|
|
234
|
+
| `GOLIVE_HOME` | data directory (default `~/.golive/`) |
|
|
235
|
+
| `GOLIVE_TOKEN` | protect `/api/sites` (Bearer or `X-Golive-Token`) |
|
|
236
|
+
| `GOLIVE_EDITOR_TOKEN` | online-editor save token (falls back to `GOLIVE_TOKEN`) |
|
|
237
|
+
| `GOLIVE_WATERMARK_TEXT` / `GOLIVE_WATERMARK_OFF` | watermark text / global kill switch |
|
|
238
|
+
| `GOLIVE_OIDC_CLIENT_SECRET` / `GOLIVE_COOKIE_SECRET` | OIDC client secret / session-cookie HMAC key |
|
|
239
|
+
| `GOLIVE_LLM_BASE_URL` / `GOLIVE_LLM_MODEL` / `GOLIVE_LLM_API_KEY` | LLM security review endpoint |
|
|
240
|
+
| `GOLIVE_FONT_CDN_BASE` | swap `fonts.googleapis.com` for your font mirror |
|
|
241
|
+
| `GOLIVE_UPLOADER_CMD` | image-upload command template (`mytool up {file}`) |
|
|
242
|
+
| `GOLIVE_SUPABASE_URL` / `_ANON_KEY` / `_SERVICE_KEY` | Supabase backends |
|
|
243
|
+
| `GOLIVE_S3_AK` / `GOLIVE_S3_SK` | S3-compatible backends |
|
|
244
|
+
| `FIRECRAWL_API_KEY` | optional JS-heavy-page fallback for `golive clone` |
|
|
245
|
+
|
|
246
|
+
### Network behavior
|
|
247
|
+
|
|
248
|
+
golive makes **no outbound calls** at publish/serve time. Exceptions:
|
|
249
|
+
`golive clone <url>` fetches the target page; `golive preview` downloads
|
|
250
|
+
a one-time Tailwind cache from `cdn.tailwindcss.com` on first run (fails
|
|
251
|
+
silently offline); injected styles reference public font CDNs
|
|
252
|
+
(override with `GOLIVE_FONT_CDN_BASE`); your own uploader command and
|
|
253
|
+
configured backends.
|
|
254
|
+
|
|
255
|
+
## Data layer: give static pages a database
|
|
256
|
+
|
|
257
|
+
Backed by your own Supabase project — no server code:
|
|
258
|
+
|
|
259
|
+
```bash
|
|
260
|
+
golive db init --print-sql # paste into Supabase SQL editor
|
|
261
|
+
golive publish app.html --data-model myapp_v1
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
Your page then simply calls:
|
|
265
|
+
|
|
266
|
+
```js
|
|
267
|
+
// namespaced record store
|
|
268
|
+
await TemplateAPI.upsert({ templateName: 'vote:alice', templateContent: {n: 1} });
|
|
269
|
+
const { total, list } = await TemplateAPI.listAll();
|
|
270
|
+
|
|
271
|
+
// or direct table access
|
|
272
|
+
const { rows } = await SupabaseAPI.query('feedback', { limit: 50 });
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
API signatures are **stable contracts** — pages built on any golive
|
|
276
|
+
deployment run unchanged on yours. Guide with RLS security notes:
|
|
277
|
+
[docs/data-layer.md](docs/data-layer.md).
|
|
278
|
+
|
|
279
|
+
> **Note**: if no data backend is configured, `--data-model` publishes
|
|
280
|
+
> still succeed — the page gets a stub API that raises a clear
|
|
281
|
+
> "data backend not configured" error at call time (a warning is also
|
|
282
|
+
> printed at publish time).
|
|
283
|
+
|
|
284
|
+
Porting pages from another deployment?
|
|
285
|
+
`golive migrate-check page.html` reports anything deployment-specific
|
|
286
|
+
([migration guide](docs/migrate-from-intranet.md)).
|
|
287
|
+
|
|
288
|
+
## Security scanning
|
|
289
|
+
|
|
290
|
+
Every publish is scanned against built-in rules — API keys, private
|
|
291
|
+
keys, database connection strings, PII patterns. Strong hits block the
|
|
292
|
+
publish; weak hits warn — and can optionally get a semantic second pass
|
|
293
|
+
from any OpenAI-compatible LLM (`security.llm.base_url`; works with
|
|
294
|
+
OpenAI / Azure / Ollama / self-hosted gateways). Unconfigured installs
|
|
295
|
+
keep pure rule verdicts; `strict_mode: true` refuses to publish without
|
|
296
|
+
AI review. Extend with your own YAML rules, or bypass a false positive
|
|
297
|
+
with `--skip-scan`. Details: [docs/security.md](docs/security.md)
|
|
298
|
+
|
|
299
|
+
## Docker
|
|
300
|
+
|
|
301
|
+
```bash
|
|
302
|
+
docker compose up -d golive # golive serve on :8787
|
|
303
|
+
docker compose --profile minio up -d # + local S3 stack for images
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
## Roadmap
|
|
307
|
+
|
|
308
|
+
- ~~**M1 — core**: publish/serve/rollback, styles, clone, preview, scan~~ ✅ v0.1
|
|
309
|
+
- ~~**M2 — data layer**: Supabase backend trio, TemplateAPI/SupabaseAPI
|
|
310
|
+
injection, S3 adapters, migrate-check, Docker Compose~~ ✅ v0.2
|
|
311
|
+
- ~~**M3 — editing & identity**: inline editor with versioned save API,
|
|
312
|
+
watermarking, OpenAI-compatible LLM security review, generic OIDC~~ ✅ v0.3
|
|
313
|
+
- ~~**M4 — docs & polish**: OIDC provider presets, editor image upload,
|
|
314
|
+
persistent cookie secret, full user manual~~ ✅ v0.4
|
|
315
|
+
- **M5 — collaboration & scale**: shared session store (redis), multi-user
|
|
316
|
+
editing conflicts UX, group-based ACLs, admin operations portal.
|
|
317
|
+
|
|
318
|
+
## License
|
|
319
|
+
|
|
320
|
+
[MIT](LICENSE) © 2026 Songhonglei
|
|
321
|
+
|
|
322
|
+
---
|
|
323
|
+
|
|
324
|
+
中文文档请见 [README.zh-CN.md](README.zh-CN.md)。
|
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
# html-golive
|
|
2
|
+
|
|
3
|
+
> **Self-hosted one-command HTML deployment — Vercel-lite for your intranet.**
|
|
4
|
+
|
|
5
|
+
Turn any HTML file, project folder or zip archive into a shareable URL on
|
|
6
|
+
your own machine, NAS, VPS or intranet server.
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
pip install git+https://github.com/Songhonglei/html-golive.git
|
|
10
|
+
|
|
11
|
+
golive publish report.html --name "Q3 Report" --slug q3
|
|
12
|
+
# ✅ Published → http://localhost:8787/q3
|
|
13
|
+
|
|
14
|
+
golive serve
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
**Zero config to start** — local storage + SQLite + built-in server.
|
|
18
|
+
**Grows with you** — swap in Supabase or any S3-compatible backend
|
|
19
|
+
(MinIO / Tencent COS / Aliyun OSS / Volcengine TOS) with one yaml file.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Table of contents
|
|
24
|
+
|
|
25
|
+
- [Why html-golive](#why-html-golive)
|
|
26
|
+
- [Quickstart](#quickstart)
|
|
27
|
+
- [Features](#features)
|
|
28
|
+
- [Architecture](#architecture)
|
|
29
|
+
- [Configuration](#configuration)
|
|
30
|
+
- [Data layer](#data-layer-give-static-pages-a-database)
|
|
31
|
+
- [Security scanning](#security-scanning)
|
|
32
|
+
- [Docker](#docker)
|
|
33
|
+
- [Roadmap](#roadmap)
|
|
34
|
+
|
|
35
|
+
> 📖 **Full user manual**: [docs/manual.md](docs/manual.md) — every feature,
|
|
36
|
+
> organised by task (publishing, editor, access control, data, security,
|
|
37
|
+
> identity, migration, FAQ).
|
|
38
|
+
|
|
39
|
+
## Why html-golive
|
|
40
|
+
|
|
41
|
+
- **One command, one URL.** No build step, no server code, no cloud
|
|
42
|
+
account. `golive publish` → share the link.
|
|
43
|
+
- **Everything becomes a single file.** Folders and zips are bundled —
|
|
44
|
+
CSS/JS inlined, images compressed and embedded (or uploaded through
|
|
45
|
+
your own image host).
|
|
46
|
+
- **Static pages, real data.** Publish a plain HTML file that reads and
|
|
47
|
+
writes a real database via `window.TemplateAPI` /
|
|
48
|
+
`window.SupabaseAPI` — no backend code required.
|
|
49
|
+
- **Own your stack.** Runs entirely on your infrastructure. No outbound
|
|
50
|
+
calls at publish/serve time ([details](#network-behavior)).
|
|
51
|
+
- **Production habits built in.** Slug collision checks, 10-snapshot
|
|
52
|
+
rollback, credential/PII scanning on every publish, audit log.
|
|
53
|
+
|
|
54
|
+
## Quickstart
|
|
55
|
+
|
|
56
|
+
### 1 · Install
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
# from GitHub (PyPI release coming soon)
|
|
60
|
+
pip install git+https://github.com/Songhonglei/html-golive.git
|
|
61
|
+
|
|
62
|
+
# extras once installed from source checkout:
|
|
63
|
+
# pip install '.[image]' # + image compression (Pillow)
|
|
64
|
+
# pip install '.[s3]' # + S3-compatible backends (boto3)
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### 2 · Publish
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
golive publish index.html --name Demo --slug demo
|
|
71
|
+
golive publish ./my-project/ --slug app # folder → bundled single HTML
|
|
72
|
+
golive publish site.zip # zip / tar.gz work too
|
|
73
|
+
golive publish page.html --style apple # apply one of 19 CSS styles
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### 3 · Serve
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
golive serve --port 8787
|
|
80
|
+
# → http://<your-host>:8787/demo
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Everyday commands
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
golive list # all published sites
|
|
87
|
+
golive publish new.html --update demo # overwrite update
|
|
88
|
+
golive rollback demo --dry-run # inspect snapshots, then --yes
|
|
89
|
+
golive preview draft.html # live preview + style panel
|
|
90
|
+
golive clone https://example.com --save-only # snapshot a public page
|
|
91
|
+
golive styles # list the 19 CSS styles
|
|
92
|
+
golive doctor # environment health check
|
|
93
|
+
|
|
94
|
+
# v0.3 — online editing & watermark
|
|
95
|
+
golive publish page.html --enable-editor --owner you@example.com
|
|
96
|
+
golive maintainer add demo teammate@example.com
|
|
97
|
+
golive publish page.html --watermark "CONFIDENTIAL"
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Online editing (v0.3)
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
export GOLIVE_EDITOR_TOKEN=$(openssl rand -hex 16)
|
|
104
|
+
golive publish report.html --slug q3 --enable-editor --owner you@example.com
|
|
105
|
+
golive serve
|
|
106
|
+
# open http://localhost:8787/q3?editor_token=<token>&editor_user=you@example.com
|
|
107
|
+
# click ✏️ → edit text inline → 💾 save (snapshot taken automatically)
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Saves go through the same security scanner as publishes, are limited to
|
|
111
|
+
the site owner + maintainers, and every overwrite is preceded by a
|
|
112
|
+
rollback snapshot. With `auth.provider: oidc` the editor accepts the
|
|
113
|
+
login session instead of the token+header pair.
|
|
114
|
+
|
|
115
|
+
## Features
|
|
116
|
+
|
|
117
|
+
**Publishing & content**
|
|
118
|
+
- Single HTML / directory / zip / tar.gz publishing with asset bundling
|
|
119
|
+
- 19 built-in CSS beautification styles (`--style`, custom font CDN via
|
|
120
|
+
`GOLIVE_FONT_CDN_BASE`)
|
|
121
|
+
- Image compression (`--compress`) and pluggable image upload
|
|
122
|
+
(`GOLIVE_UPLOADER_CMD` command template, or native S3 uploader)
|
|
123
|
+
- Website cloning (`golive clone <url>`) with static snapshot mode
|
|
124
|
+
|
|
125
|
+
**Operations**
|
|
126
|
+
- Short slugs with reserved-word and collision checks
|
|
127
|
+
- Rollback with 10 snapshots per site
|
|
128
|
+
- Built-in static server with JSON API and health endpoint
|
|
129
|
+
- Live preview with hot reload and style-switch panel
|
|
130
|
+
- `golive doctor` environment diagnostics, audit log
|
|
131
|
+
|
|
132
|
+
**Data & backends** *(v0.2)*
|
|
133
|
+
- `window.TemplateAPI` / `window.SupabaseAPI` injection — static pages
|
|
134
|
+
get a real database with zero backend code
|
|
135
|
+
- Storage / registry / data backends: local + SQLite (default),
|
|
136
|
+
Supabase (one project covers all three), S3-compatible object storage
|
|
137
|
+
- `golive migrate-check` — port pages from other golive deployments
|
|
138
|
+
- Docker Compose deployment (+ optional MinIO profile)
|
|
139
|
+
|
|
140
|
+
**Editing, identity & watermarking** *(v0.3)*
|
|
141
|
+
- In-browser inline editor (`publish --enable-editor`): contenteditable
|
|
142
|
+
text editing with a save API that re-runs the full security pipeline,
|
|
143
|
+
snapshots before every overwrite, and enforces owner/maintainer ACLs
|
|
144
|
+
(`golive maintainer add/remove/list`)
|
|
145
|
+
- Page watermarking (`--watermark [text]`): canvas-tiled identity
|
|
146
|
+
watermark — OIDC user, static text, or page meta tag; optional
|
|
147
|
+
view-report webhook; `GOLIVE_WATERMARK_OFF=1` kill switch
|
|
148
|
+
- Generic **OIDC login** (`auth.provider: oidc`): Google / Keycloak /
|
|
149
|
+
Authentik / any discovery-document IdP; PKCE + signed session cookies;
|
|
150
|
+
sessions accepted by the management and editor APIs
|
|
151
|
+
- Optional **LLM security review** of weak scan hits via any
|
|
152
|
+
OpenAI-compatible endpoint (`security.llm.*`), with a conservative
|
|
153
|
+
degrade path and a `strict_mode` gate
|
|
154
|
+
|
|
155
|
+
**Safety**
|
|
156
|
+
- Credential / PII scanning on every publish (YAML-extensible rules)
|
|
157
|
+
- Path-traversal-hardened server and archive extraction
|
|
158
|
+
- Token-protected management API (`GOLIVE_TOKEN`)
|
|
159
|
+
|
|
160
|
+
## Architecture
|
|
161
|
+
|
|
162
|
+
```
|
|
163
|
+
┌────────────── golive core (pure logic) ───────────────────┐
|
|
164
|
+
│ bundle / image compress / CSS styles / clone / preview / │
|
|
165
|
+
│ security scanner / slug checker │
|
|
166
|
+
└──────┬──────────────────┬──────────────────┬──────────────┘
|
|
167
|
+
StorageBackend RegistryBackend DataBackend
|
|
168
|
+
site HTML/assets site metadata TemplateAPI/SupabaseAPI
|
|
169
|
+
│ │ │
|
|
170
|
+
local-fs / s3 / SQLite / supabase supabase (PostgREST)
|
|
171
|
+
supabase storage
|
|
172
|
+
│
|
|
173
|
+
AuthProvider: none (default) / token (GOLIVE_TOKEN) / oidc (generic OIDC)
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
All data lives under `GOLIVE_HOME` (default `~/.golive/`):
|
|
177
|
+
|
|
178
|
+
```
|
|
179
|
+
~/.golive/
|
|
180
|
+
├── sites/<site_id>/index.html published content
|
|
181
|
+
├── backups/<site_id>/ rollback snapshots (max 10)
|
|
182
|
+
├── registry.db SQLite registry
|
|
183
|
+
├── logs/ audit log
|
|
184
|
+
└── cache/ style backups etc.
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
## Configuration
|
|
188
|
+
|
|
189
|
+
Everything works with zero config. Two layers of knobs, **env always
|
|
190
|
+
wins over yaml**:
|
|
191
|
+
|
|
192
|
+
### golive.yaml (backend selection)
|
|
193
|
+
|
|
194
|
+
Lookup order: `--config <path>` → `$GOLIVE_CONFIG` → `./golive.yaml` →
|
|
195
|
+
`$GOLIVE_HOME/golive.yaml`. Full annotated example:
|
|
196
|
+
[golive.example.yaml](golive.example.yaml) · backend combinations:
|
|
197
|
+
[docs/backends.md](docs/backends.md)
|
|
198
|
+
|
|
199
|
+
### Environment variables
|
|
200
|
+
|
|
201
|
+
| Variable | Purpose |
|
|
202
|
+
|---|---|
|
|
203
|
+
| `GOLIVE_HOME` | data directory (default `~/.golive/`) |
|
|
204
|
+
| `GOLIVE_TOKEN` | protect `/api/sites` (Bearer or `X-Golive-Token`) |
|
|
205
|
+
| `GOLIVE_EDITOR_TOKEN` | online-editor save token (falls back to `GOLIVE_TOKEN`) |
|
|
206
|
+
| `GOLIVE_WATERMARK_TEXT` / `GOLIVE_WATERMARK_OFF` | watermark text / global kill switch |
|
|
207
|
+
| `GOLIVE_OIDC_CLIENT_SECRET` / `GOLIVE_COOKIE_SECRET` | OIDC client secret / session-cookie HMAC key |
|
|
208
|
+
| `GOLIVE_LLM_BASE_URL` / `GOLIVE_LLM_MODEL` / `GOLIVE_LLM_API_KEY` | LLM security review endpoint |
|
|
209
|
+
| `GOLIVE_FONT_CDN_BASE` | swap `fonts.googleapis.com` for your font mirror |
|
|
210
|
+
| `GOLIVE_UPLOADER_CMD` | image-upload command template (`mytool up {file}`) |
|
|
211
|
+
| `GOLIVE_SUPABASE_URL` / `_ANON_KEY` / `_SERVICE_KEY` | Supabase backends |
|
|
212
|
+
| `GOLIVE_S3_AK` / `GOLIVE_S3_SK` | S3-compatible backends |
|
|
213
|
+
| `FIRECRAWL_API_KEY` | optional JS-heavy-page fallback for `golive clone` |
|
|
214
|
+
|
|
215
|
+
### Network behavior
|
|
216
|
+
|
|
217
|
+
golive makes **no outbound calls** at publish/serve time. Exceptions:
|
|
218
|
+
`golive clone <url>` fetches the target page; `golive preview` downloads
|
|
219
|
+
a one-time Tailwind cache from `cdn.tailwindcss.com` on first run (fails
|
|
220
|
+
silently offline); injected styles reference public font CDNs
|
|
221
|
+
(override with `GOLIVE_FONT_CDN_BASE`); your own uploader command and
|
|
222
|
+
configured backends.
|
|
223
|
+
|
|
224
|
+
## Data layer: give static pages a database
|
|
225
|
+
|
|
226
|
+
Backed by your own Supabase project — no server code:
|
|
227
|
+
|
|
228
|
+
```bash
|
|
229
|
+
golive db init --print-sql # paste into Supabase SQL editor
|
|
230
|
+
golive publish app.html --data-model myapp_v1
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
Your page then simply calls:
|
|
234
|
+
|
|
235
|
+
```js
|
|
236
|
+
// namespaced record store
|
|
237
|
+
await TemplateAPI.upsert({ templateName: 'vote:alice', templateContent: {n: 1} });
|
|
238
|
+
const { total, list } = await TemplateAPI.listAll();
|
|
239
|
+
|
|
240
|
+
// or direct table access
|
|
241
|
+
const { rows } = await SupabaseAPI.query('feedback', { limit: 50 });
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
API signatures are **stable contracts** — pages built on any golive
|
|
245
|
+
deployment run unchanged on yours. Guide with RLS security notes:
|
|
246
|
+
[docs/data-layer.md](docs/data-layer.md).
|
|
247
|
+
|
|
248
|
+
> **Note**: if no data backend is configured, `--data-model` publishes
|
|
249
|
+
> still succeed — the page gets a stub API that raises a clear
|
|
250
|
+
> "data backend not configured" error at call time (a warning is also
|
|
251
|
+
> printed at publish time).
|
|
252
|
+
|
|
253
|
+
Porting pages from another deployment?
|
|
254
|
+
`golive migrate-check page.html` reports anything deployment-specific
|
|
255
|
+
([migration guide](docs/migrate-from-intranet.md)).
|
|
256
|
+
|
|
257
|
+
## Security scanning
|
|
258
|
+
|
|
259
|
+
Every publish is scanned against built-in rules — API keys, private
|
|
260
|
+
keys, database connection strings, PII patterns. Strong hits block the
|
|
261
|
+
publish; weak hits warn — and can optionally get a semantic second pass
|
|
262
|
+
from any OpenAI-compatible LLM (`security.llm.base_url`; works with
|
|
263
|
+
OpenAI / Azure / Ollama / self-hosted gateways). Unconfigured installs
|
|
264
|
+
keep pure rule verdicts; `strict_mode: true` refuses to publish without
|
|
265
|
+
AI review. Extend with your own YAML rules, or bypass a false positive
|
|
266
|
+
with `--skip-scan`. Details: [docs/security.md](docs/security.md)
|
|
267
|
+
|
|
268
|
+
## Docker
|
|
269
|
+
|
|
270
|
+
```bash
|
|
271
|
+
docker compose up -d golive # golive serve on :8787
|
|
272
|
+
docker compose --profile minio up -d # + local S3 stack for images
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
## Roadmap
|
|
276
|
+
|
|
277
|
+
- ~~**M1 — core**: publish/serve/rollback, styles, clone, preview, scan~~ ✅ v0.1
|
|
278
|
+
- ~~**M2 — data layer**: Supabase backend trio, TemplateAPI/SupabaseAPI
|
|
279
|
+
injection, S3 adapters, migrate-check, Docker Compose~~ ✅ v0.2
|
|
280
|
+
- ~~**M3 — editing & identity**: inline editor with versioned save API,
|
|
281
|
+
watermarking, OpenAI-compatible LLM security review, generic OIDC~~ ✅ v0.3
|
|
282
|
+
- ~~**M4 — docs & polish**: OIDC provider presets, editor image upload,
|
|
283
|
+
persistent cookie secret, full user manual~~ ✅ v0.4
|
|
284
|
+
- **M5 — collaboration & scale**: shared session store (redis), multi-user
|
|
285
|
+
editing conflicts UX, group-based ACLs, admin operations portal.
|
|
286
|
+
|
|
287
|
+
## License
|
|
288
|
+
|
|
289
|
+
[MIT](LICENSE) © 2026 Songhonglei
|
|
290
|
+
|
|
291
|
+
---
|
|
292
|
+
|
|
293
|
+
中文文档请见 [README.zh-CN.md](README.zh-CN.md)。
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"""golive.backends.auth.base — AuthProvider interface."""
|
|
2
|
+
|
|
3
|
+
from abc import ABC, abstractmethod
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class AuthProvider(ABC):
|
|
7
|
+
"""Auth abstraction for serve-mode write operations (and M3 editor)."""
|
|
8
|
+
|
|
9
|
+
name = "base"
|
|
10
|
+
|
|
11
|
+
@abstractmethod
|
|
12
|
+
def verify(self, request_headers: dict) -> bool:
|
|
13
|
+
"""Return True when the request is allowed to perform write ops."""
|
|
14
|
+
|
|
15
|
+
def identity(self, request_headers: dict) -> str:
|
|
16
|
+
"""Best-effort caller identity (empty string when unknown)."""
|
|
17
|
+
return ""
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"""golive.backends.auth.none — no-auth provider (default for single-user)."""
|
|
2
|
+
|
|
3
|
+
from golive.backends.auth.base import AuthProvider
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class NoneAuth(AuthProvider):
|
|
7
|
+
"""Allows everything. Fine on localhost; use TokenAuth on shared hosts."""
|
|
8
|
+
|
|
9
|
+
name = "none"
|
|
10
|
+
|
|
11
|
+
def verify(self, request_headers: dict) -> bool:
|
|
12
|
+
return True
|