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,251 @@
/**
* Tests for notification middleware
*/
import { describe, it, expect, beforeEach, vi } from 'vitest';
import { notificationMiddleware } from './notification.js';
import { useSessionStore } from '../../stores/sessionStore.js';
import { useNotificationStore } from '../../stores/notificationStore.js';
import type { ClientEvent } from '../types.js';
describe('notificationMiddleware', () => {
// Mock next function
const next = vi.fn();
beforeEach(() => {
// Reset stores
useSessionStore.setState({
currentSessionId: 'current-session',
isWelcomeState: false,
isCreatingSession: false,
isSwitchingSession: false,
isReplayingHistory: false,
isLoadingHistory: false,
});
useNotificationStore.setState({
toasts: [],
maxToasts: 5,
});
// Clear mock
next.mockClear();
});
it('should always call next', () => {
const event: ClientEvent = {
name: 'llm:thinking',
sessionId: 'test-session',
};
notificationMiddleware(event, next);
expect(next).toHaveBeenCalledWith(event);
expect(next).toHaveBeenCalledTimes(1);
});
describe('notification suppression', () => {
it('should suppress notifications during history replay', () => {
useSessionStore.setState({ isReplayingHistory: true });
const event: ClientEvent = {
name: 'llm:error',
error: new Error('Test error'),
sessionId: 'test-session',
};
notificationMiddleware(event, next);
expect(next).toHaveBeenCalled();
expect(useNotificationStore.getState().toasts).toHaveLength(0);
});
it('should suppress notifications during session switch', () => {
useSessionStore.setState({ isSwitchingSession: true });
const event: ClientEvent = {
name: 'llm:error',
error: new Error('Test error'),
sessionId: 'test-session',
};
notificationMiddleware(event, next);
expect(next).toHaveBeenCalled();
expect(useNotificationStore.getState().toasts).toHaveLength(0);
});
it('should suppress notifications during history loading', () => {
useSessionStore.setState({ isLoadingHistory: true });
const event: ClientEvent = {
name: 'llm:response',
content: 'Test response',
sessionId: 'background-session',
};
notificationMiddleware(event, next);
expect(next).toHaveBeenCalled();
expect(useNotificationStore.getState().toasts).toHaveLength(0);
});
});
describe('llm:error events', () => {
it('should NOT create toast for errors in current session (shown inline)', () => {
useSessionStore.setState({ currentSessionId: 'current-session' });
const event: ClientEvent = {
name: 'llm:error',
error: new Error('Test error message'),
sessionId: 'current-session',
};
notificationMiddleware(event, next);
// Errors in current session are shown inline via ErrorBanner, not as toasts
const { toasts } = useNotificationStore.getState();
expect(toasts).toHaveLength(0);
});
it('should create toast for errors in background session', () => {
useSessionStore.setState({ currentSessionId: 'current-session' });
const event: ClientEvent = {
name: 'llm:error',
error: new Error('Test error'),
sessionId: 'background-session',
};
notificationMiddleware(event, next);
const { toasts } = useNotificationStore.getState();
expect(toasts).toHaveLength(1);
expect(toasts[0].title).toBe('Error in background session');
expect(toasts[0].description).toBe('Test error');
expect(toasts[0].intent).toBe('danger');
expect(toasts[0].sessionId).toBe('background-session');
});
it('should handle error without message in background session', () => {
useSessionStore.setState({ currentSessionId: 'current-session' });
const event: ClientEvent = {
name: 'llm:error',
error: new Error(),
sessionId: 'background-session',
};
notificationMiddleware(event, next);
const { toasts } = useNotificationStore.getState();
expect(toasts).toHaveLength(1);
expect(toasts[0].description).toBe('An error occurred');
});
});
describe('llm:response events', () => {
it('should NOT create toast for responses in current session', () => {
useSessionStore.setState({ currentSessionId: 'current-session' });
const event: ClientEvent = {
name: 'llm:response',
content: 'Test response',
sessionId: 'current-session',
};
notificationMiddleware(event, next);
const { toasts } = useNotificationStore.getState();
expect(toasts).toHaveLength(0);
});
it('should create toast for responses in background session', () => {
useSessionStore.setState({ currentSessionId: 'current-session' });
const event: ClientEvent = {
name: 'llm:response',
content: 'Test response',
sessionId: 'background-session',
};
notificationMiddleware(event, next);
const { toasts } = useNotificationStore.getState();
expect(toasts).toHaveLength(1);
expect(toasts[0].title).toBe('Response Ready');
expect(toasts[0].description).toBe('Agent completed in background session');
expect(toasts[0].intent).toBe('info');
expect(toasts[0].sessionId).toBe('background-session');
});
it('should create toast when no session is active (treated as background)', () => {
useSessionStore.setState({ currentSessionId: null });
const event: ClientEvent = {
name: 'llm:response',
content: 'Test response',
sessionId: 'some-session',
};
notificationMiddleware(event, next);
const { toasts } = useNotificationStore.getState();
// When no session is active, any session is considered "background"
expect(toasts).toHaveLength(1);
expect(toasts[0].sessionId).toBe('some-session');
});
});
describe('other events', () => {
it('should not create toast for llm:thinking', () => {
const event: ClientEvent = {
name: 'llm:thinking',
sessionId: 'test-session',
};
notificationMiddleware(event, next);
expect(useNotificationStore.getState().toasts).toHaveLength(0);
});
it('should not create toast for llm:chunk', () => {
const event: ClientEvent = {
name: 'llm:chunk',
chunkType: 'text',
content: 'Test chunk',
sessionId: 'test-session',
};
notificationMiddleware(event, next);
expect(useNotificationStore.getState().toasts).toHaveLength(0);
});
it('should not create toast for llm:tool-call', () => {
const event: ClientEvent = {
name: 'llm:tool-call',
toolName: 'test-tool',
args: {},
callId: 'call-123',
sessionId: 'test-session',
};
notificationMiddleware(event, next);
expect(useNotificationStore.getState().toasts).toHaveLength(0);
});
it('should not create toast for connection:status', () => {
const event: ClientEvent = {
name: 'connection:status',
status: 'connected',
timestamp: Date.now(),
};
notificationMiddleware(event, next);
expect(useNotificationStore.getState().toasts).toHaveLength(0);
});
});
});