# HG changeset patch # User MrJuneJune # Date 1785684868 25200 # Node ID 921ca30868796c5dcacd4609166789309b68079e # Parent fb28063dc4908fb76f1436dfb1dd71b34e4bc501 [hg-web] Add architecture wiki tree diff -r fb28063dc490 -r 921ca3086879 hg-web/README.md --- 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/?style=json + +file or README selection + -> GET /api/repo/file?path=... + -> ApiGetFile + -> GET hg-serve/raw-file/tip/ + -> 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/?graphtop=...&style=json + -> ApiGetGraph + -> GET hg-serve/graph/?... + -> 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.