feat: Add intelligent auto-router and enhanced integrations

- Add intelligent-router.sh hook for automatic agent routing
- Add AUTO-TRIGGER-SUMMARY.md documentation
- Add FINAL-INTEGRATION-SUMMARY.md documentation
- Complete Prometheus integration (6 commands + 4 tools)
- Complete Dexto integration (12 commands + 5 tools)
- Enhanced Ralph with access to all agents
- Fix /clawd command (removed disable-model-invocation)
- Update hooks.json to v5 with intelligent routing
- 291 total skills now available
- All 21 commands with automatic routing

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
admin
2026-01-28 00:27:56 +04:00
Unverified
parent 3b128ba3bd
commit b52318eeae
1724 changed files with 351216 additions and 0 deletions

View File

@@ -0,0 +1,38 @@
import { Outlet } from '@tanstack/react-router';
import { HelmetProvider, Helmet } from 'react-helmet-async';
import { QueryProvider } from '@/components/providers/QueryProvider';
import { AnalyticsProvider } from '@/lib/analytics/index';
import { EventBusProvider } from '@/components/providers/EventBusProvider';
import { ApprovalProvider } from '@/components/hooks/ApprovalContext';
import { ChatProvider } from '@/components/hooks/ChatContext';
import { SpeechReset } from '@/components/ui/speech-reset';
import { ToastContainer } from '@/components/Toast/ToastContainer';
export function RootLayout() {
return (
<HelmetProvider>
<Helmet>
<title>Dexto Web UI</title>
<meta
name="description"
content="Interactive playground for testing MCP tools and talking to AI agents"
/>
</Helmet>
<QueryProvider>
<AnalyticsProvider>
<EventBusProvider>
<ApprovalProvider>
<ChatProvider>
<SpeechReset />
<div className="flex h-screen w-screen flex-col supports-[height:100svh]:h-[100svh] supports-[height:100dvh]:h-[100dvh]">
<Outlet />
</div>
<ToastContainer />
</ChatProvider>
</ApprovalProvider>
</EventBusProvider>
</AnalyticsProvider>
</QueryProvider>
</HelmetProvider>
);
}

View File

@@ -0,0 +1,11 @@
import React from 'react';
import ReactDOM from 'react-dom/client';
import { RouterProvider } from '@tanstack/react-router';
import { router } from './router';
import './styles/globals.css';
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<RouterProvider router={router} />
</React.StrictMode>
);

View File

@@ -0,0 +1,17 @@
import { useParams } from '@tanstack/react-router';
import { Helmet } from 'react-helmet-async';
import ChatApp from '@/components/ChatApp';
export function ChatPage() {
const { sessionId } = useParams({ from: '/chat/$sessionId' });
return (
<>
<Helmet>
<title>Chat · Dexto</title>
<meta name="description" content={`Chat session ${sessionId}`} />
</Helmet>
<ChatApp sessionId={sessionId} />
</>
);
}

View File

@@ -0,0 +1,5 @@
import ChatApp from '@/components/ChatApp';
export function HomePage() {
return <ChatApp />;
}

View File

@@ -0,0 +1,20 @@
import { Link } from '@tanstack/react-router';
import { Button } from '@/components/ui/button';
import { Home } from 'lucide-react';
export function NotFoundPage() {
return (
<div className="flex h-screen items-center justify-center bg-background">
<div className="text-center space-y-6">
<h1 className="text-6xl font-bold text-foreground">404</h1>
<p className="text-xl text-muted-foreground">Page not found</p>
<Button variant="default" className="gap-2" asChild>
<Link to="/">
<Home className="h-4 w-4" />
Return Home
</Link>
</Button>
</div>
</div>
);
}

View File

@@ -0,0 +1,14 @@
import { Helmet } from 'react-helmet-async';
import PlaygroundView from '@/components/Playground/PlaygroundView';
export function PlaygroundPage() {
return (
<>
<Helmet>
<title>Playground · Dexto</title>
<meta name="description" content="Test MCP tools in an interactive playground" />
</Helmet>
<PlaygroundView />
</>
);
}

View File

@@ -0,0 +1,42 @@
import { createRouter, createRootRoute, createRoute } from '@tanstack/react-router';
import { RootLayout } from './layouts/RootLayout';
import { HomePage } from './pages/HomePage';
import { ChatPage } from './pages/ChatPage';
import { PlaygroundPage } from './pages/PlaygroundPage';
import { NotFoundPage } from './pages/NotFoundPage';
const rootRoute = createRootRoute({
component: RootLayout,
notFoundComponent: NotFoundPage,
});
const homeRoute = createRoute({
getParentRoute: () => rootRoute,
path: '/',
component: HomePage,
});
const chatRoute = createRoute({
getParentRoute: () => rootRoute,
path: '/chat/$sessionId',
component: ChatPage,
});
const playgroundRoute = createRoute({
getParentRoute: () => rootRoute,
path: '/playground',
component: PlaygroundPage,
});
const routeTree = rootRoute.addChildren([homeRoute, chatRoute, playgroundRoute]);
export const router = createRouter({
routeTree,
defaultPreload: 'intent',
});
declare module '@tanstack/react-router' {
interface Register {
router: typeof router;
}
}

View File

@@ -0,0 +1,287 @@
@import url('https://fonts.googleapis.com/css2?family=Nunito+Sans:wght@200;300;400;500;600;700;800&display=swap');
@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600&display=swap');
@import "tailwindcss";
@custom-variant dark (&:where(.dark, .dark *));
@theme inline {
--color-background: var(--background);
--color-foreground: var(--foreground);
--font-sans: 'Nunito Sans', system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
--font-mono: 'JetBrains Mono', ui-monospace, monospace;
--color-sidebar-ring: var(--sidebar-ring);
--color-sidebar-border: var(--sidebar-border);
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
--color-sidebar-accent: var(--sidebar-accent);
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
--color-sidebar-primary: var(--sidebar-primary);
--color-sidebar-foreground: var(--sidebar-foreground);
--color-sidebar: var(--sidebar);
--color-chart-5: var(--chart-5);
--color-chart-4: var(--chart-4);
--color-chart-3: var(--chart-3);
--color-chart-2: var(--chart-2);
--color-chart-1: var(--chart-1);
--color-ring: var(--ring);
--color-input: var(--input);
--color-border: var(--border);
--color-destructive: var(--destructive);
--color-accent-foreground: var(--accent-foreground);
--color-accent: var(--accent);
--color-muted-foreground: var(--muted-foreground);
--color-muted: var(--muted);
--color-secondary-foreground: var(--secondary-foreground);
--color-secondary: var(--secondary);
--color-primary-foreground: var(--primary-foreground);
--color-primary: var(--primary);
--color-popover-foreground: var(--popover-foreground);
--color-popover: var(--popover);
--color-card-foreground: var(--card-foreground);
--color-card: var(--card);
--radius-sm: calc(var(--radius) - 2px);
--radius-md: var(--radius);
--radius-lg: calc(var(--radius) + 2px);
--radius-xl: calc(var(--radius) + 6px);
}
:root {
/* Tell browsers we handle light/dark modes ourselves */
color-scheme: light dark;
--radius: 0.5rem;
/* Slightly warmer off-white background for better contrast */
--background: #faf9f7;
--foreground: #1a1a1a;
/* Better card contrast - pure white stands out more */
--card: #ffffff;
--card-foreground: #1a1a1a;
--popover: #ffffff;
--popover-foreground: #1a1a1a;
--primary: #1a1a1a;
--primary-foreground: #fafafa;
/* More differentiated secondary/muted colors */
--secondary: #f0efed;
--secondary-foreground: #1a1a1a;
--muted: #f0efed;
--muted-foreground: #636363;
--accent: #f0efed;
--accent-foreground: #1a1a1a;
--destructive: #ef4444;
--destructive-foreground: #fafafa;
/* Subtle warm borders */
--border: #e5e4e1;
--input: #ffffff;
--ring: #1a1a1a;
--chart-1: #3b82f6;
--chart-2: #10b981;
--chart-3: #f59e0b;
--chart-4: #ef4444;
--chart-5: #8b5cf6;
/* Sidebar slightly different for depth */
--sidebar: #f5f4f2;
--sidebar-foreground: #1a1a1a;
--sidebar-primary: #1a1a1a;
--sidebar-primary-foreground: #fafafa;
--sidebar-accent: #eaeae8;
--sidebar-accent-foreground: #1a1a1a;
--sidebar-border: #e5e4e1;
--sidebar-ring: #1a1a1a;
}
.dark {
--background: #0f0f0f;
--foreground: #fafafa;
--card: #141414;
--card-foreground: #fafafa;
--popover: #141414;
--popover-foreground: #fafafa;
--primary: #fafafa;
--primary-foreground: #0f0f0f;
--secondary: #262626;
--secondary-foreground: #fafafa;
--muted: #262626;
--muted-foreground: #a1a1aa;
--accent: #262626;
--accent-foreground: #fafafa;
--destructive: #dc2626;
--destructive-foreground: #fafafa;
--border: #525252;
--input: #262626;
--ring: #d4d4d8;
--chart-1: #3b82f6;
--chart-2: #10b981;
--chart-3: #f59e0b;
--chart-4: #ef4444;
--chart-5: #8b5cf6;
--sidebar: #141414;
--sidebar-foreground: #fafafa;
--sidebar-primary: #fafafa;
--sidebar-primary-foreground: #0f0f0f;
--sidebar-accent: #262626;
--sidebar-accent-foreground: #fafafa;
--sidebar-border: #525252;
--sidebar-ring: #d4d4d8;
}
@layer base {
html {
/* Use Nunito Sans with system fallback */
font-family: 'Nunito Sans', system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif;
font-weight: 400;
font-feature-settings: 'cv11', 'ss01';
}
* {
@apply border-border;
}
body {
@apply bg-background text-foreground antialiased;
font-feature-settings: 'rlig' 1, 'calt' 1;
}
/* Improved focus states */
*:focus-visible {
@apply outline-none ring-2 ring-ring ring-offset-2 ring-offset-background;
}
/* Custom scrollbar */
::-webkit-scrollbar {
width: 6px;
height: 6px;
}
::-webkit-scrollbar-track {
@apply bg-transparent;
}
::-webkit-scrollbar-thumb {
@apply bg-border rounded-full;
}
::-webkit-scrollbar-thumb:hover {
@apply bg-muted-foreground/50;
}
/* Smooth animations */
.animate-in {
animation: animateIn 200ms ease;
}
.animate-out {
animation: animateOut 150ms ease;
}
@keyframes animateIn {
from {
opacity: 0;
transform: translateY(-4px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes animateOut {
from {
opacity: 1;
transform: translateY(0);
}
to {
opacity: 0;
transform: translateY(-4px);
}
}
/* Typography improvements */
h1, h2, h3, h4, h5, h6 {
@apply font-medium tracking-tight;
}
/* Better code font */
code, pre, .font-mono {
font-family: 'JetBrains Mono', ui-monospace, monospace;
font-feature-settings: 'liga' 1, 'calt' 1;
}
/* Minimal button hover states */
.btn-minimal-hover {
@apply transition-colors duration-150 hover:bg-muted/50;
}
/* Glass effect for cards */
.glass-card {
@apply backdrop-blur-xl bg-background/80 border border-border/50;
}
/* Subtle shadows */
.shadow-minimal {
box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
}
.shadow-minimal-lg {
box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
}
/* Dark mode improvements */
.dark .shadow-minimal {
box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.3);
}
.dark .shadow-minimal-lg {
box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.4), 0 2px 4px -2px rgb(0 0 0 / 0.2);
}
/* Slide-up animation for new content */
.animate-slide-up {
animation: slide-up 0.3s ease-out;
}
@keyframes slide-up {
from {
opacity: 0;
transform: translateY(8px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* Fade-in for smooth reveals */
.animate-fade-in {
animation: fade-in 0.2s ease-out;
}
@keyframes fade-in {
from { opacity: 0; }
to { opacity: 1; }
}
/* GPU-accelerated utility */
.gpu {
transform: translateZ(0);
will-change: transform;
}
/* Thin scrollbar utility */
.scrollbar-thin::-webkit-scrollbar {
width: 4px;
height: 4px;
}
.scrollbar-thin::-webkit-scrollbar-track {
@apply bg-transparent;
}
.scrollbar-thin::-webkit-scrollbar-thumb {
@apply bg-muted-foreground/20 rounded-full;
}
.scrollbar-thin::-webkit-scrollbar-thumb:hover {
@apply bg-muted-foreground/30;
}
}