| 1 | using System.Text; |
| 2 | using System.Text.Json; |
| 3 | using Tomlyn; |
| 4 | |
| 5 | namespace AgentNotes.Core.Configuration; |
| 6 | |
| 7 | internal static class AgentNotesMcpToml |
| 8 | { |
| 9 | internal static readonly TomlSerializerOptions Options = new() |
| 10 | { |
| 11 | PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower, |
| 12 | }; |
| 13 | |
| 14 | internal static T Deserialize<T>(string text, string label) where T : class |
| 15 | { |
| 16 | try |
| 17 | { |
| 18 | return TomlSerializer.Deserialize<T>(text, Options) |
| 19 | ?? throw new InvalidOperationException($"Invalid TOML ({label}): empty document."); |
| 20 | } |
| 21 | catch (TomlException ex) |
| 22 | { |
| 23 | throw new InvalidOperationException($"Invalid TOML ({label}): {ex.Message}", ex); |
| 24 | } |
| 25 | } |
| 26 | |
| 27 | internal static T DeserializeFile<T>(string path) where T : class |
| 28 | { |
| 29 | var fullPath = Path.GetFullPath(path.Trim()); |
| 30 | if (!File.Exists(fullPath)) |
| 31 | throw new FileNotFoundException($"Config file not found: {fullPath}", fullPath); |
| 32 | return Deserialize<T>(File.ReadAllText(fullPath, Encoding.UTF8), fullPath); |
| 33 | } |
| 34 | |
| 35 | internal static T DeserializeEmbedded<T>(string resourceRelativePath) where T : class |
| 36 | { |
| 37 | if (!BundledAgentNotesContent.TryReadEmbeddedText(resourceRelativePath, out var text)) |
| 38 | throw new InvalidOperationException($"Embedded TOML is missing: {resourceRelativePath}"); |
| 39 | return Deserialize<T>(text, resourceRelativePath); |
| 40 | } |
| 41 | } |
| 42 | |
View only · write via MCP/CIDE