view .claude/skills/zenbu-personal-site/SKILL.md @ 265:056790c4fb0d

add role-aware Epi assistant prompts Add verified June knowledge, guest/member/admin Copilot profiles, profile-isolated session recovery, animated Epi greetings, and a single authoritative runtime config workflow for inference. Co-authored-by: Copilot <[email protected]>
author MrJuneJune <me@mrjunejune.com>
date Fri, 07 Aug 2026 10:50:30 -0700
parents 04fee26ecce0
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.