
AIエージェントの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 の / で配信するため、アプリは同一オリジンで 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 (リポジトリのルート) はデザインシステム — 色、スペーシング、角丸、シャドウ、フォント — の
唯一の信頼できる情報源である。編集後は 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