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>
This commit is contained in:
jules
2026-04-27 18:31:46 +10:00
commit 286e2daf95
88 changed files with 16464 additions and 0 deletions

122
CLAUDE.md Normal file
View File

@@ -0,0 +1,122 @@
# 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 typecheck``react-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.ts``useBrand()` / `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.tsx``ToastProvider` + `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:
```bash
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:
```bash
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.