# Rahman Resources > Reusable Next.js + Convex + shadcn vertical-slice catalog. Copy-first. Production-grade. Site: https://resource.rahmanef.com Repo: https://github.com/rahmanef63/resource-site Author: Rahman (https://rahmanef.com) ## Stack - [Next.js 16](https://nextjs.org/docs) - [React 19](https://react.dev) - [TypeScript 5.6](https://www.typescriptlang.org) - [Tailwind CSS 4](https://tailwindcss.com) - [shadcn/ui](https://ui.shadcn.com) - [Convex (self-hosted)](https://docs.convex.dev/self-hosting) - [@convex-dev/auth](https://labs.convex.dev/auth) - [Dokploy](https://dokploy.com) - [Radix UI](https://www.radix-ui.com) - [Lucide Icons](https://lucide.dev) ## What's in the box - **Vertical-Slice Architecture**: Each feature owns its config, page, views, components, settings, agent, and Convex mirror. Add or remove a feature by adding or removing one folder. - **Copy-First Flow**: Never greenfield. Every artifact comes from a proven source project (internal kitab-core, rahmanef.com, cescadesigns, notion-clone). Edit imports, ship. - **shadcn-only UI**: All components are shadcn primitives or composed from them. ResponsiveDialog, DateField, FileUpload — no raw HTML buttons or dialogs. - **audit-bp Gated**: Best-practice auditor pulls latest Next 16 / React 19 / Convex docs via Context7 before scoring. Score ≥80 to ship. - **Dokploy in One Command**: si-coder skill creates the GitHub repo, pushes, configures Dokploy, sets DNS, and triggers deploy. Zero human involvement. - **Self-hosted Convex + @convex-dev/auth**: No Clerk. Self-hosted Convex backend in the same docker-compose. Postgres-backed for prod. - **Auto-generated Slice Docs**: Per-slice DEPS.md, CONTRACT.md, STATUS.md, USAGE.md generated from imports + defineFeature config. - **Cookbook + Recipes**: 8 layout variants and 8 feature drop-ins (block editor, command palette, db views, comments, ...) ready to mount. ## Layouts ## Slices Drop-in vertical features. Each ships the metadata pair (`slice.json`, with an embedded `contract` block, + `slice.manifest.json`). Install with `npx rr add ` — CLI auto-augments env, installs deps, and copies into `frontend/slices//` (+ optional `convex/features//`). ### Image Editor — layered raster editor - slug: `image-editor` kind: `ui` category: `os` - A Photoshop-style raster image editor built on Konva. Layers panel (reorder, opacity, visibility, lock, 16 blend modes), free transform (move/scale/rotate/flip via a Transformer), image + text + shape + paint layers, brush & eraser with size/opacity/hardness, non-destructive adjustments + filters, canvas resize/aspect presets, and LAYER STYLES: stroke, drop shadow, outer glow, clipping mask. One-click BACKGROUND REMOVAL runs fully in-browser via @imgly/background-removal (free, no API key — downloads a small ONNX model on first use). Undo/redo, zoom/pan, shortcuts, PNG/JPG/WebP export. v2 adds an AI FUNCTION-CALLING layer: every editor operation is a named, schema'd command (EDITOR_COMMANDS registry + useEditorCommands binding) driven by an in-editor chat; the streaming bridge is injectable via configureAgentStream(fn) and everything except the chat works without it. A headless server barrel (server.ts) runs commands against documents with no DOM. Image I/O via props (initialImage / onSave). - install: `npx rr add image-editor` - detail: https://resource.rahmanef.com/slices/image-editor - prompt: https://resource.rahmanef.com/agents/image-editor - agent recipe: Stack: Next 16 + React 19 + Tailwind 4 + shadcn/ui + Konva. A layered raster image editor. Image I/O is via props; background removal runs in-browser (no backend). STEP 1 — Install. `npx rr add image-editor`. Ensure `@/features/image-editor` resolves in tsconfig paths and Tailwind scans the slice folder. STEP 2 — Deps. npm: `konva react-konva @imgly/background-removal lucide-react`. shadcn: `npx shadcn@latest add button input slider select tabs scroll-area separator tooltip label switch popover`. STEP 3 — Mount. It is fully self-contained; the Konva stage is loaded client-only (next/dynamic ssr:false) inside the slice, so just render it in a height-bearing box: ```tsx "use client"; import { ImageEditor } from "@/features/image-editor"; export default function Page() { return (
console.log(dataUrl)} />
); } ``` Props: `initialImage?` (data/object/remote URL opened on mount), `width?`/`height?` (blank canvas size, default 1080²), `onSave?(dataUrl)` (fires from the Save button with a PNG data URL; omit to hide Save), `className?`. STEP 4 — Background removal. The "Remove BG" button calls removeImageBackground() from @imgly/background-removal — free, in-browser, no key. First run downloads a small model to the browser cache, then runs locally via WASM. You can also import `removeImageBackground(src) => Promise` directly. STEP 5 — Export. PNG/JPG/WebP at 1×/2×/3× via the Export tab, or call `exportStage(stage, {...})` / `stageToDataURL(stage, {...})`. The container owns the box — render inside h-dvh / h-full. ### Reel — video timeline editor - slug: `reel-editor` kind: `ui` category: `os` - A complete in-browser video editor. Real media clips (image/video/audio) on a layered multi-track timeline — the top row renders frontmost, with ▲▼ reorder and per-track lock/hide/mute. ONE Canvas-2D draw path is shared by the live preview and the realtime MediaRecorder exporter, so what you see is exactly what renders (WebM with real mixed audio: per-clip volume/fades/auto-duck through a streaming audio graph). Per-clip trim/speed (0.25–4×)/reverse, dissolve/wipe/slide transitions via clip overlap, keyframes (opacity/scale/x/y/rotation) with easing + one-click In/Out animation presets, text styling with preset grid, color grading + vignette, filmstrip thumbnails + real waveforms, snapping, split/duplicate. The workspace is config-driven: 6 resizable layout presets (react-resizable-panels v4) incl. quick-import files-pane layouts, plus custom composition size. Drafts auto-save to localStorage. Self-contained: toasts via sonner, the files pane runs on an injectable fs adapter (configureReelFs; in-memory mock by default), and shell hooks (inspector/activity) are inert seams in lib/host.ts. - install: `npx rr add reel-editor` - detail: https://resource.rahmanef.com/slices/reel-editor - prompt: https://resource.rahmanef.com/agents/reel-editor - agent recipe: Stack: Next 16 + React 19 + Tailwind 4 + shadcn/ui. An in-browser video timeline editor with realtime WebM export. Fully client-side; no backend required. STEP 1 — Install. `npx rr add reel-editor`. Ensure `@/features/reel-editor` resolves in tsconfig paths and Tailwind scans the slice folder. STEP 2 — Deps. npm: `lucide-react react-resizable-panels sonner`. shadcn: `npx shadcn@latest add button input slider tooltip dialog dropdown-menu resizable sheet sonner`. Mount `` (sonner) once in your root layout. STEP 3 — Mount. Render in a height-bearing box: ```tsx "use client"; import { ReelEditor } from "@/features/reel-editor"; export default function Page() { return
; } ``` Or register the `reelEditorApp` descriptor in an appshell manifest for windowed hosts. STEP 4 — Files pane backend (optional). The quick-import pane ships with an in-memory mock. Wire a real filesystem with `configureReelFs({ list, mkdir, rawUrl })` — list/mkdir mirror a simple fs API, rawUrl resolves a listed path to a fetchable media URL. STEP 5 — Export. The Render button records the live canvas + mixed audio to WebM via MediaRecorder in realtime (duration = composition length). Users can also import local media via the file picker — object URLs, no upload needed. ### Preview — media quick-look - slug: `media-viewer` kind: `ui` category: `os` - A quick-look media viewer in the macOS Preview spirit. Images render on a zoomable (40–300%) checkerboard stage so transparency reads; audio gets a card player with a CSS-bar waveform + transport; video gets play/pause + scrubber + volume; PDFs embed full-bleed and text gets a simple surface. The toolbar carries a type-indicator chip, zoom, Download, Open-in-editor, and prev/next. Two integration seams in lib/host.ts make it portable: configureMediaSource maps fs paths to fetchable URLs (identity by default, so public URLs work with zero wiring) and configureMediaOpener routes the Open-in-editor handoff (image → image-editor, video/audio → reel-editor) to your shell — both inert until set. Launched bare it shows a fully offline sample gallery (inline SVG gradients, simulated A/V playback). Pairs with file-explorer (onOpenFile → MediaViewer payload) and the editors. - install: `npx rr add media-viewer` - detail: https://resource.rahmanef.com/slices/media-viewer - prompt: https://resource.rahmanef.com/agents/media-viewer - agent recipe: Stack: Next 16 + React 19 + Tailwind 4 + shadcn/ui. A quick-look media viewer (image/video/audio/pdf/text). Fully client-side; no backend required. STEP 1 — Install. `npx rr add media-viewer`. Ensure `@/features/media-viewer` resolves in tsconfig paths and Tailwind scans the slice folder. STEP 2 — Deps. npm: `lucide-react`. shadcn: `npx shadcn@latest add button badge separator tooltip slider`. STEP 3 — Mount. `` with no payload shows the offline sample gallery. Pass a file to view it: ```tsx "use client"; import { MediaViewer } from "@/features/media-viewer"; export default function Page() { return
; } ``` Or register the `mediaViewerApp` descriptor in an appshell manifest for windowed hosts. STEP 4 — Remote files (optional). Paths resolve through `configureMediaSource({ rawUrl })` — identity by default, so public/absolute URLs already work. Point rawUrl at your fs endpoint for private files. STEP 5 — Editor handoff (optional). `configureMediaOpener((appId, title, size, payload) => …)` routes the "Open in Image/Video Editor" actions to your shell (no-op until set). Wire it to openWindow when running inside appshell with image-editor / reel-editor installed. ### Code — overlay syntax editor - slug: `code-editor` kind: `ui` category: `os` - A lightweight code editor in the VS-Code spirit without the weight: a transparent textarea layered over a highlighted pre (regex tokenizer for JS/TS/JSON/CSS) gives real editing with live syntax color and a line-number gutter; a tab strip tracks dirty buffers with Cmd/Ctrl+S save; a status bar shows path, Ln/Col, tab size, language and save state. The explorer is a lazy per-directory tree — each folder lists on expand, with inline new-file/new-folder affordances — rendered as a rail on desktop and a Sheet on mobile, and the new-file form is a responsive dialog ⇄ bottom drawer. The filesystem is INJECTED via a small CodeFsAdapter (list/read/write/mkdir): point configureCodeFs at a real API or use the bundled writable in-memory mock (seeded sample tree) so it works with zero backend. Writes are best-effort — a read-only host flags the save but keeps the local buffer. Pairs with file-explorer (onOpenFile → payload) and appshell. - install: `npx rr add code-editor` - detail: https://resource.rahmanef.com/slices/code-editor - prompt: https://resource.rahmanef.com/agents/code-editor - agent recipe: Stack: Next 16 + React 19 + Tailwind 4 + shadcn/ui. A lightweight overlay-highlighting code editor with a lazy explorer tree. Fully client-side; no backend required. STEP 1 — Install. `npx rr add code-editor`. Ensure `@/features/code-editor` resolves in tsconfig paths and Tailwind scans the slice folder. STEP 2 — Deps. npm: `lucide-react`. shadcn: `npx shadcn@latest add button badge input scroll-area sheet dialog`. STEP 3 — Mount. `` opens the seeded sample tree (writable in-memory mock). Open a specific file with a payload: ```tsx "use client"; import { CodeEditor } from "@/features/code-editor"; export default function Page() { return
; } ``` Or register the `codeEditorApp` descriptor in an appshell manifest for windowed hosts. STEP 4 — Real filesystem (optional). `configureCodeFs({ list, read, write, mkdir })` — list returns { path, entries: [{ name, kind }] } for ONE directory (the tree fetches per expand), read returns the file body, write/mkdir mutate. Writes are best-effort: on failure the editor keeps the local buffer and flags the status bar. STEP 5 — Cross-app open. From a file manager (e.g. the file-explorer slice), wire onOpenFile to re-render CodeEditor with payload={{ path }} — the editor adds a tab and hydrates the buffer. ### System Monitor — host telemetry dashboard - slug: `system-monitor` kind: `ui` category: `os` - An Activity-Monitor-style dashboard: circular CPU/RAM/disk/GPU gauges, rolling CPU + network sparklines on glass panels, and a live process table — polling every 1.5s with a ~40-point history. Telemetry is INJECTED via a small SysMonAdapter (stats/processes): point configureSysmon at a real host API (/proc, an agent, a cloud endpoint) or keep the bundled wavy in-browser mock so the dashboard renders alive with zero backend. Self-contained: shell inspector hooks are inert seams in lib/host.ts. - install: `npx rr add system-monitor` - detail: https://resource.rahmanef.com/slices/system-monitor - prompt: https://resource.rahmanef.com/agents/system-monitor - agent recipe: Stack: Next 16 + React 19 + Tailwind 4 + shadcn/ui. Host telemetry dashboard. Fully client-side; no backend required. STEP 1 — Install. `npx rr add system-monitor`. Ensure `@/features/system-monitor` resolves and Tailwind scans the slice folder. STEP 2 — Deps. npm: `lucide-react`. shadcn: `npx shadcn@latest add scroll-area`. STEP 3 — Mount. `` in a height-bearing box — unwired it runs a wavy in-browser telemetry mock. Or register `systemMonitorApp` in an appshell manifest. STEP 4 — Real telemetry. `configureSysmon({ mode:"live", stats, processes })` — stats returns { cpu:{pct,cores}, mem:{used,total}, disk:{used,total}, net?:{rx,tx}, uptime }; processes returns [{ pid, name, status, cpu, mem }]. ### Booking — session request form + owner inbox - slug: `booking` kind: `ui` category: `os` - One app that is BOTH a public 'book a session' request form AND the owner's triage inbox — it flips to show the inbox when the viewer can manage. Visitors submit name/email/topic (+ optional preferred time / note); the owner sees pending requests with Confirm / Decline. The backend is INJECTED via a small BookingAdapter (submit/list/setStatus/canManage): point configureBooking at your store, or keep the bundled in-memory mock so it renders fully interactive — form + inbox — with zero backend. - install: `npx rr add booking` - detail: https://resource.rahmanef.com/slices/booking - prompt: https://resource.rahmanef.com/agents/booking - agent recipe: Stack: Next 16 + React 19 + Tailwind 4 + shadcn/ui. A booking request form + owner inbox. Fully client-side; backend optional. STEP 1 — Install. `npx rr add booking`. Ensure `@/features/booking` resolves and Tailwind scans the slice folder. STEP 2 — Deps. npm: `lucide-react`. shadcn: `npx shadcn@latest add button input textarea scroll-area`. STEP 3 — Mount. `` in a height-bearing box — unwired it runs on an in-memory mock store (form + inbox both live). Or register `bookingApp` in an appshell manifest. STEP 4 — Real backend. `configureBooking({ mode:"live", submit, list, setStatus, canManage })` — submit takes { name, email, topic, preferredTime?, note? }; list returns rows with { id, status, createdAt }; omit list/canManage for a write-only public form. ### HTML Studio — sandboxed HTML/CSS/JS editor with live preview - slug: `html-studio` kind: `ui` category: `os` - A tiny web-page studio: write HTML / CSS / JS and see it render LIVE in a sandboxed iframe (srcdoc + sandbox=allow-scripts WITHOUT allow-same-origin, so user code runs in an opaque origin and cannot read the host) — then Save to a shareable /p/. Code / Split / Preview view toggle, a device-width preview (responsive / tablet / phone), a saved-pages rail, and public/private visibility. The backend is INJECTED via a small HtmlStudioAdapter (save/load/list/remove): point configureHtmlStudio at your store, or keep the bundled in-memory mock so the editor + live preview + saved list are fully interactive with zero backend. - install: `npx rr add html-studio` - detail: https://resource.rahmanef.com/slices/html-studio - prompt: https://resource.rahmanef.com/agents/html-studio - agent recipe: Stack: Next 16 + React 19 + Tailwind 4 + shadcn/ui. A sandboxed HTML/CSS/JS studio: editor + live iframe preview + saved pages. Fully client-side; backend optional. STEP 1 — Install. `npx rr add html-studio`. Ensure `@/features/html-studio` resolves and Tailwind scans the slice folder. STEP 2 — Deps. npm: `lucide-react`. shadcn: `npx shadcn@latest add button input textarea scroll-area`. STEP 3 — Mount. `` in a height-bearing box — unwired it runs on an in-memory mock (editor + live sandboxed preview + saved list all live). Pass `payload={{ slug }}` to open a page, or register `htmlStudioApp` in an appshell manifest. STEP 4 — Real backend. `configureHtmlStudio({ mode:"live", save, load, list, remove })` — save takes { slug?, title, html, visibility } and returns { slug }; load(slug) -> SavedPage | null; omit save for a read-only sandbox or list to hide the saved rail. KEEP the iframe sandbox without allow-same-origin — it is the security boundary. ### Resources Admin — curated icon-launcher CRUD - slug: `resources-launcher-admin` kind: `ui` category: `os` - An owner-gated admin app for a curated icon-launcher: add / edit / remove / reorder links (label, lucide icon NAME, url, group, order) that open in a new tab. The backend is INJECTED via a small ResourcesAdapter (list/upsert/remove/canManage): point configureResources at your store, or keep the bundled in-memory mock so the whole CRUD — including reorder — is interactive with zero backend. Icons are stored as lucide NAME strings and resolved client-side, so the same data drives a public launcher surface. - install: `npx rr add resources-launcher-admin` - detail: https://resource.rahmanef.com/slices/resources-launcher-admin - prompt: https://resource.rahmanef.com/agents/resources-launcher-admin - agent recipe: Stack: Next 16 + React 19 + Tailwind 4 + shadcn/ui. A curated icon-launcher admin (CRUD + reorder). Fully client-side; backend optional. STEP 1 — Install. `npx rr add resources-launcher-admin`. Ensure `@/features/resources-launcher-admin` resolves and Tailwind scans the slice folder. STEP 2 — Deps. npm: `lucide-react`. shadcn: `npx shadcn@latest add button input label scroll-area native-select`. STEP 3 — Mount. `` in a height-bearing box — unwired it runs on an in-memory mock store (add / edit / remove / reorder all live). Or register `resourcesAdminApp` in an appshell manifest. STEP 4 — Real backend. `configureResources({ mode:"live", list, upsert, remove, canManage })` — list returns rows { id, label, icon, url, group, order }; upsert takes the same minus id to insert (pass id to patch); canManage gates the editor + reorder. Icons are lucide NAME strings resolved via resolveIcon. ### Profile — CV + identity card - slug: `profile` kind: `ui` category: `os` - One owner's identity in two co-located variants, behind one slug. resume: a clean one-column résumé / CV — name, roles, location, contacts, summary, skills, experience (role · org · period + bullets), projects — rendered by off a configureResume() seam, with a Print / PDF button. card: an "About This Mac"-style identity card — avatar / monogram, name, roles, outbound links, FAQ accordion — rendered by off a configureAbout() seam. Both render a populated placeholder unwired (zero backend). Install one surface with `npx rr add profile resume|card`, or both with `npx rr add profile`. - install: `npx rr add profile` - detail: https://resource.rahmanef.com/slices/profile - prompt: https://resource.rahmanef.com/agents/profile - agent recipe: Stack: Next 16 + React 19 + Tailwind 4 + shadcn/ui. Two identity renderers driven by injected data. Fully client-side; no backend required. STEP 1 — Install. `npx rr add profile` for both, or `npx rr add profile resume` / `card` for one. Ensure `@/features/profile` resolves and Tailwind scans the slice folder. STEP 2 — Deps. npm: `lucide-react`. shadcn: `npx shadcn@latest add button scroll-area avatar`. STEP 3 — Mount. `` (CV) or `` (card) in a height-bearing box — unwired each renders a generic placeholder. Or register `resumeApp` / `aboutProfileApp` in an appshell manifest. STEP 4 — Real data. `configureResume(profile)` with a ResumeProfile { name, roles[], location, summary, contacts[], skills[], experience[], projects[] }, and/or `configureAbout(card)` with { name, roles[], description, links[], faq[] }, once at boot from Convex / a CMS / a JSON file. Resume's "Print / PDF" button calls window.print() against a print-friendly layout. ### Start Here — guided OS onboarding tour - slug: `start-here` kind: `ui` category: `os` - A guided 'Start Here' tour that lays the OS out as a path of stages, each stage opening real apps from the LIVE registry — drift-proof, it reads the injected app catalog instead of a hardcoded list, so adding an app surfaces it automatically (in a stage if listed, else a final 'Everything else' bucket). The catalog, the open(id) callback, and the stage journey are INJECTED via a small StartHereAdapter (apps / open / stages): point configureStartHere at your live app registry + window opener, or keep the bundled in-memory mock (a few generic apps + 3 stages) so the welcome tour renders fully alive with zero host. - install: `npx rr add start-here` - detail: https://resource.rahmanef.com/slices/start-here - prompt: https://resource.rahmanef.com/agents/start-here - agent recipe: Stack: Next 16 + React 19 + Tailwind 4 + shadcn/ui. A guided onboarding tour that renders your live app catalog as a path of stages. Fully client-side; the catalog is injected. STEP 1 — Install. `npx rr add start-here`. Ensure `@/features/start-here` resolves and Tailwind scans the slice folder. STEP 2 — Deps. npm: `lucide-react`. shadcn: `npx shadcn@latest add button scroll-area`. STEP 3 — Mount. `` in a height-bearing box — unwired it reads an in-memory mock catalog (generic apps + 3 stages) so the tour is fully alive. Or register `startHereApp` in an appshell manifest. STEP 4 — Real catalog. `configureStartHere({ mode:"live", apps, open, stages })` — apps is your live registry as [{ id, title, icon, description? }]; open(id) launches the real app/window; stages is [{ title, blurb, appIds }] (apps not placed fall into a final "Everything else" stage). Drift-proof: read the registry, never hardcode the list. ### Terminal — shell emulator with live passthrough + PTY seam - slug: `os-terminal` kind: `ui` category: `os` - A React-DOM terminal: monospace glass aesthetic, colored prompt, arrow-key history, red stderr. Built-ins (ls·cd·pwd·cat·mkdir·touch·rm·mv·cp·echo·whoami·date·uname·df·ps·neofetch·help·clear) run against an in-memory FsModel, so it works with ZERO backend. Wire configureTerminal({ mode:"live", fs, exec }) and ls/cat read through your real filesystem, file mutations mirror to it, and any unknown command passes through exec.run as a one-shot shell call (stdout/stderr/exit rendered). Self-contained: shell inspector hooks are inert seams in lib/host.ts. - install: `npx rr add os-terminal` - detail: https://resource.rahmanef.com/slices/os-terminal - prompt: https://resource.rahmanef.com/agents/os-terminal - agent recipe: Stack: Next 16 + React 19 + Tailwind 4 + shadcn/ui. Shell emulator with optional live passthrough. Fully client-side by default. STEP 1 — Install. `npx rr add os-terminal`. Ensure `@/features/os-terminal` resolves and Tailwind scans the slice folder. STEP 2 — Deps. npm: `lucide-react`. No shadcn components required. STEP 3 — Mount. `` in a height-bearing box — mock mode runs entirely on the in-memory FsModel. Or register `osTerminalApp` in an appshell manifest. STEP 4 — Go live. `configureTerminal({ mode:"live", fs:{list,read,write,mkdir,remove,move,copy}, exec:{run} })`. In live mode ls/cat read through your fs, mutations mirror, and unknown commands hit exec.run (one-shot; treat the endpoint like SSH). ### Assistant — agent workspace with streaming chat - slug: `assistant` kind: `ui` category: `os` - A full agent workspace: streaming chat with typing deltas and graceful error notes, plus a library where users CREATE and manage agents (persona, avatar gradient, system prompt), skills, and automations (trigger + schedule forms) — all persisted in localStorage, no backend. Preset agents/skills ship as starting points. The model is INJECTED: configureAssistantStream takes any (messages) => AsyncIterable — your SSE endpoint, the AI SDK, an agent loop — and until wired a typing demo stream keeps the whole UI working offline. Self-contained: shell inspector hooks are inert seams in lib/host.ts. - install: `npx rr add assistant` - detail: https://resource.rahmanef.com/slices/assistant - prompt: https://resource.rahmanef.com/agents/assistant - agent recipe: Stack: Next 16 + React 19 + Tailwind 4 + shadcn/ui. Agent workspace with streaming chat. Fully client-side; model injected. STEP 1 — Install. `npx rr add assistant`. Ensure `@/features/assistant` resolves and Tailwind scans the slice folder. STEP 2 — Deps. npm: `lucide-react`. shadcn: `npx shadcn@latest add button input textarea tabs badge scroll-area dropdown-menu dialog select switch`. STEP 3 — Mount. `` in a height-bearing box. Unwired, a typing demo stream answers so the UI works offline; agents/skills/automations persist in localStorage. STEP 4 — Wire a model. `configureAssistantStream(async function* (messages) { ...yield text deltas... })` — SSE endpoint, AI SDK, or an agent loop. Throw Error("no_api_key") / Error("unauthorized") for the chat's friendly error notes. ### Browser — remote headless-browser chrome - slug: `browser` kind: `ui` category: `os` - Full browser chrome for a REMOTE headless browser: omnibar with search-or-URL detection, bookmark bar, history view (localStorage-persisted), favicons with globe fallback, busy states, and a screenshot viewport that forwards clicks/typing/keys/scroll into the remote page. The backend is INJECTED via a small BrowserAdapter (state/screenshot/act): point configureBrowser at a real headless-Chromium service (e.g. Playwright behind an authed route — any site renders, no X-Frame-Options problem) or keep the bundled offline canvas demo renderer that fakes the viewport so the whole chrome works with zero backend. Self-contained: shell inspector hooks are inert seams in lib/host.ts. - install: `npx rr add browser` - detail: https://resource.rahmanef.com/slices/browser - prompt: https://resource.rahmanef.com/agents/browser - agent recipe: Stack: Next 16 + React 19 + Tailwind 4 + shadcn/ui. Remote headless-browser chrome. Demo renderer by default; real backend injected. STEP 1 — Install. `npx rr add browser`. Ensure `@/features/browser` resolves and Tailwind scans the slice folder. STEP 2 — Deps. npm: `lucide-react`. shadcn: `npx shadcn@latest add button input badge dropdown-menu tooltip scroll-area`. STEP 3 — Mount. `` in a height-bearing box — unwired, an offline canvas demo renderer fakes the viewport (omnibar/bookmarks/history all work). Or register `browserApp` in an appshell manifest. STEP 4 — Real headless browser. `configureBrowser({ state, screenshot, act })` against a Playwright service: state → { url, title }; screenshot → PNG Blob; act(path, body) handles navigate|click|type|key|scroll|back|forward|reload. AUTH those routes — a remote browser holds logged-in sessions. ### App Store — install, create + toggle apps - slug: `app-store` kind: `ui` category: `os` - The dynamic half of an app registry, in two surfaces. AppStore: a storefront with featured hero, category sidebar, install/uninstall cards for a curated catalog, and toggles that disable built-in apps/shell features (the DISABLED set is persisted so new apps always ship enabled). CreateApp: build a custom app — name, glyph, accent gradient, runtime (html/node/python/shell), entry — with live manifest preview. Both write one localStorage registry; useInstalledApps() turns it into appshell-style descriptors (html apps mount in a sandboxed iframe, command apps in a terminal-style console). The console's shell is INJECTED via configureAppStoreExec (demo echo by default). Self-contained: inspector hooks are inert seams in lib/host.ts; the Create-App flow is bundled in (no cross-slice imports). - install: `npx rr add app-store` - detail: https://resource.rahmanef.com/slices/app-store - prompt: https://resource.rahmanef.com/agents/app-store - agent recipe: Stack: Next 16 + React 19 + Tailwind 4 + shadcn/ui. Storefront + Create-App over a localStorage app registry. Fully client-side. STEP 1 — Install. `npx rr add app-store`. Ensure `@/features/app-store` resolves and Tailwind scans the slice folder. STEP 2 — Deps. npm: `lucide-react`. shadcn: `npx shadcn@latest add button input badge separator scroll-area switch tooltip`. STEP 3 — Mount. `` (storefront) and/or `` (custom-app builder) — or register `appStoreApp` / `createAppApp` in an appshell manifest. STEP 4 — Feed your launcher. `useInstalledApps()` returns AppDescriptor[] for everything installed/created (html → sandboxed iframe, command → console); `useDisabledIds()` filters your built-in manifest. STEP 5 — Console exec (optional). `configureAppStoreExec({ mode:"live", exec:{run} })` so command/script apps run on a real one-shot shell (auth it like SSH). ### File Explorer — Tree + CRUD + Breadcrumb - slug: `file-explorer` kind: `full` category: `os` - A complete, portable file-directory explorer: a collapsible folder TREE sidebar (lazy-loaded per dir), a responsive BREADCRUMB that auto-collapses to a dropdown, grid + list views with sort, multi-select, a right-click context menu, drag-and-drop (internal move + external file/folder upload), inline rename, and full CRUD (new folder, rename, cut/copy/paste, move, delete/trash, empty trash). The filesystem backend is INJECTED via a small FileExplorerAdapter (list/mkdir/remove/move/copy/upload/usage/rawUrl) — point it at a real API or use the bundled createMockAdapter() (a writable in-memory tree) so it works with zero backend. Opening a file fires an onOpenFile(path, entry) callback you wire to your own viewer/editor. Self-contained: imports only @/components/ui/* + @/lib/utils. Ported from os-vps (Topside) files manager. Pairs with appshell as the file-dir counterpart to a notion-style sidebar. - install: `npx rr add file-explorer` - detail: https://resource.rahmanef.com/slices/file-explorer - prompt: https://resource.rahmanef.com/agents/file-explorer - agent recipe: Stack: Next 16 + React 19 + Tailwind 4 + shadcn/ui. The slice is self-contained — imports only @/components/ui/* + @/lib/utils (cn). The filesystem backend is injected; nothing is hardcoded. STEP 1 — Install. `npx rr add file-explorer`. Ensure `@/features/file-explorer` resolves in tsconfig paths and Tailwind's content globs scan the slice folder. STEP 2 — shadcn + npm. `npx shadcn@latest add button input scroll-area separator dropdown-menu sheet`. npm: lucide-react. STEP 3 — Mount it. Drop it in with NO adapter prop — it falls back to the backend configured in lib/backend.ts (the writable in-memory mock by default), so it works out of the box with realistic seed data and full CRUD: ```tsx "use client"; import { FileExplorer } from "@/features/file-explorer"; export default function Page() { return (
console.log("open", path)} />
); } ``` STEP 4 — The backend switch (ONE file). Go to a real filesystem without touching any component: edit `slices/file-explorer/lib/backend.ts` and set `FILE_EXPLORER_BACKEND = "mock" | "live" | "convex"` (or set env `NEXT_PUBLIC_FILE_EXPLORER_BACKEND`). "live" = REST host fs (os-vps /api/v1/fs shape, base via NEXT_PUBLIC_FILES_API_URL — see adapter/live.ts). "convex" = self-hosted Convex fs functions, PREPARED but inert until you wire your generated client + api in the switch (see adapter/convex.ts; the slice imports nothing from @convex so the build stays green even without Convex). You can still pass `adapter={…}` to override per-instance. STEP 5 — Custom adapter. Implement FileExplorerAdapter: { mode: "live"|"mock"|"readonly", list(path), mkdir(path), remove(path), move(from,to), copy(from,to), upload(dest,files), usage(), rawUrl(path), write?(path,content) }. `list` returns { path, entries:[{name,kind,size,ext?}], roots?, parent? }. Set mode:"readonly" to show an inline notice instead of mutating. `rawUrl(path)` returns a bytes URL for image thumbnails (return "" to fall back to icons). The container owns the box — render inside something with a height (h-dvh / h-full). It self-provides its adapter context; no extra provider needed. ### AppShell — Desktop + Mobile OS Shell - slug: `appshell` kind: `full` category: `os` - Generic, brand-free OS-style shell framework. One wrapper provider gives a project a macOS-style window manager (drag/snap/maximize, dock, menu bar, Spotlight) AND an iOS-style mobile surface (home pager, app library, control center, widgets), driven entirely by a manifest: brand, apps, features, surface regions, capabilities, persistence, keymap. Five shell features (search, inspector, notifications, control-center, widgets) are bundled as defineFeature() contributions inside the slice and mount via named s. Responsiveness is a single ResponsiveProvider + 4 DRY primitives (AppFrame, MasterDetail, ResponsiveToolbar, TouchList). Imports nothing project-specific — the consumer injects data/auth/AI through manifest.capabilities. Lifted from os-vps (Topside). - install: `npx rr add appshell` - detail: https://resource.rahmanef.com/slices/appshell - prompt: https://resource.rahmanef.com/agents/appshell - agent recipe: Stack required: Next 16 (App Router) + React 19 + Tailwind 4 + shadcn/ui. The slice is self-contained — it imports only @/components/ui/* + @/lib/utils (cn); everything project-specific arrives via the manifest. Follow ALL steps; the ⚠ ones are where installs break. STEP 1 — Install. `npx rr add appshell` (alias `npx rahman-resources add appshell`). It copies to your slices dir. Ensure `@/features/appshell` resolves in tsconfig paths (point it at that dir), and that Tailwind's content globs SCAN the slice folder (else the shell renders unstyled). STEP 2 — shadcn + npm deps. Add any missing shadcn primitives: `npx shadcn@latest add button tooltip scroll-area sheet drawer dialog alert-dialog dropdown-menu`. npm: lucide-react class-variance-authority clsx tailwind-merge vaul. STEP 3 — ⚠ Theme. Import the slice's tokens ONCE in the root layout: `import "@/features/appshell/appshell.css"`. These are the glass/dock/window/wallpaper CSS variables the shell needs — they are NOT shadcn defaults, so skipping this = an unstyled, broken-looking shell. It pairs with your shadcn tokens (--background etc.). Dark mode = toggle the `.dark` class on (appshell.css ships light + dark). STEP 4 — Mount full-bleed. Render from a CLIENT component that owns one full viewport (the page is h-dvh w-screen / the root). AppShell auto-picks the macOS desktop on wide viewports and the iOS surface on narrow — you write nothing extra for mobile. STEP 5 — Build the ShellManifest: • brand: { name, logo (string or ReactNode), idleAppName?, wallpaper?: "aurora"|"dusk"|"mist"|"noir" }. • apps: AppDescriptor[] — { id, title, icon (a lucide-react icon component), gradient (a CSS gradient string for the glossy icon), load: async () => ({ default: YourAppComponent }), slug?, defaultSize?: {w,h}, multi?: true (spawn a new window per open, e.g. a file manager), noDock?: true }. Your app component receives props { payload }. • features: the fastest path is `features: DEFAULT_FEATURES` — the bundled default system-feature set (all five, generic + brand-free) exported from "@/features/appshell". Or import individually and list only what you want: searchFeature (⌘K Spotlight), inspectorFeature (⌘I AI/context panel), notificationsFeature (toasts + iOS dynamic island), controlCenterFeature (iOS control center), widgetsFeature (iOS Today widgets). The surfaces are slot-driven, so spreading/trimming DEFAULT_FEATURES just mounts/omits a feature — `features: [...DEFAULT_FEATURES.filter(f => f.id !== "widgets")]`. • capabilities: ShellCapabilities — your data/auth/AI injection seam. useAppearance() and useCpuPercent() are REQUIRED; useSearch/useSystemStats/useChat/useServerToggle are optional (defaults degrade gracefully). ⚠ CRITICAL: every capability hook MUST return a REFERENTIALLY STABLE value — a module-level const, or useMemo/useCallback. Returning a fresh object/closure each render makes Spotlight's search effect re-fire forever ("Maximum update depth exceeded"). e.g. define APPEARANCE once at module scope and `useAppearance: () => APPEARANCE`. • persistKey?: localStorage namespace for the saved window layout (default "appshell:layout"). • routing?: defaults TRUE — it mirrors the focused app to the URL via the History API (window.history, NOT router.push). ⚠ If true you MUST add a catch-all route `app/[[...slug]]/page.tsx` that renders the mount AND calls notFound() for reserved paths (slug[0] === "_next"), or missing chunks return wrong-MIME 200s. SIMPLEST first install: set `routing: false` to skip the catch-all entirely. Extending: add an app = one manifest entry; add a shell feature = a new defineFeature({id, slots}) listed in features[]. No surface edits ever (open/closed). exampleCode ships BOTH variants: Variant A = routing:false mount in app/page.tsx (simplest); Variant B = catch-all app/[[...slug]]/page.tsx with routing on + app slugs for addressable, deep-linkable URLs (the catch-all MUST notFound() "_next"). ### Convex Auth — Multi-Provider Sign-in - slug: `convex-auth` kind: `backend` category: `auth` - @convex-dev/auth with Password (PBKDF2-SHA256 100k, self-hosted-friendly), Anonymous (guest), Google OAuth, and Resend magic-link. Ships a production SignInPage plus a presentational, props-driven AuthCard (v0.3) — choose `methods` (google, github, magic-link, password signin/signup tabs, phone OTP, anonymous) and render the card anywhere with different props; handlers default to a mock so it's interactive with zero wiring. i18n via labels. No Clerk. - install: `npx rr add convex-auth` - detail: https://resource.rahmanef.com/slices/convex-auth - prompt: https://resource.rahmanef.com/agents/convex-auth - agent recipe: Run `rr add convex-auth`. Then create convex/auth.ts using the kitab pattern (Resend provider). Set env via `npx convex env set` for self-hosted. ### Payment — Indonesia PSP (DOKU · Midtrans) - slug: `payment` kind: `full` category: `integrations` - Indonesia payment providers behind one slug + ONE shared Convex backend (convex/features/payment discriminates on a provider column: paymentOrders + paymentWebhookEvents, unprefixed). Two frontend variants: doku — DOKU Hosted Checkout + Direct (VA / QRIS / e-Wallet / PayLater), HMAC-SHA256 signed REST, signature-verified webhook, idempotent retries, dependency-free, server-side env only. midtrans — Snap hosted-modal checkout + orders history (needs npm midtrans-client + a NEXT_PUBLIC_MIDTRANS_CLIENT_KEY). Install one with `npx rr add payment doku|midtrans`, or both. A future stripe variant is reserved in the schema's provider union. - install: `npx rr add payment` - detail: https://resource.rahmanef.com/slices/payment - prompt: https://resource.rahmanef.com/agents/payment - agent recipe: Run `npx rr add payment` for both providers, or `npx rr add payment doku` / `midtrans`. Either variant copies the shared convex/features/payment backend. doku: Checkout (hosted) or Direct (single channel → VA/QRIS/deeplink); webhook /webhooks/doku verifies HMAC-SHA256; server-only, no NEXT_PUBLIC_*. midtrans: Snap.js + window.snap.pay(token); webhook verifies signature_key; needs NEXT_PUBLIC_MIDTRANS_CLIENT_KEY. Both patch paymentOrders by orderId; sandbox by default. ### Resend — Transactional & Newsletter - slug: `resend-newsletter` kind: `backend` category: `integrations` - Transactional email + newsletter blast via Resend. Double opt-in flow + audience segmentation. Magic-link delivery for Convex Auth. Bundles the subscribers list backend (subscribe / confirm / unsubscribe / count) — formerly the standalone `subscribers` slice, merged here in v0.1.3. - install: `npx rr add resend-newsletter` - detail: https://resource.rahmanef.com/slices/resend-newsletter - prompt: https://resource.rahmanef.com/agents/resend-newsletter - agent recipe: Run `npx rr add resend-newsletter`. Use Resend Audiences API for newsletter — store subscriber emails in Convex too for segmentation. Double opt-in: subscriber.create with status 'pending' → click link → status 'confirmed'. ### AI Workspace — chat · studio · agents - slug: `ai-workspace` kind: `full` category: `ai` - Three AI surfaces as shadcn-style variants — `npx rr add ai-workspace ` for one, or `npx rr add ai-workspace` for all + a switcher. Only the chat variant pulls a Convex backend (per-variant convex gating). • chat — floating + createAgenticChatSend: real function-calling over any ToolHost (@/shared/agentic), key-guarded, over convex/features/aiChat. • studio — single-prompt generation canvas (variation grid + version tree, Suno / Midjourney / Lovable pattern) + aiStudioTools so a shared agent can drive generations. • agents — autonomous-worker run dashboard + createAgentRunner(host) which drives the shared function-calling loop and records each tool_use as a RunStep trace. Use cases: support chatbot in a marketing site, AI generation product (image / code / text / audio), background workers (nightly audits, scheduled crawls, moderation). studio + agents are frontend-only — wire your own persistence. - install: `npx rr add ai-workspace` - detail: https://resource.rahmanef.com/slices/ai-workspace - prompt: https://resource.rahmanef.com/agents/ai-workspace - agent recipe: Run `npx rr add ai-workspace ` for one surface, or `npx rr add ai-workspace` for all. chat: mount . studio: mount + drive via aiStudioTools. agents: mount + trigger via createAgentRunner(host). ### AI Admin — Console (Instructions · Skills · Tools · Agents · Providers) - slug: `ai-admin` kind: `full` category: `ai` - Central operator console for the whole AI stack. Every other ai-* feature reads its registries from here. Tabs ordered to match the build-flow: 1. Providers — register Anthropic / OpenAI / Google / Mistral / Ollama (API keys AES-encrypted at rest) 2. Models — per-provider catalog (capabilities, context window, pricing) 3. Instructions — custom system-prompt library (Claude Projects-style) 4. Skills — named instruction + model default + tool defaults (consumed by chat + studio) 5. Tools — JSON-schema function specs + impl (http / convex / shell) + sandbox flag 6. Agents — skill × model × tools × max-iter (consumed by ai-agents) 7. Budgets — per-workspace cost caps + alerts + hard kill 8. Audit — every AI call: actor / agent / tokens / cost / latency / outcome Includes Create-Agent / Create-Skill / Create-Tool / Create-Instruction wizards. - install: `npx rr add ai-admin` - detail: https://resource.rahmanef.com/slices/ai-admin - prompt: https://resource.rahmanef.com/agents/ai-admin - agent recipe: Run `npx rr add ai-admin`. Adds an `AI` section to the admin-panel ADMIN_SECTIONS registry. Sub-tabs ordered to match build-flow: Providers → Models → Instructions → Skills → Tools → Agents → Budgets → Audit. Includes Create-* wizards for instructions / skills / tools / agents. API keys AES-encrypted via AI_ADMIN_ENCRYPTION_KEY env. The instruction / skill / tool / agent registries are SSOTs consumed by every ai-* consumer slice (chat + studio + agents). ### AI Router — Backend Provider Proxy - slug: `ai-router` kind: `backend` category: `ai` - Backend infrastructure (no UI). Single proxy that every other ai-* feature calls. Tier-routed — nano (Haiku) for classification, mid (Sonnet) for chat, flagship (Opus) for deep reasoning. Per-call usage log + cost guard. Works with direct provider keys or OpenRouter umbrella. Not something you mount — installed automatically as a peer when you add ai-workspace. - install: `npx rr add ai-router` - detail: https://resource.rahmanef.com/slices/ai-router - prompt: https://resource.rahmanef.com/agents/ai-router - agent recipe: Run `npx rr add ai-router`. Wrap every AI call through ai-router. Tiers: nano = quick classification (spam-flag, headline-suggest), mid = chat / draft, flagship = methodology-review / deep-think. Token usage logs to ai_usage table for the cost dashboard. ### Convex Vector Search - slug: `vector-search` kind: `full` category: `data` - Embeddings-based search via Convex's built-in vector index. Embed via OpenAI text-embedding-3-small (1536-dim), query via vectorIndex(). - install: `npx rr add vector-search` - detail: https://resource.rahmanef.com/slices/vector-search - prompt: https://resource.rahmanef.com/agents/vector-search - agent recipe: Run `npx rr add vector-search`. Add embedding field + vectorIndex per searchable table. Re-embed on upsert via Convex action. Cache embeddings — don't re-call OpenAI on every read. ### Cal.com Booking - slug: `cal-com-booking` kind: `full` category: `data` - Embedded Cal.com booking widget + webhook receiver to mirror bookings into Convex. - install: `npx rr add cal-com-booking` - detail: https://resource.rahmanef.com/slices/cal-com-booking - prompt: https://resource.rahmanef.com/agents/cal-com-booking - agent recipe: Run `npx rr add cal-com-booking`. Embed Cal.com via @calcom/embed-react di halaman services. Configure webhook di Cal.com dashboard → POST ke /api/cal-webhook → upsert booking di Convex. ### Command Menu - slug: `command-menu` kind: `ui` category: `ui` - Renderless ⌘K command palette + generic search modal. Consumer supplies CommandGroup[] + onSelect + label bag; slice owns dialog chrome, ⌘K hotkey, MRU history. Pulled UP from notion-page-clone's command-palette renderless surface (Wave N+3.7) — Nosion adapters dropped at the kitab boundary. - install: `npx rr add command-menu` - detail: https://resource.rahmanef.com/slices/command-menu - prompt: https://resource.rahmanef.com/agents/command-menu - agent recipe: Run `npx rr add command-menu`. Wire at the dashboard shell. Build groups from your feature registry; each item.onSelect handles navigation. Use for the search dialog — see slice README.md for adapter shapes. ### Motion Primitives (8) - slug: `motion-primitives` kind: `ui` category: `ui` - Eight ready-to-style motion components: marquee, kinetic-heading, magnetic, cursor-spotlight, stat-counter, reading-progress, grain, lightbox. Framer-Motion-powered, tree-shakeable. Facade slice — pulls from template-base/frontend/slices/motion-primitives. - install: `npx rr add motion-primitives` - detail: https://resource.rahmanef.com/slices/motion-primitives - prompt: https://resource.rahmanef.com/agents/motion-primitives - agent recipe: Run `npx rr add motion-primitives`. Each primitive is independently importable from @/features/motion-primitives. Use marquee for logo strips, kinetic-heading for hero text, magnetic for CTA buttons, cursor-spotlight for hover-reveal panels, stat-counter for animated numbers, reading-progress for blog top bar, grain for film texture, lightbox for image gallery. ### Responsive Dialog (Sheet ↔ Modal) - slug: `responsive-dialog` kind: `ui` category: `ui` - ResponsiveDialog — auto-switches between bottom Sheet (mobile) and centered Dialog (desktop) at the md breakpoint. Same API as shadcn Dialog. Kitab forbids raw ; use this everywhere. Facade slice — pulls from template-base/frontend/slices/responsive-dialog. - install: `npx rr add responsive-dialog` - detail: https://resource.rahmanef.com/slices/responsive-dialog - prompt: https://resource.rahmanef.com/agents/responsive-dialog - agent recipe: Run `npx rr add responsive-dialog`. Drop-in for shadcn Dialog. Use . On mobile renders as Sheet sliding from bottom; on desktop as centered Dialog. Threshold via useMediaQuery('(min-width: 768px)'). ### Dashboard Shell — Responsive - slug: `dashboard-shell` kind: `ui` category: `ui` - ResponsiveDashboardShell — desktop sidebar + topbar, mobile dock + sheet sidebar, breakpoint-aware. Ports superspace's layout/dashboard/{Desktop,Mobile,Responsive}DashboardShell + sidebar primary/secondary slots. Facade slice — pulls from template-base/frontend/slices/dashboard-shell. - install: `npx rr add dashboard-shell` - detail: https://resource.rahmanef.com/slices/dashboard-shell - prompt: https://resource.rahmanef.com/agents/dashboard-shell - agent recipe: Run `npx rr add dashboard-shell`. Wraps app/(admin) routes. } topbar={}>{children}. Mobile: sidebar collapses to . Desktop: persistent sidebar + topbar. Embed FullWidthToggle in topbar for instant container resize. ### Three-Column Layout — Sidebar/Content/Inspector - slug: `three-column` kind: `ui` category: `ui` - ThreeColumnLayoutAdvanced — collapsible left/right + resizable widths + responsive breakpoints + PanelSection compound (Header/Items/Footer) + per-panel footer slots. Models shadcn sidebar API for the panel interior. Pair with PanelGroup/PanelMenu/PanelSeparator primitives. Trigger ≠ header (V-wave separation rule). - install: `npx rr add three-column` - detail: https://resource.rahmanef.com/slices/three-column - prompt: https://resource.rahmanef.com/agents/three-column - agent recipe: Run `npx rr add three-column`. . Center column SHOULD pass `unstyled` to drop sidebar tokens — body is content surface. `storageKey` MUST differ per slice or persisted widths collide. ### BroadcastChannel — Cross-tab Sync - slug: `broadcast-channel-sync` kind: `ui` category: `data` - Same-origin cross-tab + cross-iframe state sync via BroadcastChannel API. Tiny, no backend, no install. - install: `npx rr add broadcast-channel-sync` - detail: https://resource.rahmanef.com/slices/broadcast-channel-sync - prompt: https://resource.rahmanef.com/agents/broadcast-channel-sync - agent recipe: Run `npx rr add broadcast-channel-sync`. Use BroadcastChannel only for demo / cross-iframe state mirroring. Production data still goes through Convex realtime. Use the useBroadcastSync(channelName, initial) hook from @/features/broadcast-channel-sync. ### RBAC — Roles & Permissions - slug: `rbac-roles` kind: `full` category: `auth` - RBAC engine ported from superspace. 6 system role presets (owner/admin/manager/staff/client/guest with levels), dot-namespaced permissions with `*` / `feature.*` wildcard matching, and pure check helpers (resolvePermissions / hasPermission / roleHasPermission). Props-driven UI primitives: , usePermissions, , . Convex template ships a tenant-scoped rbac_roles table + checkPermission / requirePermission helpers + idempotent seedSystemRoles, with a PLATFORM_ADMIN_EMAILS superadmin bypass. Pair with `user-management` for the members / invites / roles-admin UI. @convex-dev/auth aware — no Clerk. - install: `npx rr add rbac-roles` - detail: https://resource.rahmanef.com/slices/rbac-roles - prompt: https://resource.rahmanef.com/agents/rbac-roles - agent recipe: Run `npx rr add rbac-roles`. Frontend: import { PermissionGate, usePermissions, RoleBadge, PermissionMatrix, resolvePermissions, ROLE_PRESETS } from "@/features/rbac-roles". Feed usePermissions/PermissionGate the actor's resolved permission list (from your membership query or resolvePermissions(roleSlug)). Convex: spread rbacRolesTables into your schema, call seedSystemRoles({tenantId}) once, gate privileged fns with requirePermission(ctx, tenantId, "members.manage"). Set PLATFORM_ADMIN_EMAILS for superadmins. Add the user-management slice for the members/invites UI (provides um_members). ### User Management - slug: `user-management` kind: `full` category: `auth` - Full superspace-parity user management, props-driven + RBAC-agnostic. tabs Members + Roles + Teams + Access: member table (search / filter / sort, inline role dropdown, soft-remove), InviteDialog (with an optional 'propagate to sub-workspaces' toggle — same / step-down role strategy) + PendingInvites, a RolesPanel (custom roles via permission matrix; system roles read-only), a TeamsPanel (named user groups), and an AccessMatrix (users × tenants grid with inline role assignment). All permission-gated. You pass `roles` + `currentPerms` + the permission catalog (resolved from rbac-roles) + callbacks; the slice imports no other slice's frontend. Convex ships um_members + um_invites + um_teams + um_team_members + um_tenant_links + member / invite / team / hierarchy endpoints + getAccessMatrix (gated via rbac-roles' requirePermission); roles CRUD reuses rbac-roles'. The hierarchy is a generic edge tree — rr never owns the tenant entities. P0–P4c: the complete user-management epic. - install: `npx rr add user-management` - detail: https://resource.rahmanef.com/slices/user-management - prompt: https://resource.rahmanef.com/agents/user-management - agent recipe: Run `npx rr add user-management` (pulls rbac-roles + convex-auth). Frontend: ({slug:r.slug,name:r.name,color:r.color}))} currentPerms={actorPerms} onUpdateRole={useMutation(...updateMemberRole)} onRemove={useMutation(...removeMember)} onInvite={openInvite} />. Wire roles + currentPerms from rbac-roles at the app level — the slice itself imports no other slice. Convex: spread userManagementTables; listMembers/mutations gate via rbac-roles requirePermission. ### Admin Panel — Unified Product Admin - slug: `admin-panel` kind: `full` category: `infra` - 17-section admin surface (events, funnels, attribution, users, A/B, flags, pricing, CMS, email, audit, ...) gated by RBAC. Auto-filters sidebar by tier (solo/influencer/organization) and user permissions. Single backend resolver (getMyAdminAccess) mirrors frontend gate so UI can never leak. - install: `npx rr add admin-panel` - detail: https://resource.rahmanef.com/slices/admin-panel - prompt: https://resource.rahmanef.com/agents/admin-panel - agent recipe: Run `npx rr add admin-panel`. Wrap pages with . AccessGate hides UI for non-admins, AdminShell renders 2-col layout with sidebar filtered by tier+perms. ADMIN_SECTIONS in config.ts is SSOT (17 entries). Personal-brand-os = tier 'solo' = owner sees everything. ### Event Tracking — P0 Instrumentation - slug: `event-tracking` kind: `full` category: `data` - Client SDK + Convex ingestion endpoint for structured product events. Auto-captures page_view/signup/login + UTM/referrer/first-touch attribution. Batched flush via requestIdleCallback. Targets <100ms p99 ingestion. - install: `npx rr add event-tracking` - detail: https://resource.rahmanef.com/slices/event-tracking - prompt: https://resource.rahmanef.com/agents/event-tracking - agent recipe: Run `npx rr add event-tracking`. Writes to analyticsEvents table (no new schema). Anonymous page_view allowed pre-signup; other events require workspaceId. Session id per tab (sessionStorage), first-touch UTM in localStorage. Flush every ~500ms via requestIdleCallback. Cap retry queue at 500. ### Icon Picker - slug: `icon-picker` kind: `ui` category: `ui` - Emoji + lucide (outline) + phosphor (fill) icon picker with search, 10-color palette, Twemoji/native toggle, recents tracking, and smart positioning. Two-tab layout (Emoji | Icon) with sub-variant pills (Native | Twemoji / Lucide | Phosphor fill). One string stores emoji OR lucide:Name OR phosphor:Name OR with ?c=hex tint — backwards-compat with raw-emoji fields. Popover auto-flips on collision (caps to Radix `--radix-popover-content-available-height`) and falls back to centered Dialog when neither side fits. Two variants: Popover (compact trigger) and Inline (full sheet/dialog use). Lifted 2026-05-25 from open-silong. - install: `npx rr add icon-picker` - detail: https://resource.rahmanef.com/slices/icon-picker - prompt: https://resource.rahmanef.com/agents/icon-picker - agent recipe: Run `npx rr add icon-picker` then `pnpm add @phosphor-icons/react`. parseIconValue() decodes; lucideValue() / phosphorValue() / withColor() build. Storage forms: `lucide:Name?c=hex` (outline) or `phosphor:Name?c=hex` (fill) or raw emoji. Add 'icon: v.string()' to Convex table — no migration needed for existing emoji + lucide fields. wraps any trigger (auto-flips, falls back to centered Dialog on tight viewports); for sheets/dialogs. renders from parsed value. ### Activity — public productivity log - slug: `activity` kind: `full` category: `data` - Public-facing weekly activity log. Lists user-facing activities grouped by ISO week with schema.org-friendly markup, designed to maximise SEO so the question 'what is working on this week?' lands here. Convex-backed (schema + queries + unauthenticated mutations); MCP-friendly so AI workflows (Claude / GPT / custom agents) can append entries directly. All user-facing copy + per-category labels + date/time locale are prop-driven (English defaults). Lifted 2026-05-27 from rahmanef.com; 225-LOC view split into view + 2 sub-components + 4 lib helpers for the 200-LOC cap; Indonesian strings + custom primitives stripped; cross-slice auth import dropped (consumer wraps mutations). - install: `npx rr add activity` - detail: https://resource.rahmanef.com/slices/activity - prompt: https://resource.rahmanef.com/agents/activity - agent recipe: Run `npx rr add activity`. Spread `activityTables` into your root Convex schema. Wrap the unauthenticated `create`/`update`/`remove` `internalMutation`s with your auth model (see README Install section). Render ``. Override `copy`, `categoryLabels`, `locale` per consumer. MCP integration: map `activity_create` tool → your wrapped `create` mutation. ### Rate Limit - slug: `rate-limit` kind: `backend` category: `infra` - Convex-backed per-key request counter. Atomic check-and-increment via `consume` mutation; expired rows pruned by `_pruneExpired` internalMutation wired to a 5-min cron. Replaces single-replica in-memory Map so multi-replica Next deployments share buckets. Limits live in an in-code POLICY map keyed by namespace prefix (admin-login:, mcp:) — never caller-supplied; optional RATE_LIMIT_SERVER_KEY env gates anonymous calls. Lifted 2026-05-16 from rahmanef.com; hardened 2026-06-07. - install: `npx rr add rate-limit` - detail: https://resource.rahmanef.com/slices/rate-limit - prompt: https://resource.rahmanef.com/agents/rate-limit - agent recipe: Run `npx rr add rate-limit`. Compose `rateLimitTables` into root convex/schema.ts. Wire `internal.features.rate_limit.mutations._pruneExpired` into convex/crons.ts every 5 min. Add your namespace to the in-code POLICY map, then call `api.features.rate_limit.mutations.consume({ key, serverKey })` from server-side handlers — keep a fail-open wrapper so a Convex outage doesn't 503 the route. Set RATE_LIMIT_SERVER_KEY on the deployment to block anonymous consume calls. ### Testimonials - slug: `testimonials` kind: `backend` category: `content` - Quote/name/role rotator backend. Public `listAll` + `get` (no auth — testimonials are public), admin CRUD via `requireAdmin`, internal `seed` for one-shot bootstrap. Indexed by `order` so carousel/grid keeps stable rotation. Lifted 2026-05-16 from rahmanef.com; token-based admin gate swapped for rr `_shared/auth`. - install: `npx rr add testimonials` - detail: https://resource.rahmanef.com/slices/testimonials - prompt: https://resource.rahmanef.com/agents/testimonials - agent recipe: Run `npx rr add testimonials`. Compose `testimonialsTables` into root schema. Bootstrap via `npx convex run internal.features.testimonials.mutations.seed '{"items":[{"quote":"...","name":"...","role":"...","order":1}]}'`. Render with `useQuery(api.features.testimonials.queries.listAll)`. ### Services - slug: `services` kind: `backend` category: `content` - Service offerings backend — title + summary + deliverables array + sort order. Public read, admin CRUD, internal seed. Pairs with a frontend services grid/list (consumer-side). Lifted 2026-05-16 from rahmanef.com; token-based admin gate swapped for rr `_shared/auth`. - install: `npx rr add services` - detail: https://resource.rahmanef.com/slices/services - prompt: https://resource.rahmanef.com/agents/services - agent recipe: Run `npx rr add services`. Compose `servicesTables` into root schema. Use `useQuery(api.features.services.queries.listAll)` from a server component / route to render service cards. CRUD via admin UI calling `create` / `update` / `remove` after `requireAdmin` passes. ### Create Your MCP - slug: `create-your-mcp` kind: `full` category: `ai` - Turn any rr-based app into an MCP server that ChatGPT custom apps, Claude.ai connectors, Cursor MCP, and other AI clients authenticate to. OAuth 2.1 + PKCE flow with code → bearer exchange, env-configured vendor-host allowlist, single-use codes, 1-year bearer tokens, scope-tagged tools, opaque error collapsing, constant-time token compare. Static MCP_API_KEY fallback for service-account / CI scripts. Sanitized 2026-05-16 from rahmanef.com's production MCP integration — vendor literals (chatgpt.com / OpenAI paths) replaced with MCP_OAUTH_ALLOWED_HOSTS + MCP_OAUTH_ALLOWED_PATH_PREFIXES env vars so the slice ships portable. - install: `npx rr add create-your-mcp` - detail: https://resource.rahmanef.com/slices/create-your-mcp - prompt: https://resource.rahmanef.com/agents/create-your-mcp - agent recipe: Run `npx rr add create-your-mcp`. Compose `createYourMcpTables` into root schema. Move `slices/create-your-mcp/routes/mcp.route.ts` → `app/api/mcp/route.ts` and `oauth-token.route.ts` → `app/api/oauth/token/route.ts`. Set MCP_OAUTH_ALLOWED_HOSTS (CSV vendor domains). Mount `` at /admin/mcp. Connect ChatGPT/Claude/Cursor via the setup form rendered by the admin view. ### Contact Form + Resend - slug: `contact-form-resend` kind: `full` category: `integrations` - Contact form posting to Resend email API. Server Action + Zod input validation. Convex mutation for storage + Resend send. - install: `npx rr add contact-form-resend` - detail: https://resource.rahmanef.com/slices/contact-form-resend - prompt: https://resource.rahmanef.com/agents/contact-form-resend - agent recipe: Run `npx rr add contact-form-resend`. Wire contactMessages.send mutation in convex/. Server emails via Resend from form@yourdomain.com. Always validate inputs with Zod or v.* server-side. Anonymous allowed. ### Admin — generic shell + composed console - slug: `admin` kind: `full` category: `infra` - Access-gated admin surfaces behind one slug, in two variants — each pulls ONLY its own convex backend (per-variant convex gating). shell: a HEADLESS minimal generic admin shell — a titled landing region + a portable buildAdminStats(opts) nav-from-registry factory (consumer supplies a SliceRegistryAdapter + queryTable reader) over convex/features/admin; superadmin gate via SUPER_ADMIN_EMAIL. console: the composed admin panel distilled from ~15 project admin panels — a gated two-column shell (AdminConsole) over a 26-section registry (ADMIN_CONSOLE_SECTIONS: observability / identity / ai / content / commerce / config) that mounts OTHER rr slices via a consumer-supplied `components` map (users→user-management, roles→rbac-roles, ai→ai-admin, tenants→platform-admin) plus 5 owned gap sections (Analytics, Audit-log, Nav config, SEO health, Leads/CRM) over convex/features/admin_console (ac_leads + ac_nav_items); gate injected, PLATFORM_ADMIN_EMAILS allowlist. Install one with `npx rr add admin shell|console`, or both with `npx rr add admin`. NOT the multi-tenant control plane — that's the separate `platform-admin` slice (the console's `tenants` section provider). - install: `npx rr add admin` - detail: https://resource.rahmanef.com/slices/admin - prompt: https://resource.rahmanef.com/agents/admin - agent recipe: Run `npx rr add admin` for both, or `npx rr add admin shell` / `console` for one — each variant pulls only its own convex backend. shell: mount + call buildAdminStats({ sliceRegistry, queryTable }) in convex/features/admin/query.ts; lock down with SUPER_ADMIN_EMAIL. console: mount , ... }} /> — owned sections (analytics/audit-log/nav-config/seo-health/leads) render as-is, map each reuse section id to the panel from the peer slice you installed; compose adminConsoleTables into convex/schema.ts and front ac_leads.create with rate-limit; gate via PLATFORM_ADMIN_EMAILS. ### Platform Admin — Multi-Tenant Control Plane - slug: `platform-admin` kind: `full` category: `infra` - Multi-tenant SaaS control plane. Workspace lifecycle ops (list/delete/cascade), per-tenant tier presets (gates + quota), KPI dashboard grid. Consumer-domain bits injected via adapter props (tenantTablesAdapter / tierPresets / kpiSources). Contract-only scaffold; canonical implementation lands via /rr-send from superspace. See docs/contract-negotiations-2026-05-15.md §4. - install: `npx rr add platform-admin` - detail: https://resource.rahmanef.com/slices/platform-admin - prompt: https://resource.rahmanef.com/agents/platform-admin - agent recipe: Run `npx rr add platform-admin`. Contract-only scaffold. Wait for superspace /rr-send platform-admin before adopting. Distinct from per-instance `admin` slug. ### Audit Log — Workspace Events - slug: `audit-log` kind: `backend` category: `infra` - Workspace-scoped audit event recorder. Canonical logAuditEvent helper for mutations + actions; supports entity tracking, before/after diff, IP/user-agent capture. - install: `npx rr add audit-log` - detail: https://resource.rahmanef.com/slices/audit-log - prompt: https://resource.rahmanef.com/agents/audit-log - agent recipe: Run `rr add audit-log`. Import logAuditEvent from convex/_shared/auditLogger.ts and call inside every workspace-scoped mutation with { action, workspaceId, entityType, entityId, before?, after? }. ### Comments — Threaded - slug: `comments` kind: `full` category: `content` - Polymorphic-target threaded comments. Consumer picks `TargetRef = { kind, id, subId? }` (e.g. page+block, blog+slug, task+id). Reply nesting is real: `parentId` end-to-end + `buildThread(flat) → CommentNode[]` tree (oldest-first, orphan-safe). Renderless + wrappers; useComments(bindings, opts) returns items + `tree` + openCount + CRUD + forbiddenWords guard. Adapter pattern — see contract-negotiations §1. - install: `npx rr add comments` - detail: https://resource.rahmanef.com/slices/comments - prompt: https://resource.rahmanef.com/agents/comments - agent recipe: Run `rr add comments`. Wire Convex bindings ({ list, create, update, resolve, remove }) then use {render-prop} OR ...}>. v0.2.0 polymorphic — pick `kind` literal per host domain. ### SEO — AI Metadata Generator - slug: `seo` kind: `full` category: `content` - Service slice for SEO metadata generation — Anthropic-backed action with per-user 24h cost guard + portable persona prop. No public route. Backend exposes generate + generateAndApply mutations gated by requireAdmin; consumers inject brand voice via the personaContext arg (or buildSeoSystemPrompt factory). - install: `npx rr add seo` - detail: https://resource.rahmanef.com/slices/seo - prompt: https://resource.rahmanef.com/agents/seo - agent recipe: Run `rr add seo`. Call seo.generate from server actions or admin mutations with `personaContext` describing your brand voice (or rely on the generic default). Cost guard rate-limits per-user within 24h via callsInWindow query. ### Publisher — clean HTML - slug: `publisher-clean-html` kind: `ui` category: `content` - A pure render-to-clean-HTML engine harvested from the Instatic CMS publisher, decoupled from its host caching / loops / visual-components / Layer-C islands. publishPage(tree, registry, options) walks a generic node tree bottom-up: render children, escape every prop by its schema-declared control type (url -> safe-URL, richtext -> DOMPurify, svg -> SVG profile, else HTML-escape), dedup CSS by moduleId (~60-80% shrink), splice author classes + inline styles onto each rendered root, then assemble + reset + framework + module CSS + a deterministic (sorted) CSP plan. Bring your own ModuleRegistry (each module is a pure render(props, children) -> { html, css? }). Security spine: HTML escape + safe-URL, CSS-value guard (expression()/{}/ ({ html: kids.join('') }) }, { id: 'demo.h', schema: { text: { type: 'text' } }, render: (p) => ({ html: `

${p.text}

`, css: 'h1{font-size:1.5rem}' }) }]). Tree = { rootNodeId, nodes: { [id]: { id, moduleId, props?, children?, classIds?, inlineStyles?, hidden? } } }. const { html } = publishPage(tree, registry, { title, cssEmission: 'inline' }). Preview: . Enable rich HTML/SVG by calling configureRichtextSanitizer(DOMPurify) once — without it, richtext/svg props fail closed (strip/empty). Props escape by schema control type, not key name. ### Content Loops - slug: `content-loops` kind: `ui` category: `content` - A data-source-driven repeater harvested from the Instatic CMS base.loop engine, decoupled from its publisher / page-tree / entryStack machinery into a plain React slice. Register pluggable LoopEntitySource backends (each declares display fields + an async fetch returning { items, totalItems }); drop to render one component per item, round-robining items across variants so alternating / featured layouts need no per-item branching. Ships a namespaced source registry (ids must be 'ns.name', so consumer sources can't shadow each other), createMockLoopSource for env-free previews + tests, and none/infinite pagination via useLoopPagination (a shadcn Load more button accumulates pageSize chunks). LoopItem.fields is a generic resolved-value bag — variants read item.fields.title directly, no second lookup. UI-only: no Convex tables shipped; point a source's fetch at Convex/REST when you have a backend. First slice of the feature-harvest ULTRAPLAN (docs/feature-harvest) and a dependency of the planned site-templates-engine + visual-page-canvas. - install: `npx rr add content-loops` - detail: https://resource.rahmanef.com/slices/content-loops - prompt: https://resource.rahmanef.com/agents/content-loops - agent recipe: Run `npx rr add content-loops`. Env-free demo: createMockLoopSource() then — variants round-robin (item i -> variants[i % n]). Real source: implement LoopEntitySource { id: 'blog.posts' (namespaced 'ns.name'), fields, async fetch({ filters, orderBy, direction, limit, offset }) returns { items, totalItems } }, call loopSourceRegistry.registerOrReplace(source), then . item.fields holds RESOLVED values — resolve media/author inside fetch. ### Markdown — page container with CRUD tabs + diagrams - slug: `markdown` kind: `ui` category: `content` - Markdown (.md) page container with optional CRUD surfaces. — Read renders rich text (headings, lists, todo, GitHub-style callouts, fenced code, KaTeX, tables, images,
toggles, inline marks); Write is a raw-source editor with snippet toolbar + live preview; Review overlays block-anchored comments (add/resolve, controlled via onAddComment/onResolveComment or internal fallback). Fenced ```mermaid blocks render as SVG diagrams (dynamic-imported mermaid) and ```chart blocks as recharts bar/line/area/pie from a JSON spec. Self-contained: ships its own parser (parseMarkdown → MdNode[]) + inline renderer, no notion runtime dependency. Sync is by shared grammar: the notion cluster's blocksToMarkdown / markdownToBlocks bridge (@notion/shared/lib/markdown) emits/consumes the exact same markdown this slice parses, so anything readable in the notion block page is readable here and vice-versa. No store, no Convex — comments CRUD is consumer-wired callbacks. - install: `npx rr add markdown` - detail: https://resource.rahmanef.com/slices/markdown - prompt: https://resource.rahmanef.com/agents/markdown - agent recipe: Run `npx rr add markdown`. Read-only: ``. Full surface: `` (omit callbacks for internal-state demo mode). Diagrams: fence ```mermaid; charts: fence ```chart with { type: bar|line|area|pie, data: [...] }. To bridge from the notion editor call `blocksToMarkdown(page.blocks)` from `@notion/shared/lib/markdown`; reverse with `markdownToBlocks(md)`. ### Notion App — Block Editor - slug: `notion-app` kind: `full` category: `content` - Nested vertical slice (slice-of-slices) housing the full notion-page-clone block editor. Mount inside — with `{}` it is a working plain-text/markdown block editor (slash menu, markdown triggers `# - > [] etc.`, dnd-kit drag with column layouts, per-block toolbar with turn-into/color/duplicate, per-block undo, paste-markdown import); host capabilities light up per optional adapter: data (block+page CRUD), selection (multi-select), comments (per-block popover), ai (Ask-AI panel), database (render + picker), mention (@-typeahead), page (nav/uploads/covers). Cluster-private shared layer under @notion/* — vendored block/page/database model, uid, inline markdown, page→md/html export. Pure convex block helpers (_blocks/_blockOps, unit-tested) ship in convex/features/notion. Same markdown grammar as the standalone `markdown` slice (blocksToMarkdown/markdownToBlocks bridge). - install: `npx rr add notion-app` - detail: https://resource.rahmanef.com/slices/notion-app - prompt: https://resource.rahmanef.com/agents/notion-app - agent recipe: Run `npx rr add notion-app`. Wire the `@notion/*` path alias to `./slices/notion-app/*` in tsconfig. Minimal mount: `` where `data` implements EditorDataAdapter (block+page CRUD over your store — see lib/dataAdapter.ts; a localStorage reference impl lives in the rr preview). Add capabilities incrementally: `selection` for multi-select, `comments` for per-block threads, `database.renderDatabase` to mount your database renderer inside database blocks, `mention.search` for @-typeahead, `page.navigateToPage`/`uploadFile` for nav + media. Convex hosts: copy convex/features/notion (_blocks/_blockOps are pure, unit-tested array ops) and keep handlers thin. ### Sections — composable marketing/landing sections - slug: `sections` kind: `ui` category: `content` - Canonical landing-page composition slice — replaces the former standalone hero / cta / pricing-page / faq-section / feature-grid / testimonials-grid / blog-section / portfolio-section / changelog-feed slices (all merged here as `kind` variants in v0.2.0). Ships a pure reducer (v0.4.0: LANDING_UPSERT auto-shifts sibling `order` to keep positions unique; LANDING_DELETE closes the gap) + LandingProvider store adapter + admin LandingView/LandingEditorView built on the shared CRUD primitives, plus a per-section LandingSectionShell (background image + custom Tailwind className overlay + scroll-reveal). NEW in v0.4.0: a `sections/` library of config-driven public renderers (StatsSection, TestimonialsSection, FaqSection, PricingSection, NewsletterSection, CustomSection) that read `LandingSection.config` JSON merged over template defaults — content stays dashboard-controlled without per-template renderer code; plus `parse-config` helpers (parseConfigBadge/parseConfigField) and `sections/config` guards (parseConfigObject, cfg*). Sections carry { kind, order, title, subtitle, enabled, imageUrl, imageRatio, bgImageUrl, className, config (JSON) } with up/down reorder arrows. Lifted from the _templates fleet `_shared/landing` (2026-06-11) — the 8 standalone templates ship a byte-similar copy; this rr slice is the SSOT. Used by all 7 rr website templates. - install: `npx rr add sections` - detail: https://resource.rahmanef.com/slices/sections - prompt: https://resource.rahmanef.com/agents/sections - agent recipe: Run `npx rr add sections`. Fold `landingReducer` into your root reducer (cases LANDING_UPSERT + LANDING_DELETE), seed State.landingSections with `defaultLandingSections()`, wrap your StoreProvider with `` where adapter maps {items, publicBase, adminBase, create, update, remove} from your dispatch. Mount `` at `/admin/landing` and `` at `/admin/landing/[id]`. In HomePage iterate `state.landingSections.filter(s => s.enabled).sort((a,b) => a.order - b.order)` and render each inside ``; for stats/testimonials/pricing/faq/newsletter/custom kinds drop in the shipped `` etc. (they read `section.config` JSON over your template defaults), or map the remaining kinds (hero/features/blog/etc.) to your own renderer. Use `parseConfigBadge(section.config)` for a section badge. Requires the template-base shared surface that ships in every rr website template: `@/components/templates/_shared/motion` (Reveal/Stagger/CountUp/Marquee/useInView — the motion-kit primitives), `@/components/templates/_shared/ui/section-head`, and `@/components/templates/_shared/crud/*`. Sections also use shadcn accordion/card/carousel + embla-carousel-autoplay. ### Motion Kit — scroll reveals, carousel, accordion, micro-interactions - slug: `motion-kit` kind: `ui` category: `ui` - Zero-dependency scroll-motion layer (IntersectionObserver + CSS) plus an embla carousel and a radix accordion, packaged so any page gets tasteful entrance animations without pulling in a motion library. Ships Reveal (fade-up/fade/fade-left/fade-right/zoom), Stagger (incremental per-child reveal for grids/lists), CountUp (rAF count-to-value with locale formatting; integers), Marquee (infinite logo/brand strip with hover-pause + edge fade), and the useInView hook behind them; plus Carousel (embla, optional Autoplay plugin) and Accordion (radix). All reveal + keyframe motion is gated behind prefers-reduced-motion. Consumers append globals-motion.css to their app/globals.css for the [data-reveal] transitions + accordion/marquee/blob keyframes. Lifted 2026-06-10 from the _templates fleet `_shared/motion` copy — the 8 standalone website templates already ship a byte-identical copy; this rr slice is the SSOT so future scaffolds get it via `npx rr add motion-kit`. Pairs with landing-sections (its renderers consume these primitives). - install: `npx rr add motion-kit` - detail: https://resource.rahmanef.com/slices/motion-kit - prompt: https://resource.rahmanef.com/agents/motion-kit - agent recipe: Run `npx rr add motion-kit`. Append the contents of `globals-motion.css` to your `app/globals.css` (after `@import "tailwindcss";`) — without it `data-reveal` elements stay static and the accordion snaps. Then import from `@/features/motion-kit`: ``, `{cards}` for grids, `` (integers), `{logos}`. Carousel: pair with `Autoplay` from embla-carousel-autoplay. Any component consuming a passed render/icon fn AND these hooks must be `"use client"`. Hover-lift convention: `transition-[translate,box-shadow] duration-300 hover:-translate-y-1 hover:shadow-lg`. ### Storefront Checkout — guest cart + checkout composition - slug: `storefront-checkout` kind: `ui` category: `content` - Guest-friendly shopping cart for catalog storefronts. CartProvider holds items in React context with localStorage persistence (anonymous buyers keep their cart across reloads, zero backend). CartWidget is a header trigger with live count badge opening a slide-over Sheet: per-item qty steppers, remove, subtotal, checkout CTA to a host route. CheckoutSummary renders the order panel on the checkout page. Props-driven R3 — no convex/react anywhere; the host resolves a NUMERIC price per catalog item before add() and MUST re-price every line server-side when placing the order (client subtotal is display-only, never the charge). Proven end-to-end on wirausaha-os: catalog → cart → server-priced placeOrder action → DOKU Direct instructions → webhook flips paid (reactive). Pairs with doku-payment ≥0.2 (guest checkout: optional userId + buyer contact, key-guarded actions, guest-readable status query) or midtrans-payment. - install: `npx rr add storefront-checkout` - detail: https://resource.rahmanef.com/slices/storefront-checkout - prompt: https://resource.rahmanef.com/agents/storefront-checkout - agent recipe: Run `npx rr add storefront-checkout`. Wrap your public layout once with `` and mount `` in the header extras. On product surfaces call `useCart().add({ slug, name, price, priceLabel, emoji })` with a host-resolved NUMERIC price. Build a /checkout route composing `` + a payment form (doku-payment's DokuDirectForm): its onSubmit calls YOUR Convex place-order action which re-prices each {slug, qty} from your catalog table server-side, generates an unguessable orderId, calls api.features.payment.actions.doku.createDirectPayment, records your domain order row, and returns { ok, orderId, instructions, expiresAt } ({ ok:false, notice } when DOKU creds are unset — surface it in the form and offer a contact fallback). After success render DokuPaymentInstructions + reactive status via api.features.payment.query.getOrderByOrderId. Reference: template-wirausaha-os convex/checkout.ts + slices/checkout/CheckoutPage.tsx. ### Theme Presets — unified switcher with bundled tweakcn registry - slug: `theme-presets` kind: `ui` category: `ui` - Single unified theme controller for next-themes apps. ThemePresetSwitcher ships a Palette-icon Popover trigger with three stacked sections: (1) sticky light/dark/system mode tabs, (2) sticky preset-count row with a Default reset button, (3) scrollable color-preset list grouped by mood (Profesional / Bold / Hangat / Artistik / Gelap + Lainnya). Hover-to-preview + click-to-commit + restore-on-close semantics. ThemePresetProvider context wraps state so deeply-nested consumers read via useThemePreset() instead of mounting the switcher directly. ThemeColorSync wrapper enables live tweakcn-CSS-variable preview on routes that need it. Tweakcn registry (~30 curated presets after HIDDEN_PRESETS filter drops Doom 64 / Cyberpunk / Neo Brutalism / Bubblegum / Candyland / Pastel Dreams) ships inside the slice as registry-data.json and loads lazily via dynamic import — code-splits into its own chunk, zero consumer public/ setup, no network roundtrip to a hosted URL. localStorage key `host:theme-preset` (rename via slice fork). CK-1F (2026-05-23) — collapsed prior TweakcnSwitcher + ThemePicker + phantom `theme-preset-switcher` catalog entry into this single component. - install: `npx rr add theme-presets` - detail: https://resource.rahmanef.com/slices/theme-presets - prompt: https://resource.rahmanef.com/agents/theme-presets - agent recipe: Run `npx rr add theme-presets` (registry-data.json ships inside the slice — no separate public/ copy step). Wrap your tree once with `` (inside next-themes' ThemeProvider). Mount `` anywhere in your header / sidebar / settings — one component handles light/dark/system + preset palette. Wrap dashboard with `` if you need live tweakcn variable preview on inner routes. Deeply-nested consumers read state via `useThemePreset()` (returns `{ presetName, registry, setPreset, preview, restore, isReady }`). For lower-level access: `applyTweakcnPreset(name)`, `previewTweakcnPreset(name)`, `restoreTweakcnPreset()`, `groupTweakcnPresets(items)`, `tweakcnSwatches(preset)` all exported from `@/features/theme-presets`. To rename localStorage key, fork `STORAGE_KEY` in `lib/tweakcn/types.ts`. ### Site Setup Wizard — first-run site setup - slug: `site-setup-wizard` kind: `ui` category: `ui` - Post-claim onboarding wizard for clone-to-own templates, graduated from the headless template surface (2026-06-06). Multi-step card flow (Identitas / Branding / Konten / Selesai) that stores ALL site config in the host backend via a props-driven save callback — a non-coder configures their site with zero code. Branding step ships a readable shadcn Select theme-preset picker (color swatches per preset + grouped headers + live preview callback — replaces the white-on-white native select), brand color quick-chips, light/dark/system default mode, logo/favicon upload via injected ImageField, and optional Analytics ID. Identity step hints invalid email format. 'Lewati setup' marks onboarded without fields and reverts any browsed-but-unsaved preset. Props-driven (R3): no convex/react import — host wires settings.upsert / seed.seedSample / setup.status into props; pairs naturally with the theme-presets slice (registry + tweakcnSwatches + previewTweakcnPreset) but works with any theme system or none. - install: `npx rr add site-setup-wizard` - detail: https://resource.rahmanef.com/slices/site-setup-wizard - prompt: https://resource.rahmanef.com/agents/site-setup-wizard - agent recipe: Run `npx rr add site-setup-wizard`. Show from your admin gate when `setup.status().onboarded === false`: ` settingsUpsert(f)} seedSample={() => seedSample({})} seeded={status?.seeded} ImageField={ImageField} presetOptions={presets} onPresetPreview={(n) => preview(n)} />`. `save` receives Partial + `markOnboarded: true` — back it with a `settings.upsert` mutation that patches only provided fields. Theme bridge (optional): with the theme-presets slice installed build `presetOptions` from `groupTweakcnPresets(registry.items)` + `tweakcnSwatches(p)` and pass `useThemePreset().preview` as `onPresetPreview` — the picker then live-previews while the user browses and `Lewati setup` reverts via `onPresetPreview(null)`. Omit `presetOptions` to hide the picker entirely; omit `ImageField` to hide logo/favicon upload. Full wiring recipe in the slice's HOST-SETUP.md. ### File Upload — pluggable upload + URL resolver with storage-adapter contract - slug: `file-upload` kind: `ui` category: `data` - Host-pluggable file upload + URL resolution. Ships , , useFileUpload(), useFileUrl() — all reading from a FilesAdapter the host wires via . Bundled localStorage demo adapter stores blobs as data URLs (small files only). Drop in your own adapter for Convex / S3 / GCS / R2. The slice itself has zero backend coupling, proving the storage-adapter pattern for the rest of the open-silong blocked-pending-adapter wave (cover, workspace-io, templates, …). - install: `npx rr add file-upload` - detail: https://resource.rahmanef.com/slices/file-upload - prompt: https://resource.rahmanef.com/agents/file-upload - agent recipe: Run `npx rr add file-upload`. Wrap your tree with `` — pass `useLocalStorageFilesAdapter()` for a quick demo or implement `FilesAdapter` (upload + remove + useUrl) against your backend. Then drop `` anywhere; pair with `` for rendered chips. Hooks: `useFileUpload()` returns `{upload, uploading, progress, removeFromStorage}`; `useFileUrl(storageId)` resolves to a fetchable URL (Convex adapter uses useQuery for live invalidation; demo reads localStorage synchronously). To wire S3: implement the FilesAdapter interface with presigned URLs + DELETE; the slice doesn't care which backend you pick. ### Selection — marquee multi-select + bulk actions - slug: `selection` kind: `ui` category: `ui` - Framework-agnostic multi-selection for any vertical list (Notion-style blocks, table rows, cards). Hold-and-drag on empty space draws a rubber-band rectangle — AutoCAD-style: drag RIGHT selects only fully-enclosed items (solid ring), drag LEFT selects anything the rectangle touches (dashed green ring). Click an item's edge to select (Shift = range, Cmd/Ctrl = toggle). Selecting activates items with a ring + data-block-selected attribute. Backspace/Delete bulk-deletes, Escape and click-outside clear, and a floating count toolbar offers Delete/Clear. SelectionProvider owns only the id set — the host owns the data via onBulkDelete(ids). Pairs with notion-shell (the notion-clone template wires it onto the editor); lifted from notion-page-clone's block-selection slice. - install: `npx rr add selection` - detail: https://resource.rahmanef.com/slices/selection - prompt: https://resource.rahmanef.com/agents/selection - agent recipe: Run `npx rr add selection`. Zero deps (react-dom only). Wrap your list area in ` removeMany(ids)}>`, give the surface a `position: relative` div with a ref, drop `` inside it, and wrap each item in ``. Hold-drag on empty space to rubber-band: drag RIGHT = window (only fully-enclosed, solid ring), drag LEFT = crossing (anything touched, dashed green). Edge-click an item to pick it (Shift = range, Cmd/Ctrl = toggle). Backspace/Delete bulk-deletes (focus outside a contentEditable), Escape + click-outside clear, floating `N selected · Delete · Clear` toolbar. Read state anywhere via `useSelection()`. The slice owns ONLY the id set — you own the data + the delete. Works on table rows / cards too, not just notion blocks. ### Notion UI — page editor · database · sidebar primitives - slug: `notion-ui` kind: `ui` category: `ui` - The pure, props-driven Notion-clone primitives suite behind one slug, over one shared domain-type model (Block / Page / Property / Database / DbView …). page: the page + block editor (NotionPage / NotionHeader / NotionBlock, SlashMenu, block renderers, inline-markdown decorator, built-in code (highlight.js) + equation (KaTeX)). database: a drop-in 11-view database (table/board/list/gallery/calendar/feed/chart/dashboard/form/map/timeline, 18 property/cell types, per-type column config, filter/sort/group/calculate, row peek + multi-select, cell drag-fill, formula engine, CSV/JSON import-export). sidebar: a standalone tree-nav sidebar (dnd reorder + reparent with depth projection, inline rename, per-row icon picker). All stateless + callback-CRUD — the host owns the data. Install one surface with `npx rr add notion-ui page|database|sidebar`, or all with `npx rr add notion-ui`; the shared/ domain type model is copied for every variant. NOT the full Notion app — that's the separate `notion` slice (adapter + Convex backed). - install: `npx rr add notion-ui` - detail: https://resource.rahmanef.com/slices/notion-ui - prompt: https://resource.rahmanef.com/agents/notion-ui - agent recipe: **Controlled component.** `` renders the whole surface — 11 views (table, board, list, gallery, calendar, feed, chart, dashboard, form, map, timeline), 18 cell types, filter / sort / group / calculate, row peek + multi-select, table cell drag-fill, CSV / JSON import-export. It is 100% props-driven: it owns NO data state — you hold `db` + `rows` and persist every change callback. The view tab strip scrolls horizontally and the card clips to its border, so it stays inside any container width. **1. Install** — `npx rr add notion-ui database`. Cascades the `notion-shell` peer (the domain types live there). Components import from `@/features/notion-ui`; types from `@/features/notion-ui`. **2. Minimal wire-up** — keep `db: Database` + `rows: Page[]` in your store (a Convex query result or `useState`) and pass change handlers: ```tsx import { NotionDatabase } from '@/features/notion-ui'; setValue(rowId, propId, value)} onRowRemove={removeRow} onPropertyAdd={addProperty} onViewActivate={setActiveView} onViewAdd={addView} onViewConfigChange={(viewId, patch) => patchView(viewId, patch)} /> ``` Omit any callback and that affordance goes read-only; pass `readOnly` to freeze everything at once. **3. Data shape** — `Database = { id, name, properties: Property[], views: DatabaseViewConfig[], activeViewId }`; each row `Page = { id, title, rowProps: Record }`. For `relation` / `rollup` cells also pass `pages` + `databases`; for `person` / `created_by` cells pass `userLookup(id)`. **4. Import / export** — mount `` in your toolbar: CSV/JSON in (with schema-diff), CSV/JSON + live-schema templates out. New columns arrive with a `tempId` — map it to your real backend id before writing their `rowProps`. **5. Backend (optional)** — the UI is store-agnostic. For Convex persistence copy `template-base/database-silong/convex/` (handlers → `convex/`, schema fragment merges into `convex/schema.ts`). Pick `_shared/minimal/` (single-user, noop authz) or `_shared/full/` (`@convex-dev/auth` + workspaces). See CONVEX-BACKEND.md. **Just one view?** Import it directly — `import { TableView } from '@/features/notion-ui'` — and feed it `rows` + `renderCell` + `renderColumnHeader`. ### Image Picker — one-button image/wallpaper chooser (gallery · upload · link · Unsplash · reposition) - slug: `image-picker` kind: `ui` category: `ui` - Generic image/wallpaper picker — not coupled to Notion. The headline API is ONE button (ImagePickerButton) that opens a dialog with 4 tabs: Gallery (12 colours + 8 gradients + Notion textures), Upload (drag/click, ≤8MB), Link (paste any https image URL), Unsplash (bundled curated landscapes + live search). On pick, onChange fires with an ImageValue ({ type, value, positionY?, metadata? }). ImageBanner is the optional reposition-able band — render an ImageValue as a full-width cover / profile header / card hero with hover controls: Change (opens the dialog), Reposition (drag the vertical focal point), Remove. The slice imports NO other slice and NO backend — the upload backend and Unsplash search are INJECTED as props (onUpload + searchUnsplash), so it drops into any app: wire onUpload to the `files` slice and searchUnsplash to a server route via unsplashSearchVia('/api/unsplash') that holds UNSPLASH_ACCESS_KEY server-side (never NEXT_PUBLIC). Ships a curated Unsplash fallback + gallery so it works with zero config. parseImage normalizes legacy raw-string values; imageStyle builds the focal-point CSS. Wired into the notion-page-clone template as the page cover via NotionPage's coverSlot. - install: `npx rr add image-picker` - detail: https://resource.rahmanef.com/slices/image-picker - prompt: https://resource.rahmanef.com/agents/image-picker - agent recipe: Run `npx rr add image-picker`. The headline component is `save(img)} onUpload={…} searchUnsplash={…} />` — ONE button that opens the 4-tab dialog (gallery / upload / link / Unsplash). For a reposition-able cover/hero band use `` (also passable to notion-shell's ``). Inject the backend: `onUpload` = the `files` slice's useFileUpload().upload (returns a FileRef); resolve upload images for display with `resolvedUrl` = files useFileUrl(parseFileRef(imageRef(parseImage(value))).storageId). `searchUnsplash` = `unsplashSearchVia('/api/unsplash')` — add a server route that proxies api.unsplash.com with UNSPLASH_ACCESS_KEY (never expose the key client-side). Ships a curated Unsplash + gallery fallback so it works with zero wiring. ImageValue = { type, value, positionY?, metadata? }; parseImage handles legacy string values. ### Workspace Shell — atomic (workspace × menuSet) NavContext - slug: `workspace-shell` kind: `full` category: `ui` - Unified workspace + menu navigation primitive. NavContext = (workspaceId, menuSetId) atomic pair. 2-tier dropdown switcher (workspace radio + menuSet picker), ContextBadge header chip, full editor with tabs (menus / workspace tree / settings), tiered RBAC (admin menus.manage, user menus.fork). Replaces silo'd menu-store + workspace-store slices in superspace. Resolver chain: user nav-context cache > user assignment > workspace default > system. Source: superspace. - install: `npx rr add workspace-shell` - detail: https://resource.rahmanef.com/slices/workspace-shell - prompt: https://resource.rahmanef.com/agents/workspace-shell - agent recipe: Run `npx rr add workspace-shell`. Tables prefixed `workspaceShell_*` (menuSets, menuItems, itemComponents, wsAssignments, userAssignments, rolePerms, navContext). Mount `` inside your auth provider; use `useNavContext(wsId)` to read `{workspace, menuSet, source, effectiveMenuItems, setMenuSet, forkMenuSet}`. Drop-in `` in sidebar header. Tiered RBAC: `menus.manage` for workspace-default editing, `menus.fork` for user-personal copy. Resolver chain: user cache → user assignment → workspace default → none. Pair with audit-log slice for context-switch / fork events (graceful try/catch if absent). Effective items query applies role filter via workspaceShell_rolePerms (no rolePerms → show all, pre-RBAC compat). ### Library — resource hub (prompts · visuals · snippets · links) - slug: `library` kind: `full` category: `data` - Grab-bag resource hub. One polymorphic `libraryItems` table holds six kinds — prompt, image, video, link, download, snippet — with per-kind payload fields switched on `kind` (no joins). Attribution-first: every item carries optional source/license/tools so re-shares stay correct. Collections group items. Convex-backed (schema + queries + unauthenticated mutations); SEO override fields reused from the `seo` peer slice so the surface matches blog/projects rows. Public view = filterable card grid + per-item detail with copy-to-clipboard for prompts/snippets and an opt-in upvote control. Lifted 2026-05-28 from rahmanef.com; 432-LOC mutations + 330-LOC detail split for the 200-LOC cap; Indonesian copy + custom primitives stripped (prop-driven English defaults); cross-slice auth + comments-votes coupling dropped (consumer wraps mutations + supplies the upvote handler). - install: `npx rr add library` - detail: https://resource.rahmanef.com/slices/library - prompt: https://resource.rahmanef.com/agents/library - agent recipe: Run `npx rr add seo` (peer) then `npx rr add library`. Spread `seoTables` + `libraryTables` into your root Convex schema. Wrap the unauthenticated CRUD `internalMutation`s with your auth model (see README Install). Render `` and ``. Pass `onUpvote` to enable voting (consumer-owned backend); override `copy` + `kindLabels` per consumer. ### Data Table — TanStack + shadcn - slug: `data-table` kind: `ui` category: `data` - Generic DataTable on TanStack Table v8 + shadcn Table. Sorting (3-state column headers), toolbar search bound to any column, pagination, checkbox row selection with count footer, column-visibility dropdown. density compact|comfortable + selectable on|off variant axes. Pure UI — consumer supplies columns + data. - install: `npx rr add data-table` - detail: https://resource.rahmanef.com/slices/data-table - prompt: https://resource.rahmanef.com/agents/data-table - agent recipe: Run `npx rr add data-table`. Build ColumnDef[] (use sortable headers via DataTableColumnHeader), pass data + columns to . searchKey binds the toolbar input to one column; selectable prepends the checkbox column; density tightens row padding. ### Pages CMS — block-composed multi-page editor - slug: `pages-cms` kind: `ui` category: `content` - A small multi-page CMS. PagesView (list + CRUD: create/edit/duplicate/delete/publish) + PageEditorView (metadata form + block editor) + a read-only public BlockRenderer. Pages are composed of 11 block kinds: hero, text, feature-list, cta, logo-cloud, testimonial, video, image-gallery, faq, stats, pricing-table. Ships a localStorage adapter (LocalPagesProvider) + a generic Home/About/Pricing seed so it runs env-free — or wire the bundled pagesReducer + PagesProvider to your own backend (optional Convex copy-source included). Pure UI; no Convex required. - install: `npx rr add pages-cms` - detail: https://resource.rahmanef.com/slices/pages-cms - prompt: https://resource.rahmanef.com/agents/pages-cms - agent recipe: Run `npx rr add pages-cms`. Wrap your admin surface in (localStorage, zero backend) or supply your own PagesStore via . Render for the list and for the editor route. Public catch-all looks up the page by slug and renders . Add block kinds by extending the PageBlock union + emptyBlock + the renderer/editor switches. ### Feedback States — loading skeletons + empty/error states - slug: `feedback-states` kind: `ui` category: `ui` - Two co-located placeholder surfaces behind one slug. loading: a configurable LoadingSkeleton over the shadcn Skeleton (kind presets text / card / list / table / form / page / block, overridable count + columns) plus a spinner LoadingState (inline / block / overlay) for in-flight work. empty: a configurable EmptyState over the shadcn Empty (404 / 500 / 403 / no-results / empty-list / first-use, overridable icon/title/copy/actions) plus an ErrorPage full-page wrapper for app/not-found.tsx and app/error.tsx. Install one surface with `npx rr add feedback-states loading|empty`, or both with `npx rr add feedback-states`. Replaces ad-hoc animate-pulse divs, hand-rolled Loader2 spans, and one-off error pages. - install: `npx rr add feedback-states` - detail: https://resource.rahmanef.com/slices/feedback-states - prompt: https://resource.rahmanef.com/agents/feedback-states - agent recipe: Run `npx rr add feedback-states` for both, or `npx rr add feedback-states loading` / `empty` for one surface. loading: mirrors streamed content, kind="page" drops into route loading.tsx, for in-flight work. empty: in zero-data spots, in app/not-found.tsx and kind="500" in app/error.tsx. Every preset overridable per use. ### Marketing Chrome — Header + Footer - slug: `marketing-chrome` kind: `ui` category: `ui` - MarketingHeader (split | centered | minimal layouts, sticky option, mobile sheet menu) + MarketingFooter (columns | slim layouts, link columns, social icons, legal bar). Brand / nav / CTA / columns all props — no hardcoded content. Lucide stand-ins for brand glyphs; swap a brand icon set post-copy (README). - install: `npx rr add marketing-chrome` - detail: https://resource.rahmanef.com/slices/marketing-chrome - prompt: https://resource.rahmanef.com/agents/marketing-chrome - agent recipe: Run `npx rr add marketing-chrome`. Feed MarketingHeader { brand, nav[], cta, layout } and MarketingFooter { brand, columns[], social[], legal[], layout }. Header layout split is the default marketing pattern; footer columns for full sites, slim for single-pagers. ### Settings — account + appearance shells - slug: `settings` kind: `ui` category: `ui` - Two settings surfaces behind one slug, each adapter-driven so the slice owns no data. account: SettingsShell two-column surface (nav collapses to a Select on mobile) — Profile (avatar/name/email/bio), Preferences (theme/language/density), Notifications (switch rows), Danger zone (AlertDialog-confirmed delete) over an ASYNC SettingsAdapter { load, save(patch) } with optimistic save + rollback; createMemoryAdapter ships for demos. appearance: AppearancePanel (style/mode/accent/wallpaper/reduce-transparency/display) over a SYNC per-setting AppearanceAdapter, plus the generic SettingsSection / SettingsRow / Segmented / AccentSwatches primitives you compose custom panels from. Install one surface with `npx rr add settings account|appearance`, or both with `npx rr add settings`. - install: `npx rr add settings` - detail: https://resource.rahmanef.com/slices/settings - prompt: https://resource.rahmanef.com/agents/settings - agent recipe: Run `npx rr add settings` for both, or `npx rr add settings account` / `appearance` for one. account: implement SettingsAdapter { load, save } over your backend (Convex query + mutation), pass to ; save gets per-section partial patches (shallow-merge server-side); onDeleteAccount wires the danger zone. appearance: build an AppearanceAdapter (per-setting SegSetting values) from your appearance store, pass to ; or compose custom panels from ///. ### Notifications Center — bell + inbox - slug: `notifications-center` kind: `ui` category: `ui` - NotificationBell (ghost icon button, unread badge, popover or sheet surface) + NotificationList (All/Unread tabs, mark-all-read, clear, ScrollArea rows with kind icon, relative time, hover actions). NotificationsAdapter contract (list/markRead/markAllRead/dismiss/clear) with a useSyncExternalStore-friendly memory adapter included — swap in Convex for production (sketch in README). - install: `npx rr add notifications-center` - detail: https://resource.rahmanef.com/slices/notifications-center - prompt: https://resource.rahmanef.com/agents/notifications-center - agent recipe: Run `npx rr add notifications-center`. Mount in your topbar. Implement NotificationsAdapter over your feed (Convex query + mutations) or start with createMemoryNotificationsAdapter(seed). surface="sheet" for mobile-heavy apps. ### Design Studio — photo / social design canvas - slug: `design-studio` kind: `ui` category: `os` - A layered canvas studio: image/text/shape layers with filters, masks, transforms, safe-area guides and aspect presets (1:1/4:5/9:16/16:9), plus an export modal (download / copy / import JSON). Runs fully offline on bundled gradient-SVG samples. Host wiring is one call: configureMediaStudio({ saveDoc, imageSources }) lights up Save-to-host and feeds real image sources. Self-contained: inspector hooks are inert seams in lib/host.ts. - install: `npx rr add design-studio` - detail: https://resource.rahmanef.com/slices/design-studio - prompt: https://resource.rahmanef.com/agents/design-studio - agent recipe: Stack: Next 16 + React 19 + Tailwind 4 + shadcn/ui. Layered canvas editor. Fully client-side; no backend required. STEP 1 — Install. `npx rr add design-studio`. Ensure `@/features/design-studio` resolves and Tailwind scans the slice folder. STEP 2 — Deps. npm: `lucide-react`. shadcn: button, dialog, badge, tooltip, scroll-area. STEP 3 — Mount. `` in a height-bearing box — unwired it edits bundled sample layers. Or register `mediaStudioApp` in an appshell manifest. STEP 4 — Host wiring. `configureMediaStudio({ saveDoc, imageSources })` — saveDoc persists the serialized document (enables Save-to-host in the export modal); imageSources supplies image URLs for new layers. ### Quicklinks — website shortcuts with favicons - slug: `quicklinks` kind: `ui` category: `os` - A website-shortcut grid: add/remove links with auto favicons (Google s2) and new-tab open. State lives behind an injectable QuicklinksStore — createLocalStore persists to localStorage (SSR-safe hydrate), createMemoryStore suits previews/tests, configureQuicklinks swaps in a host store. Pairs with appshell: the useQuickLinks capability + QuicklinkIcon surface the same links in the dock/Launchpad/mobile grid. - install: `npx rr add quicklinks` - detail: https://resource.rahmanef.com/slices/quicklinks - prompt: https://resource.rahmanef.com/agents/quicklinks - agent recipe: Stack: Next 16 + React 19 + Tailwind 4 + shadcn/ui. Website shortcut grid. Fully client-side; no backend required. STEP 1 — Install. `npx rr add quicklinks`. Ensure `@/features/quicklinks` resolves and Tailwind scans the slice folder. STEP 2 — Deps. npm: `lucide-react`. shadcn: button. STEP 3 — Mount. `` — unwired it persists to localStorage ("rr:quicklinks") with 4 demo seeds. Or register `quicklinksApp` in an appshell manifest. STEP 4 — Host store. `configureQuicklinks(store)` with { get, subscribe, add, remove, hydrate? } — or feed appshell's useQuickLinks capability from the same store so dock shortcuts stay in sync. ## Agent API JSON catalog endpoints for AI agents: ``` GET /api/knowledge # full catalog (resources + slices + layouts) GET /api/knowledge?type=slice # only Tier-3 slices GET /api/knowledge?type=template # only website templates GET /api/knowledge?type=layout # only layouts (sections, pages) GET /api/knowledge?slice= # detail for one slice GET /api/knowledge?resource= # detail for any resource GET /api/knowledge?layout= # detail for one layout (legacy) ``` Response shape: `{ resources: [...], slices: [...], layouts: [...], counts: {...}, rules: [...] }`. Each `resources[]` entry has `{ source, slug, title, description, category, tags, href, previewPath, install }` — agents can install any via `install` field. ## Hard rules (12-rule doctrine — full text at /best-practice) - NO Clerk. Use @convex-dev/auth. - All UI = shadcn primitives. No raw HTML buttons / dialogs / native date/file inputs. - Copy-first flow. Never greenfield — copy from a source project, adjust imports. - Stack: Next 16 + React 19 + Tailwind 4 + Convex self-hosted + TS strict. - Next 16: use `proxy.ts` not `middleware.ts`; `next/link` + `next/image` only. - Workspace isolation per Convex query (`.withIndex('by_workspace', …)`). - No bare `.collect()` — use `.withIndex(...).take(N)` or paginate. - Every public mutation/query MUST declare `args:` validators + server-side authz (`requireUser`/`requireAdmin`). - RBAC + audit log on every mutation. - `NEXT_PUBLIC_*` only for non-sensitive values. - **File modularity: 200-line hard cap per source file** (excl. catalog/seed/_generated). Compose, don't accumulate. Gate: `npm run audit:file-size`. - Slice contract: `slice.json` (with an embedded `contract` block) + `slice.manifest.json` mandatory per slice. Imports resolve via `@/components/ui/*`, `@/shared/*`, `@/features//*`, `@convex/*`, or relative-within-slice. - Solo-dev: push direct to main (no PR); Dokploy auto-deploys on push. ## How to install Fresh project (recommended): ``` npx rahman-resources init my-app # or alias: npx rr init my-app cd my-app cp .env.example .env.local # fill NEXT_PUBLIC_CONVEX_URL npm install --legacy-peer-deps npx convex dev --once # generates convex/_generated npm run dev ``` Add a template or slice into an existing project: ``` npx rr add # auto-detects TEMPLATE vs SLICE, # auto-augments .env.example, # auto-installs npm deps ``` ## Audit chain (run before deploy) ``` npm run validate:all # full chain: slices + templates + file-size + manifests + contracts npm run audit:slices # slice contract violations npm run audit:templates # template scaffold violations npm run audit:file-size # 200-line modularity cap ``` ## Deploy (Dokploy via sc-all) ``` # Invoke the sc-all skill in Claude Code — orchestrates # sc-dokploy + sc-convex: creates repo, pushes, configures Dokploy, # deploys self-hosted Convex backend, sets DNS, triggers build. ```