本文へ移動
cccskills
無料GitHub で公開

rembric-dashboard-ui

Rembric dashboard UI work (dark monochrome zinc surfaces, lime accent, Geist type, Spectrum data-tables) — building / editing / extending pages, styles, components, modals, tables, filters, pagination, mobile responsive, destructive confirmations. Use when the user asks for changes under `apps/web/src/app/dashboard/` or `apps/web/src/components/dashboard/`, mentions Rembric design tokens (lime, zinc, command bar, StatusPill, hl-lime, data-table), or requests a new dashboard page / form / table.

インストール方法を見る

含まれるファイル(1)

  • SKILL.md16.4 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

Rembric Dashboard UI

Reach for this skill whenever the user wants UI work on the Rembric dashboard (/dashboard/*). The dashboard is a Next.js App Router + React 19 surface styled with Tailwind v4 and shadcn/Radix primitives. It is no longer the Hono/HTMX/SSR-helper stack the old version of this skill described — there is no src/dashboard/, dashboard-router.ts, components.ts, or templates.ts.

Trigger

Auto-trigger when the user asks for:

  • A new dashboard page, route, or view
  • Edits to an existing dashboard page (memories, sessions, entities, judgments, consolidation, prompts, projects, tokens, maintenance, settings, activity, overview, login, OAuth consent)
  • New visual components (cards, pills, buttons, banners, modals)
  • Mobile / responsive tweaks
  • New destructive actions that need confirmation
  • New tables, filters, paginators
  • Anything that mentions: lime, zinc, command bar, StatusPill, data-table, hl-lime, ConfirmSubmit, ActionForm, Time

Do NOT trigger for:

  • Server / service / DB / MCP / consolidation backend work
  • OpenSpec change scaffolding (use the openspec-* skills for that)
  • Plugin / hook / CLI / apps/plugin/ work

The surface, verified

apps/web/src/app/dashboard/layout.tsx          CommandFrame wrapper (command bar, counters, version)
apps/web/src/app/dashboard/**/page.tsx         one async server component per route
apps/web/src/components/dashboard/command-bar.tsx  CommandFrame + floating CommandBar (no sidebar)
apps/web/src/components/dashboard/sessions-table.tsx  canonical Spectrum data-table usage
apps/web/src/components/dashboard/ui.tsx       StatusPill (canonical) + LEGACY primitives
apps/web/src/components/spectrumui/data-table.tsx   the shared list-view table engine
apps/web/src/components/dashboard/filters.tsx   LEGACY FilterForm/Field/Input/Select/Actions + Pager
apps/web/src/components/dashboard/action-form.tsx   ActionForm + useActionFormId
apps/web/src/components/dashboard/csrf-field.tsx    CsrfField
apps/web/src/components/dashboard/confirm-submit.tsx ConfirmSubmit (AlertDialog ↔ form)
apps/web/src/components/dashboard/app-sidebar.tsx   LEGACY Sidebar rail (only updaterReadState is live)
apps/web/src/components/dashboard/time.tsx      Time (client, UTC fallback → viewer TZ)
apps/web/src/components/dashboard/support.ts    PAGE_SIZE, queryWithPage, relativeTime, …
apps/web/src/components/dashboard/{markdown-panel,nav-user,site-header}.tsx
apps/web/src/components/ui/*                    shadcn primitives (alert-dialog, button, table, …)
apps/web/src/app/layout.tsx                     Geist / Geist Mono localFont wiring (--font-geist*)
apps/web/src/app/fonts/                         self-hosted Geist + Geist Mono woff2
apps/web/src/app/globals.css                    Tailwind v4 theme + design tokens
apps/web/src/lib/nav.ts                         NAV / NAV_GROUPS / navEntryForPath / CHROME_FREE_PATHS
apps/web/src/lib/utils.ts                       cn()
apps/web/src/test/dashboard/*.test.tsx          per-page tests

Pages are async server components. searchParams is a Promise in this Next.js version — const params = await searchParams before reading. Data comes from getServices() (@/lib/services) — const { repos, ... } = getServices().

Identity

The dashboard was redesigned to a dark monochrome zinc system with the Rembric lime as the single accent. apps/web/src/app/globals.css is the live token surface, mapped into Tailwind via @theme inline so utilities like bg-background, bg-card, bg-popover, text-foreground, text-muted-foreground, border-border, bg-primary, text-warn, text-destructive resolve to the tokens.

  • Surfaces (dark monochrome zinc). Background #09090b; cards #101012; raised / popover / muted / secondary #18181b; accent #1c1c1f; borders #1f1f23 (1px); input #27272a; ring #3f3f46. Text ladder: #fafafa (--foreground) → #a1a1aa → #71717a (--muted-foreground).
  • Lime is the ONLY accent. --primary: #c6f24e, --primary-foreground: #09090b. Primary buttons are lime fill + near-black text. On light surfaces lime is chrome only (fills, borders, dots, bars) — never lime text on a light background. Amber --warn: #ff8c00 and --destructive stay for warn / danger tones; charts use the zinc ladder with lime as --chart-1.
  • Fonts. UI and display output use Geist (--font-geist, wired to --font-sans / --font-display). Geist Mono (--font-geist-mono, --font-mono) owns labels, meta, counters and tabular data. Both are self-hosted woff2 in apps/web/src/app/fonts/ and loaded in apps/web/src/app/layout.tsx. No CDN fonts, no second display face.
  • Radius & depth. Radius --radius: 1rem: cards rounded-2xl (16), inputs rounded-xl (12), buttons rounded-lg (10). Soft shadows only (shadow-lg shadow-black/20–shadow-black/40). Depth comes from radial lime glows — e.g. bg-[radial-gradient(640px_260px_at_50%_-60px,rgba(198,242,78,0.09),transparent_70%)] — instead of heavy borders.
  • StatusPill (ui.tsx) is the shared app-wide status pill: a rounded-full container with a dot plus a tinted background/border per tone (TONE_PILL), driven by the STATUS_TONE map (active/judged → lime, abandoned/superseded → amber, archived/ended/pending → dim, orphaned/deleted → danger). Use it for status, never a hand-rolled badge.
  • List views: Spectrum UI data-table. Every list/table page goes through DataTable from @/components/spectrumui/data-table (variant "panel"): quick-filter pills with live counts, client search, selectable rows with a rising bulk-action bar, contextual ⋯ row menu, and a detail disclosure. apps/web/src/components/dashboard/sessions-table.tsx is the canonical implementation to copy from — see also judgments-table.tsx, prompts-table.tsx, memories-table.tsx, entities-table.tsx, tokens-table.tsx.
  • Charts. activity-chart.tsx is the reference for lime/zinc bar visuals: lime for saves, amber for superseded/archived ops, rounded caps, hover tooltips on bg-popover with soft shadow-black/40.
  • Shell: floating command bar, no sidebar. command-bar.tsx renders a floating centered header (rounded-2xl border bg-card/90 backdrop-blur) with primary nav, a "More" dropdown, counters and a mobile Sheet. There is no sidebar rail. /dashboard/login and /dashboard/oauth-consent are chrome-free standalone screens — CHROME_FREE_PATHS in apps/web/src/lib/nav.ts plus isChromeFreePath() short-circuit the frame.

Pending OpenSpec change

The formal OpenSpec dashboard spec update for this identity is pending (branch feat/dashboard-identity-redesign). Until it is written and merged, the LIVE reference is the branch code — sessions-table.tsx, command-bar.tsx, activity-chart.tsx, ui.tsx and globals.css — not the old spec text or DESIGN.md, whose prose still describes the previous brutalist identity. Do not touch openspec/specs/dashboard/spec.md or archived change design.md files from UI work; that is a separate task.

Legacy primitives (do NOT use for new work)

The old brutalist primitives are still exported from ui.tsx and remain in unrestyled pages (consolidation, maintenance, and several detail pages) pending migration. Marked LEGACY; do not document or copy them as the standard: ViewHead, SectionBar, StatCard/StatGrid, Kv/KvGrid, Panel/PanelHead, DataTable/DataHead/DataTh/DataBody/DataTr/DataTd, TableEmpty, Pill/ReviewPill/Chip/Tag, Bar, Notice, Flash. The hard-bordered Pill and the ViewHead lime-block title belong to the old identity. filters.tsx (FilterForm/Pager) and the app-sidebar.tsx rail are legacy too — list pages now use the Spectrum data-table's own toolbar and pagination. When you restyle a legacy page, replace these with the new identity, not with another legacy primitive.

Hard rules

  • New list views use the Spectrum DataTable. Import DataTable/DataTableColumn from @/components/spectrumui/data-table, pass variant="panel", and mirror sessions-table.tsx: searchable, quickFilter, selectable + bulkActions, rowActions (the ⋯ menu), renderDetail, pageSize. Do not hand-roll a table and do not reach for the legacy DataTable from ui.tsx.
  • Use StatusPill for status. One pill, tone-driven, app-wide. Don't invent a second status badge.
  • Every mutation is a server action through ActionForm. Import ActionForm/ActionState from @/components/dashboard/action-form, put a <CsrfField form={FORM_NAME} /> in it, and start the action by calling guardAction(formData, FORM_NAME)/guardFailure(...) from @/lib/actions/guard (session + admin + CSRF gate). The action returns { error: string | null }.
  • Destructive actions MUST use ConfirmSubmit. It wires a Radix AlertDialog to the enclosing ActionForm via useActionFormId, so it only works inside an ActionForm, wrapping the trigger button (<Button type="button">). Pass tone="danger" for irreversible actions, "warn" for reversible ones. Mirror the call sites in sessions-table.tsx (row ⋯ menu + bulk bar) and under apps/web/src/app/dashboard/.
  • Timestamps go through <Time>. It emits <time dateTime data-rembric-ts> with a UTC fallback and re-renders in the viewer's timezone after mount. Never hand-write toISOString / toLocaleString in views.
  • Nav lives in apps/web/src/lib/nav.ts. Add entries to the NAV array (group, num, label, href, lucide icon, optional badgeKey); the command bar and its mobile sheet both read it. Chrome-free screens are listed in CHROME_FREE_PATHS in the same file.
  • export const dynamic = 'force-dynamic' on dashboard routes/layouts — the dashboard reads per-request session + DB state.
  • No new CSS files and no inline <style>. Style with Tailwind utilities bound to the tokens in globals.css.
  • PAGE_SIZE (from support.ts) stays the single page size for paginated data queries — import it, never hard-code a second one. The Spectrum table's pageSize prop controls rows per page in the client.

Recipes

  • Add a new page — create apps/web/src/app/dashboard/<name>/page.tsx (an async server component with export const dynamic = 'force-dynamic'), compose it from the new identity (Spectrum DataTable for lists, StatusPill for status), add the nav entry in apps/web/src/lib/nav.ts, and add a co-located test in apps/web/src/test/dashboard/.
  • Filterable listing — a <DataTable> with searchable, quickFilter (pills keyed on the status column), selectable + bulkActions, rowActions for the ⋯ menu, and pageSize. Copy sessions-table.tsx verbatim, then swap the columns.
  • Destructive action — server action (guardAction + verifyCsrf) inside an <ActionForm>, <CsrfField>, and a <ConfirmSubmit tone="warn|danger" title=… description=… confirmLabel=…> wrapping a type="button" trigger.
  • Row navigation — the ⋯ menu carries "View details" as a next/link; there is no data-href/ROW_LINK script anymore.
  • Chrome-free screen — if a route must render without the command bar, add it to CHROME_FREE_PATHS in lib/nav.ts; CommandFrame short-circuits on isChromeFreePath().

Quick reference: helper signatures

// spectrumui/data-table.tsx (canonical for list views)
DataTable<T>({
  data, columns, rowId, rowLabel,
  variant?: 'default'|'bordered'|'striped'|'minimal'|'panel', density,
  searchable?, searchPlaceholder?, searchText?,
  quickFilter?: { columnId, label?, getValue?, options?, allLabel? },
  selectable?, bulkActions?: (ctx) => ReactNode,
  renderDetail?: (row) => ReactNode, rowActions?: (row, actions) => ReactNode,
  onDelete?, pageSize?, emptyState?, totals?, stickyHeader?, …
})
DataTableColumn<T>({ id, header, cell?, value?, sortable?, numeric?, hideBelow?, … })

// ui.tsx — LIVE
StatusPill({ status })   Time({ value, className? })   LABEL

// ui.tsx — LEGACY (unrestyled pages only), see Legacy primitives above
ViewHead({ num?, title, hl?, meta?, titleVisible? })   BackLink({ href, label })
SectionBar({ name, meta?, more? })   StatCard / StatGrid   Kv / KvGrid
Panel / PanelHead   DataTable / DataHead / DataTh / DataBody / DataTr / DataTd
TableEmpty   Pill / ReviewPill / Chip / Tag / Bar / Notice / Flash

// filters.tsx — LEGACY
FilterForm({ action, children, className? })   FilterField / FilterInput / FilterSelect
FilterActions({ clearHref })   Pager({ page, hasMore, total, totalLabel, path, query })

// action-form.tsx
ActionForm({ action, children, className? })   // action: FormAction
useActionFormId()   ActionState = { error: string | null }

Files you will most likely touch

apps/web/src/app/dashboard/<view>/page.tsx        server component route
apps/web/src/app/dashboard/layout.tsx             CommandFrame wrapper
apps/web/src/components/dashboard/<view>-table.tsx  Spectrum data-table (copy sessions-table.tsx)
apps/web/src/components/dashboard/command-bar.tsx shared shell / nav (floating, no sidebar)
apps/web/src/components/dashboard/ui.tsx          StatusPill (live) + legacy primitives
apps/web/src/components/dashboard/confirm-submit.tsx / action-form.tsx / csrf-field.tsx
apps/web/src/lib/nav.ts                           NAV array + CHROME_FREE_PATHS
apps/web/src/app/globals.css                      design tokens (Tailwind v4 theme)
apps/web/src/app/layout.tsx                       Geist / Geist Mono localFont wiring
apps/web/src/test/dashboard/<view>.test.tsx       co-located page test

Build, test, validate

After any change:

pnpm run typecheck   # tsc --noEmit, must be clean
pnpm run lint        # ESLint, must be clean
pnpm test            # turbo test across workspaces, must stay green
pnpm run build       # next build

Dashboard component tests are Vitest + Testing Library under apps/web/src/test/dashboard/*.test.tsx; run one file with pnpm --filter @rembric/web exec vitest run src/test/dashboard/<name>.test.tsx.

For visual verification, bring up the host dev server (see docs/docker.md → "Local dev (host)"):

REMBRIC_DATA_DIR=./data-dev REMBRIC_ADMIN_TOKEN=<16+-char-token> pnpm run dev
# → http://127.0.0.1:3000/dashboard

next dev hot-reloads, so there is no build-and-restart step. Point a fresh REMBRIC_DATA_DIR at a scratch directory; never aim a dev server at a real deployment's database.

When to ask vs proceed

Proceed without asking when the change is mechanical and matches an existing pattern (e.g. new column on a data-table, new StatusPill status mapping, new destructive row action, new responsive tweak).

Ask the user first when:

  • The change introduces a new colour, font face, or radius (a token change). The new identity is not yet locked by an OpenSpec spec — the formal dashboard spec update is pending on feat/dashboard-identity-redesign — so token edits need an agreed OpenSpec change rather than a drive-by.
  • The change adds a new top-level nav item (affects the NAV array / command-bar order and the mobile sheet).
  • The change touches behaviour: pagination model, modal flow, mobile sheet behaviour.
  • The change would add a new runtime dependency or client-side framework.
  • The user's request is ambiguous about destructive vs. reversible tone (warn vs danger is a semantic decision).

Validation checklist before "done"

  1. pnpm run typecheck → clean
  2. pnpm run lint → clean
  3. pnpm test → all green
  4. pnpm run build → succeeds
  5. Visual smoke at the affected page in the host dev server, at desktop + narrow viewports
  6. If a destructive action was added: the dialog opens with the correct tone, Cancel doesn't submit, Confirm does

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

diagnose

無料

Disciplined diagnosis loop for hard bugs and performance regressions. Reproduce → minimise → hypothesise → instrument → fix → regression-test. Use when user says "diagnose this" / "debug this", reports a bug, says something is broken/throwing/failing, or describes a performance regression.

日本語の概要は準備中です。原文の説明を表示しています。

susomejias/rembric132026年10月13日 更新

Helps users discover and install agent skills when they ask questions like "how do I do X", "find a skill for X", "is there a skill that can...", or express interest in extending capabilities. This skill should be used when the user is looking for functionality that might exist as an installable skill.

日本語の概要は準備中です。原文の説明を表示しています。

susomejias/rembric132026年10月13日 更新

Find deepening opportunities in a codebase, informed by the project's own domain language and prior design decisions. Use when the user wants to improve architecture, find refactoring opportunities, consolidate tightly-coupled modules, or make a codebase more testable and AI-navigable.

日本語の概要は準備中です。原文の説明を表示しています。

susomejias/rembric132026年10月13日 更新

Resolve a verified cluster of Rembric issues from causal root to evidence-gated closure. Use after systemic triage identifies a shared root, or when the user asks to attack issues at the root, create a mechanism map, plan a deletion-first fix, or close a fixed/stale issue cluster. Use `diagnose` for a single defect whose reproduction is not yet established.

日本語の概要は準備中です。原文の説明を表示しています。

susomejias/rembric132026年10月13日 更新

Guide for creating high-quality MCP (Model Context Protocol) servers that enable LLMs to interact with external services through well-designed tools. Use when building MCP servers to integrate external APIs or services, whether in Python (FastMCP) or Node/TypeScript (MCP SDK).

日本語の概要は準備中です。原文の説明を表示しています。

susomejias/rembric132026年10月13日 更新

Migrates React projects and components from Radix UI to Base UI. Use when asked to migrate from radix, move to base-ui, convert radix primitives, or switch a shadcn project's base library. Handles single components ("migrate accordion") and whole projects.

日本語の概要は準備中です。原文の説明を表示しています。

susomejias/rembric132026年10月13日 更新

susomejias のスキルをすべて見る

このスキルの問題を報告する