diff --git a/DevProxy/Stdio/ProxySession.cs b/DevProxy/Stdio/ProxySession.cs index fe091d23..57fa451d 100644 --- a/DevProxy/Stdio/ProxySession.cs +++ b/DevProxy/Stdio/ProxySession.cs @@ -197,6 +197,11 @@ private async Task ForwardStdinAsync() { var buffer = new byte[4096]; using var stdin = Console.OpenStandardInput(); + // Buffer for accumulating partial messages that don't end with a newline + var pendingData = new StringBuilder(); + // Decoder maintains state across calls to handle multi-byte UTF-8 + // characters that may be split across buffer boundaries + var decoder = Encoding.UTF8.GetDecoder(); try { @@ -231,57 +236,92 @@ private async Task ForwardStdinAsync() break; } - var data = buffer[..bytesRead]; Log("STDIN >>>", buffer, bytesRead); - // Log intercepted stdin (similar to HTTP InterceptedRequest) - await LogInterceptedStdioAsync(data, StdioMessageDirection.Stdin); - - // Execute plugins and check if message was consumed - var responseState = new ResponseState(); - var requestArgs = new StdioRequestArgs - { - Body = data, - ResponseState = responseState, - Session = _stdioSession!, - SessionData = _sessionData, - GlobalData = _globalData - }; + // Split the buffer into individual newline-delimited messages. + // A single read may contain multiple messages when they arrive + // back-to-back (e.g., a notification followed by a request). + var charCount = decoder.GetCharCount(buffer, 0, bytesRead, flush: false); + var chars = new char[charCount]; + decoder.GetChars(buffer, 0, bytesRead, chars, 0, flush: false); + pendingData.Append(chars); - await ExecuteBeforeStdinPluginsAsync(requestArgs); + var pending = pendingData.ToString(); + var lines = pending.Split('\n'); - // Only forward to child if not consumed - if (!responseState.HasBeenSet) + // If the chunk doesn't end with a newline, the last element is + // a partial message that needs to be carried over to the next read. + if (!pending.EndsWith('\n')) { - await _writeSemaphore.WaitAsync(_cts.Token); - try - { - await _childStdin!.WriteAsync(buffer.AsMemory(0, bytesRead), _cts.Token); - await _childStdin.FlushAsync(_cts.Token); - } - finally - { - _ = _writeSemaphore.Release(); - } + pendingData.Clear(); + pendingData.Append(lines[^1]); + lines = lines[..^1]; } else { - // Send mock response if set by a plugin - await SendMockResponseAsync(requestArgs); + pendingData.Clear(); } - // Create request log entry for this stdin message - var requestLog = new StdioRequestLog + foreach (var line in lines) { - Command = _stdioSession!.Command, - StdinBody = data, - StdinTimestamp = DateTimeOffset.UtcNow, - MessageType = responseState.HasBeenSet ? MessageType.Mocked : MessageType.PassedThrough - }; - _requestLogs.Add(requestLog); + var message = line.TrimEnd('\r'); + if (message.Length == 0) + { + continue; + } + + var messageBytes = Encoding.UTF8.GetBytes(message); + + // Log intercepted stdin (similar to HTTP InterceptedRequest) + await LogInterceptedStdioAsync(messageBytes, StdioMessageDirection.Stdin); + + // Execute plugins and check if message was consumed + var responseState = new ResponseState(); + var requestArgs = new StdioRequestArgs + { + Body = messageBytes, + ResponseState = responseState, + Session = _stdioSession!, + SessionData = _sessionData, + GlobalData = _globalData + }; - // Notify plugins of the request log - await NotifyStdioRequestLogAsync(requestLog); + await ExecuteBeforeStdinPluginsAsync(requestArgs); + + // Only forward to child if not consumed + if (!responseState.HasBeenSet) + { + var forwardBytes = Encoding.UTF8.GetBytes(message + "\n"); + await _writeSemaphore.WaitAsync(_cts.Token); + try + { + await _childStdin!.WriteAsync(forwardBytes.AsMemory(), _cts.Token); + await _childStdin.FlushAsync(_cts.Token); + } + finally + { + _ = _writeSemaphore.Release(); + } + } + else + { + // Send mock response if set by a plugin + await SendMockResponseAsync(requestArgs); + } + + // Create request log entry for this stdin message + var requestLog = new StdioRequestLog + { + Command = _stdioSession!.Command, + StdinBody = messageBytes, + StdinTimestamp = DateTimeOffset.UtcNow, + MessageType = responseState.HasBeenSet ? MessageType.Mocked : MessageType.PassedThrough + }; + _requestLogs.Add(requestLog); + + // Notify plugins of the request log + await NotifyStdioRequestLogAsync(requestLog); + } } } catch (OperationCanceledException) diff --git a/DevProxy/packages.lock.json b/DevProxy/packages.lock.json index 441046d2..288d91d3 100644 --- a/DevProxy/packages.lock.json +++ b/DevProxy/packages.lock.json @@ -18,7 +18,10 @@ "contentHash": "HH9/nnRF/YmRrc3hUlgXjMBYKH5kFmd5UWC81l9U0ySQhwHTcgvDPSewB8DyQHzFJzNGgG7VFK6ynC6+XQz9WA==", "dependencies": { "Microsoft.EntityFrameworkCore.Sqlite.Core": "10.0.9", + "Microsoft.Extensions.Caching.Memory": "10.0.9", + "Microsoft.Extensions.Configuration.Abstractions": "10.0.9", "Microsoft.Extensions.DependencyModel": "10.0.9", + "Microsoft.Extensions.Logging": "10.0.9", "SQLitePCLRaw.bundle_e_sqlite3": "2.1.11", "SQLitePCLRaw.core": "2.1.11" } @@ -56,6 +59,8 @@ "resolved": "1.16.0", "contentHash": "nE/Px3MUvQC8c0UG0DOP5OJE7vMtiMaPYi/6TkSS/o/O0s/oPq+8WaPYTVEPzb7lwu/QyLgknc+sFm2FjPXe2A==", "dependencies": { + "Microsoft.Extensions.Diagnostics.Abstractions": "10.0.0", + "Microsoft.Extensions.Logging.Configuration": "10.0.0", "OpenTelemetry.Api.ProviderBuilderExtensions": "1.16.0" } }, @@ -90,7 +95,9 @@ "resolved": "0.1.5", "contentHash": "HiICGm0e44+i4aVHpLn+aphmSC2eQnDvlTttw1rE0hntOZKoLGRy37sydqqbRP1ZokMf3Mt0GEgSWxDwnucKGg==", "dependencies": { - "BouncyCastle.Cryptography": "2.4.0" + "BouncyCastle.Cryptography": "2.4.0", + "Microsoft.Extensions.Logging.Abstractions": "8.0.1", + "System.Runtime.CompilerServices.Unsafe": "6.0.0" } }, "Azure.Core": { @@ -99,6 +106,8 @@ "contentHash": "x9c/toFMOtRrlTdFuE7rlGCVAduQzWVfKmLz5juj41zJAXEhYD5hluiUyyAEzJ6OxpBnKtiaBztzwpZITAVjtg==", "dependencies": { "Microsoft.Bcl.AsyncInterfaces": "10.0.3", + "Microsoft.Extensions.Configuration.Abstractions": "10.0.3", + "Microsoft.Extensions.Hosting.Abstractions": "10.0.3", "Microsoft.Identity.Client": "4.83.1", "Microsoft.Identity.Client.Extensions.Msal": "4.83.1", "System.ClientModel": "1.10.0", @@ -139,7 +148,9 @@ "contentHash": "tu85SRzOT021V7EQlViCiAE7TqldVn469Y6lt5TEn/+XC4/MeNCHgMRSxqYuWqvF4zAQZUhCmtNEZuM3ss4LeA==", "dependencies": { "Microsoft.EntityFrameworkCore.Abstractions": "10.0.9", - "Microsoft.EntityFrameworkCore.Analyzers": "10.0.9" + "Microsoft.EntityFrameworkCore.Analyzers": "10.0.9", + "Microsoft.Extensions.Caching.Memory": "10.0.9", + "Microsoft.Extensions.Logging": "10.0.9" } }, "Microsoft.EntityFrameworkCore.Abstractions": { @@ -157,7 +168,10 @@ "resolved": "10.0.9", "contentHash": "dEoyYKgiaZHHgOFm1WMWm1sFEsEuhPWufX4L9PekKtqd/RaIcPjkCjvbrVvJtApErb5wPSJhYvnTlxhH+p9h2g==", "dependencies": { - "Microsoft.EntityFrameworkCore": "10.0.9" + "Microsoft.EntityFrameworkCore": "10.0.9", + "Microsoft.Extensions.Caching.Memory": "10.0.9", + "Microsoft.Extensions.Configuration.Abstractions": "10.0.9", + "Microsoft.Extensions.Logging": "10.0.9" } }, "Microsoft.EntityFrameworkCore.Sqlite.Core": { @@ -167,21 +181,211 @@ "dependencies": { "Microsoft.Data.Sqlite.Core": "10.0.9", "Microsoft.EntityFrameworkCore.Relational": "10.0.9", + "Microsoft.Extensions.Caching.Memory": "10.0.9", + "Microsoft.Extensions.Configuration.Abstractions": "10.0.9", "Microsoft.Extensions.DependencyModel": "10.0.9", + "Microsoft.Extensions.Logging": "10.0.9", "SQLitePCLRaw.core": "2.1.11" } }, + "Microsoft.Extensions.Caching.Abstractions": { + "type": "Transitive", + "resolved": "10.0.9", + "contentHash": "5fGxcw2vuYp8s0wio9H1ECiuk4iKSdTIlNuigdLIrkhg+5XAwgFVDB/5Ots3pfN/QhABLYXutA79JFtnUKDSHA==", + "dependencies": { + "Microsoft.Extensions.Primitives": "10.0.9" + } + }, + "Microsoft.Extensions.Caching.Memory": { + "type": "Transitive", + "resolved": "10.0.9", + "contentHash": "G9mregdatGWMCQWeCw012LDeJVP7G/XIxH8Ddbjc8bD1//dA+8VVQdcRE9jI1moyoJxSSZhHITUnNQ8FUDl5+Q==", + "dependencies": { + "Microsoft.Extensions.Caching.Abstractions": "10.0.9", + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.9", + "Microsoft.Extensions.Logging.Abstractions": "10.0.9", + "Microsoft.Extensions.Options": "10.0.9", + "Microsoft.Extensions.Primitives": "10.0.9" + } + }, + "Microsoft.Extensions.Configuration": { + "type": "Transitive", + "resolved": "10.0.9", + "contentHash": "woZsWLhOQsASuxbmgiZJqiGUBNo3IjRdXC92xt8rRokza+P6/nIsnzq7sm9Or6ZYcRl2kL1ufj8HVzp1QlPTXw==", + "dependencies": { + "Microsoft.Extensions.Configuration.Abstractions": "10.0.9", + "Microsoft.Extensions.Primitives": "10.0.9" + } + }, + "Microsoft.Extensions.Configuration.Abstractions": { + "type": "Transitive", + "resolved": "10.0.9", + "contentHash": "qGhRPd3VxfLV9UqatVOiD9mAeUbj2KiMwGFYC5uXlzExiZQoe4X/hdmzGIU7BQjNLTqCnnbTHVyBglG3668/HA==", + "dependencies": { + "Microsoft.Extensions.Primitives": "10.0.9" + } + }, + "Microsoft.Extensions.Configuration.Binder": { + "type": "Transitive", + "resolved": "10.0.9", + "contentHash": "Tp/+LPb70RyjjtLg9m5C959eP4KrUpJHThZfAegZVpsfmGvzfuNkuYbI/ft+LvXhMSyUcAeOPaN6rzTccwnZAg==", + "dependencies": { + "Microsoft.Extensions.Configuration": "10.0.9", + "Microsoft.Extensions.Configuration.Abstractions": "10.0.9" + } + }, + "Microsoft.Extensions.Configuration.FileExtensions": { + "type": "Transitive", + "resolved": "10.0.9", + "contentHash": "NgLB9cYnIb0/djSDcnqo4GIGGWooxGmr/gCUe3/CRXcKqLizOFui8MyW4EVkTB/KNJL+oXdMXnD6ZRm3Y+qkrQ==", + "dependencies": { + "Microsoft.Extensions.Configuration": "10.0.9", + "Microsoft.Extensions.Configuration.Abstractions": "10.0.9", + "Microsoft.Extensions.FileProviders.Abstractions": "10.0.9", + "Microsoft.Extensions.FileProviders.Physical": "10.0.9", + "Microsoft.Extensions.Primitives": "10.0.9" + } + }, + "Microsoft.Extensions.Configuration.Json": { + "type": "Transitive", + "resolved": "10.0.9", + "contentHash": "LiFKJgc9jZEW+7RhcSfsvCwoikt1lDdOqOn+whZC5zVHyg/gExftHl2QPtmfiHsEdDNg+Y+BDr6835tOfj8Y7A==", + "dependencies": { + "Microsoft.Extensions.Configuration": "10.0.9", + "Microsoft.Extensions.Configuration.Abstractions": "10.0.9", + "Microsoft.Extensions.Configuration.FileExtensions": "10.0.9", + "Microsoft.Extensions.FileProviders.Abstractions": "10.0.9" + } + }, + "Microsoft.Extensions.DependencyInjection": { + "type": "Transitive", + "resolved": "10.0.9", + "contentHash": "NijozhERJDIaJ4k5TSMy1jOi0cSC2HfkvRD/Sl+kGSSKgVbFnF4GxgtMN/MrzHB8D1JxIrD4xSer9Blh9v3axQ==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.9" + } + }, + "Microsoft.Extensions.DependencyInjection.Abstractions": { + "type": "Transitive", + "resolved": "10.0.9", + "contentHash": "g41l/30G3K4B/d/L8kjux0+30e27c8D0FVQ/PFCpbekgfDpj9mnDhieP67EqXWvl1EWNeZh2rpR4F5B/jcDOHA==" + }, "Microsoft.Extensions.DependencyModel": { "type": "Transitive", "resolved": "10.0.9", "contentHash": "SCDTQ6HubnRvTUjR7dgMKHZvNoCb03t44ttHL8trlFTGgfDteWn/0nRdOxDhcI+lTWhKgd/flCVJEtAOPhSLNg==" }, + "Microsoft.Extensions.Diagnostics.Abstractions": { + "type": "Transitive", + "resolved": "10.0.3", + "contentHash": "mQiTzAj7PIJ2A9YXR5QhgulS1fTWhmQc3ckd1Mrf3hKW07d03fBDqx8vVaFw+cRTebDOeB6pNqdWdnRxsi1hBA==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.3", + "Microsoft.Extensions.Options": "10.0.3" + } + }, + "Microsoft.Extensions.FileProviders.Abstractions": { + "type": "Transitive", + "resolved": "10.0.9", + "contentHash": "Oxn4vqDk+EwceTMpZxVm7L/UZEAM1qIQlNP1+7tBZckD+P4SKrm/5X4gMTPCTdpnau/xY8Sb4/0d6onomSg4ZA==", + "dependencies": { + "Microsoft.Extensions.Primitives": "10.0.9" + } + }, + "Microsoft.Extensions.FileProviders.Physical": { + "type": "Transitive", + "resolved": "10.0.9", + "contentHash": "zm8WVod4swgprGrkxkuSILlbXqdDRqF+3y6U0I7jlmj4PMyKN6d8pzXZHUn5lr/gZVULzk/+FeTYlTupt6akpg==", + "dependencies": { + "Microsoft.Extensions.FileProviders.Abstractions": "10.0.9", + "Microsoft.Extensions.FileSystemGlobbing": "10.0.9", + "Microsoft.Extensions.Primitives": "10.0.9" + } + }, + "Microsoft.Extensions.FileSystemGlobbing": { + "type": "Transitive", + "resolved": "10.0.9", + "contentHash": "mvRf9qOH/LslWIee/h+lsElnoUyKotEwoPL31soqScmO/eoxObaTCLCdx2DdqPdRi9LnB+7qKZ49jfyrLZuc+w==" + }, + "Microsoft.Extensions.Hosting.Abstractions": { + "type": "Transitive", + "resolved": "10.0.3", + "contentHash": "GdMpC10Jf6poxSvUJ4lgYpJ5F/kJeaAoJmrPufjBoPYyCTKKY5Dyl0rZA+LBNvFqTq1cZa/lhlptlUhNvU6xrg==", + "dependencies": { + "Microsoft.Extensions.Configuration.Abstractions": "10.0.3", + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.3", + "Microsoft.Extensions.Diagnostics.Abstractions": "10.0.3", + "Microsoft.Extensions.FileProviders.Abstractions": "10.0.3", + "Microsoft.Extensions.Logging.Abstractions": "10.0.3" + } + }, + "Microsoft.Extensions.Logging": { + "type": "Transitive", + "resolved": "10.0.9", + "contentHash": "N7Gm9SjugYjmmnhwbBKC9DFqGqjfJvh6YfOJgtwh0AW0Xpok3dIVors1ik050XmUxKAgAc7nNngDIJyFb06K2g==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection": "10.0.9", + "Microsoft.Extensions.Logging.Abstractions": "10.0.9", + "Microsoft.Extensions.Options": "10.0.9" + } + }, + "Microsoft.Extensions.Logging.Abstractions": { + "type": "Transitive", + "resolved": "10.0.9", + "contentHash": "9S/DFt4cohlMPpzIxjG6kk0L8MuN2vDm9pbMCulxtJzzk82oJHVLBd8vuQxaPskaYQwKqmFmbannf5eoChgjYg==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.9" + } + }, + "Microsoft.Extensions.Logging.Configuration": { + "type": "Transitive", + "resolved": "10.0.0", + "contentHash": "j8zcwhS6bYB6FEfaY3nYSgHdpiL2T+/V3xjpHtslVAegyI1JUbB9yAt/BFdvZdsNbY0Udm4xFtvfT/hUwcOOOg==", + "dependencies": { + "Microsoft.Extensions.Configuration": "10.0.0", + "Microsoft.Extensions.Configuration.Abstractions": "10.0.0", + "Microsoft.Extensions.Configuration.Binder": "10.0.0", + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.0", + "Microsoft.Extensions.Logging": "10.0.0", + "Microsoft.Extensions.Logging.Abstractions": "10.0.0", + "Microsoft.Extensions.Options": "10.0.0", + "Microsoft.Extensions.Options.ConfigurationExtensions": "10.0.0" + } + }, + "Microsoft.Extensions.Options": { + "type": "Transitive", + "resolved": "10.0.9", + "contentHash": "hyNdX4c2UwkRkzb9byw0H2DQkRzwBM3mzY2sCM9egwzTyg8dvQJmp5noQHGEaaCORQrNK3DD2gREBsc2DlXS4A==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.9", + "Microsoft.Extensions.Primitives": "10.0.9" + } + }, + "Microsoft.Extensions.Options.ConfigurationExtensions": { + "type": "Transitive", + "resolved": "10.0.0", + "contentHash": "tL9cSl3maS5FPzp/3MtlZI21ExWhni0nnUCF8HY4npTsINw45n9SNDbkKXBMtFyUFGSsQep25fHIDN4f/Vp3AQ==", + "dependencies": { + "Microsoft.Extensions.Configuration.Abstractions": "10.0.0", + "Microsoft.Extensions.Configuration.Binder": "10.0.0", + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.0", + "Microsoft.Extensions.Options": "10.0.0", + "Microsoft.Extensions.Primitives": "10.0.0" + } + }, + "Microsoft.Extensions.Primitives": { + "type": "Transitive", + "resolved": "10.0.9", + "contentHash": "fmEbAUFsaIKirgLt/lYhuFRBwhcSJN31jjHgCdbQxJiWOum6EdLjkbgGuukSP9z/a+9LibaxII/kF+GwOXgC4g==" + }, "Microsoft.Identity.Client": { "type": "Transitive", "resolved": "4.83.1", "contentHash": "jOLIrZ3cynoqHLLO1cXplFFabrhrMEYs/EuKHvmCyrOm1axqiVFT6nCSnHxk7w5+d2BeQfCdM12Yf/0X7OeS1g==", "dependencies": { - "Microsoft.IdentityModel.Abstractions": "8.14.0" + "Microsoft.IdentityModel.Abstractions": "8.14.0", + "System.Diagnostics.DiagnosticSource": "6.0.1", + "System.ValueTuple": "4.5.0" } }, "Microsoft.Identity.Client.Extensions.Msal": { @@ -228,13 +432,17 @@ "contentHash": "KDiuSLXud2AFVNAOottd8ztVysfPeHyr4r8gofU3/VKUXlI7oytzGTnPsNJ/B3nui17rgz8wAdWNJOtzPjkUxw==", "dependencies": { "Microsoft.Bcl.Cryptography": "10.0.2", + "Microsoft.Extensions.Logging.Abstractions": "8.0.0", "Microsoft.IdentityModel.Logging": "8.19.1" } }, "Microsoft.OpenApi": { "type": "Transitive", "resolved": "3.7.0", - "contentHash": "7Ld/wUsxSEKBjAk8nPZ13qkju5kNoh20gf0JHPeHrK41tMZRpIq9amXFAOHncicjg0U5M035I+6/z3cBsYBHfg==" + "contentHash": "7Ld/wUsxSEKBjAk8nPZ13qkju5kNoh20gf0JHPeHrK41tMZRpIq9amXFAOHncicjg0U5M035I+6/z3cBsYBHfg==", + "dependencies": { + "System.Text.Json": "8.0.5" + } }, "Microsoft.OpenApi.YamlReader": { "type": "Transitive", @@ -242,7 +450,8 @@ "contentHash": "+KSHfoEiXDFmCeIG6T5xAuYNFulwfxxBh4AJOY6dvGrDeFVV4eL4/xP/RNEaFYvcSZpLkj3ZoQ8Vn3vtUViu5g==", "dependencies": { "Microsoft.OpenApi": "3.7.0", - "SharpYaml": "2.1.4" + "SharpYaml": "2.1.4", + "System.Text.Json": "8.0.5" } }, "Microsoft.VisualStudio.Threading.Analyzers": { @@ -281,6 +490,7 @@ "resolved": "1.16.0", "contentHash": "hZwaHAkXvUNn9+cS+vEvYBgIrIQOQRz2cIRUODZ5gxHsDsLeNCueLgZFkybopjE0jUhLut6lm5eL3LTqbW0hMg==", "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.0", "OpenTelemetry.Api": "1.16.0" } }, @@ -306,7 +516,10 @@ "SQLitePCLRaw.core": { "type": "Transitive", "resolved": "2.1.11", - "contentHash": "PK0GLFkfhZzLQeR3PJf71FmhtHox+U3vcY6ZtswoMjrefkB9k6ErNJEnwXqc5KgXDSjige2XXrezqS39gkpQKA==" + "contentHash": "PK0GLFkfhZzLQeR3PJf71FmhtHox+U3vcY6ZtswoMjrefkB9k6ErNJEnwXqc5KgXDSjige2XXrezqS39gkpQKA==", + "dependencies": { + "System.Memory": "4.5.3" + } }, "SQLitePCLRaw.lib.e_sqlite3": { "type": "Transitive", @@ -326,19 +539,50 @@ "resolved": "1.10.0", "contentHash": "lBEWs54F5Y5pZ9hC+8z4S/X76957ex+DPk7WecRHlbIHtrPfbRMMlOgI3iDn4Jpb3bSxvBnKaaHoD59auFjlBA==", "dependencies": { + "Microsoft.Extensions.Configuration.Abstractions": "10.0.3", + "Microsoft.Extensions.Hosting.Abstractions": "10.0.3", + "Microsoft.Extensions.Logging.Abstractions": "10.0.3", "System.Memory.Data": "10.0.3" } }, + "System.Diagnostics.DiagnosticSource": { + "type": "Transitive", + "resolved": "6.0.1", + "contentHash": "KiLYDu2k2J82Q9BJpWiuQqCkFjRBWVq4jDzKKWawVi9KWzyD0XG3cmfX0vqTQlL14Wi9EufJrbL0+KCLTbqWiQ==", + "dependencies": { + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } + }, + "System.Memory": { + "type": "Transitive", + "resolved": "4.5.3", + "contentHash": "3oDzvc/zzetpTKWMShs1AADwZjQ/36HnsufHRPcOjyRAAMLDlu2iD33MBI2opxnezcVUtXyqDXXjoFMOU9c7SA==" + }, "System.Memory.Data": { "type": "Transitive", "resolved": "10.0.3", "contentHash": "MaGhRfGunmrj/nHjtsi9XkhlYJ/ERGWrbA+BiSKNtGnAjc9XlG5EhAvak6VRcX5LYzPF6pBO8nJ613dTgzabig==" }, + "System.Runtime.CompilerServices.Unsafe": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg==" + }, "System.Security.Cryptography.ProtectedData": { "type": "Transitive", "resolved": "4.5.0", "contentHash": "wLBKzFnDCxP12VL9ANydSYhk59fC4cvOr9ypYQLPnAj48NQIhqnjdD2yhP8yEKyBJEjERWS9DisKL7rX5eU25Q==" }, + "System.Text.Json": { + "type": "Transitive", + "resolved": "8.0.5", + "contentHash": "0f1B50Ss7rqxXiaBJyzUu9bWFOO2/zSlifZ/UNMdiIpDYe4cY4LQQicP4nirK1OS31I43rn062UIJ1Q9bpmHpg==" + }, + "System.ValueTuple": { + "type": "Transitive", + "resolved": "4.5.0", + "contentHash": "okurQJO6NRE/apDIP23ajJ0hpiNmJ+f0BwOlB/cSqTLQlw5upkf+5+96+iG2Jw40G1fCVCyPz/FhIABUjMR+RQ==" + }, "YamlDotNet": { "type": "Transitive", "resolved": "18.1.0", @@ -349,6 +593,11 @@ "dependencies": { "Markdig": "[1.3.2, )", "Microsoft.EntityFrameworkCore.Sqlite": "[10.0.9, )", + "Microsoft.Extensions.Configuration": "[10.0.9, )", + "Microsoft.Extensions.Configuration.Binder": "[10.0.9, )", + "Microsoft.Extensions.Configuration.Json": "[10.0.9, )", + "Microsoft.Extensions.FileSystemGlobbing": "[10.0.9, )", + "Microsoft.Extensions.Logging.Abstractions": "[10.0.9, )", "Microsoft.OpenApi": "[3.7.0, )", "Microsoft.OpenApi.YamlReader": "[3.7.0, )", "Newtonsoft.Json.Schema": "[4.0.1, )",