auv-design
Use this skill to generate well-branded interfaces and assets for AUV (the Moeru AI command-replay / inspect runtime), either for production or throwaway prototypes/mocks. Contains essential design guidelines, colors, type, fonts, assets, and UI kit components for prototyping.
Install
npx skills add https://github.com/moeru-ai/auv/tree/main/docs/design
claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install moeru-ai-auv@llmmart
git clone https://github.com/moeru-ai/auv.git
The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole moeru-ai/auv collection as a plugin from our marketplace. Git is the plain clone.
README
auv Design System (vendored)
This directory is a vendored copy of the AUV Design System bundle that was handed off from Claude Design (claude.ai/design) on 2026-05-21.
The original handoff bundle's own README files are preserved verbatim:
HANDOFF_README.md— Claude Design's per-handoff instructions to coding agents.SOURCE_README.md— the design system's own README (product context, voice, visual foundations).SKILL.md— agent-skill metadata.
For agents picking up the already-landed viewer implementation or remaining follow-on design work, read:
IMPLEMENTATION_HANDOFF.md— cold- start spec: what shipped, what's left, exact visual + data contracts for each remaining phase. Designed so an agent with no prior session context can implement a phase end-to-end.
Why vendor it?
The Rust runtime today consumes exactly one part of the design
system at compile time — the cursor sprite + brand pill in
crates/auv-driver-overlay-macos/native/swift/Sources/AuvMacosOverlayNative/Overlay.swift,
which ports rect data verbatim from assets/cursor-auv.svg.
The rest of the bundle is reference material for surfaces that do not
exist in the repo yet (the browser-based inspect viewer, an HTML CLI
mock, the broader component library). Keeping the canonical assets +
tokens in docs/design/ means future implementations can match
pixel-perfectly against the same source the Overlay.swift sprite came
from, without re-fetching the original bundle.
Layout
| Path | Purpose |
|---|---|
assets/ |
Logo marks, cursor sprites, accents, sprite icons. All SVG (pixel-art, viewBox="0 0 24 24", shape-rendering="crispEdges"). |
colors_and_type.css |
Single source of truth for design tokens — colors, type stack, spacing, radii, shadows, motion. |
preview/ |
One-card-per-concept HTML previews (color cards, type cards, component cards). |
ui_kits/cli/ |
High-fidelity HTML recreation of auv-cli terminal output. Not yet wired into the Rust CLI. |
ui_kits/viewer/ |
Speculative recreation of the still-unbuilt browser viewer described in docs/ai/references/inspect/2026-05-19-trace-run-inspect-design.md. |
What's implemented from this bundle
| Bundle element | Repo location | Status |
|---|---|---|
assets/cursor-auv.svg rect data |
crates/auv-driver-overlay-macos/.../Overlay.swift (auvSprite) |
done (Phase A) |
assets/cursor-you.svg rect data |
crates/auv-driver-overlay-macos/.../Overlay.swift (youSprite) |
ported (used by viewer mocks, not by the live overlay yet) |
Brand cyan pill (#009ba6) |
crates/auv-driver-overlay-macos/.../Overlay.swift |
done (Phase A) |
assets/logo-mark.svg (top-bar pixel logo) |
crates/auv-inspect-server/viewer/src/App.vue |
done (Phase C.1; served from Vite build) |
colors_and_type.css core tokens (shell, brand, status) |
crates/auv-inspect-server/viewer/src/styles/viewer.css |
done (Phase C.1; served from Vite build) |
ui_kits/viewer/Sidebar.jsx (run list) |
crates/auv-inspect-server/viewer/src/App.vue + src/viewer.ts |
done (Phase C.1; served from Vite build) |
ui_kits/viewer/SpanTree.jsx |
crates/auv-inspect-server/viewer/src/App.vue + src/viewer.ts |
done (Phase C.2; served from Vite build) |
ui_kits/viewer/EventsRail.jsx |
crates/auv-inspect-server/viewer/src/App.vue + src/viewer.ts |
done (Phase C.3a; served from Vite build) |
ui_kits/viewer/ArtifactPanel.jsx |
crates/auv-inspect-server/viewer/src/App.vue + src/viewer.ts |
done (Phase C.3b; served from Vite build) |
WebSocket live streaming on /runs/:id/stream |
crates/auv-inspect-server/viewer/src/viewer.ts + crates/auv-inspect-server/src/server.rs |
done (Phase C.4; served from Vite build) |
Extract assets to /assets/:name route |
crates/auv-inspect-server/src/server.rs |
done (Phase C.5, landed early) |
assets/cursor-auv-click.svg (4-ray burst) |
— | pending (future Overlay click-state) |
ui_kits/cli/* |
— | reference only; the Rust CLI ships plain text today |
Editing this directory
This is a vendored bundle. If the design system updates upstream, replace
the contents wholesale rather than hand-editing files here. The original
bundle ID was Cnhoa_hmraSs_HJx96DFxw; re-fetch from
https://api.anthropic.com/v1/design/h/<id> to obtain a fresh tarball.
The one file in this directory that is not part of the upstream
bundle is this README.md — it records the vendoring decision and the
implementation status. Keep it in sync with what the repo actually
consumes from the bundle.
Skill manifest
AUV Design
Read README.md in this skill first — it establishes product context, content
fundamentals (the deliberately anti-marketing AUV voice), visual foundations,
and iconography rules.
Then explore the other files:
colors_and_type.css— all design tokens (--auv-*).assets/— logo mark + wordmark.preview/— small reference cards for each system concept.ui_kits/cli/—auv-cliterminal output recreation.ui_kits/viewer/— speculative inspect-viewer mock (the browser viewer described in2026-05-19-trace-run-inspect-design.md; not built yet in the source repo).
Operating principles for this brand
- Honesty over polish. AUV documents what is
validated,candidate, andnot-validatedin JSON. Reflect that in every artifact. Never invent a status not on the canonical list. - Monospace carries identity. IDs, paths, span names, and JSON keys
live in
JetBrains Mono. Body prose lives inGeist. - No emoji. No gradients. No glassy overlays. This is forensic-grade UI.
- Status pill is the smallest unit. Use
.auv-status--{validated, candidate, boundary, frozen, running, failed}everywhere a status is shown — sidebars, lists, headers, terminal output, marketing.
When the user invokes this skill
If creating visual artifacts (slides, mocks, throwaway prototypes), copy
assets out of this skill and produce static HTML the user can view. Reuse the
<Terminal> / <SpanTree> / <Sidebar> components from the UI kits when the
output is product-facing.
If working on production code (Rust CLI, future browser viewer, future docs
site), copy colors_and_type.css and assets/logo-*.svg into the project,
and follow the rules in README.md (sections Content Fundamentals and
Visual Foundations) to extend the system.
If invoked without other guidance, ask the user what they want to build — typical asks are:
- a mock of
auv-clioutput for a docs page or social post - a wireframe / mock of the inspect viewer
- a slide deck explaining a phase-1 boundary
- copy in the AUV voice (status report, freeze note, boundary callout)
Then act as an expert designer on the AUV brand and output HTML artifacts or production code, depending on the need.
Files (auv)
-
assets
-
accent-bandage.svg 1.2 KB · in bundle
-
accent-hairclip.svg 751 B · in bundle
-
accent-heart.svg 630 B · in bundle
-
accent-star.svg 758 B · in bundle
-
cursor-auv-click.svg 2.3 KB · in bundle
-
cursor-auv.svg 1.8 KB · in bundle
-
cursor-you.svg 1.7 KB · in bundle
-
icon-bin.svg 827 B · in bundle
-
icon-json.svg 1.3 KB · in bundle
-
icon-png.svg 802 B · in bundle
-
logo-mark.svg 2.1 KB · in bundle
-
logo-wordmark.svg 4 KB · in bundle
-
moeru-ai-logo.png 6.5 KB · in bundle
-
moeru-ai-logo.svg 151.4 KB · in bundle
-
sparkle.svg 945 B · in bundle
-
sprite-check.svg 633 B · in bundle
-
sprite-hourglass.svg 826 B · in bundle
-
sprite-inspector.svg 6.6 KB · in bundle
-
sprite-moe.svg 1.2 KB · in bundle
-
sprite-prompt.svg 642 B · in bundle
-
sprite-x.svg 827 B · in bundle
-
-
preview
-
brand-cli-welcome.html 1.6 KB · in bundle
-
brand-hero.html 3.4 KB · in bundle
-
brand-logo.html 974 B · in bundle
-
brand-moeru.html 2.8 KB · in bundle
-
brand-pixel-motifs.html 4.6 KB · in bundle
-
brand-replay-cursor.html 6.1 KB · in bundle
-
brand-terminal.html 1.4 KB · in bundle
-
card.css 3.5 KB · in bundle
-
color-brand.html 2.9 KB · in bundle
-
color-disturbance.html 2.2 KB · in bundle
-
color-neutrals-paper.html 1.7 KB · in bundle
-
color-neutrals-shell.html 2.1 KB · in bundle
-
color-status.html 2.5 KB · in bundle
-
component-buttons.html 2.4 KB · in bundle
-
component-callouts.html 1.5 KB · in bundle
-
component-cursors.html 3.1 KB · in bundle
-
component-disturbance.html 1.7 KB · in bundle
-
component-manifest.html 1.4 KB · in bundle
-
component-pills-pixel.html 2.1 KB · in bundle
-
component-pills.html 1.3 KB · in bundle
-
component-recipe-card.html 1.4 KB · in bundle
-
component-run-list.html 2.9 KB · in bundle
-
component-span-tree.html 1.9 KB · in bundle
-
component-statusbar.html 1.8 KB · in bundle
-
spacing-radii.html 1.6 KB · in bundle
-
spacing-scale.html 3.6 KB · in bundle
-
spacing-shadows.html 1.7 KB · in bundle
-
type-families.html 1.9 KB · in bundle
-
type-mono.html 866 B · in bundle
-
type-pixel.html 1.5 KB · in bundle
-
type-scale.html 2.7 KB · in bundle
-
-
ui_kits
-
cli
-
index-print.html 4.9 KB · in bundle
-
index.html 2.7 KB · in bundle
-
Prompt.jsx 3.1 KB · in bundle
-
README.md 1.5 KB
# `auv-cli` — UI Kit High-fidelity recreation of `auv-cli` terminal output. The CLI is the primary product surface today; this kit reproduces its layout, syntax coloring, and status vocabulary so designers can place real-looking CLI blocks in mocks, docs, and marketing surfaces. **Source of truth:** `src/cli.rs` / `src/main.rs` / `recipes/macos/qqmusic/README.md` in [`moeru-ai/auv`](https://github.com/moeru-ai/auv). ## What's in here - `index.html` — a click-through demo of three sessions: listing skill cases, running a skill dry-run, and inspecting a finished run. Toggle the macOS traffic-light tabs. - `Terminal.jsx` — terminal window chrome + scrollback primitive. - `Prompt.jsx` — `$ cargo run --quiet -- …` line, plus inline output rows. - `Output.jsx` — colored output rows (paths, ids, status sigils). - `tokens.js` — shared color tokens lifted from `colors_and_type.css`. ## What's faithful - Command invocations come from `help_text()` in `src/cli.rs` and from the documented examples in `recipes/macos/qqmusic/README.md`. - Recipe/bundle/case IDs are the actual phase-1 IDs. - Status sigils (`● validated`, `◐ candidate`) and disturbance ladder are the real vocabulary in `src/model.rs`. ## What's approximated - Exact column widths in real terminal output may differ; I'm matching the *layout* (`key: value` indent two spaces) but not byte-for-byte spacing. - macOS Terminal.app traffic-light proportions are simplified — this is not a Tahoe-grade window mock. -
Sessions.jsx 6.5 KB · in bundle
-
Terminal.jsx 3.4 KB · in bundle
-
tokens.js 867 B
// tokens.js — shared design tokens for the CLI UI kit // Mirrors a subset of ../../colors_and_type.css window.AUV_TOKENS = { boundary: '#a73b41', boundarySoft: '#d68f93', brand: '#00c4d2', brandSoft: '#8de1e8', candidate: '#b46a14', candidateSoft: '#e2b86f', failed: '#d05a4c', fg: '#e7e5dd', fg2: '#b8b6ad', fg3: '#7a7972', fg4: '#4f4e49', fontMono: '"JetBrains Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace', fontSans: '"Geist", ui-sans-serif, system-ui, sans-serif', frozen: '#7c8694', jsonComment: '#7a7972', // syntax-ish jsonKey: '#8de1e8', // brand-soft (tinted blue) jsonNum: '#e2b86f', // amber jsonStr: '#a8d3b0', // validated-soft greenish running: '#3aa9b8', shell: '#0e1013', shell2: '#16181d', shell3: '#1e2127', shellLine: '#2a2e36', validated: '#2f7d4f', validatedSoft: '#7fb88e', }
-
-
viewer
-
ArtifactPanel.jsx 6.4 KB · in bundle
-
data.js 5.5 KB
// data.js — mock data lifted verbatim from the AUV v1alpha1 spec shape. // Used by every viewer component. window.AUV_RUNS = [ { artifacts: 3, duration: '4.71s (live)', recipe_id: 'macos.qqmusic.play_visible_anchor.v0', run_id: 'run_1778947574511_68037_4', run_type: 'execute', spans: 6, started_at: '2026-05-20T14:32:54.511Z', state: 'running', status_code: 'unset', summary: 'macos.qqmusic.play_visible_anchor.v0 · query=aa anchor="Cure For Me"', trace_id: '4b9e2c7f1a3d6e0b8f5a1c2d3e4f5061', }, { artifacts: 6, duration: '2m 18s', recipe_id: 'macos.notes.create_and_verify_note.v0', run_id: 'run_1778946131088_67910_2', run_type: 'validate', spans: 12, started_at: '2026-05-20T14:08:51.088Z', state: 'ended', status_code: 'ok', summary: 'macos.notes.create_and_verify_note.v0 · case=notes-marker-baseline', trace_id: 'f31c08ad2e8a4b117f5b1c2d3e4f5072', }, { artifacts: 4, duration: '3.50s', recipe_id: 'macos.qqmusic.play_visible_anchor.v0', run_id: 'run_1778945002311_67885_1', run_type: 'execute', spans: 5, started_at: '2026-05-20T13:50:02.311Z', state: 'ended', status_code: 'error', summary: 'resolve-ocr-anchor returned 0 matches for 晴天', trace_id: 'b22f9c0c1e3d4a607f5b1c2d3e4f5071', }, { artifacts: 9, duration: '8.04s', recipe_id: null, run_id: 'run_1778944887210_67830_0', run_type: 'probe', spans: 11, started_at: '2026-05-20T13:48:07.210Z', state: 'ended', status_code: 'ok', summary: 'com.tencent.QQMusicMac · permissions, window-state, ax-tree', trace_id: '1e8a7c45f2b9405a8f6b1c2d3e4f5099', }, { artifacts: 4, duration: '1m 02s', recipe_id: 'macos.textedit.create_and_verify_text.v0', run_id: 'run_1778942100001_67801_0', run_type: 'validate', spans: 9, started_at: '2026-05-20T13:01:40.001Z', state: 'ended', status_code: 'ok', summary: 'macos.textedit.create_and_verify_text.v0 · textedit-marker-baseline', trace_id: '9c3e0a76f2b94055eef6b1c2d3e4f50a8', }, ] // Span tree for the active live run (#1). Order in render = depth-first. window.AUV_SPANS = [ { attrs: { recipe_id: 'macos.qqmusic.play_visible_anchor.v0', target: 'com.tencent.QQMusicMac' }, id: 's00', name: 'auv.execute', parent: null, status: 'running', t: '4.71s' }, { attrs: { step_id: 'open-search' }, id: 's01', name: 'auv.recipe.step', parent: 's00', status: 'ok', t: '0.32s' }, { attrs: { command_id: 'debug.pressKey', key: 'cmd+f' }, id: 's02', name: 'auv.command.invoke', parent: 's01', status: 'ok', t: '0.30s' }, { attrs: { step_id: 'paste-query' }, id: 's03', name: 'auv.recipe.step', parent: 's00', status: 'ok', t: '0.94s' }, { attrs: { command_id: 'debug.pasteTextPreserveClipboard', text: 'aa' }, id: 's04', name: 'auv.command.invoke', parent: 's03', status: 'ok', t: '0.92s' }, { attrs: { step_id: 'dismiss-search-overlay' }, id: 's05', name: 'auv.recipe.step', parent: 's00', status: 'ok', t: '0.28s' }, { attrs: { step_id: 'wait-for-ocr-anchor' }, id: 's06', name: 'auv.recipe.step', parent: 's00', status: 'ok', t: '1.10s' }, { attrs: { anchor_text: 'Cure For Me', step_id: 'resolve-ocr-anchor' }, id: 's07', name: 'auv.recipe.step', parent: 's00', status: 'ok', t: '0.42s' }, { attrs: { step_id: 'double-click-row-anchor' }, id: 's08', name: 'auv.recipe.step', parent: 's00', status: 'running', t: '1.65s' }, { attrs: { click_count: 2, command_id: 'debug.clickScreenText' }, id: 's09', name: 'auv.command.invoke', parent: 's08', status: 'running', t: '1.62s' }, { attrs: { step_id: 'capture-evidence' }, id: 's10', name: 'auv.recipe.step', parent: 's00', status: 'unset', t: '—' }, { attrs: { step_id: 'verify-player-title' }, id: 's11', name: 'auv.recipe.step', parent: 's00', status: 'unset', t: '—' }, ] window.AUV_EVENTS = [ { body: 'run_type=execute recipe_id=macos.qqmusic.play_visible_anchor.v0', name: 'run.started', span: 's00', t: '+0.000s' }, { body: 'command_id=debug.pressKey driver=macos', name: 'command.resolved', span: 's02', t: '+0.020s' }, { body: 'macos.keyboard.pressKey key=cmd+f', name: 'driver.invoke', span: 's02', t: '+0.040s' }, { body: 'settle_ms=300', name: 'action.completed', span: 's02', t: '+0.320s' }, { body: 'command_id=debug.pasteTextPreserveClipboard', name: 'command.resolved', span: 's04', t: '+0.500s' }, { body: '// global clipboard lock acquired', name: 'clipboard.locked', span: 's04', t: '+0.510s' }, { body: 'previous clipboard contents restored', name: 'clipboard.restored', span: 's04', t: '+0.900s' }, { body: 'best_match_text="Cure For Me" confidence=0.94', name: 'ocr.match_found', span: 's07', t: '+1.520s' }, { body: 'artifact_0001_screenshot.png', name: 'artifact.captured', span: 's07', t: '+2.020s' }, { body: 'macos.pointer.clickPoint x=512.3 y=388.6 count=2', live: true, name: 'driver.invoke', span: 's09', t: '+3.060s' }, { body: 'settle_ms=900 (running)', live: true, name: 'action.started', span: 's09', t: '+4.700s' }, ] window.AUV_ARTIFACTS = [ { bytes: '2.8 MB', id: 'a01', mime: 'image/png', path: 'artifacts/artifact_0001_screenshot.png', role: 'screenshot.before', sha: 'f3c1…0a44', span: 's07' }, { bytes: '412 KB', id: 'a02', mime: 'application/json', path: 'artifacts/artifact_0002_ax.json', role: 'ax.before', sha: 'c4a0…91b2', span: 's07' }, { bytes: '3.1 MB', id: 'a03', live: true, mime: 'image/png', path: 'artifacts/artifact_0003_click_overlay.png', role: 'click.overlay', sha: '918d…44e0', span: 's09' }, ] -
EventsRail.jsx 3.1 KB · in bundle
-
index.html 3.1 KB · in bundle
-
Layout.jsx 3.8 KB · in bundle
-
README.md 2 KB
# `auv` Inspect Viewer — UI Kit A speculative recreation of the **browser-based inspect viewer** described in [`docs/ai/references/inspect/2026-05-19-trace-run-inspect-design.md`](https://github.com/moeru-ai/auv/blob/main/docs/ai/references/inspect/2026-05-19-trace-run-inspect-design.md) from `moeru-ai/auv`. **Important caveat:** This viewer does **not exist yet** in the repository. The design doc specifies the data model, the HTTP/WebSocket endpoints, and the viewer's load flow — but no UI code has been written. This kit is one opinionated rendering of that contract, useful for explorations and as a visual target for a future implementation. ## What's grounded - **Layout vocabulary** — the design doc explicitly mentions a fixed left sidebar for run-list nav, a span-tree view, an events stream, and an artifact panel. This kit places all four. - **Endpoints** shown on the connection bar are exactly the ones in `auv-cli inspect serve [--host --port]` with default `127.0.0.1:8765`. - **Run/Span/Event/Artifact** shapes are lifted from the `v1alpha1` manifest specs in the design doc. - **Status vocabulary** comes from `src/model.rs` (`RunStatus::{Completed, Failed}`) and the OpenTelemetry-compatible `status_code: unset | ok | error`. - **Live-stream pulsing dot** mirrors the WebSocket live stream described in §10 of the design doc. ## What's invented - All visual styling: layouts, padding, hover states, focus rings. - The artifact thumbnail/preview pane — the doc says artifacts have metadata and a file path, but doesn't dictate how they render. - The "filter by status" controls in the sidebar — implied, not specified. ## Files - `index.html` — a working click-through with three runs and a live-streaming span tree. - `Layout.jsx` — top status bar, sidebar, main pane, right rail scaffold. - `Sidebar.jsx` — run list. - `SpanTree.jsx` — collapsible indented span tree. - `EventsRail.jsx` — events.jsonl tail. - `ArtifactPanel.jsx` — selected artifact preview. -
Sidebar.jsx 4.9 KB · in bundle
-
SpanTree.jsx 4.6 KB · in bundle
-
-
-
colors_and_type.css 13.1 KB · in bundle
-
HANDOFF_README.md 1.5 KB
# CODING AGENTS: READ THIS FIRST This is a **handoff bundle** from Claude Design (claude.ai/design). A user mocked up designs in HTML/CSS/JS using an AI design tool, then exported this bundle so a coding agent can implement the designs for real. ## What you should do — IMPORTANT **Find the primary design file under `auv-design-system/project/` and read it top to bottom.** Then **follow its imports**: open every file it pulls in (shared components, CSS, scripts) so you understand how the pieces fit together before you start implementing. **If anything is ambiguous, ask the user to confirm before you start implementing.** It's much cheaper to clarify scope up front than to build the wrong thing. ## About the design files The design medium is **HTML/CSS/JS** — these are prototypes, not production code. Your job is to **recreate them pixel-perfectly** in whatever technology makes sense for the target codebase (React, Vue, native, whatever fits). Match the visual output; don't copy the prototype's internal structure unless it happens to fit. **Don't render these files in a browser or take screenshots unless the user asks you to.** Everything you need — dimensions, colors, layout rules — is spelled out in the source. Read the HTML and CSS directly; a screenshot won't tell you anything they don't. ## Bundle contents - `auv-design-system/README.md` — this file - `auv-design-system/project/` — the `AUV Design System` project files (HTML prototypes, assets, components) -
IMPLEMENTATION_HANDOFF.md 16.4 KB
# Implementation Handoff — AUV Design System This document is a **cold-start spec** for the remaining design-system implementation work. Any agent (Codex, Claude, human) should be able to pick up an unfinished phase below without re-reading the prior session context. ## Already shipped | Phase | Commit | What landed | |---|---|---| | **A — overlay cursor** | `7f18b27` | `NativeOverlayCursorView.draw()` renders the pixel cyan+lime AUV cursor + cyan-strong (`#009ba6`) brand pill; default label `auv · replay`. Sprite ported from `assets/cursor-auv.svg`. | | **B — vendor bundle** | `7b7061f` | Full upstream bundle vendored to `docs/design/` with `README.md` recording vendoring decisions + implementation status. | | **C.1 — viewer shell + run list** | `3ae972b` | `GET /` on `auv-inspect-server` returns a vanilla HTML+CSS+JS viewer. Pixel logo top bar, 320px sidebar fetching `/runs`, status pills, run cards. | | **C.2 — viewer span tree** | `4f0cbe0` | Run selection fetches `/runs/:id` + `/runs/:id/spans`; renders span sigils, statuses, durations, and timing bars. (Landed by Codex.) | | **C.3a — viewer events rail** | `132ef3d` | 320px events rail below the span tree, fetching `/runs/:id/events`. Span-detail panel above the rail re-renders on row click. | | **C.5 — viewer asset route (early)** | `e7726a4` | `GET /assets/:name` serves design-system SVGs from a compile-time map (path-traversal hardened, immutable cache). Inlined logo + sparkle migrated. | | **C.3b — viewer artifact panel** | `a0b924a` | 340px right rail with artifact list + mime-routed preview (text/`<pre>`, image/`<img>`, else diagonal-stripe placeholder). Uses `/assets/icon-*.svg` + `/assets/sprite-inspector.svg`. | | **C.4 — viewer WebSocket live stream** | `34eb07c` | When a `running` run is selected, the viewer opens `ws://host/runs/:id/stream` and handles `span_started` / `span_finished` / `event_appended` / `artifact_created` / `run_finished` frames; one 2 s reconnect on error, then `disconnected`. Streamed events get the `_live` tint reserved in C.3a. | ## Architecture decisions (do not relitigate) These were settled in C.1. New phases should follow: 1. **Vite/Vue shell with a DOM-oriented viewer module.** The viewer source lives in `crates/auv-inspect-server/viewer/src/App.vue`, `src/viewer.ts`, and `src/styles/viewer.css`, then ships through the checked-in Vite build under `crates/auv-inspect-server/viewer/dist/`. The upstream JSX mocks in `ui_kits/viewer/*.jsx` are **prototypes to match visually**, not code to port directly. Preserve the existing DOM IDs/classes until the DOM module is deliberately split into typed Vue components. 2. **Design tokens are inlined.** The viewer's `:root` CSS block duplicates the relevant tokens from `docs/design/colors_and_type.css`. A regression test (`root_serves_inline_viewer_html` in `crates/auv-inspect-server/src/server.rs`) asserts `--brand: #00c4d2` is present so drift is caught. When adding tokens, copy from `colors_and_type.css` verbatim, keep the same names (`--brand`, `--validated`, etc.), and add a matching assertion if the token is new. 3. **Routes by purpose.** `GET /` returns the viewer payload; `GET /assets/:name` (added in C.5) serves design-system SVGs from a compile-time `include_bytes!` map keyed on `docs/design/assets/` filenames. To add a new asset, drop the SVG into that directory and add an entry to `DESIGN_ASSETS` in `crates/auv-inspect-server/src/server.rs`. The filename is the URL — keep them stable. 4. **The JSON contract is fixed.** Endpoints already exist: `/runs`, `/runs/:id`, `/runs/:id/spans`, `/runs/:id/events`, `/runs/:id/artifacts`, `/runs/:id/artifacts/:artifact_id`, `/runs/:id/stream` (WebSocket). JSON shapes are `RunRecordV1Alpha1` etc. in `src/trace.rs:118-173`. Do not change these to fit the UI; render against them as-is. 5. **Honest boundaries.** Match the AUV voice from `docs/ai/references/archive/phase-history/2026-05-18-phase-1-freeze.md`: when a feature isn't shipped yet, say so explicitly in the UI (e.g. C.1's placeholder reads "span tree, events, and artifact panel land in a follow-on commit"). Do not paper over. ## Source-of-truth mapping When implementing any phase, the visual contract is the matching JSX mock; the data contract is the matching Rust struct. | Phase | Visual mock | Data shape | Endpoint | |---|---|---|---| | C.1 (done) | `docs/design/ui_kits/viewer/Sidebar.jsx` | `RunRecordV1Alpha1` | `GET /runs` | | C.2 | `docs/design/ui_kits/viewer/SpanTree.jsx` + `Layout.jsx` (PaneHeader) | `RunRecordV1Alpha1` + `SpanRecordV1Alpha1` | `GET /runs/:id` + `GET /runs/:id/spans` | | C.3a | `docs/design/ui_kits/viewer/EventsRail.jsx` | `EventRecordV1Alpha1` | `GET /runs/:id/events` | | C.3b | `docs/design/ui_kits/viewer/ArtifactPanel.jsx` | `ArtifactRecordV1Alpha1` | `GET /runs/:id/artifacts` + `GET /runs/:id/artifacts/:id` for previews | | C.4 | the pulsing `live` connection pill in the top bar (already styled in C.1) + the `live: true` event background tint in `EventsRail.jsx` | `RunStreamEvent` in `src/recording.rs` | `GET /runs/:id/stream` (WebSocket, text frames are serialized `RunStreamEvent`) | | C.5 | — | n/a | new routes under `/assets/*` | ## Phase C.2 — span tree + run detail pane > **Shipped in `4f0cbe0`** (by Codex). Section kept for historical > context + future extension. **Goal**: when the user clicks a run in the sidebar, replace the placeholder with the span tree. **Where to add code**: 1. Edit `crates/auv-inspect-server/viewer/src/App.vue`, `src/viewer.ts`, and `src/styles/viewer.css`. Rebuild the Vite output before validating the Rust server. 2. The `selectRun(runId)` function is the entry point. Today it updates the pane header and the placeholder. Replace the placeholder branch with `await loadRunDetail(runId)` that: - Fetches `/runs/:id` (run record — has `summary`, `status_code`, `state`, `started_at_millis`, `finished_at_millis`, `trace_id`, `run_type`). - Fetches `/runs/:id/spans` (array of `SpanRecordV1Alpha1`). - Renders into a new `<div class="main">` body region (currently a `.placeholder` div). **Visual contract** (from `SpanTree.jsx`): - Header row in `.pane-header` shows `Run · <run_id>` on the left, on the right a small mono crumb (`run_type · trace_id=<first 12>…`) and a status pill (reuse the same `.status-pill` CSS). - Sticky table header inside the span tree: columns `span · name / step_id`, `status`, `dur`, `timing`. - Column widths: `0 0 300px`, `0 0 70px`, `0 0 70px`, `1 1 auto`. - 28px height, sticky `top: 0`, `background: var(--shell-2)`, border-bottom hairline. - Each row: 7px vertical padding, 16px horizontal padding, mono 12.5px text, hover/selected → `background: var(--shell-3)` and 2px brand left border. - Status sigil glyphs: `●` (ok / running), `×` (error), `○` (unset), `·` (none). Color = matching status token. Running sigil pulses via the existing `@keyframes auv-pulse` 1.2s linear. - Indentation: `padding-left: depth * 16px` on the name column. Compute depth by walking `parent_span_id` chain to a root. - Duration: `(finished_at_millis - started_at_millis) / 1000` to seconds with 2 decimals, or `—` when running. - Timing bar: an 8px-tall track at `background: var(--shell-2)`, with a fill rect at `background: <status color>, opacity: 0.85` whose width = `(span_duration / max_duration) * 100%`. The upstream mock fakes the start offset (`indexOf * 5%`); compute the real offset as `(span.started - run.started) / (run.finished - run.started) * 100` if both ends are known, else stick to the cumulative-offset fake. **Helper functions you'll want**: - `depthOf(spans, span_id)` — recursive walk to root, memoized. - `spanGlyph(span)` returning `{ glyph, color, pulse }`. - `fmtSeconds(ms)` (2 decimals or `—`). **Test to add** alongside `root_serves_inline_viewer_html`: ```rust #[tokio::test] async fn root_payload_includes_span_tree_markers() { // Smoke that the new SpanTree HTML hooks exist in the payload. // E.g. assert html.contains("span · name / step_id") // and html.contains("@keyframes auv-pulse") (already present). } ``` Pure HTML assertion — no need to round-trip data. **Out of scope for C.2**: events rail (C.3a), artifact panel (C.3b), WebSocket (C.4). ## Phase C.3a — events rail > **Shipped in `132ef3d`.** Section kept for historical context. **Goal**: a 320px-tall horizontal rail below the span tree, showing `events.jsonl` tail. **Where**: - Historical implementation note: this originally changed the single-file viewer. Current work should edit the Vite viewer source under `crates/auv-inspect-server/viewer/src/`, then rebuild `viewer/dist`. The `<main class="main">` is a vertical flex column with two children: the span tree (flex 1) and the events rail (flex `0 0 320px`). - New `loadEvents(runId)` function fetching `/runs/:id/events`. **Visual contract** (from `EventsRail.jsx`): - Top sub-section: `SpanDetail` — when a span is selected, render its `name`, `span_id`, and a `key/value` grid of `attributes`. When nothing selected, the empty state pairs a `sparkle.svg` (24×24) with the line "Select a span to inspect its attributes." Current code references `/assets/sparkle.svg`; do not re-inline design SVGs. - Pane header reading `Events · events.jsonl` with right-side count `<n> · tail`. - Each event row: `grid-template-columns: 70px 160px 60px 1fr`, 4px/20px padding, mono 12px, line-height 1.45. - Col 1: relative timestamp (compute `event.timestamp_millis - run.started_at_millis`, format as `+12.34s`). - Col 2: `event.name` — color by name substring: `failed` → `--failed`, `started`/`invoke` → `--brand-soft`, everything else → `--fg`. - Col 3: `span_id` (truncated to 8 chars). - Col 4: `event.message` or join of `attributes` if no message. - Tint live events at `background: rgba(31, 125, 140, 0.08)` — C.4 will set the `live` flag from the WebSocket stream; for C.3a leave it always false (no tint). **Span selection wiring**: span clicks in C.2's tree should set a shared `state.activeSpanId`. When set, find the matching span and pass it to `renderSpanDetail`. When unset, show the empty state. ## Phase C.3b — artifact panel > **Shipped in `a0b924a`.** Uses `/assets/icon-*.svg` + > `/assets/sprite-inspector.svg` (C.5 was pulled forward; see > below). Note: the mock's `bytes` field is omitted from the > metadata grid because the v1alpha1 `ArtifactRecord` doesn't > carry it. **Goal**: a 340px-wide right rail with artifact list + preview pane. **Visual contract** (from `ArtifactPanel.jsx`): - Same dark shell-2 column with hairline left border. - Pane header `Artifacts · /artifacts` + count. - Artifact rows: 10/12 padding, 28×28 mime-typed icon (`icon-png.svg` for `image/*`, `icon-json.svg` for `application/json`, `icon-bin.svg` otherwise — these three SVGs are in `docs/design/assets/`). Below the icon: role + filename basename in mono. Selected row gets the cyan brand left border and `--shell-3` background, same as run rows. - Preview pane (bottom half): - Empty state: `sprite-inspector.svg` 96×112 + "Select an artifact to preview." + "<n> artifacts on this run". - Selected: 6-row metadata grid (`role`, `mime`, `path`, `sha256`, `bytes`, `span_id`). - Below metadata: a 220px content surface. - `application/json` → `<pre>` in mono with the actual artifact bytes (fetch via `/runs/:id/artifacts/:artifact_id`). - `image/*` → `<img>` tag with the same URL. - Anything else → a diagonal-stripe placeholder background (`repeating-linear-gradient(45deg, var(--shell-2) 0 12px, var(--shell-3) 12px 24px)`) with center caption `binary · <bytes>`. **Historical asset note**: the original C.3b design considered inlining `icon-png`, `icon-json`, `icon-bin`, and `sprite-inspector`. C.5 has since landed, so current viewer work should reference `/assets/<name>.svg` and keep the design asset map in `crates/auv-inspect-server/src/server.rs` in sync. ## Phase C.4 — WebSocket live streaming > **Shipped in _this commit_.** Section kept for historical context. > Handles `span_started` / `span_finished` / `event_appended` / > `artifact_created` / `run_finished` per `RunStreamEvent` in > `src/recording.rs:215`. Single 2 s retry on error, then > `disconnected`. Streamed events get the `_live` tint reserved > in C.3a. **Goal**: when the selected run is `state == "running"`, open the `/runs/:id/stream` WebSocket and append events live; pulse the connection pill cyan. **Where**: - Same viewer source. Add a `connectStream(runId)` function that opens `new WebSocket(\`ws://\${location.host}/runs/\${runId}/stream\`)`. - On `message`, parse JSON (each frame is a serialized `RunStreamEvent` — see `src/recording.rs`). Push the event into `state.events`, re-render the events rail, mark the row as live (`live: true`) so it gets the 8% running-cyan tint, mark the artifact row if `RunStreamEvent::ArtifactPersisted` arrives. - Tear down the socket when selecting a different run. **Connection pill**: it's already wired in C.1 — `setConnection(ok, endpoint)` flips classes. C.4 should update the endpoint readout to `ws://.../stream` while a stream is open, and back to `/runs` when no stream is open. **Reconnect policy**: on `onerror` / `onclose` of an active stream, schedule a single retry after 2s; on the second failure flip to `disconnected` and stop. Don't infinite-loop. ## Phase C.5 — extract assets to /assets/* route > **Shipped in `e7726a4` (pulled forward to land before C.3b).** > Hand-rolled `GET /assets/:name` against a compile-time > `DESIGN_ASSETS` map (option 2 from the original recommendation). > Path traversal hardened. Cache-Control: immutable, 1 year. Only do this when total inlined-SVG bytes start to feel bloated, or when the same asset is needed from multiple HTML payloads. Two options: 1. **`tower-http::services::ServeDir`** mounted at `/assets` → serves files from `docs/design/assets/` directly. Adds the `tower-http` dependency. Smallest code. 2. **Hand-rolled** `GET /assets/:name` that matches a small compile-time map of `(filename, bytes, mime)` produced by `include_bytes!`. Zero new dependencies. More boilerplate. When you do this, also remove inline SVG copies from the viewer source and reference `/assets/<name>.svg` instead. ## Common pitfalls - **Run record duration**: a `running` run has `finished_at_millis: null`. Always guard against `null` before arithmetic. - **Span ordering**: `/runs/:id/spans` returns spans in the order they were recorded, not topologically. Render in tree order (parent-first) by sorting by `started_at_millis` or by walking from the run's `root_span_id` and emitting children in start-time order. The mock `SpanTree.jsx` doesn't sort; the real data may have multiple roots if `parent_span_id` is `None` for more than one span. - **WebSocket origin**: `location.host` (not `location.hostname`) carries the port, so `ws://${location.host}/...` is correct even on non-default ports. - **Status name mismatch**: the Rust `TraceState` is `ended` / `running`; the JSX mocks use `running` / `unset`. Map both to the right pill class. ## How to verify a phase landed For each new phase: 1. `cargo test -p auv-inspect-server` — every new viewer feature should have at least one assertion in `crates/auv-inspect-server/src/server.rs` that the payload contains a stable marker string (e.g. `"events.jsonl"` for C.3a). 2. End-to-end smoke: ``` auv-cli inspect serve --port 18765 & curl -s http://127.0.0.1:18765/ | grep -F "<expected marker>" curl -s http://127.0.0.1:18765/runs | jq 'length' kill %1 ``` 3. Visual: open `http://127.0.0.1:18765/` in a real browser. The user has live runs in `.auv/runs/`; the sidebar should fill with them. Document any visual deltas in the commit body. ## Don't do - Don't switch to React or another framework. The viewer is currently Vue/Vite; keep changes inside that toolchain unless the owner approves a migration. - Don't edit generated `viewer/dist` by hand. Change `viewer/src/*`, run the Vite build, and commit the generated asset changes with the source change. - Don't add emoji or icons from Lucide or any icon font. Use the `assets/` SVG sprites or status sigil glyphs only. - Don't rename frozen contract fields (`cursorDisturbance`, `pressMechanism`, run/span/event v1alpha1 fields). The Phase 2 freeze doc lists what's locked. -
README.md 4.6 KB
# `auv` Design System (vendored) This directory is a **vendored copy** of the AUV Design System bundle that was handed off from Claude Design (claude.ai/design) on **2026-05-21**. The original handoff bundle's own README files are preserved verbatim: - [`HANDOFF_README.md`](./HANDOFF_README.md) — Claude Design's per-handoff instructions to coding agents. - [`SOURCE_README.md`](./SOURCE_README.md) — the design system's own README (product context, voice, visual foundations). - [`SKILL.md`](./SKILL.md) — agent-skill metadata. For agents picking up the **already-landed viewer implementation** or remaining follow-on design work, read: - [`IMPLEMENTATION_HANDOFF.md`](./IMPLEMENTATION_HANDOFF.md) — cold- start spec: what shipped, what's left, exact visual + data contracts for each remaining phase. Designed so an agent with no prior session context can implement a phase end-to-end. ## Why vendor it? The Rust runtime today consumes exactly **one** part of the design system at compile time — the cursor sprite + brand pill in `crates/auv-driver-overlay-macos/native/swift/Sources/AuvMacosOverlayNative/Overlay.swift`, which ports rect data verbatim from `assets/cursor-auv.svg`. The rest of the bundle is reference material for surfaces that **do not exist in the repo yet** (the browser-based inspect viewer, an HTML CLI mock, the broader component library). Keeping the canonical assets + tokens in `docs/design/` means future implementations can match pixel-perfectly against the same source the Overlay.swift sprite came from, without re-fetching the original bundle. ## Layout | Path | Purpose | |---|---| | `assets/` | Logo marks, cursor sprites, accents, sprite icons. All SVG (pixel-art, `viewBox="0 0 24 24"`, `shape-rendering="crispEdges"`). | | `colors_and_type.css` | Single source of truth for design tokens — colors, type stack, spacing, radii, shadows, motion. | | `preview/` | One-card-per-concept HTML previews (color cards, type cards, component cards). | | `ui_kits/cli/` | High-fidelity HTML recreation of `auv-cli` terminal output. Not yet wired into the Rust CLI. | | `ui_kits/viewer/` | Speculative recreation of the still-unbuilt browser viewer described in `docs/ai/references/inspect/2026-05-19-trace-run-inspect-design.md`. | ## What's implemented from this bundle | Bundle element | Repo location | Status | |---|---|---| | `assets/cursor-auv.svg` rect data | `crates/auv-driver-overlay-macos/.../Overlay.swift` (auvSprite) | done (Phase A) | | `assets/cursor-you.svg` rect data | `crates/auv-driver-overlay-macos/.../Overlay.swift` (youSprite) | ported (used by viewer mocks, not by the live overlay yet) | | Brand cyan pill (`#009ba6`) | `crates/auv-driver-overlay-macos/.../Overlay.swift` | done (Phase A) | | `assets/logo-mark.svg` (top-bar pixel logo) | `crates/auv-inspect-server/viewer/src/App.vue` | done (Phase C.1; served from Vite build) | | `colors_and_type.css` core tokens (shell, brand, status) | `crates/auv-inspect-server/viewer/src/styles/viewer.css` | done (Phase C.1; served from Vite build) | | `ui_kits/viewer/Sidebar.jsx` (run list) | `crates/auv-inspect-server/viewer/src/App.vue` + `src/viewer.ts` | done (Phase C.1; served from Vite build) | | `ui_kits/viewer/SpanTree.jsx` | `crates/auv-inspect-server/viewer/src/App.vue` + `src/viewer.ts` | done (Phase C.2; served from Vite build) | | `ui_kits/viewer/EventsRail.jsx` | `crates/auv-inspect-server/viewer/src/App.vue` + `src/viewer.ts` | done (Phase C.3a; served from Vite build) | | `ui_kits/viewer/ArtifactPanel.jsx` | `crates/auv-inspect-server/viewer/src/App.vue` + `src/viewer.ts` | done (Phase C.3b; served from Vite build) | | WebSocket live streaming on `/runs/:id/stream` | `crates/auv-inspect-server/viewer/src/viewer.ts` + `crates/auv-inspect-server/src/server.rs` | done (Phase C.4; served from Vite build) | | Extract assets to `/assets/:name` route | `crates/auv-inspect-server/src/server.rs` | done (Phase C.5, landed early) | | `assets/cursor-auv-click.svg` (4-ray burst) | — | pending (future Overlay click-state) | | `ui_kits/cli/*` | — | reference only; the Rust CLI ships plain text today | ## Editing this directory This is a vendored bundle. If the design system updates upstream, replace the contents wholesale rather than hand-editing files here. The original bundle ID was `Cnhoa_hmraSs_HJx96DFxw`; re-fetch from `https://api.anthropic.com/v1/design/h/<id>` to obtain a fresh tarball. The one file in this directory that is **not** part of the upstream bundle is this `README.md` — it records the vendoring decision and the implementation status. Keep it in sync with what the repo actually consumes from the bundle. -
SKILL.md 2.6 KB
--- name: auv-design description: Use this skill to generate well-branded interfaces and assets for AUV (the Moeru AI command-replay / inspect runtime), either for production or throwaway prototypes/mocks. Contains essential design guidelines, colors, type, fonts, assets, and UI kit components for prototyping. user-invocable: true --- # AUV Design Read `README.md` in this skill first — it establishes product context, content fundamentals (the deliberately anti-marketing AUV voice), visual foundations, and iconography rules. Then explore the other files: - `colors_and_type.css` — all design tokens (`--auv-*`). - `assets/` — logo mark + wordmark. - `preview/` — small reference cards for each system concept. - `ui_kits/cli/` — `auv-cli` terminal output recreation. - `ui_kits/viewer/` — speculative inspect-viewer mock (the browser viewer described in `2026-05-19-trace-run-inspect-design.md`; **not built yet** in the source repo). ## Operating principles for this brand 1. **Honesty over polish.** AUV documents what is `validated`, `candidate`, and `not-validated` in JSON. Reflect that in every artifact. Never invent a status not on the canonical list. 2. **Monospace carries identity.** IDs, paths, span names, and JSON keys live in `JetBrains Mono`. Body prose lives in `Geist`. 3. **No emoji. No gradients. No glassy overlays.** This is forensic-grade UI. 4. **Status pill is the smallest unit.** Use `.auv-status--{validated, candidate, boundary, frozen, running, failed}` everywhere a status is shown — sidebars, lists, headers, terminal output, marketing. ## When the user invokes this skill If creating visual artifacts (slides, mocks, throwaway prototypes), copy assets out of this skill and produce static HTML the user can view. Reuse the `<Terminal>` / `<SpanTree>` / `<Sidebar>` components from the UI kits when the output is product-facing. If working on production code (Rust CLI, future browser viewer, future docs site), copy `colors_and_type.css` and `assets/logo-*.svg` into the project, and follow the rules in `README.md` (sections **Content Fundamentals** and **Visual Foundations**) to extend the system. If invoked without other guidance, ask the user what they want to build — typical asks are: - a mock of `auv-cli` output for a docs page or social post - a wireframe / mock of the inspect viewer - a slide deck explaining a phase-1 boundary - copy in the AUV voice (status report, freeze note, boundary callout) Then act as an expert designer on the AUV brand and output HTML artifacts or production code, depending on the need. -
SOURCE_README.md 13.7 KB
# AUV Design System A visual + interaction system for **AUV** — a Rust CLI for turning application UI workflows into inspectable, replayable operations. AUV is **one project among several** under the [Moeru AI](https://github.com/moeru-ai) umbrella — an online hobby group exploring the intersection of **Moe (萌え) + AI**. Sibling projects in the same org include [`airi`](https://github.com/moeru-ai/airi) (virtual AI persona, targeting a Neuro-sama recreation), [`plast-mem`](https://github.com/moeru-ai/plast-mem) (memory layer for cyber waifus), [`xsai`](https://github.com/moeru-ai/xsai) (extra-small AI SDK), and [`citrus`](https://github.com/moeru-ai/citrus) (inactive). This design system is AUV-specific, but it visually inherits the Moeru AI parent identity (cyan + lime, pixel-art accents). Source repos used to build this system: - [`moeru-ai/auv`](https://github.com/moeru-ai/auv) — primary source of truth (Rust runtime, CLI, recipes, app-local commands, docs). The reader is encouraged to skim those before designing anything substantial against AUV. The repository does not ship a UI; the design language here is *derived* from terminal output, JSON manifest shapes, and the planned browser-based viewer described in [`docs/ai/references/inspect/2026-05-19-trace-run-inspect-design.md`](https://github.com/moeru-ai/auv/blob/main/docs/ai/references/inspect/2026-05-19-trace-run-inspect-design.md). --- ## 1. Product Context AUV is **not** a generic LLM agent and **not** a CLI wrapper. It is a recording + replay runtime: an explicit execution model that turns ad-hoc UI automation into: | Artifact | What it is | Where it lives | |---|---|---| | **Recipe** | A JSON manifest of steps against a target app | `recipes/macos/<app>/<recipe>.v0.json` | | **Case matrix** | Validated/candidate inputs that exercise a recipe | `recipes/macos/<app>/<recipe>.cases.v0.json` | | **Trace / Run** | The recording of one workflow execution | `.auv/runs/<run_id>/` | | **Span / Event / Artifact** | OTLP-shaped records inside a run | `.auv/runs/<run_id>/{spans,events,artifacts}.jsonl` | ### Current surfaces 1. **`auv-cli`** — the user-facing executable. Subcommands: `list-commands`, `list-drivers`, `app probe|analyze|distill|validate`, `invoke`, `inspect`, `inspect serve`, `skill list|show|run`, `skill cases list|show|report|run`. 2. **`auv-cli inspect serve`** — a read-only HTTP + WebSocket inspect server that surfaces stored and live run data. Default endpoint `127.0.0.1:8765`. The browser viewer that consumes it is **not yet implemented** but is fully designed in `2026-05-19-trace-run-inspect-design.md`. 3. **macOS driver** — the only platform-native driver shipped today. Currently validated against QQ音乐, Notes, and TextEdit. ### Phase-1 freeze (2026-05-18) The product is intentionally narrow. Phase-1 is **frozen**: - macOS runtime + driver + recipe + case-matrix flow exists; the former bundle package flow has been retired. - QQ音乐 has two validated narrow playback strategies (OCR-anchor + row fallback). - Notes + TextEdit ship as native-app AX-text samples. - The unresolved boundary — Chinese requested-title semantic selection in the row-fallback path — is recorded explicitly as `semanticSelectionStatus = not-validated`, not hidden. This design system reflects that culture: status is always declared, never implied. --- ## 2. Index | File | What's in it | |---|---| | `README.md` | This document. | | `colors_and_type.css` | All design tokens (colors, type, spacing, radii, shadows, motion). | | `SKILL.md` | Agent Skill manifest — load this skill in Claude Code or as guidance. | | `assets/` | Logo mark + wordmark (pixel-art), sparkle accent, parent-org Moeru AI logo. | | `preview/` | One-card-per-concept previews populating the **Design System** tab. | | `ui_kits/cli/` | High-fidelity recreation of `auv-cli` terminal output. | | `ui_kits/viewer/` | Mock of the unbuilt browser viewer described in `trace-run-inspect-design.md`. | --- ## 3. Content Fundamentals AUV documentation has a strong, recognizable voice. It is one of the most *aggressively honest* engineering tones in any modern repo. Match this register in every artifact this system produces. ### Voice attributes - **Anti-marketing.** No persuasion, no superlatives, no "powerful" or "seamless". Every claim is qualified. - **Boundary-first.** Every spec lists what is **not** proven alongside what is. The reader is given the failure mode before the success mode. - **Provisional naming.** Names like `v1alpha1`, "phase-1", "candidate" are used to flag instability. Do not stabilize names too early. - **Lowercase command identifiers.** `recipe`, `case matrix`, `run`, `span`, `event`, `artifact` are nouns; `probe`, `analyze`, `distill`, `validate`, `invoke`, `inspect` are verbs. Reuse them. ### Casing - **Headings, prose:** sentence case. Never title case. - **CLI commands and recipe IDs:** lowercase with dots and underscores. `macos.qqmusic.play_visible_anchor.v0`. - **Run IDs:** literal monospace strings, e.g. `run_1778947574511_68037_4`. - **Status vocabulary:** lowercase, hyphenated. `validated`, `not-validated`, `candidate`, `phase-1-frozen`, `running`, `failed`, `ok`. ### Pronouns + register - **"This recipe does not …"**, **"This run does not claim …"** — the artifact is the subject, not the user. Avoid "you". - Imperatives are reserved for operational instructions (`Run formatting and tests before submitting changes that touch Rust code.`). ### Example phrasings — verbatim from the repo > "Phase 1 is frozen. That does **not** mean every behavior is solved." > > "The remaining failures are explicit boundaries, not hidden contradictions." > > "Do not twist this freeze into false product claims." > > "If phase 2 immediately collapses back into 'let's just chase one more OCR > edge case', that is not progress. That is avoidance." > > "This is a freeze of scope, not a claim that every QQ音乐 edge case is > solved." ### Emoji / icons in prose - **No emoji.** Anywhere. Not in headers, not in callouts, not in CLI output. - **Unicode disc characters** (`●`, `○`, `◐`) are used as status sigils inside the visual system, never in prose. - Mermaid graphs are used to describe trees (see `2026-05-17-auv-native-app-skill-tree.md`). --- ## 4. Visual Foundations There is no existing visual brand to inherit; AUV ships zero pixels. This section *establishes* the system based on the project's culture. ### Color vibe - **Two ground tones:** warm paper (`--auv-paper`, `#f6f5f1`) for docs + prose; deep ink (`--auv-shell`, `#0e1013`) for terminal-grade surfaces. Both ship; the viewer is dark-by-default, prose is light-by-default. - **No gradients.** A CLI tool. Flat surfaces with hairline borders. - **Two brand hues** — `--auv-brand: #00c4d2` (moeru cyan) + `--auv-brand-2: #7fd030` (moeru lime). Sampled from the [Moeru AI org logo](https://github.com/moeru-ai). Cyan is the single primary-action color; lime accents validated states, sparkles, and the pixel-art logo's bottom half. - **Status-coded everything.** Validated green, candidate amber, boundary rose, frozen slate, running cyan-teal, failed red. These map 1:1 onto recipe/case-matrix JSON fields and the OTLP `status_code`. ### Type - **`Geist`** (sans, 300–700) — UI prose, headings, navigation. - **`JetBrains Mono`** (mono, 400–700) — IDs, run IDs, code, JSON, status pills, span names. - **`Geist Mono`** — mono used in UI chrome (smaller chip text, table headers) where JetBrains Mono is too dense. - **`Silkscreen`** (pixel, 400/700) — the moeru-ai pixel-art accent. Used only on the wordmark, hero accents, and section dividers. **Never body text.** It is functionally legible only above ~13px. - Headings are mid-weight (500), never extra-bold. The wordmark uses hand-drawn pixel rects rather than a web-font glyph so the mark renders consistently even when Silkscreen has not loaded. ### Backgrounds - Solid colors only. **No imagery, no full-bleed photos, no illustration in product surfaces.** The one inherited motif from the parent org is **pixel-art**: see `assets/logo-mark.svg` and `assets/sparkle.svg`. Pixel sprites may appear as small accents in the viewer's empty states, hero surfaces, or `auv-cli` welcome banners — but **never inside data views** (span trees, JSON, terminal output). - Repeating textures: a **1px hairline grid** is acceptable on empty inspect-viewer canvases (1px `#e6e4dc` every 24px). A second permitted texture is the **pixel-checkerboard placeholder** used in the viewer's artifact preview (2px squares in `--auv-shell-2` / `--auv-shell-3`). ### Animation - **Linear-ish ease** — `cubic-bezier(0.2, 0.0, 0.2, 1)`. No bounces, no springs. - **140ms** default duration, **80ms** for chrome feedback, **220ms** for larger surfaces. - The only animated primitive is `auv-pulse`: a 7px disc, 1.2s loop, used on the **running** status pill while a live run streams via WebSocket. - Page transitions: none. The viewer mounts and renders in place. ### Hover / press states - **Hover:** swap to one step darker on neutral surfaces (`--auv-paper-2` recessing). No glow, no underline, no scale. - **Press:** `transform: translateY(0.5px)` only; color does not change on press. Buttons feel mechanical, like a key click. - Links: solid `--auv-brand`, underline on hover only. ### Borders + shadows - **Hairline-first.** `1px solid var(--auv-paper-line)` is the default card border. Shadows are used **only** for popovers + dropdowns. - Three shadow steps total: `--auv-shadow-1` (cards lifted off the page), `--auv-shadow-2` (panels), `--auv-shadow-pop` (popovers / context menus). - No inset shadows. ### Transparency + blur - **Avoid.** This is a forensic inspection tool; the user must trust pixel values they see. No backdrop-filter, no glassy overlays. - The one exception: the live-run streaming overlay in the viewer may use a 4% black wash to dim the underlying span while a span is `state: running`. ### Corner radii - `2px` — pills, status chips - `4px` — inputs, small buttons - `6px` — cards, terminal blocks (default) - `8px` — large content cards - **No fully-rounded cards.** Pill buttons are reserved for the status vocabulary, nothing else. ### Layout rules - **Fixed grid:** 24px column gutter, 16px row rhythm. - **Hairline dividers** separate sibling sections rather than whitespace alone — this echoes the JSONL log shape AUV emits. - The viewer uses a **fixed left sidebar** (256px) for the run list and a **fixed top status bar** (44px) for the connection state to `127.0.0.1:8765`. - Long IDs are never truncated visually without a tooltip; truncation happens at the *middle* of the string (so the trailing sequence number stays visible). ### Cards - White (or `--auv-shell-2`) fill, 1px hairline, 6px radius, no shadow. - Header row uses `--auv-meta` (uppercase mono micro-caps) for the artifact kind label, then the ID in mono. - A status pill always sits on the **right** of the header row. - Card padding: `16px 20px`. ### Imagery - The project has no photography, no people, no illustration. If a marketing surface needs imagery, prefer: - Screenshots of real terminal output (use the `ui_kits/cli` recreations). - A mermaid skill-tree diagram (the `skill-tree.md` reference is canonical). - Architectural diagrams in plain SVG, monochrome. --- ## 5. Iconography AUV ships **no icons**. There is no icon font, no SVG sprite, no Lucide import in the repo. The closest thing to an iconographic system is the **status sigil**: | Sigil | Meaning | Token | |---|---|---| | `●` filled | validated | `--auv-validated` | | `◐` half | candidate / pending | `--auv-candidate` | | `○` open | not-validated / boundary | `--auv-boundary` | | `■` filled square | frozen / locked | `--auv-frozen` | | `●` pulsing | running / live stream | `--auv-running` | | `×` cross | failed | `--auv-failed` | These are rendered as colored CSS pseudo-elements (see `.auv-status`), not glyphs from a font. Match this approach instead of importing an icon set. ### When iconography is needed in the viewer The browser viewer (when built) will need a small functional icon set for: - run-list navigation (chevrons, copy-link) - span-tree expand/collapse - artifact-type indicators (image / json / log) - the `inspect serve` connection state For these, **substitute Lucide** (`https://unpkg.com/lucide-static`) at stroke-width 1.5, 16px, current-color. **Flag this substitution to the user — the repo has not standardized an icon set.** Lucide is a stand-in. ### Emoji Do not use emoji. The repo contains none in code, commits, or docs. The only non-ASCII characters that appear are Chinese characters in app names and test queries (`QQ音乐`, `周杰伦`, `晴天`). --- ## 6. Caveats + flagged substitutions - **AUV ships zero pixels of UI.** The brand here was reverse-engineered from the parent org's pixel-art logo + the AUV repo's voice. The cyan `#00c4d2` and lime `#7fd030` are sampled from [`moeru-ai/.github/moeru-ai.svg`](https://github.com/moeru-ai/.github); the AUV pixel mark in `assets/logo-mark.svg` is a derivative I drew, not an asset from the org. - **Fonts** — `Geist`, `JetBrains Mono`, and `Silkscreen` are all open- licensed via Google Fonts. If the project owner prefers different families (Berkeley Mono, IBM Plex, Press Start 2P), swap in `colors_and_type.css`. - **Icons** — Lucide is a CDN stand-in. If/when the project standardizes, swap. - **The viewer UI kit** (`ui_kits/viewer/`) recreates a UI that **does not exist yet**. It is faithful to the design doc but speculative on visual detail. If the project owner wants different brand colors, a different mark, or a different type system, those should override every choice in `colors_and_type.css`.
Comments (0)
Sign in to join the conversation.
Reviews (0)
No reviews yet.
No comments yet.