Disambiguates the Phoenix/auth client lib from lib-arcadia-agents-client. Dir lib-arcadia-client → lib-arcadia-core-client; alias updated in tsconfig paths, vite config, app.css @source, imports, CI and docs. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
147 lines
9.6 KiB
Markdown
147 lines
9.6 KiB
Markdown
# CLAUDE.md
|
|
|
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
|
|
Admin webapp for arcadia-core. Built on the Crema design system, themed with Skyrise, started from the Vibespace starter.
|
|
This file is a quick map, not a duplication of upstream docs.
|
|
|
|
## What Arcadia Admin is
|
|
|
|
- **Arcadia Admin** is the operator/admin UI for [arcadia-core](../reference/arcadia-app), a multi-tenant Phoenix backend. Surfaces tenant management, user/role admin, billing, audit logs, storage configs, scheduled tasks, feature flags, and platform monitoring on top of arcadia's `/api/v1` and `/admin/*` endpoints.
|
|
- **Cloned from** [Vibespace](../vibespace) — the starter for webapps in this style. Vibespace and Skyrise are the upstream sources of truth for the shell and the theme; don't backport arcadia-admin-specific changes into Vibespace unless they're broadly applicable.
|
|
- **Backend reference** lives at `../reference/arcadia-app/`. Treat it as read-only documentation — it's the Phoenix umbrella app that owns the OpenAPI spec, controllers, schemas, and seed data. Spec is regenerated from a running arcadia at `http://localhost:4000/api/openapi` via `node ../lib-arcadia-core-client/scripts/sync-spec.mjs` (run from this directory).
|
|
- **Skyrise** (`lib-theme-skyrise`) is the canonical theme — premium AI-first glass, iridescent body, vivid text, Apple-spring motion. Theme tweaks belong upstream in Vibespace + Skyrise, not here.
|
|
- The brand string lives in **one place**: `app/lib/identity.ts` (`useBrand()` / `getBrand()`). Don't hardcode "Arcadia Admin" in components, page titles, or copy.
|
|
|
|
## Arcadia integration (already wired)
|
|
|
|
- **`<ArcadiaProvider>`** in `app/root.tsx` reads `VITE_ARCADIA_URL` (default `http://localhost:4000`) and `VITE_ARCADIA_TENANT` (default `default`). `getToken` reads `arcadia_access_token` from `sessionStorage`. `onUnauthorized` clears the token.
|
|
- **`useArcadiaClient()`** for typed/generic HTTP. `arcadia.typed.GET("/api/v1/...")` infers paths from the generated `paths` type; `arcadia.GET<T>(path)` is the generic escape hatch for spec-incomplete endpoints.
|
|
- **Login** — `app/routes/login.tsx` renders `<LoginForm>` from `@crema/arcadia-auth-ui`. Successful login writes tokens via `persistFromArcadiaLogin()` in `app/lib/session.ts`, which preserves the existing `Session` shape used by `useUser` / `AppShell`.
|
|
- **Realtime** — supported by the lib but not enabled at the provider here; pass `enableRealtime` + `userId` to opt in.
|
|
- **Search admin sidecar** — the `/search` route (`app/routes/search.tsx`) calls arcadia-search's privileged `/admin/*` surface (default `127.0.0.1:7801`) via `app/lib/search-admin.ts`. Configured by `VITE_ARCADIA_SEARCH_ADMIN_URL` + `VITE_ARCADIA_SEARCH_ADMIN_TOKEN`; the token must match `ADMIN_TOKEN` on the search box. See `arcadia-search/README.md` § *Admin sidecar*.
|
|
|
|
## 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.
|
|
|
|
- `npm run test` — Vitest run (vibespace-inherited setup; jsdom + @testing-library/react).
|
|
|
|
## 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="skyrise">` 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)
|
|
|
|
- **Lib catalog:** see `docs/LIBS.md` for a snapshot of every `@crema/*-ui` lib
|
|
(the ones wired into this project AND the ones available to add). Before
|
|
building any UI primitive, check there first — there's a good chance a lib
|
|
already does it. Refresh the snapshot with `npm run sync-libs`.
|
|
- **Each `@crema/*-ui` lib is its own git repo** at
|
|
`https://git.sky-ai.com/CremaUIStudio/lib-<name>-ui`, 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.
|
|
- **Live manifest** (which `docs/LIBS.md` is generated from) is the
|
|
`crema-manifest` repo. Gitea's raw-file HTTP URL 404s; clone instead:
|
|
```bash
|
|
git clone --depth 1 https://git.sky-ai.com/CremaUIStudio/crema-manifest.git /tmp/crema-manifest
|
|
cat /tmp/crema-manifest/manifest.json
|
|
```
|
|
|
|
## 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.
|
|
|
|
Then run `npm run sync-libs` to refresh `docs/LIBS.md`.
|
|
|
|
## Theme convention
|
|
|
|
- A single theme (`lib-theme-skyrise` 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="skyrise">…</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-skyrise`, 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.
|