Files
crema-app-aifirst-template/CLAUDE.md
jules 286e2daf95 feat: initial commit — crema-app-aifirst-template
Hybrid traditional + AI-first webapp scaffold. Sibling to crema-app-template,
adds the AI assistant surface, command bus, scripts dialog, and virtual
cursor.

What's pre-wired:
- 6 routes: Overview, Resources, Activity, Assistant, Library, Settings
- Collapsible rail + appbar + avatar dropdown shell (template code, not a lib)
- Mobile sheet at <md
- /assistant: streaming chat via @crema/llm-ui, mock fallback, model selector,
  token meter, retry probe, stop-while-streaming, persistent UI Control toggle
- /settings: editable LM Studio endpoint + context window + response cap, with
  test-connection button
- Markdown rendering for assistant replies; ```action``` blocks rendered as a
  small "Ran N actions" pill
- ⌘⇧P script runner dialog + Play icon in the appbar
- Two demo scripts in public/scripts/
- mightypix theme as default, scoped via <AppShell theme="mightypix">

Libs wired in tsconfig + app.css:
- @crema/action-bus (the bus, parser, runner, cursor, provider, ws, llm-bridge)
- @crema/llm-ui, @crema/chat-ui, @crema/aifirst-ui, @crema/notification-ui
- lib-theme-mightypix

Docs:
- README.md — pitch + quick start + structure
- docs/AI_FIRST.md — full system tour (data-action contract, bus, DSL, scripts,
  cursor, LLM integration)
- app/components/layout/THEME_CONTRACT.md — every CSS variable a theme must declare
- CLAUDE.md — orientation for an LLM working in the repo

Genericized from comfy-cloud (the original prototype):
- Brand defaults to "App" / Sparkles icon (override via app/lib/identity.ts)
- User defaults to a stub (swap useUser() for real auth)
- localStorage namespace is "crema.*" (was "comfy.*")

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 18:31:46 +10:00

7.1 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Hybrid traditional + AI-first webapp built on the Crema design system. This file is a quick map, not a duplication of upstream docs.

Scripts

  • npm run dev — Vite dev server (React Router 7).
  • npm run build — production build (react-router build).
  • npm run start — serve the built app (react-router-serve ./build/server/index.js).
  • npm run typecheckreact-router typegen && tsc. See gotcha below; may crash.
  • start.sh / stop.sh — repo's preferred way to run/stop the dev server in the background.

There is no test runner configured. package.json has no test script and no vitest dep — verify changes by reading code and running the dev server.

App layout (app/)

  • routes/ + routes.ts — file-based React Router 7 routes (Overview, Resources, Activity, Assistant, Library, Settings).
  • components/layout/app-shell.tsx (rail + appbar + avatar dropdown), appbar.tsx, theme-toggle.tsx. Template code, not a lib — fork it freely.
  • components/assistant/message-body.tsx — markdown rendering for assistant replies + action-block pill.
  • components/scripts-dialog.tsx — ⌘⇧P script runner UI.
  • lib/identity.tsuseBrand() / useUser() (default stubs; swap for real session).
  • lib/llm-settings.ts — persisted LLM endpoint + context budget config.
  • lib/page-meta.ts, lib/utils.ts — small helpers.
  • app.css — Tailwind v4 entrypoint; theme @import first, then tailwind, then per-lib @source lines.
  • root.tsxToastProvider + CommandBusProvider wrap point.

What this is

  • React Router 7 + Tailwind v4 SPA.
  • Hybrid traditional + AI-first scaffold. Most surfaces are normal; the Assistant surface is wrapped in <AppShell theme="mightypix"> for the AI-styled mood (warm cream + ink-blue + serif prose).
  • Built on Crema libs (@crema/*-ui) cloned as sibling directories, not npm packages.
  • The @crema/action-bus lib is the foundation: anything (LLM, scripts, WebSocket, tests) can drive the UI via [data-action]-tagged elements. See docs/AI_FIRST.md.

Crema system (authoritative)

  • Manifest (canonical catalog of all libs and themes) lives in the crema-manifest repo. The Gitea raw-file HTTP URL 404s, but the repo is publicly cloneable — fetch it with:
    git clone --depth 1 https://git.sky-ai.com/CremaUIStudio/crema-manifest.git /tmp/crema-manifest && cat /tmp/crema-manifest/manifest.json
    
    Each entry has name, alias (@crema/<name>), category, description, navLabel, navIcon, and demo.files[]. Check this before building any UI primitive — there's a good chance a lib-*-ui already does it. The per-lib src/index.tsx // PURPOSE / // EXPORTS header in the sibling repo is the same info at finer grain.
  • Each @crema/*-ui lib is its own git repo at https://git.sky-ai.com/CremaUIStudio/lib-<name>-ui.git, cloned as a sibling of this app. Edits to lib code commit to that lib's repo, not this one.
  • Themes (lib-theme-*) are CSS-only token files at the same Gitea org.

Adding a lib after scaffold

Prefer the CLI:

crema add <lib-name>      # e.g. crema add status-ui chart-ui

It clones the lib as a sibling, adds the @source line to app/app.css, and wires tsconfig.json paths.

Manual fallback (3 edits):

  1. Clone lib-<name>-ui as a sibling.
  2. app/app.css → add @source "../../lib-<name>-ui/src";
  3. tsconfig.json paths → add "@crema/<name>-ui": ["../lib-<name>-ui/src/index.tsx"] and the /* variant.

Theme convention

  • A single theme (lib-theme-mightypix by default) is loaded via :root in app/app.css, first so its embedded @import url(...) Google Fonts declarations resolve to the top of the output.
  • Themes are self-contained: tokens and their font @import url(...) ship inside the theme's CSS file.
  • Per-surface alt themes can be scoped via [data-theme="<name>"] and applied with the shell's theme prop. The Assistant route already does this: <AppShell title="Assistant" theme="mightypix">…</AppShell>.
  • Components reference tokens (var(--card), bg-card, etc.), never hex values. See app/components/layout/THEME_CONTRACT.md for the full token list any theme must implement.
  • Assistant prose uses var(--font-ai-prose). Don't hard-code font families.

Coding conventions

  • lib-*-ui components use inline styles with CSS variables (style={{ background: "var(--card)", color: "var(--foreground)" }}), not Tailwind classes. App routes use Tailwind freely with theme-variable utilities (bg-card, text-muted-foreground).
  • Every shadcn-style component has a [data-slot="..."] attribute — themes target these for surface treatment overrides. Preserve them when editing libs.
  • Lib src/index.tsx files start with // PURPOSE: and // EXPORTS blocks, plus "use client" at the top. Maintain the header.
  • Don't hardcode colors. Use tokens.

Polyrepo gotchas

  • git status at this app's root only shows app changes. To see lib edits, cd ../lib-<name>-ui && git status.
  • Each repo commits and pushes separately.
  • Don't bundle lib edits into app commits.
  • Sibling libs already cloned next to this app include the full Crema set (lib-chat-ui, lib-table-ui, lib-chart-ui, lib-theme-mightypix, etc.) — check ../lib-* before adding anything new.

Marker contract (CLI-managed regions)

This repo was scaffolded from create-crema-app, which patches marker comments. Preserve them when editing:

File Marker
tsconfig.json "// CREMA:PATHS"
app/app.css /* CREMA:SOURCES */
app/routes.ts // CREMA:ROUTES
app/components/layout/app-shell.tsx // CREMA:NAV-ICONS, // CREMA:NAV-ITEMS
app/root.tsx // CREMA:PROVIDERS-IMPORTS, /* CREMA:PROVIDERS-WRAP-OPEN */, /* CREMA:PROVIDERS-WRAP-CLOSE */

Common tasks

  • Run dev: npm run dev
  • Add a UI primitive: check the manifest first; if it exists, crema add <lib>; if not, build inline and consider whether it should become a lib.
  • Add a route: create the file under app/routes/, register in app/routes.ts, add a nav entry in the sidenav (traditional) or chat shell (AI).
  • Switch theme on a route: pass theme="<name>" to <AppShell>. Default (no prop) uses the :root theme.
  • Add a script: drop a .script file into public/scripts/, register it in KNOWN_SCRIPTS in app/components/scripts-dialog.tsx if you want it in the dialog list, or invoke programmatically with runScript("<name>").
  • Make a component scriptable: add data-action="<id>". The bus auto-discovers it.

Known gotchas

  • npm run typecheck may crash with a TypeScript internal error — pre-existing in the Crema toolchain. There's no test runner here, so rely on careful reads + dev server.
  • Vite "Outdated Optimize Dep" 504s after editing vite.config.ts or tsconfig.json: stop dev, rm -rf node_modules/.vite, restart, hard-reload.
  • After editing a sibling lib's exports, the dev server sometimes needs a manual restart to pick up the new types.