Kapable starter template: Lightweight Helpdesk (auth, data, board, comms)
- TypeScript 81.8%
- CSS 14.7%
- JavaScript 3.5%
Multi-service starter: kapable-data is the source of truth for tickets + replies; kapable-board mirrors each ticket as a triage story (open/in_progress/ resolved lanes); kapable-comms sends real email replies to the requester via the org's at_ app token. Impeccable RR7 UI on the --kp-* token system. |
||
|---|---|---|
| app | ||
| public | ||
| .gitignore | ||
| .npmrc | ||
| bun.lock | ||
| package.json | ||
| react-router.config.ts | ||
| README.md | ||
| seed.ts | ||
| tsconfig.json | ||
| vite.config.ts | ||
Kapable Starter Kit
The on-brand fork-point for Kapable v2 apps. Every starter/template app forks this repo, then builds its own routes on top.
What you get out of the box:
- React Router 7 SSR + TypeScript, with the
/healthresource route the deploy pipeline gates on (keep it). - Kapable theme system — the canonical
--kp-*token set fromkapable-theme.css,[data-theme="dark|light"]on<html>, FOUC-free first paint (the in-<head>script +kapable-theme.js), and a theme toggle wired towindow.KapableTheme.cycle(). Tailwind v4 is bridged to the same tokens (bg-surface,text-fg,border-line,text-accent, …). @kapable/sdkwired server-side inapp/lib/kapable.server.tswith explicit per-service base URLs (never the bareapi.kapable.aidefault for everything). Session (kses_) read from the request; tokens never reach the client bundle.- Error → toast on every fetch (sonner), a skip-to-content link, a
global
:focus-visiblering, 44px touch targets, and a branded error boundary.
Develop
bun install
bun run dev
Build + run (what the platform does)
bun run build
bun run start # react-router-serve on :3000
Calling the SDK
All SDK calls are server-side (loaders/actions). Always pin the client to the service you're calling — each has its own base URL:
import { kapable } from "~/lib/kapable.server";
export async function loader({ request }) {
const data = kapable("data", { request }); // data.kapable.ai
const { data: rows } = await data.data.listRows("my_table");
return { rows };
}
| Service | Base URL | Notes |
|---|---|---|
| auth, ai, data, comms, board, billing, store, harbor | dedicated subdomain | own Caddy host block |
| wiki, knowledge, secrets, warrant, projects, herald | https://api.kapable.ai |
path-routed gateway (no dedicated subdomain — the subdomain falls through to launchpad) |
api.kapable.ai reaches every service via /v1/* and is the safe universal
choice. Prefer the caller's kses_ session over a bare sk_live_ for writes.
Add a route
- Create
app/routes/<name>.tsx. - Register it in
app/routes.ts— RR7 404s unregistered routes silently.
Theme tokens
Defined in public/kapable-theme.css. Use var(--kp-bg), --kp-surface,
--kp-text, --kp-accent, --kp-border, --kp-danger/success/warn/info, or
the Tailwind aliases. A single data-theme flip recolors everything.