| 1 | using System.Diagnostics; |
| 2 | using System.Security.Cryptography; |
| 3 | using System.Text; |
| 4 | using System.Text.Json; |
| 5 | using CascadeIDE.Contracts.Experimental; |
| 6 | using CascadeIDE.Contracts.Experimental.Capabilities; |
| 7 | |
| 8 | namespace CascadeIDE.Services.Capabilities; |
| 9 | |
| 10 | /// <summary>Простая in-memory реализация <see cref="ICapabilityRegistry"/> для v1.</summary> |
| 11 | public sealed class SimpleCapabilityRegistry : ICapabilityRegistry |
| 12 | { |
| 13 | private readonly List<ServiceCapabilityDescriptor> _services = []; |
| 14 | private readonly List<CommandCapabilityDescriptor> _commands = []; |
| 15 | private readonly List<UiSurfaceCapabilityDescriptor> _uiSurfaces = []; |
| 16 | private readonly List<Action<IMcpHandlerRegistrar>> _mcpHandlerRegistrations = []; |
| 17 | |
| 18 | public void RegisterService(ServiceCapabilityDescriptor descriptor) => _services.Add(descriptor); |
| 19 | public void RegisterCommand(CommandCapabilityDescriptor descriptor) => _commands.Add(descriptor); |
| 20 | public void RegisterUiSurface(UiSurfaceCapabilityDescriptor descriptor) => _uiSurfaces.Add(descriptor); |
| 21 | public void RegisterMcpHandlers(Action<IMcpHandlerRegistrar> register) => _mcpHandlerRegistrations.Add(register); |
| 22 | |
| 23 | /// <summary>Invoke stored MCP handler registrations (spine executor).</summary> |
| 24 | public void InvokeMcpHandlerRegistrations(IMcpHandlerRegistrar registrar) |
| 25 | { |
| 26 | foreach (var registration in _mcpHandlerRegistrations) |
| 27 | registration(registrar); |
| 28 | } |
| 29 | |
| 30 | public CapabilityMap BuildMap() |
| 31 | { |
| 32 | foreach (var s in _uiSurfaces) |
| 33 | { |
| 34 | var issue = CapabilityAttentionConsistency.TryGetUiSurfaceIssue(s); |
| 35 | if (issue is not null) |
| 36 | Debug.WriteLine("CapabilityAttentionConsistency: " + issue); |
| 37 | } |
| 38 | |
| 39 | var map = new CapabilityMap |
| 40 | { |
| 41 | Services = _services.ToArray(), |
| 42 | Commands = _commands.ToArray(), |
| 43 | UiSurfaces = _uiSurfaces.ToArray() |
| 44 | }; |
| 45 | |
| 46 | return map with { Hash = ComputeHash(map) }; |
| 47 | } |
| 48 | |
| 49 | private static string ComputeHash(CapabilityMap map) |
| 50 | { |
| 51 | // Canonical-ish JSON to stabilize hash across runs. |
| 52 | var json = JsonSerializer.Serialize(map, new JsonSerializerOptions |
| 53 | { |
| 54 | WriteIndented = false |
| 55 | }); |
| 56 | var bytes = SHA256.HashData(Encoding.UTF8.GetBytes(json)); |
| 57 | return Convert.ToHexString(bytes); |
| 58 | } |
| 59 | } |
| 60 | |
| 61 | |