Files
LazyBearWorks/LazyBear.MCP/Services/Mcp/McpWebHostedService.cs
Shahovalov MIkhail 9b27cd7dc2 fix: исправить навигацию клавиатуры в TUI через GlobalKeyboardService
- Добавить GlobalKeyboardService — выделенный поток с блокирующим
  Console.ReadKey, единственный источник клавишных событий для TUI
- Убрать FocusManager из App.razor: перехватывал Tab до компонентов
- Удалить @onkeydown с <Select>: RazorConsole не пробрасывает Tab/стрелки
  через этот механизм
- Использовать FocusedValue вместо Value в Select для корректной подсветки
- Обновить CLAUDE.md и AGENTS.md: архитектура TUI, RazorConsole gotchas
- Добавить docs/tui_log.md: разбор проблемы и справочник по RazorConsole

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-13 23:31:53 +03:00

67 lines
2.5 KiB
C#

using LazyBear.MCP.Services.Confluence;
using LazyBear.MCP.Services.Jira;
using LazyBear.MCP.Services.Kubernetes;
using LazyBear.MCP.Services.Logging;
using LazyBear.MCP.Services.ToolRegistry;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
namespace LazyBear.MCP.Services.Mcp;
/// <summary>
/// Поднимает HTTP MCP endpoint в фоне, не вмешиваясь в основной TUI event loop.
/// Использует общие singleton-экземпляры из root host.
/// </summary>
public sealed class McpWebHostedService(
IServiceProvider rootServices,
IConfiguration configuration,
ILogger<McpWebHostedService> logger) : IHostedService
{
private WebApplication? _webApp;
public async Task StartAsync(CancellationToken cancellationToken)
{
var builder = WebApplication.CreateBuilder();
var urls = Environment.GetEnvironmentVariable("ASPNETCORE_URLS") ?? "http://localhost:5000";
builder.WebHost.UseUrls(urls);
// Используем тот же IConfiguration и те же singleton-сервисы, что и в TUI host.
builder.Services.AddSingleton(configuration);
builder.Services.AddSingleton(rootServices.GetRequiredService<InMemoryLogSink>());
builder.Services.AddSingleton(rootServices.GetRequiredService<ToolRegistryService>());
builder.Services.AddSingleton(rootServices.GetRequiredService<K8sClientProvider>());
builder.Services.AddSingleton(rootServices.GetRequiredService<JiraClientProvider>());
builder.Services.AddSingleton(rootServices.GetRequiredService<ConfluenceClientProvider>());
foreach (var module in rootServices.GetServices<IToolModule>())
{
builder.Services.AddSingleton(module);
builder.Services.AddSingleton(typeof(IToolModule), module);
}
builder.Services.AddMcpServer()
.WithHttpTransport()
.WithToolsFromAssembly();
_webApp = builder.Build();
_webApp.MapMcp();
await _webApp.StartAsync(cancellationToken);
logger.LogInformation("HTTP MCP endpoint запущен на {Urls}", urls);
}
public async Task StopAsync(CancellationToken cancellationToken)
{
if (_webApp is null)
{
return;
}
await _webApp.StopAsync(cancellationToken);
await _webApp.DisposeAsync();
_webApp = null;
}
}