Cursor Skill

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.

LLM Mart · 0 points · 13 views 23 listing impressions 0 install-command copies
Virus-scanned Reviewed automatically before listing.

Full trust report

Download moeru-ai-auv-docs_design-372a07b.zip · 99 KB
moeru-ai/auv 51 6 forks Apache-2.0 Updated 10h ago
Part of moeru-ai/auv — 28 skills

Install

skills CLI npx skills add https://github.com/moeru-ai/auv/tree/main/docs/design
Claude Code claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install moeru-ai-auv@llmmart
Git 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-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.

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.

No comments yet.

Reviews (0)

No reviews yet.

Related