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,136 @@
import React from 'react';
import { Paperclip, File, FileAudio } from 'lucide-react';
import { Button } from '../ui/button';
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from '../ui/dropdown-menu';
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '../ui/tooltip';
import { cn } from '@/lib/utils';
interface AttachButtonProps {
onImageAttach: () => void;
onPdfAttach: () => void;
onAudioAttach: () => void;
className?: string;
supports?: {
image?: boolean;
pdf?: boolean;
audio?: boolean;
};
/** Use lg breakpoint instead of md for responsive text */
useLargeBreakpoint?: boolean;
}
export function AttachButton({
onImageAttach,
onPdfAttach,
onAudioAttach,
className,
supports,
useLargeBreakpoint = false,
}: AttachButtonProps) {
const [open, setOpen] = React.useState(false);
const imageSupported = supports?.image !== false; // default to true if unknown
const pdfSupported = supports?.pdf !== false; // default to true if unknown
const audioSupported = supports?.audio !== false;
return (
<DropdownMenu open={open} onOpenChange={setOpen}>
<DropdownMenuTrigger asChild>
<Button
variant="ghost"
size="sm"
className={cn(
'h-8 px-2 text-sm text-muted-foreground hover:text-foreground rounded-full',
useLargeBreakpoint ? 'lg:px-3' : 'md:px-3',
className
)}
aria-label="Attach File"
>
<Paperclip
className={cn('h-3 w-3', useLargeBreakpoint ? 'lg:mr-1.5' : 'md:mr-1.5')}
/>
<span className={cn('hidden', useLargeBreakpoint ? 'lg:inline' : 'md:inline')}>
Attach
</span>
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent side="top" align="start">
<DropdownMenuItem
onClick={() => {
if (!imageSupported) return;
onImageAttach();
setOpen(false);
}}
className={!imageSupported ? 'opacity-50 cursor-not-allowed' : undefined}
aria-disabled={!imageSupported}
>
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<div className="flex items-center">
<Paperclip className="h-4 w-4 mr-2" /> Image
</div>
</TooltipTrigger>
{!imageSupported && (
<TooltipContent side="bottom">
Unsupported for this model
</TooltipContent>
)}
</Tooltip>
</TooltipProvider>
</DropdownMenuItem>
<DropdownMenuItem
onClick={() => {
if (!pdfSupported) return;
onPdfAttach();
setOpen(false);
}}
className={!pdfSupported ? 'opacity-50 cursor-not-allowed' : undefined}
aria-disabled={!pdfSupported}
>
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<div className="flex items-center">
<File className="h-4 w-4 mr-2" /> PDF
</div>
</TooltipTrigger>
{!pdfSupported && (
<TooltipContent side="bottom">
Unsupported for this model
</TooltipContent>
)}
</Tooltip>
</TooltipProvider>
</DropdownMenuItem>
<DropdownMenuItem
onClick={() => {
if (!audioSupported) return;
onAudioAttach();
setOpen(false);
}}
className={!audioSupported ? 'opacity-50 cursor-not-allowed' : undefined}
aria-disabled={!audioSupported}
>
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<div className="flex items-center">
<FileAudio className="h-4 w-4 mr-2" /> Audio file
</div>
</TooltipTrigger>
{!audioSupported && (
<TooltipContent side="bottom">
Unsupported for this model
</TooltipContent>
)}
</Tooltip>
</TooltipProvider>
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
);
}

View File

@@ -0,0 +1,30 @@
import React from 'react';
import { cn } from '@/lib/utils';
interface ButtonFooterProps {
leftButtons?: React.ReactNode;
rightButtons?: React.ReactNode;
className?: string;
}
export function ButtonFooter({ leftButtons, rightButtons, className }: ButtonFooterProps) {
return (
<div
className={cn(
// Normal flow footer row
'flex items-center justify-between',
// Fixed footer height with safe area padding for mobile
'h-12 px-3 pr-4',
// No visual separator; seamless with editor area
// Ensure interactions work normally
className
)}
>
{/* Left side buttons (Attach, Record, etc.) */}
<div className="flex items-center gap-2">{leftButtons}</div>
{/* Right side buttons (Send) */}
<div className="flex items-center gap-2">{rightButtons}</div>
</div>
);
}

View File

@@ -0,0 +1,31 @@
import React from 'react';
import { cn } from '@/lib/utils';
interface ChatInputContainerProps {
children: React.ReactNode;
className?: string;
}
export function ChatInputContainer({ children, className }: ChatInputContainerProps) {
return (
<div
className={cn(
'relative',
'w-full',
// Vertical layout: editor (scrollable) + footer (fixed)
// Allow overlays (e.g., slash autocomplete) to escape the editor area
'flex flex-col overflow-visible',
'max-h-[max(35svh,5rem)]', // commonly used responsive height
'border border-border/30',
// Opaque background to prevent underlying text/blur artifacts
'bg-background',
'rounded-3xl',
'shadow-lg hover:shadow-xl',
'transition-all duration-200',
className
)}
>
{children}
</div>
);
}

View File

@@ -0,0 +1,66 @@
import React from 'react';
import { Mic, StopCircle } from 'lucide-react';
import { Button } from '../ui/button';
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '../ui/tooltip';
import { cn } from '@/lib/utils';
interface RecordButtonProps {
isRecording: boolean;
onToggleRecording: () => void;
className?: string;
disabled?: boolean;
/** Use lg breakpoint instead of md for responsive text */
useLargeBreakpoint?: boolean;
}
export function RecordButton({
isRecording,
onToggleRecording,
className,
disabled,
useLargeBreakpoint = false,
}: RecordButtonProps) {
const btn = (
<Button
variant="ghost"
size="sm"
onClick={() => {
if (!disabled) onToggleRecording();
}}
className={cn(
'h-8 px-2 text-sm rounded-full',
useLargeBreakpoint ? 'lg:px-3' : 'md:px-3',
disabled
? 'opacity-50 cursor-not-allowed'
: 'text-muted-foreground hover:text-foreground',
className
)}
aria-label={isRecording ? 'Stop recording' : 'Record audio'}
aria-disabled={disabled ? true : undefined}
>
{isRecording ? (
<StopCircle
className={cn(
'h-3 w-3 text-red-500',
useLargeBreakpoint ? 'lg:mr-1.5' : 'md:mr-1.5'
)}
/>
) : (
<Mic className={cn('h-3 w-3', useLargeBreakpoint ? 'lg:mr-1.5' : 'md:mr-1.5')} />
)}
<span className={cn('hidden', useLargeBreakpoint ? 'lg:inline' : 'md:inline')}>
{isRecording ? 'Stop' : 'Record'}
</span>
</Button>
);
return disabled ? (
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>{btn}</TooltipTrigger>
<TooltipContent side="bottom">Unsupported for this model</TooltipContent>
</Tooltip>
</TooltipProvider>
) : (
btn
);
}

View File

@@ -0,0 +1,40 @@
import React from 'react';
import { Zap } from 'lucide-react';
import { Switch } from '../ui/switch';
import { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider } from '../ui/tooltip';
interface StreamToggleProps {
isStreaming: boolean;
onStreamingChange: (enabled: boolean) => void;
className?: string;
}
export function StreamToggle({ isStreaming, onStreamingChange, className }: StreamToggleProps) {
return (
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<div className={`flex items-center gap-1.5 cursor-pointer ${className || ''}`}>
<Zap
className={`h-3 w-3 ${isStreaming ? 'text-blue-500' : 'text-muted-foreground'}`}
/>
<Switch
checked={isStreaming}
onCheckedChange={onStreamingChange}
className="scale-75"
aria-label="Toggle streaming"
/>
</div>
</TooltipTrigger>
<TooltipContent side="bottom">
<p>{isStreaming ? 'Streaming enabled' : 'Streaming disabled'}</p>
<p className="text-xs opacity-75">
{isStreaming
? 'Responses will stream in real-time'
: 'Responses will arrive all at once'}
</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
);
}

View File

@@ -0,0 +1,5 @@
export { ChatInputContainer } from './ChatInputContainer';
export { ButtonFooter } from './ButtonFooter';
export { StreamToggle } from './StreamToggle';
export { AttachButton } from './AttachButton';
export { RecordButton } from './RecordButton';