Mercurial
view .claude/skills/zenbu-personal-site/SKILL.md @ 271:13d61401c57d
redirect Copilot cache to service state
Set XDG_CACHE_HOME from the configured inference state so the systemd service can extract Copilot outside its protected home directory.
Co-authored-by: Copilot <[email protected]>
| author | MrJuneJune <me@mrjunejune.com> |
|---|---|
| date | Fri, 07 Aug 2026 13:24:05 -0700 |
| parents | 056790c4fb0d |
| children |
line wrap: on
line source
--- name: zenbu-personal-site description: Use this skill when updating the mrjunejune personal website, blog, resume, tools, notes/editor APIs, uploads, PWA assets, or deployment bundle. --- # Mrjunejune Personal Site Use this skill for `mrjunejune/`, the personal website served by a C backend. ## Structure - `mrjunejune/main.c`: C web server, routes, APIs, S3 upload URL generation, editor persistence, media conversion, WebSocket chat. - `mrjunejune/src/`: static site source files and HTML templates. - `mrjunejune/src/parts/`: shared HTML includes used by `{{...}}` template placeholders. - `mrjunejune/src/public/`: public assets, PWA files, media, generated JS, icons, resume PDF. - Zenbu UI assets are copied from `//design_system:components` and `//design_system:styles` into `src/public/design-system/` by Bazel. Do not hand-copy or fork shared component files. - Preserve the site's established transparent content and plain header/icon presentation. Use `appearance="plain"` when shared behavior is useful, and do not introduce cards, shadows, borders, or surfaces without a concrete UX reason. - Every site-owned `zen-button` declares an `xs` / `sm` / `md` / `lg` / `xl` size. Site CSS must consume inherited `--zenbu-control-*` aliases plus `--zenbu-sys-padding-*` and typography roles instead of hardcoding control padding or height. - New site CSS uses `--zenbu-sys-*` semantic roles. Do not consume `--zenbu-ref-color-*` or add new `--zen-*` compatibility-token usage. - `mrjunejune/test/`: integration tests and snapshots. - `mrjunejune/BUILD`: Bazel build, bundle, asset movement, and test-visible filegroups. - `mrjunejune/.config` is the single ignored runtime configuration source for the server, auth, S3, inference, LiteLLM, and Copilot token paths. `.config.development` is the committed copyable template. Do not use `.env` files or require shell exports for normal build/run/deploy workflows. - The JRPG chat is a production route. Seobeo owns conversation CRUD and POST SSE, Deita stores turns, and a Bazel-managed Python Copilot SDK sidecar uses a loopback LiteLLM `github_copilot` provider. Never use a virtualenv or pip install workflow. ## How rendering works Handlers allocate a response body from `Dowa_Arena`, render an HTML file with `Seobeo_Render_Html_FilePath`, and return a response map: ```c Seobeo_Request_Entry *resp = NULL; char *final_body = Dowa_Arena_Allocate(arena, 50 * 1024); Seobeo_Render_Html_FilePath(final_body, "/tools/index.html", arena); Dowa_HashMap_Push_Arena(resp, "body", final_body, arena); return resp; ``` The simple template renderer replaces `{{...}}` tokens with file contents loaded through `Seobeo_Web_LoadFile`. Before adding or changing HTML controls, read `design_system/wiki/HTML_AUTHORING.md` and `PRIMITIVE_MAP.md`. Every authored interactive control must have exactly one appropriate Zenbu owner while retaining its native element underneath. ## Routes and features Existing route areas include: - Home, resume, tools, markdown-to-HTML, file converter, blog, talk/chat, notes, and editor pages. - Redirect helpers built with `CREATE_REDIRECT_HANDLER`. - File/media conversion APIs using `ffmpeg` and temporary files under `/tmp`. - S3 presigned upload URL API using `Authorization: Bearer <token>`. - Editor save/load APIs backed by `deita` SQLite. - WebSocket chat broadcasting through seobeo WebSocket server APIs. When adding pages, add the HTML/CSS/JS under `src/`, register a route in `main.c`, and update tests/snapshots if the route should be covered. ## Build and test ```bash bazel build //mrjunejune:mrjunejune_server bazel build //mrjunejune:mrjunejune_server_bundle bazel test //mrjunejune/test:integration_test bazel test //mrjunejune/test:theme_and_webp_test ``` The JRPG browser acceptance is sharded by concern: - `//mrjunejune/test:jrpg_core_test` - `//mrjunejune/test:jrpg_jrpg_test` - `//mrjunejune/test:jrpg_routing_test` - `//mrjunejune/test:jrpg_hls_test` `//mrjunejune/test:theme_and_webp_test` is the aggregate `test_suite`; Bazel runs its shards in parallel. Keep future slow browser scenarios in the narrowest independent shard, or create another shard rather than extending one serial test process. Give every shard its own port, temporary database, and fixture state. Authenticate Copilot once, using the token directory from `.config`: ```bash bazel run //mrjunejune:run_inference_stack -- --authenticate ``` Then run live inference with no shell configuration: ```bash bazel run //mrjunejune:run_inference_stack ``` Use `bazel run //mrjunejune:run_inference_stack -- --mock` for deterministic UI development through the real Seobeo, Deita, inference bridge, and SSE path without Copilot authentication or a LiteLLM key. Mock stream scenarios are maintained as `!command` event scripts in `mrjunejune/inference/mock_responses.json`; custom event types pass through Seobeo to the page's `mjj-jrpg-stream-event`. ## Production-minded checklist - Use Dowa's fixed-width aliases and `boolean`/`TRUE`/`FALSE` in first-party C instead of introducing `<stdint.h>` `_t` types or `<stdbool.h>` `bool`. - Keep auth-protected APIs strict: missing auth should be `401`, invalid token `403`, malformed JSON/input `400`, unavailable DB/S3/ffmpeg `500`. - Never hardcode secrets. Normal runtime configuration and secrets come from the single ignored `.config`. - Normal runtime settings belong in the single ignored `.config`. Environment variables may be used internally between supervised subprocesses or as backwards-compatible test/deployment overrides, but must not be required user setup and must not replace `.config` with a `.env` file. - For uploads and downloads, validate filenames and content lengths before touching `/tmp`. - For binary responses, set `content-length` and avoid string-only operations on body bytes. - If a route is part of the public website, add or update snapshot coverage in `mrjunejune/test`. - Keep PWA changes consistent across `manifest.json`, `sw.js`, icons, and `PWA_SETUP.md`. - Site themes use `data-zen-theme` with Auto, Paper, Ink, Playful, and Cyberpunk states. Preserve the More Sugar font aliases and keep theme-specific values in shared design-system tokens rather than branching inside components. - Reuse `seobeo`, `dowa`, `deita`, `s3`, and `markdown_converter` instead of adding parallel implementations.