diff 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
line wrap: on
line diff
--- a/hg-web/README.md	Sun Jan 25 20:19:42 2026 -0800
+++ b/hg-web/README.md	Sun Aug 02 08:34:28 2026 -0700
@@ -1,34 +1,264 @@
 # hg-web
 
-A web-based Mercurial repository browser. Provides a GitHub-style interface for browsing files, viewing code with syntax highlighting, and reading markdown documentation.
+A custom Mercurial forge and repository browser. The application keeps the
+networking and HTTP stack in C with Seobeo, while the hand-drawn web interface
+is implemented in React and TypeScript.
+
+## Wiki tree
 
-## Features
+```text
+hg-web
+├── Runtime
+│   ├── hg_web_server :6970
+│   │   ├── React application and static assets
+│   │   ├── repository browsing API
+│   │   ├── commit graph API
+│   │   └── Mercurial wire-protocol proxy
+│   └── hg serve :4444
+│       ├── repository files and graph data
+│       └── Mercurial pull/push protocol
+├── Backend
+│   ├── main.c
+│   └── ../seobeo
+│       ├── s_network.c
+│       ├── s_web.c
+│       ├── s_http_client.c
+│       └── s_ssl.c
+├── Frontend
+│   └── src
+│       ├── main.tsx
+│       ├── components
+│       │   ├── app.tsx
+│       │   ├── directory-browser.tsx
+│       │   ├── graph.tsx
+│       │   ├── header.tsx
+│       │   ├── footer.tsx
+│       │   ├── theme.tsx
+│       │   └── repo-browser.tsx
+│       ├── index.html
+│       ├── index.css
+│       ├── base.css
+│       └── custom pencil, panda, icon, and background assets
+├── Build
+│   ├── BUILD
+│   ├── ../gui_ze/gui_ze.bzl
+│   ├── ../markdown_converter
+│   └── ../third_party/highlight
+└── Operations
+    └── deploy.sh
+```
+
+`repo-browser.tsx` is an older standalone browser implementation. The active
+entry point is `main.tsx`, which renders `app.tsx`; `app.tsx` embeds
+`directory-browser.tsx`.
+
+## Runtime topology
 
-- Browse repository files and directories
-- View code files with syntax highlighting (highlight.js)
-- Render markdown files with WASM-based converter
-- Dark/light theme support with system preference detection
-- Prefetch on hover for faster navigation
+```text
+Browser
+  |
+  | HTTPS
+  v
+nginx
+  |
+  | HTTP :6970
+  v
+hg_web_server (main.c + Seobeo)
+  |
+  | HTTP :4444
+  v
+hg serve (Zenbu Mercurial repository)
+```
+
+The C server owns the public routes. It serves the application shell and
+assets, translates browser API requests into `hg serve` requests, and streams
+Mercurial wire-protocol traffic without routing bundle data through the normal
+buffered HTTP response path.
+
+## Request flows
+
+### Application shell
+
+```text
+GET /, /directories, or /graph
+  -> GetReactHome
+  -> hg-web/src/index.html
+  -> /page.js
+  -> src/main.tsx
+  -> components/app.tsx
+```
 
-## Structure
+### Repository browser
 
+```text
+directory-browser.tsx
+  -> GET /api/repo/list?path=...
+  -> ApiListDirectory
+  -> GET hg-serve/file/tip/<path>?style=json
+
+file or README selection
+  -> GET /api/repo/file?path=...
+  -> ApiGetFile
+  -> GET hg-serve/raw-file/tip/<path>
+  -> highlight.js or markdown_converter WASM
 ```
-hg-web/
-├── BUILD           # Bazel build configuration
-├── deploy.sh       # Deployment script
-├── main.c          # C server handling API routes
-└── src/            # Frontend source files
+
+### Commit graph
+
+```text
+graph.tsx
+  -> GET /api/graph/<revision>?graphtop=...&style=json
+  -> ApiGetGraph
+  -> GET hg-serve/graph/<revision>?...
+  -> React rows + custom pencil/panda canvas
+```
+
+### Mercurial clone, pull, and push
+
+```text
+Mercurial client
+  -> GET or POST /repo
+  -> StreamHgWireProtocol
+  -> hg serve /?cmd=...
+  -> binary-safe streamed response
 ```
 
-## Building
+## Route map
+
+| Method | Route | Owner | Purpose |
+| --- | --- | --- | --- |
+| `GET` | `/` | `GetReactHome` | Application shell |
+| `GET` | `/directories` | `GetReactHome` | Legacy application-shell route |
+| `GET` | `/graph` | `GetReactHome` | Commit graph application route |
+| `GET` | `/api/repo/list` | `ApiListDirectory` | Directory listing JSON |
+| `GET` | `/api/repo/file` | `ApiGetFile` | Raw tracked file |
+| `GET` | `/api/repo/readme` | `ApiGetReadme` | Alias of the raw-file handler |
+| `GET` | `/api/graph/:graph_id` | `ApiGetGraph` | Mercurial graph JSON |
+| `GET`, `POST` | `/repo` | `StreamHgWireProtocol` | Mercurial wire protocol |
+
+## Frontend ownership
+
+| File | Responsibility |
+| --- | --- |
+| `src/components/app.tsx` | Client-side routes, landing page, tabs, and history |
+| `src/components/directory-browser.tsx` | Breadcrumbs, listings, prefetch, file modals, README rendering |
+| `src/components/graph.tsx` | Graph fetching, pagination, canvas edges, panda nodes |
+| `src/components/theme.tsx` | Stored light/dark preference and system-theme integration |
+| `src/components/header.tsx` | Forge identity and theme control |
+| `src/components/footer.tsx` | Shared footer |
+| `src/index.css`, `src/base.css` | Custom visual language and layout |
+
+Keep the custom assets and visual language in this package. New forge screens
+should reuse the existing CSS variables, typography, textures, and components
+instead of introducing a generic design system.
+
+## Build and local run
+
+Build the server and deployable bundle from the repository root:
 
 ```bash
-bazel build //hg-web:hg_web
+bazel build //hg-web:hg_web_server
+bazel build //hg-web:hg_web_server_bundle
+```
+
+Run the Mercurial backend:
+
+```bash
+hg serve -a 127.0.0.1 -p 4444
+```
+
+Run the deployable bundle from its own directory so the static root resolves:
+
+```bash
+cd bazel-bin/hg-web/hg_web_server_bundle
+./hg_web_server
+```
+
+The bundle contains `hg_web_server` and `hg-web/src/`, including generated
+`page.js`, markdown WASM, highlight.js, styles, and image assets.
+
+## Deployment contract
+
+The expected production layout is:
+
+```text
+nginx
+  -> hg_web_server.service
+     -> /opt/hg_web_server_bundle_active/hg_web_server
+     -> working directory: /opt/hg_web_server_bundle_active
+  -> hg serve service on 127.0.0.1:4444
 ```
 
-## API Endpoints
+`deploy.sh` currently builds an optimized bundle, copies it to `/opt`, swaps
+the active directory, changes ownership to `hg_web_server:zenbu_team`, and
+restarts `hg_web_server.service`.
+
+## Forge capability tree
+
+```text
+Zenbu Forge
+├── Repository
+│   ├── File and directory browsing            available
+│   ├── Syntax highlighting                    available
+│   ├── README rendering                       available
+│   ├── Commit graph                           available
+│   ├── Changeset detail and diff              planned
+│   ├── Branches, bookmarks, and tags          planned
+│   ├── File history and blame                 planned
+│   └── Search                                 planned
+├── Collaboration
+│   ├── Authentication and authorization       planned
+│   ├── Changeset review                       planned
+│   ├── Issues                                 planned
+│   └── Releases and artifacts                 planned
+└── Automation
+    ├── Mercurial incoming/changegroup hook    planned
+    ├── Durable SQLite job queue               planned
+    ├── Isolated Bazel runner                  planned
+    ├── Live logs and job status API           planned
+    ├── Forge status and log screens           planned
+    ├── Artifact retention                     planned
+    └── Atomic deploy, health check, rollback  planned
+```
+
+## Automation data flow
+
+The Actions-like subsystem should extend the existing server rather than
+replace it:
 
-The C server (`main.c`) provides:
+```text
+hg push
+  -> Mercurial hook records repository + revision
+  -> small enqueue command writes a SQLite job
+  -> runner service claims one queued job
+  -> isolated shared checkout updates to the exact revision
+  -> Bazel build and test steps stream logs
+  -> job result and artifacts are recorded
+  -> hg-web status API exposes the result
+  -> custom React screens render runs, steps, logs, and artifacts
+  -> successful protected jobs may call atomic deployment
+```
+
+Start with one runner on the same host. Keep the hook fast, never execute build
+steps inside the Mercurial request, and make the queue durable before adding
+parallel or remote runners.
 
-- `GET /api/repo/list?path=` - List directory contents
-- `GET /api/repo/file?path=` - Fetch file contents
+## Safe extension order
+
+1. Harden proxy errors, path validation, response headers, and timeouts.
+2. Add changeset detail and diff APIs, then wire graph clicks to those screens.
+3. Make deployment atomic with health checks and rollback.
+4. Add the hook, SQLite queue, single runner, and retained logs.
+5. Add run/status/log pages using the existing custom UI.
+6. Add authentication and authorization before accepting public pushes or
+   user-defined automation.
+
+## Invariants
+
+- Keep public application code on Seobeo APIs.
+- Decode and validate every path before forwarding it to Mercurial.
+- Keep `/repo` binary-safe; bundle data can contain null bytes.
+- Do not buffer large wire-protocol responses through the regular HTTP client.
+- Keep backend route names synchronized with frontend fetch and navigation code.
+- Preserve accurate status codes, content lengths, and content types.
+- Keep secrets in service-owned environment files, not in source or job logs.