
MCP 도구 호출과 LLM 트래픽을 보안, 거버넌스, 관찰하는 오픈소스 게이트웨이로, API 키 인증과 모니터링용 관리자 콘솔을 제공합니다.
Tuskira AI Agent Gateway의 관리자 콘솔. React 19 + Vite + TypeScript (strict) + Tailwind CSS 4 + shadcn/ui.
Node 26+ 및 npm 11+ 필요 (pnpm 미사용).
npm install
npm run dev
개발 서버는 /api를 http://localhost:8081로 프록시하므로(vite.config.ts 참조),
UI와 함께 게이트웨이를 :8081에서 실행하세요. /login에서 게이트웨이가 발급한
API 키(gk_…)로 로그인하세요.
리포지토리 루트에서 대신 다음을 실행할 수 있습니다:
make ui-install
make ui-dev
npm run build
dist/에 프로덕션 번들을 생성합니다. 프로덕션에서는 게이트웨이 자체가 :8081의
/에서 이 번들을 제공하므로, 앱은 동일 출처(same-origin)로 API와 통신합니다 —
프록시가 필요하지 않습니다.
make ui-build # 리포지토리 루트에서
npm run lint # eslint
npm run typecheck # tsc --noEmit (project references)
npm run test # vitest
npm run format:check # prettier --check
npx shadcn@latest add <component>
이 프로젝트의 components.json은 Vite 템플릿, radix 베이스, neutral 베이스
컬러, 테마용 CSS 변수를 대상으로 하며, @/* 임포트 별칭은 src/*로 해석됩니다.
새 컴포넌트는 src/components/ui/에 작성됩니다.
tokens.json(리포지토리 루트)은 디자인 시스템의 단일 진실 공급원(single source of
truth)입니다 — 색상, 간격, 반경, 그림자, 폰트. 편집 후 npm run gen:tokens를
실행하여 다음을 재생성하세요:
src/styles/tokens.css — 원시 토큰을 CSS 사용자 정의 속성으로 표현
(라이트 값은 :root, 다크 오버라이드는 .dark), 디자이너의 자체 토큰 이름
(--indigo-9, --sev-high, --r-4, --shadow-1, ...)을 유지합니다.src/styles/tokens.ts — 동일한 범주형 색상 스케일(colors.indigo,
colors.slate, colors.sev, colors.status, colors.brand)과 fonts,
radii, shadows를 비CSS 소비자(예: recharts 시리즈 색상)를 위해 제공합니다.src/index.css는 shadcn의 시맨틱 변수(--background, --primary,
--sidebar, ...)를 이 토큰들에 매핑하고, Tailwind v4 @theme 항목을 등록하여
bg-indigo-9, text-text-muted, border-border-strong, shadow-1,
rounded-r-4, font-mono와 같은 유틸리티를 앱 어디서나 사용할 수 있게 합니다.
src/styles/tokens.css / src/styles/tokens.ts를 직접 편집하지 마세요 — 생성기에
의해 덮어쓰여집니다. src/test/tokens.test.ts는 모든 tokens.ts 항목이
tokens.css에 일치하는 선언을 가지고 있는지 검증합니다.
web/
├── index.html
├── vite.config.ts # React + Tailwind plugins, /api dev proxy, vitest config
├── components.json # shadcn/ui config
├── tokens.json # design-token source of truth (see Design tokens)
├── scripts/
│ └── gen-tokens.mjs # tokens.json -> src/styles/tokens.{css,ts}
├── src/
│ ├── main.tsx # ReactDOM root
│ ├── App.tsx # QueryClientProvider, AuthProvider, RouterProvider
│ ├── index.css # Tailwind entrypoint + semantic token mapping
│ ├── styles/
│ │ ├── tokens.css # generated — raw design tokens as CSS vars
│ │ └── tokens.ts # generated — same tokens for non-CSS use
│ ├── auth/
│ │ ├── AuthContext.tsx # AuthProvider / useAuth — principal, signIn, signOut
│ │ └── RequireAuth.tsx # route guard for the authenticated shell
│ ├── components/
│ │ ├── ui/ # shadcn/ui primitives (generated, don't hand-edit)
│ │ ├── layout/ # AppShell, Sidebar, TopBar
│ │ └── app/ # ComingSoon, StatCard
│ ├── hooks/
│ │ └── use-theme.ts # light/dark toggle, class strategy, localStorage
│ ├── lib/
│ │ ├── api.ts # fetch wrapper: bearer auth, 401 handling, ApiError
│ │ ├── nav.ts # single source of truth for sidebar nav + routes
│ │ ├── queries.ts # react-query hooks (useHealth)
│ │ ├── query-client.ts # QueryClient instance
│ │ ├── types.ts # Principal, HealthResponse, ApiErrorBody
│ │ └── utils.ts # cn() (shadcn)
│ ├── routes/
│ │ ├── router.tsx # createBrowserRouter (data router)
│ │ ├── LoginPage.tsx
│ │ ├── OverviewPage.tsx
│ │ └── DocsPage.tsx
│ └── test/
│ ├── setup.ts
│ ├── LoginPage.test.tsx
│ ├── Sidebar.test.tsx
│ ├── SignOut.test.tsx
│ └── tokens.test.ts