comparison hg-web/README.md @ 218:921ca3086879 hg-web

[hg-web] Add architecture wiki tree
author MrJuneJune <me@mrjunejune.com>
date Sun, 02 Aug 2026 08:34:28 -0700
parents b818a4561a3c
children ce7f4400c2de
comparison
equal deleted inserted replaced
194:fb28063dc490 218:921ca3086879
1 # hg-web 1 # hg-web
2 2
3 A web-based Mercurial repository browser. Provides a GitHub-style interface for browsing files, viewing code with syntax highlighting, and reading markdown documentation. 3 A custom Mercurial forge and repository browser. The application keeps the
4 4 networking and HTTP stack in C with Seobeo, while the hand-drawn web interface
5 ## Features 5 is implemented in React and TypeScript.
6 6
7 - Browse repository files and directories 7 ## Wiki tree
8 - View code files with syntax highlighting (highlight.js) 8
9 - Render markdown files with WASM-based converter 9 ```text
10 - Dark/light theme support with system preference detection 10 hg-web
11 - Prefetch on hover for faster navigation 11 ├── Runtime
12 12 │ ├── hg_web_server :6970
13 ## Structure 13 │ │ ├── React application and static assets
14 14 │ │ ├── repository browsing API
15 ``` 15 │ │ ├── commit graph API
16 hg-web/ 16 │ │ └── Mercurial wire-protocol proxy
17 ├── BUILD # Bazel build configuration 17 │ └── hg serve :4444
18 ├── deploy.sh # Deployment script 18 │ ├── repository files and graph data
19 ├── main.c # C server handling API routes 19 │ └── Mercurial pull/push protocol
20 └── src/ # Frontend source files 20 ├── Backend
21 ``` 21 │ ├── main.c
22 22 │ └── ../seobeo
23 ## Building 23 │ ├── s_network.c
24 │ ├── s_web.c
25 │ ├── s_http_client.c
26 │ └── s_ssl.c
27 ├── Frontend
28 │ └── src
29 │ ├── main.tsx
30 │ ├── components
31 │ │ ├── app.tsx
32 │ │ ├── directory-browser.tsx
33 │ │ ├── graph.tsx
34 │ │ ├── header.tsx
35 │ │ ├── footer.tsx
36 │ │ ├── theme.tsx
37 │ │ └── repo-browser.tsx
38 │ ├── index.html
39 │ ├── index.css
40 │ ├── base.css
41 │ └── custom pencil, panda, icon, and background assets
42 ├── Build
43 │ ├── BUILD
44 │ ├── ../gui_ze/gui_ze.bzl
45 │ ├── ../markdown_converter
46 │ └── ../third_party/highlight
47 └── Operations
48 └── deploy.sh
49 ```
50
51 `repo-browser.tsx` is an older standalone browser implementation. The active
52 entry point is `main.tsx`, which renders `app.tsx`; `app.tsx` embeds
53 `directory-browser.tsx`.
54
55 ## Runtime topology
56
57 ```text
58 Browser
59 |
60 | HTTPS
61 v
62 nginx
63 |
64 | HTTP :6970
65 v
66 hg_web_server (main.c + Seobeo)
67 |
68 | HTTP :4444
69 v
70 hg serve (Zenbu Mercurial repository)
71 ```
72
73 The C server owns the public routes. It serves the application shell and
74 assets, translates browser API requests into `hg serve` requests, and streams
75 Mercurial wire-protocol traffic without routing bundle data through the normal
76 buffered HTTP response path.
77
78 ## Request flows
79
80 ### Application shell
81
82 ```text
83 GET /, /directories, or /graph
84 -> GetReactHome
85 -> hg-web/src/index.html
86 -> /page.js
87 -> src/main.tsx
88 -> components/app.tsx
89 ```
90
91 ### Repository browser
92
93 ```text
94 directory-browser.tsx
95 -> GET /api/repo/list?path=...
96 -> ApiListDirectory
97 -> GET hg-serve/file/tip/<path>?style=json
98
99 file or README selection
100 -> GET /api/repo/file?path=...
101 -> ApiGetFile
102 -> GET hg-serve/raw-file/tip/<path>
103 -> highlight.js or markdown_converter WASM
104 ```
105
106 ### Commit graph
107
108 ```text
109 graph.tsx
110 -> GET /api/graph/<revision>?graphtop=...&style=json
111 -> ApiGetGraph
112 -> GET hg-serve/graph/<revision>?...
113 -> React rows + custom pencil/panda canvas
114 ```
115
116 ### Mercurial clone, pull, and push
117
118 ```text
119 Mercurial client
120 -> GET or POST /repo
121 -> StreamHgWireProtocol
122 -> hg serve /?cmd=...
123 -> binary-safe streamed response
124 ```
125
126 ## Route map
127
128 | Method | Route | Owner | Purpose |
129 | --- | --- | --- | --- |
130 | `GET` | `/` | `GetReactHome` | Application shell |
131 | `GET` | `/directories` | `GetReactHome` | Legacy application-shell route |
132 | `GET` | `/graph` | `GetReactHome` | Commit graph application route |
133 | `GET` | `/api/repo/list` | `ApiListDirectory` | Directory listing JSON |
134 | `GET` | `/api/repo/file` | `ApiGetFile` | Raw tracked file |
135 | `GET` | `/api/repo/readme` | `ApiGetReadme` | Alias of the raw-file handler |
136 | `GET` | `/api/graph/:graph_id` | `ApiGetGraph` | Mercurial graph JSON |
137 | `GET`, `POST` | `/repo` | `StreamHgWireProtocol` | Mercurial wire protocol |
138
139 ## Frontend ownership
140
141 | File | Responsibility |
142 | --- | --- |
143 | `src/components/app.tsx` | Client-side routes, landing page, tabs, and history |
144 | `src/components/directory-browser.tsx` | Breadcrumbs, listings, prefetch, file modals, README rendering |
145 | `src/components/graph.tsx` | Graph fetching, pagination, canvas edges, panda nodes |
146 | `src/components/theme.tsx` | Stored light/dark preference and system-theme integration |
147 | `src/components/header.tsx` | Forge identity and theme control |
148 | `src/components/footer.tsx` | Shared footer |
149 | `src/index.css`, `src/base.css` | Custom visual language and layout |
150
151 Keep the custom assets and visual language in this package. New forge screens
152 should reuse the existing CSS variables, typography, textures, and components
153 instead of introducing a generic design system.
154
155 ## Build and local run
156
157 Build the server and deployable bundle from the repository root:
24 158
25 ```bash 159 ```bash
26 bazel build //hg-web:hg_web 160 bazel build //hg-web:hg_web_server
27 ``` 161 bazel build //hg-web:hg_web_server_bundle
28 162 ```
29 ## API Endpoints 163
30 164 Run the Mercurial backend:
31 The C server (`main.c`) provides: 165
32 166 ```bash
33 - `GET /api/repo/list?path=` - List directory contents 167 hg serve -a 127.0.0.1 -p 4444
34 - `GET /api/repo/file?path=` - Fetch file contents 168 ```
169
170 Run the deployable bundle from its own directory so the static root resolves:
171
172 ```bash
173 cd bazel-bin/hg-web/hg_web_server_bundle
174 ./hg_web_server
175 ```
176
177 The bundle contains `hg_web_server` and `hg-web/src/`, including generated
178 `page.js`, markdown WASM, highlight.js, styles, and image assets.
179
180 ## Deployment contract
181
182 The expected production layout is:
183
184 ```text
185 nginx
186 -> hg_web_server.service
187 -> /opt/hg_web_server_bundle_active/hg_web_server
188 -> working directory: /opt/hg_web_server_bundle_active
189 -> hg serve service on 127.0.0.1:4444
190 ```
191
192 `deploy.sh` currently builds an optimized bundle, copies it to `/opt`, swaps
193 the active directory, changes ownership to `hg_web_server:zenbu_team`, and
194 restarts `hg_web_server.service`.
195
196 ## Forge capability tree
197
198 ```text
199 Zenbu Forge
200 ├── Repository
201 │ ├── File and directory browsing available
202 │ ├── Syntax highlighting available
203 │ ├── README rendering available
204 │ ├── Commit graph available
205 │ ├── Changeset detail and diff planned
206 │ ├── Branches, bookmarks, and tags planned
207 │ ├── File history and blame planned
208 │ └── Search planned
209 ├── Collaboration
210 │ ├── Authentication and authorization planned
211 │ ├── Changeset review planned
212 │ ├── Issues planned
213 │ └── Releases and artifacts planned
214 └── Automation
215 ├── Mercurial incoming/changegroup hook planned
216 ├── Durable SQLite job queue planned
217 ├── Isolated Bazel runner planned
218 ├── Live logs and job status API planned
219 ├── Forge status and log screens planned
220 ├── Artifact retention planned
221 └── Atomic deploy, health check, rollback planned
222 ```
223
224 ## Automation data flow
225
226 The Actions-like subsystem should extend the existing server rather than
227 replace it:
228
229 ```text
230 hg push
231 -> Mercurial hook records repository + revision
232 -> small enqueue command writes a SQLite job
233 -> runner service claims one queued job
234 -> isolated shared checkout updates to the exact revision
235 -> Bazel build and test steps stream logs
236 -> job result and artifacts are recorded
237 -> hg-web status API exposes the result
238 -> custom React screens render runs, steps, logs, and artifacts
239 -> successful protected jobs may call atomic deployment
240 ```
241
242 Start with one runner on the same host. Keep the hook fast, never execute build
243 steps inside the Mercurial request, and make the queue durable before adding
244 parallel or remote runners.
245
246 ## Safe extension order
247
248 1. Harden proxy errors, path validation, response headers, and timeouts.
249 2. Add changeset detail and diff APIs, then wire graph clicks to those screens.
250 3. Make deployment atomic with health checks and rollback.
251 4. Add the hook, SQLite queue, single runner, and retained logs.
252 5. Add run/status/log pages using the existing custom UI.
253 6. Add authentication and authorization before accepting public pushes or
254 user-defined automation.
255
256 ## Invariants
257
258 - Keep public application code on Seobeo APIs.
259 - Decode and validate every path before forwarding it to Mercurial.
260 - Keep `/repo` binary-safe; bundle data can contain null bytes.
261 - Do not buffer large wire-protocol responses through the regular HTTP client.
262 - Keep backend route names synchronized with frontend fetch and navigation code.
263 - Preserve accurate status codes, content lengths, and content types.
264 - Keep secrets in service-owned environment files, not in source or job logs.