From 111824c43d8e870a8dc2e9cddccf18641d8f8132 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 4 Feb 2026 23:09:25 +0000 Subject: [PATCH 01/19] Initial plan From a19cd6f96dd94727b0fc919944c7a6dc0ae8246a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 4 Feb 2026 23:21:09 +0000 Subject: [PATCH 02/19] Fix VS2022 extension by adding specific content type registrations Visual Studio does not activate ILanguageClient for base content types like "code". Each specific content type must be explicitly registered for the language client to be activated when files of that type are opened. Added content type registrations for: C/C++, CSharp, F#, JavaScript, TypeScript, HTML, JSON, XML, XAML, Python, Ruby, Perl, PHP, Java, Go, Rust, SQL, Lua, Swift, PowerShell, shellscript, yaml, plaintext. Kept "code" as fallback for any types not explicitly listed. Co-authored-by: gfs <98900+gfs@users.noreply.github.com> --- .../DevSkimLanguageClient.cs | 29 ++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/DevSkimLanguageClient.cs b/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/DevSkimLanguageClient.cs index c89173dd..e8730452 100644 --- a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/DevSkimLanguageClient.cs +++ b/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/DevSkimLanguageClient.cs @@ -18,7 +18,34 @@ namespace Microsot.DevSkim.LanguageClient { - [ContentType("code")] + // NOTE: Visual Studio does NOT activate ILanguageClient for base content types like "code". + // Each specific content type must be explicitly registered for the language client to be activated + // when files of that type are opened. This list corresponds to the languages that DevSkim supports + // for security analysis. See also: DevSkim-VSCode-Plugin/client/common/selectors.ts + [ContentType("C/C++")] + [ContentType("CSharp")] + [ContentType("F#")] + [ContentType("JavaScript")] + [ContentType("TypeScript")] + [ContentType("HTML")] + [ContentType("JSON")] + [ContentType("XML")] + [ContentType("XAML")] + [ContentType("Python")] + [ContentType("Ruby")] + [ContentType("Perl")] + [ContentType("PHP")] + [ContentType("Java")] + [ContentType("Go")] + [ContentType("Rust")] + [ContentType("SQL")] + [ContentType("Lua")] + [ContentType("Swift")] + [ContentType("PowerShell")] + [ContentType("shellscript")] + [ContentType("yaml")] + [ContentType("plaintext")] + [ContentType("code")] // Kept as fallback for any types not explicitly listed [Export(typeof(ILanguageClient))] public class DevSkimLanguageClient : ILanguageClient, ILanguageClientCustomMessage2 { From b206264bab1ca8d70f2aeff00167c288cd55de2e Mon Sep 17 00:00:00 2001 From: Giulia Stocco Date: Thu, 5 Feb 2026 13:42:41 -0800 Subject: [PATCH 03/19] Rewrite VS Extension for new VS SDK +VS 2026 compatibility. --- .gitignore | 1 + .../ManualUpdateSettingsGenerator.csproj | 14 - DevSkim-DotNet/ManualGenerator/Program.cs | 77 --- .../PortableScannerSettings.cs | 20 +- .../CodeActionHandler.cs | 139 +++++ .../DidChangeConfigurationHandler.cs | 34 -- .../Program.cs | 16 +- .../StaticScannerSettings.cs | 16 +- .../TextDocumentSyncHandler.cs | 24 +- ...evSkim.VisualStudio.SourceGenerator.csproj | 19 - .../UpdateSettingsGenerator.cs | 75 --- .../.vsextension/string-resources.json | 3 + .../DevSkimExtension.cs | 32 ++ .../DevSkimFixMessageTarget.cs | 83 --- .../DevSkimLanguageClient.cs | 163 ------ .../DevSkimLanguageServerProvider.cs | 127 +++++ .../DevSkimSuggestedAction.cs | 116 ----- .../Microsoft.DevSkim.VisualStudio.csproj | 187 ++----- .../Options/GeneralOptionsPage.cs | 193 ------- .../Options/OptionsPackage.cs | 37 -- .../ProcessTracker/IProcessTracker.cs | 20 - .../ProcessTracker/IWindowEventsListener.cs | 15 - .../ProcessTracker/JobObjectProcessTracker.cs | 116 ----- .../ProcessTracker/NativeMethods.cs | 493 ------------------ .../ProcessTracker/SafeObjectHandle.cs | 39 -- .../ProcessTracker/WindowEventArgs.cs | 19 - .../ProcessTracker/WindowEventsListener.cs | 89 ---- .../ProcessTracker/WindowsSystemEvents.cs | 59 --- .../Properties/AssemblyInfo.cs | 30 -- .../Properties/Resources.Designer.cs | 99 ---- .../Properties/Resources.resx | 136 ----- .../Properties/launchSettings.json | 9 + .../SafeObjectHandle.cs | 43 -- .../SettingsChangedNotifier.cs | 33 -- .../StaticData.cs | 13 - .../SuggestedActionsSourceProvider.cs | 28 - .../SuggestionActionsSource.cs | 125 ----- .../VisualStudioSettingsManager.cs | 289 ---------- .../publish.manifest.json | 13 - .../source.extension.vsixmanifest | 29 -- DevSkim-DotNet/Microsoft.DevSkim.sln | 90 +--- DevSkim-DotNet/devskim-server-log20260205.txt | 201 +++++++ 42 files changed, 600 insertions(+), 2764 deletions(-) delete mode 100644 DevSkim-DotNet/ManualGenerator/ManualUpdateSettingsGenerator.csproj delete mode 100644 DevSkim-DotNet/ManualGenerator/Program.cs create mode 100644 DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/CodeActionHandler.cs delete mode 100644 DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/DidChangeConfigurationHandler.cs delete mode 100644 DevSkim-DotNet/Microsoft.DevSkim.VisualStudio.SourceGenerator/Microsoft.DevSkim.VisualStudio.SourceGenerator.csproj delete mode 100644 DevSkim-DotNet/Microsoft.DevSkim.VisualStudio.SourceGenerator/UpdateSettingsGenerator.cs create mode 100644 DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/.vsextension/string-resources.json create mode 100644 DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/DevSkimExtension.cs delete mode 100644 DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/DevSkimFixMessageTarget.cs delete mode 100644 DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/DevSkimLanguageClient.cs create mode 100644 DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/DevSkimLanguageServerProvider.cs delete mode 100644 DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/DevSkimSuggestedAction.cs delete mode 100644 DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/Options/GeneralOptionsPage.cs delete mode 100644 DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/Options/OptionsPackage.cs delete mode 100644 DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/ProcessTracker/IProcessTracker.cs delete mode 100644 DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/ProcessTracker/IWindowEventsListener.cs delete mode 100644 DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/ProcessTracker/JobObjectProcessTracker.cs delete mode 100644 DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/ProcessTracker/NativeMethods.cs delete mode 100644 DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/ProcessTracker/SafeObjectHandle.cs delete mode 100644 DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/ProcessTracker/WindowEventArgs.cs delete mode 100644 DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/ProcessTracker/WindowEventsListener.cs delete mode 100644 DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/ProcessTracker/WindowsSystemEvents.cs delete mode 100644 DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/Properties/AssemblyInfo.cs delete mode 100644 DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/Properties/Resources.Designer.cs delete mode 100644 DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/Properties/Resources.resx create mode 100644 DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/Properties/launchSettings.json delete mode 100644 DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/SafeObjectHandle.cs delete mode 100644 DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/SettingsChangedNotifier.cs delete mode 100644 DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/StaticData.cs delete mode 100644 DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/SuggestedActionsSourceProvider.cs delete mode 100644 DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/SuggestionActionsSource.cs delete mode 100644 DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/VisualStudioSettingsManager.cs delete mode 100644 DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/publish.manifest.json delete mode 100644 DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/source.extension.vsixmanifest create mode 100644 DevSkim-DotNet/devskim-server-log20260205.txt diff --git a/.gitignore b/.gitignore index 74920eab..5e986add 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,7 @@ DevSkim-DotNet/Microsoft.DevSkim.sln.DotSettings.user DevSkim-VSCode-Plugin/client/dist/* DevSkim-VSCode-Plugin/devskimBinaries/* DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/generatedLanguageServerBinaries/* +DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/Server/* # Debug artifacts DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/devskim-server-*.txt diff --git a/DevSkim-DotNet/ManualGenerator/ManualUpdateSettingsGenerator.csproj b/DevSkim-DotNet/ManualGenerator/ManualUpdateSettingsGenerator.csproj deleted file mode 100644 index e75bc7a7..00000000 --- a/DevSkim-DotNet/ManualGenerator/ManualUpdateSettingsGenerator.csproj +++ /dev/null @@ -1,14 +0,0 @@ - - - - Exe - net7.0 - enable - enable - - - - - - - diff --git a/DevSkim-DotNet/ManualGenerator/Program.cs b/DevSkim-DotNet/ManualGenerator/Program.cs deleted file mode 100644 index fb510bdc..00000000 --- a/DevSkim-DotNet/ManualGenerator/Program.cs +++ /dev/null @@ -1,77 +0,0 @@ -namespace ManualGenerator -{ - using Microsoft.DevSkim.LanguageProtoInterop; - using System.Text; - - /// - /// Run this to generate the update settinsg method for all implemented settings - /// - internal class Program - { - static void Main(string[] args) - { - Console.WriteLine(Execute()); - } - - public static string Execute() - { - StringBuilder source = new StringBuilder(); - source.Append($@"// - namespace Microsoft.DevSkim.VisualStudio - {{ - using System; - using Microsoft.DevSkim.LanguageProtoInterop; - using System.Collections.Generic; - - internal partial class VisualStudioSettingsManager - {{ - partial void UpdateSettings(string propertyName) - {{ - switch(propertyName) - {{ -"); - - string baseIndentation = " "; - var props = typeof(IDevSkimOptions).GetProperties().Select(x => (x.Name, x.PropertyType)); - foreach (var prop in props) - { - var typeNameString = GetTypeNameString(prop.PropertyType); - source.Append($@"{baseIndentation}case ""{prop.Name}"": - {{ - var res = Get<{typeNameString}>(propertyName); - if (res.Item1 == ValueResultEnum.Success) - {{ - _currentSettings.{prop.Name} = res.Item2{ConditionallyUseNullCoalescing(typeNameString)} - }} - break; - }} -"); - } - - source.Append($@"{baseIndentation}default: break; - }} - }} - }} - }}"); - return source.ToString(); - } - - private static string ConditionallyUseNullCoalescing(string typeNameString) - { - return typeNameString.StartsWith("List") ? $" ?? new {typeNameString}();" : ";"; - } - - private static string GetTypeNameString(Type propPropertyType) - { - return propPropertyType.Name switch - { - "String" => "string", - "List`1" => $"List<{GetTypeNameString(propPropertyType.GetGenericArguments()[0])}>", - "Boolean" => "bool", - "Int32" => "int", - "CommentStylesEnum" => "CommentStylesEnum", - _ => "string" - }; - } - } -} \ No newline at end of file diff --git a/DevSkim-DotNet/Microsoft.DevSkim.LanguageProtoInterop/PortableScannerSettings.cs b/DevSkim-DotNet/Microsoft.DevSkim.LanguageProtoInterop/PortableScannerSettings.cs index 32753a84..46e25a6e 100644 --- a/DevSkim-DotNet/Microsoft.DevSkim.LanguageProtoInterop/PortableScannerSettings.cs +++ b/DevSkim-DotNet/Microsoft.DevSkim.LanguageProtoInterop/PortableScannerSettings.cs @@ -21,14 +21,16 @@ public class PortableScannerSettings : IDevSkimOptions public bool RemoveFindingsOnClose { get; set; } = true; public string CustomLanguagesPath { get; set; } = string.Empty; public string CustomCommentsPath { get; set; } = string.Empty; - public string GuidanceBaseURL { get; set; } - public bool EnableCriticalSeverityRules { get; set; } - public bool EnableImportantSeverityRules { get; set; } - public bool EnableModerateSeverityRules { get; set; } - public bool EnableManualReviewSeverityRules { get; set; } - public bool EnableBestPracticeSeverityRules { get; set; } - public bool EnableHighConfidenceRules { get; set; } - public bool EnableLowConfidenceRules { get; set; } - public bool EnableMediumConfidenceRules { get; set; } + public string GuidanceBaseURL { get; set; } = "https://github.com/microsoft/devskim/tree/main/guidance"; + // Default all severity rules to enabled + public bool EnableCriticalSeverityRules { get; set; } = true; + public bool EnableImportantSeverityRules { get; set; } = true; + public bool EnableModerateSeverityRules { get; set; } = true; + public bool EnableManualReviewSeverityRules { get; set; } = true; + public bool EnableBestPracticeSeverityRules { get; set; } = true; + // Default high and medium confidence to enabled, low disabled + public bool EnableHighConfidenceRules { get; set; } = true; + public bool EnableLowConfidenceRules { get; set; } = false; + public bool EnableMediumConfidenceRules { get; set; } = true; } } \ No newline at end of file diff --git a/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/CodeActionHandler.cs b/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/CodeActionHandler.cs new file mode 100644 index 00000000..cdc3224e --- /dev/null +++ b/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/CodeActionHandler.cs @@ -0,0 +1,139 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +using System.Collections.Concurrent; +using MediatR; +using Microsoft.DevSkim; +using Microsoft.DevSkim.LanguageProtoInterop; +using Microsoft.Extensions.Logging; +using OmniSharp.Extensions.LanguageServer.Protocol; +using OmniSharp.Extensions.LanguageServer.Protocol.Client.Capabilities; +using OmniSharp.Extensions.LanguageServer.Protocol.Document; +using OmniSharp.Extensions.LanguageServer.Protocol.Models; + +namespace DevSkim.LanguageServer +{ + /// + /// Handles textDocument/codeAction requests from the LSP client. + /// Provides quick fixes for DevSkim security findings. + /// + internal class CodeActionHandler : ICodeActionHandler + { + private readonly ILogger _logger; + + // Store code fixes keyed by document URI and diagnostic key + private static readonly ConcurrentDictionary>> _codeFixCache = new(); + + public CodeActionHandler(ILogger logger) + { + _logger = logger; + } + + public CodeActionRegistrationOptions GetRegistrationOptions(CodeActionCapability capability, ClientCapabilities clientCapabilities) + { + return new CodeActionRegistrationOptions + { + DocumentSelector = TextDocumentSelector.ForPattern("**/*"), + CodeActionKinds = new Container(CodeActionKind.QuickFix), + ResolveProvider = false + }; + } + + public Task Handle(CodeActionParams request, CancellationToken cancellationToken) + { + var result = new List(); + var documentUri = request.TextDocument.Uri.ToString(); + + _logger.LogDebug($"CodeActionHandler: Processing request for {documentUri}"); + _logger.LogDebug($"CodeActionHandler: {request.Context.Diagnostics.Count()} diagnostics in context"); + + foreach (var diagnostic in request.Context.Diagnostics) + { + // Only process DevSkim diagnostics + if (diagnostic.Source != "DevSkim Language Server") + { + continue; + } + + var diagnosticKey = CreateDiagnosticKey(documentUri, diagnostic); + _logger.LogDebug($"CodeActionHandler: Looking for fixes for diagnostic key: {diagnosticKey}"); + + if (_codeFixCache.TryGetValue(documentUri, out var documentFixes) && + documentFixes.TryGetValue(diagnosticKey, out var fixes)) + { + _logger.LogDebug($"CodeActionHandler: Found {fixes.Count} fixes"); + foreach (var fix in fixes) + { + var codeAction = new CodeAction + { + Title = fix.friendlyString, + Kind = CodeActionKind.QuickFix, + Diagnostics = new Container(diagnostic), + Edit = CreateWorkspaceEdit(request.TextDocument.Uri, diagnostic, fix) + }; + result.Add(codeAction); + } + } + } + + _logger.LogDebug($"CodeActionHandler: Returning {result.Count} code actions"); + return Task.FromResult(new CommandOrCodeActionContainer(result)); + } + + private static WorkspaceEdit CreateWorkspaceEdit(DocumentUri uri, Diagnostic diagnostic, CodeFixMapping fix) + { + var textEdit = fix.isSuppression + ? new TextEdit + { + // For suppressions, insert at the end of the line + Range = new OmniSharp.Extensions.LanguageServer.Protocol.Models.Range( + diagnostic.Range.End.Line, int.MaxValue, + diagnostic.Range.End.Line, int.MaxValue), + NewText = fix.replacement + } + : new TextEdit + { + Range = diagnostic.Range, + NewText = fix.replacement + }; + + return new WorkspaceEdit + { + Changes = new Dictionary> + { + [uri] = new[] { textEdit } + } + }; + } + + /// + /// Register code fixes for a diagnostic. Called by TextDocumentSyncHandler when processing documents. + /// + public static void RegisterCodeFix(DocumentUri uri, Diagnostic diagnostic, CodeFixMapping fix) + { + var documentUri = uri.ToString(); + var diagnosticKey = CreateDiagnosticKey(documentUri, diagnostic); + + var documentFixes = _codeFixCache.GetOrAdd(documentUri, _ => new ConcurrentDictionary>()); + var fixes = documentFixes.GetOrAdd(diagnosticKey, _ => new List()); + + lock (fixes) + { + fixes.Add(fix); + } + } + + /// + /// Clear all code fixes for a document. Called when document is closed or rescanned. + /// + public static void ClearCodeFixes(DocumentUri uri) + { + _codeFixCache.TryRemove(uri.ToString(), out _); + } + + private static string CreateDiagnosticKey(string documentUri, Diagnostic diagnostic) + { + return $"{documentUri}: {diagnostic.Message}, {diagnostic.Code}, {diagnostic.Range.Start.Line}, {diagnostic.Range.Start.Character}, {diagnostic.Range.End.Line}, {diagnostic.Range.End.Character}"; + } + } +} diff --git a/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/DidChangeConfigurationHandler.cs b/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/DidChangeConfigurationHandler.cs deleted file mode 100644 index d82830f0..00000000 --- a/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/DidChangeConfigurationHandler.cs +++ /dev/null @@ -1,34 +0,0 @@ -using MediatR; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Configuration; -using OmniSharp.Extensions.LanguageServer.Protocol.Models; -using OmniSharp.Extensions.LanguageServer.Protocol.Server; -using OmniSharp.Extensions.LanguageServer.Protocol.Workspace; - -namespace DevSkim.LanguageServer; - -internal class DidChangeConfigurationHandler : DidChangeConfigurationHandlerBase -{ - private readonly ILogger _logger; - private readonly ILanguageServerConfiguration _configuration; - - /// - /// Handle configuration changes from vscode - /// - /// - /// - public DidChangeConfigurationHandler(ILogger logger, ILanguageServerConfiguration configuration) - { - _logger = logger; - _configuration = configuration; - } - - public override async Task Handle(DidChangeConfigurationParams request, CancellationToken cancellationToken) - { - _logger.LogDebug("DidChangeConfigurationHandler.cs: DidChangeConfigurationParams"); - ConfigHelpers.SetScannerSettings( - (IConfiguration)await _configuration.GetConfiguration(new ConfigurationItem { Section = "MS-CST-E.vscode-devskim" }) - ); - return Unit.Value; - } -} \ No newline at end of file diff --git a/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/Program.cs b/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/Program.cs index 38330965..6b4be26f 100644 --- a/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/Program.cs +++ b/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/Program.cs @@ -1,11 +1,10 @@ using CommandLine; -using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using OmniSharp.Extensions.LanguageServer.Protocol.Models; +using OmniSharp.Extensions.LanguageServer.Protocol.Server.Capabilities; using OmniSharp.Extensions.LanguageServer.Server; using Serilog; -using System.Diagnostics; namespace DevSkim.LanguageServer; @@ -46,20 +45,29 @@ static async Task Main(string[] args) options .WithInput(Console.OpenStandardInput()) .WithOutput(Console.OpenStandardOutput()) + .WithServerInfo(new ServerInfo { Name = "DevSkim Language Server" }) .ConfigureLogging( x => x .AddSerilog(Log.Logger) .AddLanguageProtocolLogging() ) .WithHandler() - .WithHandler() + .WithHandler() + // Handle settings push from clients (devskim/setSettings custom method) + // This works for both VS Code and VS - avoids workspace/configuration issues .WithHandler() .WithServices(x => x.AddLogging(b => b.SetMinimumLevel(LogLevel.Debug))) - .WithConfigurationSection(ConfigHelpers.Section) .OnInitialize( async (server, request, token) => { Log.Logger.Debug("Server is starting..."); + + // Initialize with default settings immediately + // This ensures rules are enabled even if the client + // doesn't push settings via workspace/configuration + StaticScannerSettings.UpdateWith(new Microsoft.DevSkim.LanguageProtoInterop.PortableScannerSettings()); + Log.Logger.Debug("Default settings applied"); + OmniSharp.Extensions.LanguageServer.Protocol.Server.WorkDone.IWorkDoneObserver manager = server.WorkDoneManager.For( request, new WorkDoneProgressBegin { diff --git a/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/StaticScannerSettings.cs b/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/StaticScannerSettings.cs index 804be1db..4f794853 100644 --- a/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/StaticScannerSettings.cs +++ b/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/StaticScannerSettings.cs @@ -25,8 +25,20 @@ internal static class StaticScannerSettings internal static bool ScanOnChange { get; set; } = true; internal static bool RemoveFindingsOnClose { get; set; } = true; internal static DevSkimRuleSet RuleSet { get; set; } = new DevSkimRuleSet(); - internal static DevSkimRuleProcessorOptions RuleProcessorOptions { get; set; } = new DevSkimRuleProcessorOptions(); - internal static DevSkimRuleProcessor Processor { get; set; } = new DevSkimRuleProcessor(DevSkimRuleSet.GetDefaultRuleSet(), new DevSkimRuleProcessorOptions()); + internal static DevSkimRuleProcessorOptions RuleProcessorOptions { get; set; } = CreateDefaultOptions(); + internal static DevSkimRuleProcessor Processor { get; set; } = new DevSkimRuleProcessor(DevSkimRuleSet.GetDefaultRuleSet(), CreateDefaultOptions()); + + private static DevSkimRuleProcessorOptions CreateDefaultOptions() + { + return new DevSkimRuleProcessorOptions + { + // Include all severities by default + SeverityFilter = Severity.Critical | Severity.Important | Severity.Moderate | Severity.BestPractice | Severity.ManualReview, + // Include all confidence levels by default + ConfidenceFilter = Confidence.High | Confidence.Medium | Confidence.Low, + EnableSuppressions = true + }; + } public static void UpdateWith(PortableScannerSettings request) { diff --git a/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/TextDocumentSyncHandler.cs b/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/TextDocumentSyncHandler.cs index 7ea29b6c..2f06df4d 100644 --- a/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/TextDocumentSyncHandler.cs +++ b/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/TextDocumentSyncHandler.cs @@ -20,7 +20,9 @@ internal class TextDocumentSyncHandler : TextDocumentSyncHandlerBase { private readonly ILogger _logger; private readonly ILanguageServerFacade _facade; - private readonly TextDocumentSelector _documentSelector = TextDocumentSelector.ForLanguage(StaticScannerSettings.RuleProcessorOptions.Languages.GetNames()); + // Use a broad document selector to handle all common code file types + // The actual language detection happens in GetTextDocumentAttributes + private readonly TextDocumentSelector _documentSelector = TextDocumentSelector.ForPattern("**/*"); private DevSkimRuleProcessor _processor => StaticScannerSettings.Processor; public TextDocumentSyncHandler(ILogger logger, ILanguageServerFacade facade) @@ -47,6 +49,8 @@ private async Task GenerateDiagnosticsForTextDocumentAsync(string text, in } // Diagnostics are sent a document at a time _logger.LogDebug($"\tProcessing document: {filename}"); + _logger.LogDebug($"\tRuleSet has {StaticScannerSettings.RuleSet.Count()} rules"); + _logger.LogDebug($"\tScanOnOpen: {StaticScannerSettings.ScanOnOpen}, ScanOnChange: {StaticScannerSettings.ScanOnChange}"); List issues = await Task.Run(() => _processor.Analyze(text, filename).ToList()); ImmutableArray.Builder diagnostics = ImmutableArray.Empty.ToBuilder(); ImmutableArray.Builder codeFixes = ImmutableArray.Empty.ToBuilder(); @@ -103,6 +107,9 @@ private async Task GenerateDiagnosticsForTextDocumentAsync(string text, in } } + // Clear previous code fixes for this document and register new ones + CodeActionHandler.ClearCodeFixes(uri); + _logger.LogDebug("\tPublishing diagnostics..."); _facade.TextDocument.PublishDiagnostics(new PublishDiagnosticsParams() { @@ -110,10 +117,19 @@ private async Task GenerateDiagnosticsForTextDocumentAsync(string text, in Uri = uri, Version = version }); - _facade.TextDocument.SendNotification(DevSkimMessages.FileVersion, new MappingsVersion() { version = version, fileName = uri.ToUri() }); - foreach (var mapping in codeFixes) + + // Register code fixes with the CodeActionHandler for standard LSP code action requests + _logger.LogDebug($"\tRegistering {codeFixes.Count} code fixes..."); + for (int i = 0; i < diagnostics.Count; i++) { - _facade.TextDocument.SendNotification(DevSkimMessages.CodeFixMapping, mapping); + var diag = diagnostics[i]; + // Find matching code fixes for each diagnostic by comparing the string representation of the code + foreach (var mapping in codeFixes.Where(cf => + cf.diagnostic.Code?.String == diag.Code?.String && + cf.diagnostic.Range.Start.Line == diag.Range.Start.Line)) + { + CodeActionHandler.RegisterCodeFix(uri, diag, mapping); + } } return Unit.Value; diff --git a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio.SourceGenerator/Microsoft.DevSkim.VisualStudio.SourceGenerator.csproj b/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio.SourceGenerator/Microsoft.DevSkim.VisualStudio.SourceGenerator.csproj deleted file mode 100644 index 7eeb54fd..00000000 --- a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio.SourceGenerator/Microsoft.DevSkim.VisualStudio.SourceGenerator.csproj +++ /dev/null @@ -1,19 +0,0 @@ - - - - netstandard2.0 - enable - enable - 11 - SourceGenerator - - - - - - - - - - - diff --git a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio.SourceGenerator/UpdateSettingsGenerator.cs b/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio.SourceGenerator/UpdateSettingsGenerator.cs deleted file mode 100644 index 58e657c9..00000000 --- a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio.SourceGenerator/UpdateSettingsGenerator.cs +++ /dev/null @@ -1,75 +0,0 @@ -using System.Text; -using Microsoft.CodeAnalysis; -using Microsoft.DevSkim.LanguageProtoInterop; - -namespace Microsoft.DevSkim.VisualStudio -{ - [Generator] - public class UpdateSettingsGenerator : ISourceGenerator - { - public void Initialize(GeneratorInitializationContext context) - { - } - - public void Execute(GeneratorExecutionContext context) - { - StringBuilder source = new StringBuilder(); - source.Append($@"// - namespace Microsoft.DevSkim.VisualStudio - {{ - using System; - using Microsoft.DevSkim.LanguageProtoInterop; - using System.Collections.Generic; - - internal partial class VisualStudioSettingsManager - {{ - partial void UpdateSettings(string propertyName) - {{ - switch(propertyName) - {{ -"); - - string baseIndentation = " "; - var props = typeof(IDevSkimOptions).GetProperties().Select(x => (x.Name, x.PropertyType)); - foreach (var prop in props) - { - var typeNameString = GetTypeNameString(prop.PropertyType); - source.Append($@"{baseIndentation}case ""{prop.Name}"": - {{ - var res = Get<{typeNameString}>(propertyName); - if (res.Item1 == ValueResultEnum.Success) - {{ - _currentSettings.{prop.Name} = res.Item2{ConditionallyUseNullCoalescing(typeNameString)} - }} - break; - }} -"); - } - - source.Append($@"{baseIndentation}default: break; - }} - }} - }} - }}"); - context.AddSource("VisualStudioSettingsManager.g.cs", source.ToString()); - } - - private string ConditionallyUseNullCoalescing(string typeNameString) - { - return typeNameString.StartsWith("List") ? $" ?? new {typeNameString}();" : ";"; - } - - private string GetTypeNameString(Type propPropertyType) - { - return propPropertyType.Name switch - { - "String" => "string", - "List`1" => $"List<{GetTypeNameString(propPropertyType.GetGenericArguments()[0])}>", - "Boolean" => "bool", - "Int32" => "int", - "CommentStylesEnum" => "CommentStylesEnum", - _ => "string" - }; - } - } -} \ No newline at end of file diff --git a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/.vsextension/string-resources.json b/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/.vsextension/string-resources.json new file mode 100644 index 00000000..faa21d49 --- /dev/null +++ b/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/.vsextension/string-resources.json @@ -0,0 +1,3 @@ +{ + "DevSkim.LanguageServerProvider.DisplayName": "DevSkim Security Analyzer" +} diff --git a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/DevSkimExtension.cs b/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/DevSkimExtension.cs new file mode 100644 index 00000000..fc6b1860 --- /dev/null +++ b/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/DevSkimExtension.cs @@ -0,0 +1,32 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +namespace Microsoft.DevSkim.VisualStudio; + +using global::Microsoft.Extensions.DependencyInjection; +using global::Microsoft.VisualStudio.Extensibility; +using System.Security.Cryptography; + +/// +/// Extension entry point for the DevSkim Visual Studio extension. +/// +[VisualStudioContribution] +internal class DevSkimExtension : Extension +{ + /// + public override ExtensionConfiguration ExtensionConfiguration => new() + { + Metadata = new( + id: "Microsoft.DevSkim.VisualStudio.f3a2c5e8-7d9b-4a1c-8e6f-2b3d4c5e6f7a", + version: this.ExtensionAssemblyVersion, + publisherName: "Microsoft DevLabs", + displayName: "Microsoft DevSkim", + description: "Security-focused static analysis tool for identifying vulnerabilities in source code."), + }; + + /// + protected override void InitializeServices(IServiceCollection serviceCollection) + { + base.InitializeServices(serviceCollection); + } +} diff --git a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/DevSkimFixMessageTarget.cs b/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/DevSkimFixMessageTarget.cs deleted file mode 100644 index d7b42022..00000000 --- a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/DevSkimFixMessageTarget.cs +++ /dev/null @@ -1,83 +0,0 @@ -namespace Microsot.DevSkim.LanguageClient -{ - using Microsoft.DevSkim.LanguageProtoInterop; - using Microsoft.DevSkim.VisualStudio; - using Newtonsoft.Json.Linq; - using StreamJsonRpc; - using System; - using System.Collections.Concurrent; - using System.Collections.Generic; - using System.Threading.Tasks; - - public class DevSkimFixMessageTarget - { - public DevSkimFixMessageTarget() - { - } - - /// - /// Remove all Code fixes for the specified filename that are not of the specified version - /// - /// JToken representation of - /// - [JsonRpcMethod(DevSkimMessages.FileVersion)] - public async Task RemoveOldMappingsByVersionAsync(JToken token) - { - await Task.Run(() => - { - MappingsVersion version = token.ToObject(); - if (version is { }) - { - if (StaticData.FileToCodeFixMap.ContainsKey(version.fileName)) - { - foreach (var key in StaticData.FileToCodeFixMap[version.fileName].Keys) - { - if (key != version.version) - { - StaticData.FileToCodeFixMap[version.fileName].TryRemove(key, out _); - } - } - } - } - }); - } - - - /// - /// Update the client cache of available fixes for published diagnostics - /// - /// JToken representation of - /// - [JsonRpcMethod(DevSkimMessages.CodeFixMapping)] - public async Task CodeFixMappingEventAsync(JToken jToken) - { - await Task.Run(() => - { - CodeFixMapping mapping = jToken.ToObject(); - if (mapping is { }) - { - StaticData.FileToCodeFixMap.AddOrUpdate(mapping.fileName, - // Add New Nested Dictionary - (Uri _) => new (new Dictionary> - { { mapping.version ?? -1, new (new Dictionary() - { {mapping, true } }) } }), - // Update Nested Dictionary - (key, oldValue) => - { - oldValue.AddOrUpdate(mapping.version ?? -1, - // Add new Set of mappings - (int _) => - { - var addedMapping = new ConcurrentDictionary(); - addedMapping.TryAdd(mapping, true); - return addedMapping; - }, - // Update Set of CodeFixMappings - (versionKey, oldSet) => { oldSet.TryAdd(mapping, true); return oldSet; }); - return oldValue; - }); - } - }); - } - } -} \ No newline at end of file diff --git a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/DevSkimLanguageClient.cs b/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/DevSkimLanguageClient.cs deleted file mode 100644 index e8730452..00000000 --- a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/DevSkimLanguageClient.cs +++ /dev/null @@ -1,163 +0,0 @@ -using Microsoft.VisualStudio.LanguageServer.Client; -using Microsoft.VisualStudio.Shell; -using Microsoft.VisualStudio.Utilities; -using StreamJsonRpc; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Reflection; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.VisualStudio.Threading; -using Task = System.Threading.Tasks.Task; -using System.ComponentModel.Composition; -using Microsoft.Build.Framework.XamlTypes; -using Microsoft.DevSkim.VisualStudio.ProcessTracker; -using Microsoft.DevSkim.VisualStudio; - -namespace Microsot.DevSkim.LanguageClient -{ - // NOTE: Visual Studio does NOT activate ILanguageClient for base content types like "code". - // Each specific content type must be explicitly registered for the language client to be activated - // when files of that type are opened. This list corresponds to the languages that DevSkim supports - // for security analysis. See also: DevSkim-VSCode-Plugin/client/common/selectors.ts - [ContentType("C/C++")] - [ContentType("CSharp")] - [ContentType("F#")] - [ContentType("JavaScript")] - [ContentType("TypeScript")] - [ContentType("HTML")] - [ContentType("JSON")] - [ContentType("XML")] - [ContentType("XAML")] - [ContentType("Python")] - [ContentType("Ruby")] - [ContentType("Perl")] - [ContentType("PHP")] - [ContentType("Java")] - [ContentType("Go")] - [ContentType("Rust")] - [ContentType("SQL")] - [ContentType("Lua")] - [ContentType("Swift")] - [ContentType("PowerShell")] - [ContentType("shellscript")] - [ContentType("yaml")] - [ContentType("plaintext")] - [ContentType("code")] // Kept as fallback for any types not explicitly listed - [Export(typeof(ILanguageClient))] - public class DevSkimLanguageClient : ILanguageClient, ILanguageClientCustomMessage2 - { - [ImportingConstructor] - public DevSkimLanguageClient(IProcessTracker processTracker) - { - ThreadHelper.ThrowIfNotOnUIThread(); - _manager = new VisualStudioSettingsManager(ServiceProvider.GlobalProvider, this); - _processTracker = processTracker; - } - - /// - /// A reference to the Rpc connection between the client and server - /// - internal JsonRpc Rpc - { - get; - set; - } - /// Pushes changed settings to the server - public SettingsChangedNotifier SettingsNotifier { get; private set; } - /// - public string Name => "DevSkim Visual Studio Extension"; - // This handles incoming messages to the language client about fixes - public object CustomMessageTarget => new DevSkimFixMessageTarget(); - /// Detects changes in the client settings - private readonly VisualStudioSettingsManager _manager; - /// Keeps track of the started language server process and ensures that it is properly closed when the extension closes. - private readonly IProcessTracker _processTracker; - /// - public async Task ActivateAsync(CancellationToken token) - { - await Task.Yield(); - ProcessStartInfo info = new ProcessStartInfo(); - info.FileName = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Server", @"Microsoft.DevSkim.LanguageServer.exe"); - info.RedirectStandardInput = true; - info.RedirectStandardOutput = true; - info.UseShellExecute = false; - info.CreateNoWindow = true; - - Process process = new Process(); - process.StartInfo = info; - - if (process.Start()) - { - _processTracker.AddProcess(process); - return new Connection(process.StandardOutput.BaseStream, process.StandardInput.BaseStream); - } - return null; - } - /// - public event AsyncEventHandler StartAsync; - /// - public event AsyncEventHandler StopAsync; - /// - public async Task OnLoadedAsync() - { - if (StartAsync != null) - { - await StartAsync.InvokeAsync(this, EventArgs.Empty); - } - } - /// - public async Task StopServerAsync() - { - if (StopAsync != null) - { - await StopAsync.InvokeAsync(this, EventArgs.Empty); - } - } - - /// - public Task AttachForCustomMessageAsync(JsonRpc rpc) - { - Rpc = rpc; - SettingsNotifier = new SettingsChangedNotifier(Rpc); - return Task.CompletedTask; - } - - /// - public async Task OnServerInitializedAsync() - { - await _manager.UpdateAllSettingsAsync(); - } - - /// - public Task OnServerInitializeFailedAsync(ILanguageClientInitializationInfo initializationState) - { - string message = "DevSkim Language Client failed to activate."; - string exception = initializationState.InitializationException?.ToString() ?? string.Empty; - message = $"{message}\n {exception}"; - - InitializationFailureContext failureContext = new InitializationFailureContext() - { - FailureMessage = message, - }; - - return Task.FromResult(failureContext); - } - - // Not used but required by Interface - /// - public IEnumerable ConfigurationSections => null; - /// - public object InitializationOptions => null; - /// - public IEnumerable FilesToWatch => null; - /// - public bool ShowNotificationOnInitializeFailed => true; - - // This handles modifying outgoing messages to the language server - /// - object ILanguageClientCustomMessage2.MiddleLayer => null; - } -} diff --git a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/DevSkimLanguageServerProvider.cs b/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/DevSkimLanguageServerProvider.cs new file mode 100644 index 00000000..39bf23ef --- /dev/null +++ b/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/DevSkimLanguageServerProvider.cs @@ -0,0 +1,127 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +namespace Microsoft.DevSkim.VisualStudio; + +using System.Diagnostics; +using System.IO.Pipelines; +using System.Reflection; +using global::Microsoft.VisualStudio.Extensibility; +using global::Microsoft.VisualStudio.Extensibility.Editor; +using global::Microsoft.VisualStudio.Extensibility.LanguageServer; +using global::Microsoft.VisualStudio.RpcContracts.LanguageServerProvider; +using Nerdbank.Streams; + +/// +/// DevSkim Language Server Provider. +/// Activates the DevSkim language server for security analysis when supported files are opened. +/// +#pragma warning disable VSEXTPREVIEW_LSP // Type is for evaluation purposes only and is subject to change or removal in future updates. +[VisualStudioContribution] +internal class DevSkimLanguageServerProvider : LanguageServerProvider +{ + /// + public override LanguageServerProviderConfiguration LanguageServerProviderConfiguration => new( + "%DevSkim.LanguageServerProvider.DisplayName%", + [ + // Try using "text" base document type to activate for all text files + // The language server itself determines which files it can analyze + DocumentFilter.FromDocumentType("text"), + ]); + + /// + public override Task CreateServerConnectionAsync(CancellationToken cancellationToken) + { + // Log to a file for debugging since Debug.WriteLine may not be visible + var logPath = Path.Combine(Path.GetTempPath(), "devskim-vs-extension.log"); + File.AppendAllText(logPath, $"[{DateTime.Now}] CreateServerConnectionAsync called\n"); + + var serverPath = GetLanguageServerPath(); + File.AppendAllText(logPath, $"[{DateTime.Now}] Server path: {serverPath}\n"); + File.AppendAllText(logPath, $"[{DateTime.Now}] Assembly location: {Assembly.GetExecutingAssembly().Location}\n"); + + if (string.IsNullOrEmpty(serverPath) || !File.Exists(serverPath)) + { + File.AppendAllText(logPath, $"[{DateTime.Now}] ERROR: Language server not found at: {serverPath}\n"); + Debug.WriteLine($"DevSkim: Language server not found at: {serverPath}"); + return Task.FromResult(null); + } + + File.AppendAllText(logPath, $"[{DateTime.Now}] Server exists, starting process...\n"); + + var startInfo = new ProcessStartInfo + { + FileName = serverPath, + RedirectStandardInput = true, + RedirectStandardOutput = true, + RedirectStandardError = true, + UseShellExecute = false, + CreateNoWindow = true, + WorkingDirectory = Path.GetDirectoryName(serverPath), + }; + +#pragma warning disable CA2000 // The process is disposed after Visual Studio sends the stop command. + var process = new Process { StartInfo = startInfo }; +#pragma warning restore CA2000 + + // Log stderr for debugging + process.ErrorDataReceived += (sender, e) => + { + if (!string.IsNullOrEmpty(e.Data)) + { + Debug.WriteLine($"DevSkim Server: {e.Data}"); + } + }; + + if (process.Start()) + { + process.BeginErrorReadLine(); + File.AppendAllText(logPath, $"[{DateTime.Now}] Language server started (PID: {process.Id})\n"); + Debug.WriteLine($"DevSkim: Language server started (PID: {process.Id})"); + + return Task.FromResult(new DuplexPipe( + PipeReader.Create(process.StandardOutput.BaseStream), + PipeWriter.Create(process.StandardInput.BaseStream))); + } + + File.AppendAllText(logPath, $"[{DateTime.Now}] ERROR: Failed to start language server process\n"); + Debug.WriteLine("DevSkim: Failed to start language server process"); + return Task.FromResult(null); + } + + /// + public override Task OnServerInitializationResultAsync( + ServerInitializationResult serverInitializationResult, + LanguageServerInitializationFailureInfo? initializationFailureInfo, + CancellationToken cancellationToken) + { + var logPath = Path.Combine(Path.GetTempPath(), "devskim-vs-extension.log"); + + if (serverInitializationResult == ServerInitializationResult.Failed) + { + File.AppendAllText(logPath, $"[{DateTime.Now}] ERROR: Language server initialization failed: {initializationFailureInfo?.StatusMessage}\n"); + Debug.WriteLine($"DevSkim: Language server initialization failed: {initializationFailureInfo?.StatusMessage}"); + // Disable the server from being activated again + this.Enabled = false; + } + else + { + File.AppendAllText(logPath, $"[{DateTime.Now}] Language server initialized successfully\n"); + Debug.WriteLine("DevSkim: Language server initialized successfully"); + } + + return base.OnServerInitializationResultAsync(serverInitializationResult, initializationFailureInfo, cancellationToken); + } + + private static string GetLanguageServerPath() + { + var extensionDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); + if (string.IsNullOrEmpty(extensionDirectory)) + { + return string.Empty; + } + + return Path.Combine(extensionDirectory, "Server", "Microsoft.DevSkim.LanguageServer.exe"); + } +} +#pragma warning restore VSEXTPREVIEW_LSP diff --git a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/DevSkimSuggestedAction.cs b/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/DevSkimSuggestedAction.cs deleted file mode 100644 index 80d004bb..00000000 --- a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/DevSkimSuggestedAction.cs +++ /dev/null @@ -1,116 +0,0 @@ -// Copyright (C) Microsoft. All rights reserved. Licensed under the MIT License. - -using Microsoft.VisualStudio.Imaging.Interop; -using Microsoft.VisualStudio.Language.Intellisense; -using Microsoft.VisualStudio.Text; -using System.Threading; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Documents; -using System.Windows.Media; -namespace Microsoft.DevSkim.VisualStudio -{ - using Microsoft.DevSkim.LanguageProtoInterop; - using System; - using System.Collections.Generic; - using System.Threading.Tasks; - - internal class DevSkimSuggestedAction: ISuggestedAction - { - public DevSkimSuggestedAction(SnapshotSpan span, CodeFixMapping mapping) - { - _span = span; - _snapshot = span.Snapshot; - _mapping = mapping; - DisplayText = mapping.friendlyString; - } - - public string DisplayText { get; } - - public bool HasActionSets - { - get - { - return false; - } - } - - public bool HasPreview - { - get - { - return false; - } - } - - public string IconAutomationText - { - get - { - return null; - } - } - - ImageMoniker ISuggestedAction.IconMoniker - { - get - { - return default(ImageMoniker); - } - } - - public string InputGestureText - { - get - { - return null; - } - } - - public void Dispose() - { - } - - public Task> GetActionSetsAsync(CancellationToken cancellationToken) - { - return Task.FromResult>(Array.Empty()); - } - - public Task GetPreviewAsync(CancellationToken cancellationToken) - { - ITextSnapshotLine line = _snapshot.GetLineFromPosition(_span.Start.Position); - - TextBlock textBlock = new TextBlock(); - textBlock.Padding = new Thickness(5); - textBlock.Inlines.Add(new Run() { Text = _mapping.replacement, Foreground = new SolidColorBrush(Color.FromRgb(0x34, 0xAF, 0x00)) }); - return Task.FromResult(textBlock); - } - - public void Invoke(CancellationToken cancellationToken) - { - if (cancellationToken.IsCancellationRequested) - { - return; - } - if (!_mapping.isSuppression) - { - _span.Snapshot.TextBuffer.Replace(new Microsoft.VisualStudio.Text.Span(_mapping.matchStart, _mapping.matchEnd - _mapping.matchStart), _mapping.replacement); - } - else - { - ITextSnapshotLine line = _span.Snapshot.GetLineFromLineNumber(_mapping.diagnostic.Range.End.Line); - _span.Snapshot.TextBuffer.Insert(line.End.Position, _mapping.replacement); - } - } - - public bool TryGetTelemetryId(out Guid telemetryId) - { - telemetryId = Guid.Empty; - return false; - } - - private readonly CodeFixMapping _mapping; - private readonly ITextSnapshot _snapshot; - private readonly SnapshotSpan _span; - } -} \ No newline at end of file diff --git a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/Microsoft.DevSkim.VisualStudio.csproj b/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/Microsoft.DevSkim.VisualStudio.csproj index ad0e3a7b..30a2d0ed 100644 --- a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/Microsoft.DevSkim.VisualStudio.csproj +++ b/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/Microsoft.DevSkim.VisualStudio.csproj @@ -1,169 +1,42 @@ - - + - 17.0 - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - - - - Debug - AnyCPU - 2.0 - {82b43b9b-a64c-4715-b499-d71e9ca2bd60};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - {E7A5F71D-137D-4D65-AB27-2ADD1FA6B26B} - Library - Properties + net8.0-windows8.0 + enable + 12 + en-US Microsoft.DevSkim.VisualStudio Microsoft.DevSkim.VisualStudio - v4.7.2 - win - true - true - false - true - true - true - Program - $(DevEnvDir)devenv.exe - /rootsuffix Exp - enable - latest - MIT + + + enable - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - - - - Component - - - - - - - - - - - - - True - True - Resources.resx - - - - - - - - - - PreserveNewest - Content - - - Designer - - - - - - 17.13.33 - - - 17.2.8 - - - compile; build; native; contentfiles; analyzers; buildtransitive - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - + - - - - - - - - - - - + + + + + + + - - {774e78f3-b48a-4d01-b70b-9cfb03a55663} - Microsoft.DevSkim.LanguageProtoInterop - + + + + + + + + + + + + - - PreserveNewest - true - Content - - + PreserveNewest - true - Content - - PreserveNewest - true - Content - - - PreserveNewest - true - Content - - - - - ResXFileCodeGenerator - Resources.Designer.cs - - - - - - - - - - - - - - true - Server - - - - - - \ No newline at end of file + diff --git a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/Options/GeneralOptionsPage.cs b/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/Options/GeneralOptionsPage.cs deleted file mode 100644 index 2779a4fc..00000000 --- a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/Options/GeneralOptionsPage.cs +++ /dev/null @@ -1,193 +0,0 @@ -using Microsoft.DevSkim.LanguageProtoInterop; - -namespace Microsoft.DevSkim.VisualStudio.Options -{ - using Microsoft.Build.Framework.XamlTypes; - using Microsoft.VisualStudio.Shell; - using System; - using System.ComponentModel; - using System.Drawing; - using System.Runtime.InteropServices; - using System.Windows.Forms; - // When adding any property here, be sure to add it to IDevSkimOptions as well - [Guid(PageGuidString)] - public class GeneralOptionsPage : DialogPage, IDevSkimOptions - { - const string StringCollectionEditor = "System.Windows.Forms.Design.StringCollectionEditor, System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"; - - [Browsable(false)] - [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] - protected override IWin32Window Window - { - get - { - PropertyGrid propertyGrid = new PropertyGrid(); - propertyGrid.Location = new Point(0, 0); - propertyGrid.ToolbarVisible = false; - propertyGrid.CommandsVisibleIfAvailable = false; - propertyGrid.PropertySort = PropertySort.Categorized; - propertyGrid.SelectedObject = AutomationObject; - return propertyGrid; - } - } - - public const string PageGuidString = "c88696f6-dd46-380e-a706-14e73fd51564"; - private const string RulesCategory = "Rules"; - private const string SuppressionsCategory = "Suppressions"; - private const string GuidanceCategory = "Guidance"; - private const string IgnoresCategory = "Ignores"; - private const string FindingsCategory = "Findings"; - private const string TriggersCategory = "Triggers"; - - /// - /// Rule Options - /// - [Category(RulesCategory)] - [DisplayName("Enable Critical Severity Rules")] - [Description("Turn on the rules with severity \"Critical\".")] - public bool EnableCriticalSeverityRules { get; set; } = true; - - [Category(RulesCategory)] - [DisplayName("Enable Important Severity Rules")] - [Description("Turn on the rules with severity \"Important\".")] - public bool EnableImportantSeverityRules { get; set; } = true; - - [Category(RulesCategory)] - [DisplayName("Enable Moderate Severity Rules")] - [Description("Turn on the rules with severity \"Moderate\".")] - public bool EnableModerateSeverityRules { get; set; } = true; - - [Category(RulesCategory)] - [DisplayName("Enable Best Practice Severity Rules")] - [Description("Turn on the rules with severity \"Best-Practice\". " + - "These rules either flag issues that are typically of a lower severity, " + - "or recommended practices that lead to more secure code, but aren't typically outright vulnerabilities.")] - public bool EnableBestPracticeSeverityRules { get; set; } = true; - - [Category(RulesCategory)] - [DisplayName("Enable Manual Review Severity Rules")] - [Description("Turn on the rules that flag things for manual review. " + - "These are typically scenarios that *could* be incredibly severe if tainted data can be inserted, " + - "but are often programmatically necessary (for example, dynamic code generation with \"eval\"). " + - "Since these rules tend to require further analysis upon flagging an issue, they are disabled by default.")] - public bool EnableManualReviewSeverityRules { get; set; } = true; - - [Category(RulesCategory)] - [DisplayName("Enable High Confidence Rules")] - [Description("Turn on the rules of confidence \"High\".")] - public bool EnableHighConfidenceRules { get; set; } = true; - - [Category(RulesCategory)] - [DisplayName("Enable Medium Confidence Rules")] - [Description("Turn on the rules of confidence \"Medium\".")] - public bool EnableMediumConfidenceRules { get; set; } = true; - - [Category(RulesCategory)] - [DisplayName("Enable Low Confidence Rules")] - [Description("Turn on the rules of confidence \"Low\".")] - public bool EnableLowConfidenceRules { get; set; } = false; - - [Category(RulesCategory)] - [DisplayName("Custom Rules Paths")] - [Description("A comma separated list of local paths on disk to rules files or folders containing rule files, " + - "for DevSkim to use in analysis.")] - public string CustomRulesPathsString { get; set; } = string.Empty; - - [Category(RulesCategory)] - [DisplayName("Custom Languages Path")] - [Description( - "A local path to a custom language file for analysis. Also requires customCommentsPath to be set.")] - public string CustomLanguagesPath { get; set; } = string.Empty; - - [Category(RulesCategory)] - [DisplayName("Custom Comments Path")] - [Description( - "A local path to a custom comments file for analysis. Also requires customLanguagesPath to be set.")] - public string CustomCommentsPath { get; set; } = string.Empty; - - - /// - /// Suppression Options - /// - [Category(SuppressionsCategory)] - [DisplayName("Suppression Duration In Days")] - [Description("DevSkim allows for findings to be suppressed for a temporary period of time. " + - "The default is 30 days. Set to 0 to disable temporary suppressions.")] - public int SuppressionDurationInDays { get; set; } = 30; - - [Category(SuppressionsCategory)] - [DisplayName("Suppression Comment Style")] - [Description("When DevSkim inserts a suppression comment it defaults to using single line comments for " + - "every language that has them. Setting this to 'block' will instead use block comments for the languages " + - "that support them. Block comments are suggested if regularly adding explanations for why a finding " + - "was suppressed")] - public CommentStylesEnum SuppressionCommentStyle { get; set; } = CommentStylesEnum.Line; - - [Category(SuppressionsCategory)] - [DisplayName("Manual Reviewer Name")] - [Description("If set, insert this name in inserted suppression comments.")] - public string ManualReviewerName { get; set; } = string.Empty; - - - /// - /// Guidance Options - /// - [Category(GuidanceCategory)] - [DisplayName("Guidance Base URL")] - [Description("Each finding has a guidance file that describes the issue and solutions in more detail. " + - "By default, those files live on the DevSkim github repo however, with this setting, " + - "organizations can clone and customize that repo, and specify their own base URL for the guidance.")] - public string GuidanceBaseURL { get; set; } = "https://github.com/microsoft/devskim/tree/main/guidance"; - - - /// - /// Ignore Options - /// - [Category(IgnoresCategory)] - [DisplayName("Ignore Files by Globs")] - [Description("Comma separated glob expression patterns to exclude files and folders which match from analysis.")] - public string IgnoreFilesString { get; set; } = string.Empty; - - [Category(IgnoresCategory)] - [DisplayName("Ignore Rules by Id")] - [Description("Comma separated list of exact string identity of DevSkim Rule IDs to ignore.")] - public string IgnoreRulesListString { get; set; } = string.Empty; - - [Category(IgnoresCategory)] - [DisplayName("Ignore Default Rules")] - [Description("Disable all default DevSkim rules.")] - public bool IgnoreDefaultRules { get; set; } = false; - - - /// - /// Finding Options - /// - // TODO: Do we even have a scan all files in workspace type of commmand here? - [Category(FindingsCategory)] - [DisplayName("Remove Findings On Close")] - [Description("By default, when a source file is closed the findings remain in the 'Error List' window. " + - "Setting this value to true will cause findings to be removed from 'Error List' when the document is closed. " + - "Note, setting this to true will cause findings that are listed when invoking the 'Scan all files in workspace' " + - "command to automatically clear away after a couple of minutes.")] - public bool RemoveFindingsOnClose { get; set; } = true; - - - /// - /// Trigger Options - /// - [Category(TriggersCategory)] - [DisplayName("Scan On Open")] - [Description("Scan files on open.")] - public bool ScanOnOpen { get; set; } = true; - - [Category(TriggersCategory)] - [DisplayName("Scan On Save")] - [Description("Scan files on save.")] - public bool ScanOnSave { get; set; } = true; - - [Category(TriggersCategory)] - [DisplayName("Scan On Change")] - [Description("Scan files on change.")] - public bool ScanOnChange { get; set; } = true; - } -} diff --git a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/Options/OptionsPackage.cs b/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/Options/OptionsPackage.cs deleted file mode 100644 index 55620c15..00000000 --- a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/Options/OptionsPackage.cs +++ /dev/null @@ -1,37 +0,0 @@ -namespace Microsoft.DevSkim.VisualStudio.Options -{ - using Microsoft.VisualStudio.Shell; - using System.Diagnostics.CodeAnalysis; - using System.Runtime.InteropServices; - - /// - /// This is the class that implements the package exposed by this assembly. - /// - [ProvideBindingPath] - [Guid(PackageGuidString)] - [PackageRegistration(UseManagedResourcesOnly = true, AllowsBackgroundLoading = true)] - [InstalledProductRegistration("#110", "#112", "1.0", IconResourceID = 400)] // Info on this package for Help/About - [ProvideMenuResource("Menus.ctmenu", 1)] - [ProvideOptionPage(typeof(GeneralOptionsPage), "DevSkim", "General", 1000, 1001, true)] - [ProvideProfile(typeof(GeneralOptionsPage), "DevSkim", "General", 1000, 1002, true, DescriptionResourceID = 1003)] - [SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1650:ElementDocumentationMustBeSpelledCorrectly", Justification = "pkgdef, VS and vsixmanifest are valid VS terms")] - public sealed class OptionsPackage : AsyncPackage - { - /// - /// OptionPackage GUID string. - /// - public const string PackageGuidString = "ef3feecc-7c99-42f5-aa32-95c3b0d389aa"; - - /// - /// Initializes a new instance of the class. - /// - public OptionsPackage() - { - // Initialization code - } - - #region Package Members - - #endregion - } -} diff --git a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/ProcessTracker/IProcessTracker.cs b/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/ProcessTracker/IProcessTracker.cs deleted file mode 100644 index 8ac843c7..00000000 --- a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/ProcessTracker/IProcessTracker.cs +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -using System; -using System.Diagnostics; - -namespace Microsoft.DevSkim.VisualStudio.ProcessTracker -{ - /// - /// Provides tracking and termination for a collection of processes. Processes are killed when the tracker is disposed. - /// - public interface IProcessTracker : IDisposable - { - /// - /// Adds a process to be tracked. - /// - /// - public void AddProcess(Process process); - } -} diff --git a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/ProcessTracker/IWindowEventsListener.cs b/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/ProcessTracker/IWindowEventsListener.cs deleted file mode 100644 index 650f8a30..00000000 --- a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/ProcessTracker/IWindowEventsListener.cs +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -using System; - -namespace Microsoft.DevSkim.VisualStudio.ProcessTracker -{ - /// - /// Can listen to specified window's events and fire callback when events received. - /// - public interface IWindowEventsListener : IDisposable - { - event EventHandler SystemEvent; - } -} diff --git a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/ProcessTracker/JobObjectProcessTracker.cs b/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/ProcessTracker/JobObjectProcessTracker.cs deleted file mode 100644 index 47bd723a..00000000 --- a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/ProcessTracker/JobObjectProcessTracker.cs +++ /dev/null @@ -1,116 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -using System; -using System.ComponentModel; -using System.ComponentModel.Composition; -using System.Diagnostics; -using System.Runtime.InteropServices; - -namespace Microsoft.DevSkim.VisualStudio.ProcessTracker -{ - /// - /// Allows processes to be automatically killed if this parent process unexpectedly quits - /// (or when an instance of this class is disposed). - /// - [Export(typeof(IProcessTracker))] - public sealed class JobObjectProcessTracker : IProcessTracker - { - private bool disposed; - private readonly object disposeLock = new(); - - /// - /// The job handle. - /// - /// - /// Closing this handle would close all tracked processes. This will happen automatically when - /// our process exits. - /// - private readonly SafeObjectHandle jobHandle; - - /// - /// Initializes a new instance of the class. - /// - public JobObjectProcessTracker() - { - // The job name is optional (and can be null) but it helps with diagnostics. - // If it's not null, it has to be unique. Use SysInternals' Handle command-line - // utility: handle -a JobObjectProcessTracker - string jobName = nameof(JobObjectProcessTracker) + Process.GetCurrentProcess().Id; - - jobHandle = NativeMethods.CreateJobObject(IntPtr.Zero, jobName); - - JOBOBJECT_EXTENDED_LIMIT_INFORMATION extendedInfo = new() - { - BasicLimitInformation = new JOBOBJECT_BASIC_LIMIT_INFORMATION - { - LimitFlags = JOB_OBJECT_LIMIT_FLAGS.JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE | - JOB_OBJECT_LIMIT_FLAGS.JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK, - }, - }; - - // This code can be a lot simpler if we use pointers, but since this class is so generally interesting - // and may be copied and pasted to other projects that prefer to avoid unsafe code, we use Marshal and IntPtr's instead. - int length = Marshal.SizeOf(extendedInfo); - IntPtr pExtendedInfo = Marshal.AllocHGlobal(length); - try - { - Marshal.StructureToPtr(extendedInfo, pExtendedInfo, fDeleteOld: false); - try - { - if (!NativeMethods.SetInformationJobObject(jobHandle, JOBOBJECTINFOCLASS.JobObjectExtendedLimitInformation, pExtendedInfo, (uint)length)) - { - throw new Win32Exception(); - } - } - finally - { - Marshal.DestroyStructure(pExtendedInfo); - } - } - finally - { - Marshal.FreeHGlobal(pExtendedInfo); - } - } - - /// - /// Ensures a given process is killed when the current process exits. - /// - /// The process whose lifetime should never exceed the lifetime of the current process. - public void AddProcess(Process process) - { - _ = process ?? throw new ArgumentNullException(nameof(process)); - - lock (disposeLock) - { - // Do not assign the new process handle to the job object if it is disposed. - // Use a lock to avoid race conditions with disposing and assigning processes to the job object. - if (!disposed) - { - bool success = NativeMethods.AssignProcessToJobObject(jobHandle, new SafeObjectHandle(process.Handle, ownsHandle: false)); - if (!success && !process.HasExited) - { - throw new Win32Exception(); - } - } - } - } - - /// - /// Kills all processes previously tracked with by closing the Windows Job. - /// - public void Dispose() - { - lock (disposeLock) - { - if (!disposed) - { - jobHandle?.Dispose(); - } - - disposed = true; - } - } - } -} diff --git a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/ProcessTracker/NativeMethods.cs b/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/ProcessTracker/NativeMethods.cs deleted file mode 100644 index 557240ae..00000000 --- a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/ProcessTracker/NativeMethods.cs +++ /dev/null @@ -1,493 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -using System; -using System.Diagnostics.CodeAnalysis; -using System.Runtime.InteropServices; - -namespace Microsoft.DevSkim.VisualStudio.ProcessTracker -{ -#pragma warning disable 0649 - /// - /// Pinvoke and other win32 declarations. - /// - public static class NativeMethods - { - public const int WM_SYSCOMMAND = 0x0112; - public const int SC_CLOSE = 0xF060; - public const int STATE_SYSTEM_INVISIBLE = 0x00008000; - public const int GWL_EXSTYLE = -0x14; - public const int WS_EX_TOOLWINDOW = 0x0080; - public const int BUFFER_E_RELOAD_OCCURRED = unchecked((int)0x80041009); - public const int PROCESS_CREATE_PROCESS = (0x0080); - public const int PROCESS_QUERY_LIMITED_INFORMATION = 0x001000; - public const uint LOGON_NETCREDENTIALS_ONLY = 0x2; - public const uint CREATE_NEW_PROCESS_GROUP = 0x200; - - public const int TOKEN_ASSIGN_PRIMARY = 0x0001; - public const int TOKEN_DUPLICATE = 0x0002; - public const int TOKEN_QUERY = 0x0008; - public const int TOKEN_ADJUST_DEFAULT = 0x0080; - public const int TOKEN_ADJUST_SESSIONID = 0x0100; - - public const int SecurityAnonymous = 0x0; - public const int TokenPrimary = 0x1; - - // ListView messages - public const int LVM_EDITLABEL = (0x1000 + 118); - - [DllImport("kernel32.dll", SetLastError = true)] - [DefaultDllImportSearchPaths(DllImportSearchPath.UserDirectories)] - public static extern bool CloseHandle(IntPtr handle); - - [DllImport("User32.dll", SetLastError = true)] - [DefaultDllImportSearchPaths(DllImportSearchPath.UserDirectories)] - public static extern IntPtr SetWinEventHook( - WindowsSystemEvents eventMin, - WindowsSystemEvents eventMax, - IntPtr hmodWinEventProc, - WindowEventHandler lpfnWinEventProc, - uint idProcess, - uint idThread, - uint dwFlags); - - [DllImport("user32.dll")] - [DefaultDllImportSearchPaths(DllImportSearchPath.UserDirectories)] - public static extern bool UnhookWinEvent(IntPtr hWinEventHook); - - /// - /// Creates or opens a job object. - /// - /// A pointer to a structure that specifies the security descriptor for the job object and determines whether child processes can inherit the returned handle. - /// If lpJobAttributes is NULL, the job object gets a default security descriptor and the handle cannot be inherited. - /// The ACLs in the default security descriptor for a job object come from the primary or impersonation token of the creator. - /// - /// The name of the job. The name is limited to MAX_PATH characters. Name comparison is case-sensitive. - /// If lpName is NULL, the job is created without a name. - /// If lpName matches the name of an existing event, semaphore, mutex, waitable timer, or file-mapping object, the function fails and the GetLastError function returns ERROR_INVALID_HANDLE. - /// This occurs because these objects share the same namespace.The object can be created in a private namespace.For more information, see Object Namespaces. - /// Terminal Services: The name can have a "Global\" or "Local\" prefix to explicitly create the object in the global or session namespace. The remainder of the name can contain any character except the backslash character (\). For more information, see Kernel Object Namespaces. - /// - /// - /// If the function succeeds, the return value is a handle to the job object. The handle has the JOB_OBJECT_ALL_ACCESS access right. If the object existed before the function call, the function returns a handle to the existing job object and GetLastError returns ERROR_ALREADY_EXISTS. - /// If the function fails, the return value is NULL.To get extended error information, GetLastError/>. - /// - [DllImport("Kernel32", SetLastError = true, CharSet = CharSet.Unicode)] - [DefaultDllImportSearchPaths(DllImportSearchPath.UserDirectories)] - public static extern SafeObjectHandle CreateJobObject(IntPtr lpJobAttributes, string lpName); - - /// - /// Assigns a process to an existing job object. - /// - /// - /// A handle to the job object to which the process will be associated. - /// The CreateJobObject or OpenJobObject function returns this handle. - /// The handle must have the JOB_OBJECT_ASSIGN_PROCESS access right. For more information, see Job Object Security and Access Rights. - /// - /// - /// A handle to the process to associate with the job object. The handle must have the PROCESS_SET_QUOTA and PROCESS_TERMINATE access rights. For more information, see Process Security and Access Rights. - /// If the process is already associated with a job, the job specified by hJob must be empty or it must be in the hierarchy of nested jobs to which the process already belongs, and it cannot have UI limits set(SetInformationJobObject with JobObjectBasicUIRestrictions). - /// For more information, see Remarks. - /// Windows 7, Windows Server 2008 R2, Windows XP with SP3, Windows Server 2008, Windows Vista, and Windows Server 2003: The process must not already be assigned to a job; if it is, the function fails with ERROR_ACCESS_DENIED.This behavior changed starting in Windows 8 and Windows Server 2012. - /// Terminal Services: All processes within a job must run within the same session as the job. - /// - /// - /// If the function succeeds, the return value is nonzero. - /// If the function fails, the return value is zero.To get extended error information, call GetLastError/>. - /// - [DllImport("Kernel32", SetLastError = true)] - [DefaultDllImportSearchPaths(DllImportSearchPath.UserDirectories)] - public static extern bool AssignProcessToJobObject(SafeObjectHandle hJob, SafeObjectHandle hProcess); - - /// - /// Sets limits for a job object. - /// - /// - /// A handle to the job whose limits are being set. The CreateJobObject or OpenJobObject function returns this handle. The handle must have the JOB_OBJECT_SET_ATTRIBUTES access right. For more information, see Job Object Security and Access Rights. - /// - /// - /// The information class for the limits to be set. - /// - /// - /// The limits or job state to be set for the job. The format of this data depends on the value of JobObjectInfoClass. - /// - /// - /// The size of the job information being set, in bytes. - /// - /// - /// If the function succeeds, the return value is nonzero. - /// If the function fails, the return value is zero.To get extended error information, call GetLastError/>. - /// - [DllImport("Kernel32", SetLastError = true)] - [DefaultDllImportSearchPaths(DllImportSearchPath.UserDirectories)] - public static extern bool SetInformationJobObject(SafeObjectHandle hJob, JOBOBJECTINFOCLASS jobObjectInfoClass, IntPtr lpJobObjectInfo, uint cbJobObjectInfoLength); - } - - internal delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam); - - [Flags] - public enum ThreadAccess : int - { - TERMINATE = (0x0001), - SUSPEND_RESUME = (0x0002), - GET_CONTEXT = (0x0008), - SET_CONTEXT = (0x0010), - SET_INFORMATION = (0x0020), - QUERY_INFORMATION = (0x0040), - SET_THREAD_TOKEN = (0x0080), - IMPERSONATE = (0x0100), - DIRECT_IMPERSONATION = (0x0200) - } - - [StructLayout(LayoutKind.Sequential)] - public struct TITLEBARINFO - { - public int cbSize; - public RECT rcTitleBar; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] - public int[] rgstate; - } - - [StructLayout(LayoutKind.Sequential)] - public struct RECT - { - public int left; - public int top; - public int right; - public int bottom; - } - - [Flags] - internal enum WinEventHookFlags - { - // The callback function is NOT mapped into the address space of the process that generates the event. -#pragma warning disable CA1008 // Enums should have zero value - OutOfContext = 0x0000, -#pragma warning restore CA1008 // Enums should have zero value - // Prevents this instance of the hook from receiving the events that are generated by the thread that - // is registering this hook. - SkipOwnThread = 0x0001, - // Prevents this instance of the hook from receiving the events that are generated by threads - // in this process. This flag does not prevent threads from generating events. - SkipOwnProcess = 0x0002, - // The callback function IS mapped into the address space of the process that generates the event. - InContext = 0x0004 - } - - [Flags] - public enum STARTFLAGS - { - STARTF_USESHOWWINDOW = 0x00000001, - STARTF_USESIZE = 0x00000002, - STARTF_USEPOSITION = 0x00000004, - STARTF_USECOUNTCHARS = 0x00000008, - STARTF_USEFILLATTRIBUTE = 0x00000010, - STARTF_RUNFULLSCREEN = 0x00000020, - STARTF_FORCEONFEEDBACK = 0x00000040, - STARTF_FORCEOFFFEEDBACK = 0x00000080, - STARTF_USESTDHANDLES = 0x00000100, - STARTF_USEHOTKEY = 0x00000200 - }; - - [StructLayout(LayoutKind.Sequential)] - internal struct SECURITY_ATTRIBUTES - { - public int nLength; - public IntPtr lpSecurityDescriptor; - public int bInheritHandle; - } - - /// - /// Contains basic and extended limit information for a job object. - /// - /// - /// The system tracks the value of PeakProcessMemoryUsed and PeakJobMemoryUsed constantly. This allows you know the peak memory usage of each job. You can use this information to establish a memory limit using the JOB_OBJECT_LIMIT_PROCESS_MEMORY or JOB_OBJECT_LIMIT_JOB_MEMORY value. - /// Note that the job memory and process memory limits are very similar in operation, but they are independent. You could set a job-wide limit of 100 MB with a per-process limit of 10 MB. In this scenario, no single process could commit more than 10 MB, and the set of processes associated with a job could never exceed 100 MB. - /// To register for notifications that a job has exceeded its peak memory limit while allowing processes to continue to commit memory, use the SetInformationJobObject function with the JobObjectNotificationLimitInformation information class. - /// - internal struct JOBOBJECT_EXTENDED_LIMIT_INFORMATION - { - /// - /// A structure that contains basic limit information. - /// - internal JOBOBJECT_BASIC_LIMIT_INFORMATION BasicLimitInformation; - - /// - /// Reserved. - /// - internal IO_COUNTERS IoInfo; - - /// - /// If the member of the structure specifies the - /// value, this member specifies the limit for the virtual memory that can be committed by a process. - /// Otherwise, this member is ignored. - /// - internal UIntPtr ProcessMemoryLimit; - - /// - /// If the member of the structure specifies the - /// value, - /// this member specifies the limit for the virtual memory that can be committed for the job. Otherwise, this member is ignored. - /// - internal UIntPtr JobMemoryLimit; - - /// - /// The peak memory used by any process ever associated with the job. - /// - internal UIntPtr PeakProcessMemoryUsed; - - /// - /// The peak memory usage of all processes currently associated with the job. - /// - internal UIntPtr PeakJobMemoryUsed; - } - - /// - /// Contains basic limit information for a job object. - /// - internal struct JOBOBJECT_BASIC_LIMIT_INFORMATION - { - /// - /// If LimitFlags specifies JOB_OBJECT_LIMIT_PROCESS_TIME, this member is the per-process user-mode execution time limit, in 100-nanosecond ticks. Otherwise, this member is ignored. - /// - internal long PerProcessUserTimeLimit; - - /// - /// If LimitFlags specifies JOB_OBJECT_LIMIT_JOB_TIME, this member is the per-job user-mode execution time limit, in 100-nanosecond ticks. Otherwise, this member is ignored. - /// - internal long PerJobUserTimeLimit; - - /// - /// The limit flags that are in effect. This member is a bitfield that determines whether other structure members are used. - /// - internal JOB_OBJECT_LIMIT_FLAGS LimitFlags; - - /// - /// If LimitFlags specifies JOB_OBJECT_LIMIT_WORKINGSET, this member is the minimum working set size in bytes for each process associated with the job. Otherwise, this member is ignored. - /// - internal UIntPtr MinWorkingSetSize; - - /// - /// If LimitFlags specifies JOB_OBJECT_LIMIT_WORKINGSET, this member is the maximum working set size in bytes for each process associated with the job. Otherwise, this member is ignored. - /// - internal UIntPtr MaxWorkingSetSize; - - /// - /// If LimitFlags specifies JOB_OBJECT_LIMIT_ACTIVE_PROCESS, this member is the active process limit for the job. Otherwise, this member is ignored. - /// - internal uint ActiveProcessLimit; - - /// - /// If LimitFlags specifies JOB_OBJECT_LIMIT_AFFINITY, this member is the processor affinity for all processes associated with the job. Otherwise, this member is ignored. - /// - internal UIntPtr Affinity; - - /// - /// If LimitFlags specifies JOB_OBJECT_LIMIT_PRIORITY_CLASS, this member is the priority class for all processes associated with the job. Otherwise, this member is ignored. - /// - internal uint PriorityClass; - - /// - /// If LimitFlags specifies JOB_OBJECT_LIMIT_SCHEDULING_CLASS, this member is the scheduling class for all processes associated with the job. Otherwise, this member is ignored. - /// - internal uint SchedulingClass; - } - - /// - /// Contains I/O accounting information for a process or a job object. - /// For a job object, the counters include all operations performed by all processes that have ever been associated with the job, - /// in addition to all processes currently associated with the job. - /// - internal struct IO_COUNTERS - { - /// - /// The number of read operations performed. - /// - internal ulong ReadOperationCount; - - /// - /// The number of write operations performed. - /// - internal ulong WriteOperationCount; - - /// - /// The number of I/O operations performed, other than read and write operations. - /// - internal ulong OtherOperationCount; - - /// - /// The number of bytes read. - /// - internal ulong ReadTransferCount; - - /// - /// The number of bytes written. - /// - internal ulong WriteTransferCount; - - /// - /// The number of bytes transferred during operations other than read and write operations. - /// - internal ulong OtherTransferCount; - } - - /// - /// The limit flags that are in effect. - /// - [Flags] - internal enum JOB_OBJECT_LIMIT_FLAGS - { - /// - /// Causes all processes associated with the job to use the same minimum and maximum working set sizes. - /// - JOB_OBJECT_LIMIT_WORKINGSET = 0x1, - - /// - /// Causes all processes associated with the job to use the same priority class. - /// - JOB_OBJECT_LIMIT_PROCESS_TIME = 0x2, - - /// - /// Establishes a user-mode execution time limit for the job. - /// - JOB_OBJECT_LIMIT_JOB_TIME = 0x4, - - /// - /// Establishes a maximum number of simultaneously active processes associated with the job. - /// - JOB_OBJECT_LIMIT_ACTIVE_PROCESS = 0x8, - - /// - /// Causes all processes associated with the job to use the same processor affinity. - /// - JOB_OBJECT_LIMIT_AFFINITY = 0x10, - - /// - /// Causes all processes associated with the job to use the same priority class. - /// - JOB_OBJECT_LIMIT_PRIORITY_CLASS = 0x20, - - /// - /// Preserves any job time limits you previously set. As long as this flag is set, you can establish a per-job time limit once, then alter other limits in subsequent calls. - /// - JOB_OBJECT_LIMIT_PRESERVE_JOB_TIME = 0x40, - - /// - /// Causes all processes in the job to use the same scheduling class. - /// - JOB_OBJECT_LIMIT_SCHEDULING_CLASS = 0x80, - - /// - /// Causes all processes associated with the job to limit their committed memory. - /// - JOB_OBJECT_LIMIT_PROCESS_MEMORY = 0x100, - - /// - /// Causes all processes associated with the job to limit the job-wide sum of their committed memory. - /// - JOB_OBJECT_LIMIT_JOB_MEMORY = 0x200, - - /// - /// Forces a call to the SetErrorMode function with the SEM_NOGPFAULTERRORBOX flag for each process associated with the job. - /// - JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION = 0x400, - - /// - /// If any process associated with the job creates a child process using the CREATE_BREAKAWAY_FROM_JOB flag while this limit is in effect, the child process is not associated with the job. - /// - JOB_OBJECT_LIMIT_BREAKAWAY_OK = 0x800, - - /// - /// Allows any process associated with the job to create child processes that are not associated with the job. - /// - JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK = 0x1000, - - /// - /// Causes all processes associated with the job to terminate when the last handle to the job is closed. - /// - JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE = 0x2000, - - /// - /// Allows processes to use a subset of the processor affinity for all processes associated with the job. - /// - JOB_OBJECT_LIMIT_SUBSET_AFFINITY = 0x4000, - } - - /// - /// The information class for the limits to be set. - /// - /// - /// Taken from https://msdn.microsoft.com/en-us/library/windows/desktop/ms686216(v=vs.85).aspx. - /// - [SuppressMessage("Design", "CA1008:Enums should have zero value", Justification = "PInvoke API")] - public enum JOBOBJECTINFOCLASS - { - /// - /// The lpJobObjectInfo parameter is a pointer to a structure. - /// - JobObjectBasicLimitInformation = 2, - - /// - /// The lpJobObjectInfo parameter is a pointer to a JOBOBJECT_BASIC_UI_RESTRICTIONS structure. - /// - JobObjectBasicUIRestrictions = 4, - - /// - /// This flag is not supported. Applications must set security limitations individually for each process. - /// - JobObjectSecurityLimitInformation = 5, - - /// - /// The lpJobObjectInfo parameter is a pointer to a JOBOBJECT_END_OF_JOB_TIME_INFORMATION structure. - /// - JobObjectEndOfJobTimeInformation = 6, - - /// - /// The lpJobObjectInfo parameter is a pointer to a JOBOBJECT_ASSOCIATE_COMPLETION_PORT structure. - /// - JobObjectAssociateCompletionPortInformation = 7, - - /// - /// The lpJobObjectInfo parameter is a pointer to a structure. - /// - JobObjectExtendedLimitInformation = 9, - - /// - /// The lpJobObjectInfo parameter is a pointer to a USHORT value that specifies the list of processor groups to assign the job to. - /// The cbJobObjectInfoLength parameter is set to the size of the group data. Divide this value by sizeof(USHORT) to determine the number of groups. - /// - JobObjectGroupInformation = 11, - - /// - /// The lpJobObjectInfo parameter is a pointer to a JOBOBJECT_NOTIFICATION_LIMIT_INFORMATION structure. - /// - JobObjectNotificationLimitInformation = 12, - - /// - /// The lpJobObjectInfo parameter is a pointer to a buffer that contains an array of GROUP_AFFINITY structures that specify the affinity of the job for the processor groups to which the job is currently assigned. - /// The cbJobObjectInfoLength parameter is set to the size of the group affinity data. Divide this value by sizeof(GROUP_AFFINITY) to determine the number of groups. - /// - JobObjectGroupInformationEx = 14, - - /// - /// The lpJobObjectInfo parameter is a pointer to a JOBOBJECT_CPU_RATE_CONTROL_INFORMATION structure. - /// - JobObjectCpuRateControlInformation = 15, - - /// - /// The lpJobObjectInfo parameter is a pointer to a JOBOBJECT_NET_RATE_CONTROL_INFORMATION structure. - /// - JobObjectNetRateControlInformation = 32, - - /// - /// The lpJobObjectInfo parameter is a pointer to a JOBOBJECT_NOTIFICATION_LIMIT_INFORMATION_2 structure. - /// - JobObjectNotificationLimitInformation2 = 34, - - /// - /// The lpJobObjectInfo parameter is a pointer to a JOBOBJECT_LIMIT_VIOLATION_INFORMATION_2 structure. - /// - JobObjectLimitViolationInformation2 = 35, - } -#pragma warning restore 649 -} diff --git a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/ProcessTracker/SafeObjectHandle.cs b/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/ProcessTracker/SafeObjectHandle.cs deleted file mode 100644 index 18b2174b..00000000 --- a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/ProcessTracker/SafeObjectHandle.cs +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -using System; -using Microsoft.Win32.SafeHandles; - -namespace Microsoft.DevSkim.VisualStudio.ProcessTracker -{ - /// - /// Represents a Win32 handle that can be closed with CloseHandle/>. - /// - public class SafeObjectHandle : SafeHandleZeroOrMinusOneIsInvalid - { - /// - /// Initializes a new instance of the class. - /// - public SafeObjectHandle() - : base(true) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// An object that represents the pre-existing handle to use. - /// - /// to have the native handle released when this safe handle is disposed or finalized; - /// otherwise. - /// - public SafeObjectHandle(IntPtr preexistingHandle, bool ownsHandle = true) - : base(ownsHandle) - { - SetHandle(preexistingHandle); - } - - /// - protected override bool ReleaseHandle() => NativeMethods.CloseHandle(handle); - } -} diff --git a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/ProcessTracker/WindowEventArgs.cs b/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/ProcessTracker/WindowEventArgs.cs deleted file mode 100644 index 05fec1b5..00000000 --- a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/ProcessTracker/WindowEventArgs.cs +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -using System; - -namespace Microsoft.DevSkim.VisualStudio.ProcessTracker -{ - public class WindowEventArgs : EventArgs - { - public WindowEventArgs(WindowsSystemEvents anEvent, IntPtr windowHandle) - { - SystemEvent = anEvent; - WindowHandle = windowHandle; - } - - public WindowsSystemEvents SystemEvent { get; } - public IntPtr WindowHandle { get; } - } -} diff --git a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/ProcessTracker/WindowEventsListener.cs b/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/ProcessTracker/WindowEventsListener.cs deleted file mode 100644 index 2b4f129e..00000000 --- a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/ProcessTracker/WindowEventsListener.cs +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -using System; -using System.Runtime.InteropServices; - -namespace Microsoft.DevSkim.VisualStudio.ProcessTracker -{ - public class WindowEventsListener : IWindowEventsListener - { - private WindowEventHandler handler; - private GCHandle handlerGCPin; - private IntPtr hWinEventHook; - - public WindowEventsListener( - WindowsSystemEvents min = WindowsSystemEvents.EventMin, - WindowsSystemEvents max = WindowsSystemEvents.EventMax) - { - handler = new WindowEventHandler(InternalSystemEventHandler); - handlerGCPin = GCHandle.Alloc(handler); - - hWinEventHook = NativeMethods.SetWinEventHook( - min, - max, - IntPtr.Zero, - handler, - 0, - 0, - (uint)(WinEventHookFlags.OutOfContext | WinEventHookFlags.SkipOwnProcess)); - } - - public event EventHandler? SystemEvent; - - private void InternalSystemEventHandler( - IntPtr hWinEventHook, - WindowsSystemEvents anEvent, - IntPtr hwnd, - int idObject, - int idChild, - uint dwEventThread, - uint dwmsEventTime) - { - SystemEvent?.Invoke(this, new WindowEventArgs(anEvent, hwnd)); - } - - ~WindowEventsListener() - { - Dispose(false); - } - - #region IDisposable Members - - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - #endregion - - protected virtual void Dispose(bool disposing) - { - if (hWinEventHook != IntPtr.Zero) - { - NativeMethods.UnhookWinEvent(hWinEventHook); - hWinEventHook = IntPtr.Zero; - } - - if (disposing) - { - if (handlerGCPin.IsAllocated) - { - handlerGCPin.Free(); - } - - handler = null!; - } - } - } - - public delegate void WindowEventHandler( - IntPtr hWinEventHook, - WindowsSystemEvents anEvent, - IntPtr hwnd, - int idObject, - int idChild, - uint dwEventThread, - uint dwmsEventTime); -} diff --git a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/ProcessTracker/WindowsSystemEvents.cs b/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/ProcessTracker/WindowsSystemEvents.cs deleted file mode 100644 index 3588c6c0..00000000 --- a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/ProcessTracker/WindowsSystemEvents.cs +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -namespace Microsoft.DevSkim.VisualStudio.ProcessTracker -{ - public enum WindowsSystemEvents - { - EventMin = 0x00000001, // EVENT_MIN - SystemSound = 0x0001, // EVENT_SYSTEM_SOUND - SystemAlert = 0x0002, // EVENT_SYSTEM_ALERT - SystemForeground = 0x0003, // EVENT_SYSTEM_FOREGROUND - SystemMenuStart = 0x0004, // EVENT_SYSTEM_MENUSTART - SystemMenuEnd = 0x0005, // EVENT_SYSTEM_MENUEND - SystemMenuPopupStart = 0x0006, // EVENT_SYSTEM_MENUPOPUPSTART - SystemMenuPopupEnd = 0x0007, // EVENT_SYSTEM_MENUPOPUPEND - SystemCaptureStart = 0x0008, // EVENT_SYSTEM_CAPTURESTART - SystemCaptureEnd = 0x0009, // EVENT_SYSTEM_CAPTUREEND - SystemMoveSizeStart = 0x000A, // EVENT_SYSTEM_MOVESIZESTART - SystemMoveSizeEnd = 0x000B, // EVENT_SYSTEM_MOVESIZEEND - SystemContextHelpStart = 0x000C, // EVENT_SYSTEM_CONTEXTHELPSTART - SystemContextHelpEnd = 0x000D, // EVENT_SYSTEM_CONTEXTHELPEND - SystemDragStart = 0x000E, // EVENT_SYSTEM_DRAGDROPSTART - SystemDragEnd = 0x000F, // EVENT_SYSTEM_DRAGDROPEND - SystemDialogStart = 0x0010, // EVENT_SYSTEM_DIALOGSTART - SystemDialogEnd = 0x0011, // EVENT_SYSTEM_DIALOGEND - SystemScrollingStart = 0x0012, // EVENT_SYSTEM_SCROLLINGSTART - SystemScrollingEnd = 0x0013, // EVENT_SYSTEM_SCROLLINGEND - SystemSwitchStart = 0x0014, // EVENT_SYSTEM_SWITCHSTART - SystemSwitchEnd = 0x0015, // EVENT_SYSTEM_SWITCHEND - SystemMinimizeStart = 0x0016, // EVENT_SYSTEM_MINIMIZESTART - SystemMinimizeEnd = 0x0017, // EVENT_SYSTEM_MINIMIZEEND - ObjectCreate = 0x8000, // EVENT_OBJECT_CREATE - ObjectDestroy = 0x8001, // EVENT_OBJECT_DESTROY - ObjectShow = 0x8002, // EVENT_OBJECT_SHOW - ObjectHide = 0x8003, // EVENT_OBJECT_HIDE - ObjectReorder = 0x8004, // EVENT_OBJECT_REORDER - ObjectFocus = 0x8005, // EVENT_OBJECT_FOCUS - ObjectSelection = 0x8006, // EVENT_OBJECT_SELECTION - ObjectSelectionAdd = 0x8007, // EVENT_OBJECT_SELECTIONADD - ObjectSelectionRemove = 0x8008, // EVENT_OBJECT_SELECTIONREMOVE - ObjectSelectionWithin = 0x8009, // EVENT_OBJECT_SELECTIONWITHIN - ObjectStateChange = 0x800A, // EVENT_OBJECT_STATECHANGE - ObjectLocationChange = 0x800B, // EVENT_OBJECT_LOCATIONCHANGE - ObjectNameChange = 0x800C, // EVENT_OBJECT_NAMECHANGE - ObjectDescriptionChange = 0x800D, // EVENT_OBJECT_DESCRIPTIONCHANGE - ObjectValueChange = 0x800E, // EVENT_OBJECT_VALUECHANGE - ObjectParentChange = 0x800F, // EVENT_OBJECT_PARENTCHANGE - ObjectHelpChange = 0x8010, // EVENT_OBJECT_HELPCHANGE - ObjectDefactionChange = 0x8011, // EVENT_OBJECT_DEFACTIONCHANGE - ObjectAcceleratorChange = 0x8012, // EVENT_OBJECT_ACCELERATORCHANGE - EventMax = 0x7FFFFFFF, // EVENT_MAX - - // Vista or later. - ObjectContentScrolled = 0x8015, // EVENT_OBJECT_CONTENTSCROLLED - ObjectTextSelectionChanged = 0x8014, // EVENT_OBJECT_TEXTSELECTIONCHANGED - ObjectInvoked = 0x8013, // EVENT_OBJECT_INVOKED - SystemDesktopSwitch = 0x00000020, // EVENT_SYSTEM_DESKTOPSWITCH - } -} diff --git a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/Properties/AssemblyInfo.cs b/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/Properties/AssemblyInfo.cs deleted file mode 100644 index f6166b99..00000000 --- a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("Microsoft.DevSkim.VisualStudio")] -[assembly: AssemblyDescription("Visual Studio extension for DevSkim")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Microsoft Corporation")] -[assembly: AssemblyProduct("Microsoft.DevSkim.VisualStudio")] -[assembly: AssemblyCopyright("Microsoft Corporation. See LICENSE file in the project root for full license information.")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] \ No newline at end of file diff --git a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/Properties/Resources.Designer.cs b/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/Properties/Resources.Designer.cs deleted file mode 100644 index 9c5f4a76..00000000 --- a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/Properties/Resources.Designer.cs +++ /dev/null @@ -1,99 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.42000 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace Microsoft.DevSkim.VisualStudio.Properties { - using System; - - - /// - /// A strongly-typed resource class, for looking up localized strings, etc. - /// - // This class was auto-generated by the StronglyTypedResourceBuilder - // class via a tool like ResGen or Visual Studio. - // To add or remove a member, edit your .ResX file then rerun ResGen - // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class Resources { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal Resources() { - } - - /// - /// Returns the cached ResourceManager instance used by this class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager { - get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.DevSkim.VisualStudio.Properties.Resources", typeof(Resources).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// Overrides the current thread's CurrentUICulture property for all - /// resource lookups using this strongly typed resource class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - - /// - /// Looks up a localized string similar to DevSkim. - /// - internal static string _1000 { - get { - return ResourceManager.GetString("1000", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to General. - /// - internal static string _1001 { - get { - return ResourceManager.GetString("1001", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to DevSkim Settings. - /// - internal static string _1002 { - get { - return ResourceManager.GetString("1002", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to All DevSkim settings. - /// - internal static string _1003 { - get { - return ResourceManager.GetString("1003", resourceCulture); - } - } - } -} diff --git a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/Properties/Resources.resx b/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/Properties/Resources.resx deleted file mode 100644 index 9b77e2a4..00000000 --- a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/Properties/Resources.resx +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - DevSkim - DevSkim Category ID - - - General - DevSkim Settings ID - - - DevSkim Settings - DevSkim Export ID - - - All DevSkim settings - DevSkim Export Desc - - \ No newline at end of file diff --git a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/Properties/launchSettings.json b/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/Properties/launchSettings.json new file mode 100644 index 00000000..c8ae9057 --- /dev/null +++ b/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/Properties/launchSettings.json @@ -0,0 +1,9 @@ +{ + "profiles": { + "Microsoft.DevSkim.VisualStudio": { + "commandName": "Executable", + "executablePath": "$(DevEnvDir)devenv.exe", + "commandLineArgs": "/rootsuffix Exp" + } + } +} diff --git a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/SafeObjectHandle.cs b/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/SafeObjectHandle.cs deleted file mode 100644 index 469b67a7..00000000 --- a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/SafeObjectHandle.cs +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -using System; -using Microsoft.Win32.SafeHandles; - -namespace Microsoft.DevSkim.VisualStudio -{ - using Microsoft.Win32.SafeHandles; - - using System; - - /// - /// Represents a Win32 handle that can be closed with CloseHandle/>. - /// - public class SafeObjectHandle : SafeHandleZeroOrMinusOneIsInvalid - { - /// - /// Initializes a new instance of the class. - /// - public SafeObjectHandle() - : base(true) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// An object that represents the pre-existing handle to use. - /// - /// to have the native handle released when this safe handle is disposed or finalized; - /// otherwise. - /// - public SafeObjectHandle(IntPtr preexistingHandle, bool ownsHandle = true) - : base(ownsHandle) - { - SetHandle(preexistingHandle); - } - - /// - protected override bool ReleaseHandle() => ProcessTracker.NativeMethods.CloseHandle(handle); - } -} \ No newline at end of file diff --git a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/SettingsChangedNotifier.cs b/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/SettingsChangedNotifier.cs deleted file mode 100644 index 143e1237..00000000 --- a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/SettingsChangedNotifier.cs +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -using System.Threading.Tasks; -using MediatR; -using Microsoft.DevSkim.LanguageProtoInterop; -using StreamJsonRpc; - -namespace Microsoft.DevSkim.VisualStudio -{ - /// - /// VS lsp doesn't automatically send settings from the settings panel, so we need to manually refresh them on change - /// - public class SettingsChangedNotifier - { - public record DevSkimSetLanguageServerSettingsParams : IRequest - { - public PortableScannerSettings ScannerSettings { get; set; } - } - - private readonly JsonRpc rpc; - - public SettingsChangedNotifier(JsonRpc rpc) - { - this.rpc = rpc; - } - - public async Task SendSettingsChangedNotificationAsync(PortableScannerSettings settings) - { - await rpc.NotifyWithParameterObjectAsync(DevSkimMessages.SetServerSettings, new DevSkimSetLanguageServerSettingsParams() { ScannerSettings = settings }); - } - } -} \ No newline at end of file diff --git a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/StaticData.cs b/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/StaticData.cs deleted file mode 100644 index 8e940ad6..00000000 --- a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/StaticData.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Microsoft.DevSkim.VisualStudio -{ - using Microsoft.DevSkim.LanguageProtoInterop; - using System; - using System.Collections.Concurrent; - using System.Collections.Generic; - - internal static class StaticData - { - // Maps file name to a dictionary of file versions to a deduplicated set of CodeFixMappings - internal static ConcurrentDictionary>> FileToCodeFixMap { get; } = new(); - } -} diff --git a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/SuggestedActionsSourceProvider.cs b/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/SuggestedActionsSourceProvider.cs deleted file mode 100644 index 915721e4..00000000 --- a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/SuggestedActionsSourceProvider.cs +++ /dev/null @@ -1,28 +0,0 @@ -namespace Microsoft.DevSkim.VisualStudio -{ - using Microsoft.VisualStudio.Language.Intellisense; - using Microsoft.VisualStudio.Text.Editor; - using Microsoft.VisualStudio.Text.Operations; - using Microsoft.VisualStudio.Text; - using Microsoft.VisualStudio.Utilities; - using System.ComponentModel.Composition; - - [Export(typeof(ISuggestedActionsSourceProvider))] - [Name("DevSkim Suggested Actions")] - [ContentType("text")] - internal class SuggestedActionsSourceProvider : ISuggestedActionsSourceProvider - { - public ISuggestedActionsSource CreateSuggestedActionsSource(ITextView textView, ITextBuffer textBuffer) - { - if (textBuffer == null || textView == null) - { - return null; - } - - return new SuggestedActionsSource(this, textView, textBuffer); - } - - [Import(typeof(ITextStructureNavigatorSelectorService))] - internal ITextStructureNavigatorSelectorService NavigatorService { get; set; } - } -} \ No newline at end of file diff --git a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/SuggestionActionsSource.cs b/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/SuggestionActionsSource.cs deleted file mode 100644 index 325ced5e..00000000 --- a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/SuggestionActionsSource.cs +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright (C) Microsoft. All rights reserved. Licensed under the MIT License. - -using Microsoft.DevSkim.LanguageProtoInterop; -using Microsoft.VisualStudio.Language.Intellisense; -using Microsoft.VisualStudio.Text; -using Microsoft.VisualStudio.Text.Editor; -using Microsoft.VisualStudio.Text.Operations; -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; - -namespace Microsoft.DevSkim.VisualStudio -{ - internal class SuggestedActionsSource : ISuggestedActionsSource - { - private readonly SuggestedActionsSourceProvider _factory; - private readonly ITextBuffer _textBuffer; - private readonly ITextView _textView; - private readonly string _fileName; - - public SuggestedActionsSource(SuggestedActionsSourceProvider testSuggestedActionsSourceProvider, ITextView textView, ITextBuffer textBuffer) - { - _factory = testSuggestedActionsSourceProvider; - _textBuffer = textBuffer; - _textView = textView; - _fileName = _textBuffer.Properties.GetProperty(typeof(ITextDocument)).FilePath; - } - -#pragma warning disable 0067 - - public event EventHandler SuggestedActionsChanged; - -#pragma warning restore 0067 - - public void Dispose() - { - } - - public IEnumerable GetSuggestedActions(ISuggestedActionCategorySet requestedActionCategories, SnapshotSpan range, CancellationToken cancellationToken) - { - List suggestedActions = new List(); - if (TryGetWordUnderCaret(out TextExtent wordExtent) && wordExtent.IsSignificant) - { - if (StaticData.FileToCodeFixMap.TryGetValue(new Uri(_fileName), out ConcurrentDictionary> dictForFile)) - { - if (dictForFile.TryGetValue(wordExtent.Span.Snapshot.Version.VersionNumber, out ConcurrentDictionary fixes)) - { - suggestedActions.AddRange(fixes.Where(codeFixMapping => - Intersects(codeFixMapping.Key, wordExtent)) - .OrderBy(fix => fix.Key.friendlyString) - .Select(intersectedMapping => new DevSkimSuggestedAction(wordExtent.Span, intersectedMapping.Key))); - } - } - yield return new SuggestedActionSet(suggestedActions, wordExtent.Span); - // TODO: The above API is marked obsolete, and they want use of the below, which requires registering the category - //yield return new SuggestedActionSet("DevSkim Suggestions", suggestedActions, applicableToSpan: wordExtent.Span); - } - yield return new SuggestedActionSet(suggestedActions); - } - - private bool Intersects(CodeFixMapping codeFixMapping, TextExtent wordExtent) - { - // Extent start is inside mapping - if (wordExtent.Span.Start >= codeFixMapping.matchStart && wordExtent.Span.Start <= codeFixMapping.matchEnd) - { - return true; - } - // Extend end is inside mapping - if (wordExtent.Span.End >= codeFixMapping.matchStart && wordExtent.Span.End <= codeFixMapping.matchEnd) - { - return true; - } - return false; - } - - public Task HasSuggestedActionsAsync(ISuggestedActionCategorySet requestedActionCategories, SnapshotSpan range, CancellationToken cancellationToken) - { - return Task.Factory.StartNew(() => - { - bool res = TryGetWordUnderCaret(out TextExtent wordExtent); - if (res && wordExtent.IsSignificant) - { - if (StaticData.FileToCodeFixMap.TryGetValue(new Uri(_fileName), out ConcurrentDictionary> dictForFile)) - { - if (dictForFile.TryGetValue(wordExtent.Span.Snapshot.Version.VersionNumber, out ConcurrentDictionary fixes)) - { - return fixes.Any(codeFixMapping => Intersects(codeFixMapping.Key, wordExtent)); - } - } - } - return false; - }, new CancellationTokenSource().Token, TaskCreationOptions.None, TaskScheduler.Default); - } - - private bool TryGetWordUnderCaret(out TextExtent wordExtent) - { - ITextCaret caret = _textView.Caret; - SnapshotPoint point; - - if (caret.Position.BufferPosition > 0) - { - point = caret.Position.BufferPosition - 1; - } - else - { - wordExtent = default(TextExtent); - return false; - } - - ITextStructureNavigator navigator = _factory.NavigatorService.GetTextStructureNavigator(_textBuffer); - - wordExtent = navigator.GetExtentOfWord(point); - return true; - } - - public bool TryGetTelemetryId(out Guid telemetryId) - { - telemetryId = Guid.Empty; - return false; - } - } -} \ No newline at end of file diff --git a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/VisualStudioSettingsManager.cs b/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/VisualStudioSettingsManager.cs deleted file mode 100644 index ec9d5167..00000000 --- a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/VisualStudioSettingsManager.cs +++ /dev/null @@ -1,289 +0,0 @@ -namespace Microsoft.DevSkim.VisualStudio -{ - using Microsoft; - using System; - using Microsoft.DevSkim.LanguageProtoInterop; - using Microsoft.DevSkim.VisualStudio.Options; - using System.Linq; - using Microsoft.VisualStudio.Settings; - using Microsoft.VisualStudio.Shell; - using Microsot.DevSkim.LanguageClient; - using System.ComponentModel.Composition; - using System.Runtime.InteropServices; - using System.Threading.Tasks; - - internal partial class VisualStudioSettingsManager - { - private SettingsChangedNotifier _notifier; - private DevSkimLanguageClient _client; - private ISettingsManager _settingsManager; - - [Guid("9B164E40-C3A2-4363-9BC5-EB4039DEF653")] - private class SVsSettingsPersistenceManager { } - - private PortableScannerSettings _currentSettings = new PortableScannerSettings(); - private string _subsetName = typeof(GeneralOptionsPage).FullName; - public VisualStudioSettingsManager([Import(typeof(SVsServiceProvider))] IServiceProvider serviceProvider, DevSkimLanguageClient client) - { - _client = client; - _settingsManager = serviceProvider.GetService(typeof(SVsSettingsPersistenceManager)) as ISettingsManager; - Assumes.Present(_settingsManager); - ISettingsSubset setting = _settingsManager.GetSubset($"{_subsetName}.*"); - setting.SettingChangedAsync += (sender, args) => UpdateSettingsTaskAsync(args.PropertyName.Substring(_subsetName.Length+1)); - } - - /// - /// Gets the specified of the from the - /// This is called by the generated code for - /// - /// The of the parameter in - /// The name of the parameter - /// When successful, Success and the value, when unsuccessful, an enum other than success and undefined. - private (ValueResultEnum, T) Get(string propertyName) - { - return (GetValueResultEnumToValueResultEnum(_settingsManager.TryGetValue($"{_subsetName}.{propertyName}", out T val)), val); - } - - private ValueResultEnum GetValueResultEnumToValueResultEnum(GetValueResult getValueResult) => getValueResult switch - { - GetValueResult.Success => ValueResultEnum.Success, - GetValueResult.Missing => ValueResultEnum.Missing, - GetValueResult.Corrupt => ValueResultEnum.Corrupt, - GetValueResult.IncompatibleType => ValueResultEnum.IncompatibleType, - GetValueResult.ObsoleteFormat => ValueResultEnum.ObsoleteFormat, - GetValueResult.UnknownError => ValueResultEnum.UnknownError, - _ => ValueResultEnum.UnknownError - }; - - private async Task PushSettingsToServerAsync() - { - await _client.SettingsNotifier?.SendSettingsChangedNotificationAsync(_currentSettings); - } - - private async Task UpdateSettingsTaskAsync(string propertyName) - { - UpdateSettings(propertyName); - await PushSettingsToServerAsync(); - } - - public async Task UpdateAllSettingsAsync() - { - foreach (string name in typeof(IDevSkimOptions).GetProperties().Select(x => x.Name)) - { - UpdateSettings(name); - } - await PushSettingsToServerAsync(); - } - - /// - /// See the ManualUpdateSettingsGenerator project to generate this method - /// Auto-generated - /// - /// - private void UpdateSettings(string propertyName) - { - switch (propertyName) - { - case "EnableCriticalSeverityRules": - { - var res = Get(propertyName); - if (res.Item1 == ValueResultEnum.Success) - { - _currentSettings.EnableCriticalSeverityRules = res.Item2; - } - break; - } - case "EnableImportantSeverityRules": - { - var res = Get(propertyName); - if (res.Item1 == ValueResultEnum.Success) - { - _currentSettings.EnableImportantSeverityRules = res.Item2; - } - break; - } - case "EnableModerateSeverityRules": - { - var res = Get(propertyName); - if (res.Item1 == ValueResultEnum.Success) - { - _currentSettings.EnableModerateSeverityRules = res.Item2; - } - break; - } - case "EnableManualReviewSeverityRules": - { - var res = Get(propertyName); - if (res.Item1 == ValueResultEnum.Success) - { - _currentSettings.EnableManualReviewSeverityRules = res.Item2; - } - break; - } - case "EnableBestPracticeSeverityRules": - { - var res = Get(propertyName); - if (res.Item1 == ValueResultEnum.Success) - { - _currentSettings.EnableBestPracticeSeverityRules = res.Item2; - } - break; - } - case "EnableHighConfidenceRules": - { - var res = Get(propertyName); - if (res.Item1 == ValueResultEnum.Success) - { - _currentSettings.EnableHighConfidenceRules = res.Item2; - } - break; - } - case "EnableMediumConfidenceRules": - { - var res = Get(propertyName); - if (res.Item1 == ValueResultEnum.Success) - { - _currentSettings.EnableMediumConfidenceRules = res.Item2; - } - break; - } - case "EnableLowConfidenceRules": - { - var res = Get(propertyName); - if (res.Item1 == ValueResultEnum.Success) - { - _currentSettings.EnableLowConfidenceRules = res.Item2; - } - break; - } - case "CustomRulesPathsString": - { - var res = Get(propertyName); - if (res.Item1 == ValueResultEnum.Success) - { - _currentSettings.CustomRulesPathsString = res.Item2; - } - break; - } - case "CustomLanguagesPath": - { - var res = Get(propertyName); - if (res.Item1 == ValueResultEnum.Success) - { - _currentSettings.CustomLanguagesPath = res.Item2; - } - break; - } - case "CustomCommentsPath": - { - var res = Get(propertyName); - if (res.Item1 == ValueResultEnum.Success) - { - _currentSettings.CustomCommentsPath = res.Item2; - } - break; - } - case "SuppressionDurationInDays": - { - var res = Get(propertyName); - if (res.Item1 == ValueResultEnum.Success) - { - _currentSettings.SuppressionDurationInDays = res.Item2; - } - break; - } - case "SuppressionCommentStyle": - { - var res = Get(propertyName); - if (res.Item1 == ValueResultEnum.Success) - { - _currentSettings.SuppressionCommentStyle = res.Item2; - } - break; - } - case "ManualReviewerName": - { - var res = Get(propertyName); - if (res.Item1 == ValueResultEnum.Success) - { - _currentSettings.ManualReviewerName = res.Item2; - } - break; - } - case "GuidanceBaseURL": - { - var res = Get(propertyName); - if (res.Item1 == ValueResultEnum.Success) - { - _currentSettings.GuidanceBaseURL = res.Item2; - } - break; - } - case "IgnoreFilesString": - { - var res = Get(propertyName); - if (res.Item1 == ValueResultEnum.Success) - { - _currentSettings.IgnoreFilesString = res.Item2; - } - break; - } - case "IgnoreRulesListString": - { - var res = Get(propertyName); - if (res.Item1 == ValueResultEnum.Success) - { - _currentSettings.IgnoreRulesListString = res.Item2; - } - break; - } - case "IgnoreDefaultRules": - { - var res = Get(propertyName); - if (res.Item1 == ValueResultEnum.Success) - { - _currentSettings.IgnoreDefaultRules = res.Item2; - } - break; - } - case "RemoveFindingsOnClose": - { - var res = Get(propertyName); - if (res.Item1 == ValueResultEnum.Success) - { - _currentSettings.RemoveFindingsOnClose = res.Item2; - } - break; - } - case "ScanOnOpen": - { - var res = Get(propertyName); - if (res.Item1 == ValueResultEnum.Success) - { - _currentSettings.ScanOnOpen = res.Item2; - } - break; - } - case "ScanOnSave": - { - var res = Get(propertyName); - if (res.Item1 == ValueResultEnum.Success) - { - _currentSettings.ScanOnSave = res.Item2; - } - break; - } - case "ScanOnChange": - { - var res = Get(propertyName); - if (res.Item1 == ValueResultEnum.Success) - { - _currentSettings.ScanOnChange = res.Item2; - } - break; - } - default: break; - } - } - } -} \ No newline at end of file diff --git a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/publish.manifest.json b/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/publish.manifest.json deleted file mode 100644 index 58d18146..00000000 --- a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/publish.manifest.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "$schema": "http://json.schemastore.org/vsix-publish", - "categories": [ "coding", "programming languages", "security" ], - "identity": { - "internalName": "MicrosoftDevSkim" - }, - "overview": "readme-gallery.md", - "priceCategory": "free", - "publisher": "MS-CST-E", - "private": false, - "qna": true, - "repo": "https://github.com/Microsoft/DevSkim" -} \ No newline at end of file diff --git a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/source.extension.vsixmanifest b/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/source.extension.vsixmanifest deleted file mode 100644 index d725de8d..00000000 --- a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/source.extension.vsixmanifest +++ /dev/null @@ -1,29 +0,0 @@ - - - - - Microsoft DevSkim - DevSkim for Visual Studio is a highly configurable regular expression based linter with a default RuleSet focused on common security related issues. - https://github.com/Microsoft/DevSkim - Content\LICENSE.txt - Content\devskim-icon-32.png - Content\devskim-icon-200.png - linter;linters;coding;security;static analysis - - - - amd64 - - - - - - - - - - - - - - diff --git a/DevSkim-DotNet/Microsoft.DevSkim.sln b/DevSkim-DotNet/Microsoft.DevSkim.sln index 2cdd8e64..af3b71fd 100644 --- a/DevSkim-DotNet/Microsoft.DevSkim.sln +++ b/DevSkim-DotNet/Microsoft.DevSkim.sln @@ -10,154 +10,66 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.DevSkim.Tests", " EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.DevSkim.LanguageServer", "Microsoft.DevSkim.LanguageServer\Microsoft.DevSkim.LanguageServer.csproj", "{1668F782-FE09-4106-8393-9A9D9823E027}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.DevSkim.VisualStudio", "Microsoft.DevSkim.VisualStudio\Microsoft.DevSkim.VisualStudio.csproj", "{E7A5F71D-137D-4D65-AB27-2ADD1FA6B26B}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.DevSkim.VisualStudio", "Microsoft.DevSkim.VisualStudio\Microsoft.DevSkim.VisualStudio.csproj", "{E7A5F71D-137D-4D65-AB27-2ADD1FA6B26B}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.DevSkim.LanguageProtoInterop", "Microsoft.DevSkim.LanguageProtoInterop\Microsoft.DevSkim.LanguageProtoInterop.csproj", "{774E78F3-B48A-4D01-B70B-9CFB03A55663}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.DevSkim.VisualStudio.SourceGenerator", "Microsoft.DevSkim.VisualStudio.SourceGenerator\Microsoft.DevSkim.VisualStudio.SourceGenerator.csproj", "{5D12BB81-B659-4CCB-9FAC-8224A6728196}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ManualGenerator", "ManualGenerator\ManualUpdateSettingsGenerator.csproj", "{C4722145-3CF5-431D-8F47-416F3E6CFB9F}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU - Debug|arm64 = Debug|arm64 Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 Release|Any CPU = Release|Any CPU - Release|arm64 = Release|arm64 Release|x64 = Release|x64 - Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {7B8D0088-645A-4D4B-9DB9-046EED07B47A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {7B8D0088-645A-4D4B-9DB9-046EED07B47A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {7B8D0088-645A-4D4B-9DB9-046EED07B47A}.Debug|arm64.ActiveCfg = Debug|Any CPU - {7B8D0088-645A-4D4B-9DB9-046EED07B47A}.Debug|arm64.Build.0 = Debug|Any CPU {7B8D0088-645A-4D4B-9DB9-046EED07B47A}.Debug|x64.ActiveCfg = Debug|Any CPU {7B8D0088-645A-4D4B-9DB9-046EED07B47A}.Debug|x64.Build.0 = Debug|Any CPU - {7B8D0088-645A-4D4B-9DB9-046EED07B47A}.Debug|x86.ActiveCfg = Debug|Any CPU - {7B8D0088-645A-4D4B-9DB9-046EED07B47A}.Debug|x86.Build.0 = Debug|Any CPU {7B8D0088-645A-4D4B-9DB9-046EED07B47A}.Release|Any CPU.ActiveCfg = Release|Any CPU {7B8D0088-645A-4D4B-9DB9-046EED07B47A}.Release|Any CPU.Build.0 = Release|Any CPU - {7B8D0088-645A-4D4B-9DB9-046EED07B47A}.Release|arm64.ActiveCfg = Release|Any CPU - {7B8D0088-645A-4D4B-9DB9-046EED07B47A}.Release|arm64.Build.0 = Release|Any CPU {7B8D0088-645A-4D4B-9DB9-046EED07B47A}.Release|x64.ActiveCfg = Release|Any CPU {7B8D0088-645A-4D4B-9DB9-046EED07B47A}.Release|x64.Build.0 = Release|Any CPU - {7B8D0088-645A-4D4B-9DB9-046EED07B47A}.Release|x86.ActiveCfg = Release|Any CPU - {7B8D0088-645A-4D4B-9DB9-046EED07B47A}.Release|x86.Build.0 = Release|Any CPU {6330E8E3-8D91-458E-945C-CE9B71FE809B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {6330E8E3-8D91-458E-945C-CE9B71FE809B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6330E8E3-8D91-458E-945C-CE9B71FE809B}.Debug|arm64.ActiveCfg = Debug|Any CPU - {6330E8E3-8D91-458E-945C-CE9B71FE809B}.Debug|arm64.Build.0 = Debug|Any CPU {6330E8E3-8D91-458E-945C-CE9B71FE809B}.Debug|x64.ActiveCfg = Debug|Any CPU {6330E8E3-8D91-458E-945C-CE9B71FE809B}.Debug|x64.Build.0 = Debug|Any CPU - {6330E8E3-8D91-458E-945C-CE9B71FE809B}.Debug|x86.ActiveCfg = Debug|Any CPU - {6330E8E3-8D91-458E-945C-CE9B71FE809B}.Debug|x86.Build.0 = Debug|Any CPU {6330E8E3-8D91-458E-945C-CE9B71FE809B}.Release|Any CPU.ActiveCfg = Release|Any CPU {6330E8E3-8D91-458E-945C-CE9B71FE809B}.Release|Any CPU.Build.0 = Release|Any CPU - {6330E8E3-8D91-458E-945C-CE9B71FE809B}.Release|arm64.ActiveCfg = Release|Any CPU - {6330E8E3-8D91-458E-945C-CE9B71FE809B}.Release|arm64.Build.0 = Release|Any CPU {6330E8E3-8D91-458E-945C-CE9B71FE809B}.Release|x64.ActiveCfg = Release|Any CPU {6330E8E3-8D91-458E-945C-CE9B71FE809B}.Release|x64.Build.0 = Release|Any CPU - {6330E8E3-8D91-458E-945C-CE9B71FE809B}.Release|x86.ActiveCfg = Release|Any CPU - {6330E8E3-8D91-458E-945C-CE9B71FE809B}.Release|x86.Build.0 = Release|Any CPU {22E5C50D-93C9-4007-881F-D8B751B880D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {22E5C50D-93C9-4007-881F-D8B751B880D0}.Debug|Any CPU.Build.0 = Debug|Any CPU - {22E5C50D-93C9-4007-881F-D8B751B880D0}.Debug|arm64.ActiveCfg = Debug|Any CPU - {22E5C50D-93C9-4007-881F-D8B751B880D0}.Debug|arm64.Build.0 = Debug|Any CPU {22E5C50D-93C9-4007-881F-D8B751B880D0}.Debug|x64.ActiveCfg = Debug|Any CPU {22E5C50D-93C9-4007-881F-D8B751B880D0}.Debug|x64.Build.0 = Debug|Any CPU - {22E5C50D-93C9-4007-881F-D8B751B880D0}.Debug|x86.ActiveCfg = Debug|Any CPU - {22E5C50D-93C9-4007-881F-D8B751B880D0}.Debug|x86.Build.0 = Debug|Any CPU {22E5C50D-93C9-4007-881F-D8B751B880D0}.Release|Any CPU.ActiveCfg = Release|Any CPU {22E5C50D-93C9-4007-881F-D8B751B880D0}.Release|Any CPU.Build.0 = Release|Any CPU - {22E5C50D-93C9-4007-881F-D8B751B880D0}.Release|arm64.ActiveCfg = Release|Any CPU - {22E5C50D-93C9-4007-881F-D8B751B880D0}.Release|arm64.Build.0 = Release|Any CPU {22E5C50D-93C9-4007-881F-D8B751B880D0}.Release|x64.ActiveCfg = Release|Any CPU {22E5C50D-93C9-4007-881F-D8B751B880D0}.Release|x64.Build.0 = Release|Any CPU - {22E5C50D-93C9-4007-881F-D8B751B880D0}.Release|x86.ActiveCfg = Release|Any CPU - {22E5C50D-93C9-4007-881F-D8B751B880D0}.Release|x86.Build.0 = Release|Any CPU {1668F782-FE09-4106-8393-9A9D9823E027}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {1668F782-FE09-4106-8393-9A9D9823E027}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1668F782-FE09-4106-8393-9A9D9823E027}.Debug|arm64.ActiveCfg = Debug|Any CPU - {1668F782-FE09-4106-8393-9A9D9823E027}.Debug|arm64.Build.0 = Debug|Any CPU {1668F782-FE09-4106-8393-9A9D9823E027}.Debug|x64.ActiveCfg = Debug|Any CPU {1668F782-FE09-4106-8393-9A9D9823E027}.Debug|x64.Build.0 = Debug|Any CPU - {1668F782-FE09-4106-8393-9A9D9823E027}.Debug|x86.ActiveCfg = Debug|Any CPU - {1668F782-FE09-4106-8393-9A9D9823E027}.Debug|x86.Build.0 = Debug|Any CPU {1668F782-FE09-4106-8393-9A9D9823E027}.Release|Any CPU.ActiveCfg = Release|Any CPU {1668F782-FE09-4106-8393-9A9D9823E027}.Release|Any CPU.Build.0 = Release|Any CPU - {1668F782-FE09-4106-8393-9A9D9823E027}.Release|arm64.ActiveCfg = Release|Any CPU - {1668F782-FE09-4106-8393-9A9D9823E027}.Release|arm64.Build.0 = Release|Any CPU {1668F782-FE09-4106-8393-9A9D9823E027}.Release|x64.ActiveCfg = Release|Any CPU {1668F782-FE09-4106-8393-9A9D9823E027}.Release|x64.Build.0 = Release|Any CPU - {1668F782-FE09-4106-8393-9A9D9823E027}.Release|x86.ActiveCfg = Release|Any CPU - {1668F782-FE09-4106-8393-9A9D9823E027}.Release|x86.Build.0 = Release|Any CPU {E7A5F71D-137D-4D65-AB27-2ADD1FA6B26B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {E7A5F71D-137D-4D65-AB27-2ADD1FA6B26B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E7A5F71D-137D-4D65-AB27-2ADD1FA6B26B}.Debug|arm64.ActiveCfg = Debug|arm64 - {E7A5F71D-137D-4D65-AB27-2ADD1FA6B26B}.Debug|arm64.Build.0 = Debug|arm64 {E7A5F71D-137D-4D65-AB27-2ADD1FA6B26B}.Debug|x64.ActiveCfg = Debug|Any CPU {E7A5F71D-137D-4D65-AB27-2ADD1FA6B26B}.Debug|x64.Build.0 = Debug|Any CPU - {E7A5F71D-137D-4D65-AB27-2ADD1FA6B26B}.Debug|x86.ActiveCfg = Debug|x86 - {E7A5F71D-137D-4D65-AB27-2ADD1FA6B26B}.Debug|x86.Build.0 = Debug|x86 {E7A5F71D-137D-4D65-AB27-2ADD1FA6B26B}.Release|Any CPU.ActiveCfg = Release|Any CPU {E7A5F71D-137D-4D65-AB27-2ADD1FA6B26B}.Release|Any CPU.Build.0 = Release|Any CPU - {E7A5F71D-137D-4D65-AB27-2ADD1FA6B26B}.Release|arm64.ActiveCfg = Release|arm64 - {E7A5F71D-137D-4D65-AB27-2ADD1FA6B26B}.Release|arm64.Build.0 = Release|arm64 {E7A5F71D-137D-4D65-AB27-2ADD1FA6B26B}.Release|x64.ActiveCfg = Release|Any CPU {E7A5F71D-137D-4D65-AB27-2ADD1FA6B26B}.Release|x64.Build.0 = Release|Any CPU - {E7A5F71D-137D-4D65-AB27-2ADD1FA6B26B}.Release|x86.ActiveCfg = Release|x86 - {E7A5F71D-137D-4D65-AB27-2ADD1FA6B26B}.Release|x86.Build.0 = Release|x86 {774E78F3-B48A-4D01-B70B-9CFB03A55663}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {774E78F3-B48A-4D01-B70B-9CFB03A55663}.Debug|Any CPU.Build.0 = Debug|Any CPU - {774E78F3-B48A-4D01-B70B-9CFB03A55663}.Debug|arm64.ActiveCfg = Debug|Any CPU - {774E78F3-B48A-4D01-B70B-9CFB03A55663}.Debug|arm64.Build.0 = Debug|Any CPU {774E78F3-B48A-4D01-B70B-9CFB03A55663}.Debug|x64.ActiveCfg = Debug|Any CPU {774E78F3-B48A-4D01-B70B-9CFB03A55663}.Debug|x64.Build.0 = Debug|Any CPU - {774E78F3-B48A-4D01-B70B-9CFB03A55663}.Debug|x86.ActiveCfg = Debug|Any CPU - {774E78F3-B48A-4D01-B70B-9CFB03A55663}.Debug|x86.Build.0 = Debug|Any CPU {774E78F3-B48A-4D01-B70B-9CFB03A55663}.Release|Any CPU.ActiveCfg = Release|Any CPU {774E78F3-B48A-4D01-B70B-9CFB03A55663}.Release|Any CPU.Build.0 = Release|Any CPU - {774E78F3-B48A-4D01-B70B-9CFB03A55663}.Release|arm64.ActiveCfg = Release|Any CPU - {774E78F3-B48A-4D01-B70B-9CFB03A55663}.Release|arm64.Build.0 = Release|Any CPU {774E78F3-B48A-4D01-B70B-9CFB03A55663}.Release|x64.ActiveCfg = Release|Any CPU {774E78F3-B48A-4D01-B70B-9CFB03A55663}.Release|x64.Build.0 = Release|Any CPU - {774E78F3-B48A-4D01-B70B-9CFB03A55663}.Release|x86.ActiveCfg = Release|Any CPU - {774E78F3-B48A-4D01-B70B-9CFB03A55663}.Release|x86.Build.0 = Release|Any CPU - {5D12BB81-B659-4CCB-9FAC-8224A6728196}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {5D12BB81-B659-4CCB-9FAC-8224A6728196}.Debug|Any CPU.Build.0 = Debug|Any CPU - {5D12BB81-B659-4CCB-9FAC-8224A6728196}.Debug|arm64.ActiveCfg = Debug|Any CPU - {5D12BB81-B659-4CCB-9FAC-8224A6728196}.Debug|arm64.Build.0 = Debug|Any CPU - {5D12BB81-B659-4CCB-9FAC-8224A6728196}.Debug|x64.ActiveCfg = Debug|Any CPU - {5D12BB81-B659-4CCB-9FAC-8224A6728196}.Debug|x64.Build.0 = Debug|Any CPU - {5D12BB81-B659-4CCB-9FAC-8224A6728196}.Debug|x86.ActiveCfg = Debug|Any CPU - {5D12BB81-B659-4CCB-9FAC-8224A6728196}.Debug|x86.Build.0 = Debug|Any CPU - {5D12BB81-B659-4CCB-9FAC-8224A6728196}.Release|Any CPU.ActiveCfg = Release|Any CPU - {5D12BB81-B659-4CCB-9FAC-8224A6728196}.Release|Any CPU.Build.0 = Release|Any CPU - {5D12BB81-B659-4CCB-9FAC-8224A6728196}.Release|arm64.ActiveCfg = Release|Any CPU - {5D12BB81-B659-4CCB-9FAC-8224A6728196}.Release|arm64.Build.0 = Release|Any CPU - {5D12BB81-B659-4CCB-9FAC-8224A6728196}.Release|x64.ActiveCfg = Release|Any CPU - {5D12BB81-B659-4CCB-9FAC-8224A6728196}.Release|x64.Build.0 = Release|Any CPU - {5D12BB81-B659-4CCB-9FAC-8224A6728196}.Release|x86.ActiveCfg = Release|Any CPU - {5D12BB81-B659-4CCB-9FAC-8224A6728196}.Release|x86.Build.0 = Release|Any CPU - {C4722145-3CF5-431D-8F47-416F3E6CFB9F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C4722145-3CF5-431D-8F47-416F3E6CFB9F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C4722145-3CF5-431D-8F47-416F3E6CFB9F}.Debug|arm64.ActiveCfg = Debug|Any CPU - {C4722145-3CF5-431D-8F47-416F3E6CFB9F}.Debug|arm64.Build.0 = Debug|Any CPU - {C4722145-3CF5-431D-8F47-416F3E6CFB9F}.Debug|x64.ActiveCfg = Debug|Any CPU - {C4722145-3CF5-431D-8F47-416F3E6CFB9F}.Debug|x64.Build.0 = Debug|Any CPU - {C4722145-3CF5-431D-8F47-416F3E6CFB9F}.Debug|x86.ActiveCfg = Debug|Any CPU - {C4722145-3CF5-431D-8F47-416F3E6CFB9F}.Debug|x86.Build.0 = Debug|Any CPU - {C4722145-3CF5-431D-8F47-416F3E6CFB9F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C4722145-3CF5-431D-8F47-416F3E6CFB9F}.Release|Any CPU.Build.0 = Release|Any CPU - {C4722145-3CF5-431D-8F47-416F3E6CFB9F}.Release|arm64.ActiveCfg = Release|Any CPU - {C4722145-3CF5-431D-8F47-416F3E6CFB9F}.Release|arm64.Build.0 = Release|Any CPU - {C4722145-3CF5-431D-8F47-416F3E6CFB9F}.Release|x64.ActiveCfg = Release|Any CPU - {C4722145-3CF5-431D-8F47-416F3E6CFB9F}.Release|x64.Build.0 = Release|Any CPU - {C4722145-3CF5-431D-8F47-416F3E6CFB9F}.Release|x86.ActiveCfg = Release|Any CPU - {C4722145-3CF5-431D-8F47-416F3E6CFB9F}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/DevSkim-DotNet/devskim-server-log20260205.txt b/DevSkim-DotNet/devskim-server-log20260205.txt new file mode 100644 index 00000000..dbafad2f --- /dev/null +++ b/DevSkim-DotNet/devskim-server-log20260205.txt @@ -0,0 +1,201 @@ +2026-02-05 12:13:58.280 -08:00 [DBG] Configuring server... +2026-02-05 12:13:58.971 -08:00 [DBG] Finding descriptors for initialize +2026-02-05 12:13:59.087 -08:00 [DBG] Queueing "Serial":initialize:2 request for processing +2026-02-05 12:13:59.101 -08:00 [DBG] Starting: Processing request initialize 2 +2026-02-05 12:13:59.106 -08:00 [DBG] Starting: Routing Request (2) initialize +2026-02-05 12:13:59.111 -08:00 [VRB] Converting params for Request (2) initialize to OmniSharp.Extensions.LanguageServer.Protocol.Models.InternalInitializeParams +2026-02-05 12:13:59.112 -08:00 [VRB] Converting params for Notification initialize to OmniSharp.Extensions.LanguageServer.Protocol.Models.InternalInitializeParams +2026-02-05 12:13:59.335 -08:00 [DBG] Server is starting... +2026-02-05 12:13:59.380 -08:00 [DBG] Server started +2026-02-05 12:13:59.383 -08:00 [VRB] Response value was OmniSharp.Extensions.LanguageServer.Protocol.Models.InitializeResult +2026-02-05 12:13:59.384 -08:00 [DBG] Finished: Routing Request (2) initialize in 278ms +2026-02-05 12:13:59.385 -08:00 [DBG] Finished: Processing request initialize 2 in 281ms +2026-02-05 12:13:59.430 -08:00 [DBG] Finding descriptors for initialized +2026-02-05 12:13:59.431 -08:00 [DBG] Queueing "Serial":initialized request for processing +2026-02-05 12:13:59.433 -08:00 [DBG] Starting: Processing notification initialized +2026-02-05 12:13:59.435 -08:00 [DBG] Starting: Routing Notification initialized +2026-02-05 12:13:59.435 -08:00 [VRB] Converting params for Notification initialized to OmniSharp.Extensions.LanguageServer.Protocol.Models.InitializedParams +2026-02-05 12:13:59.460 -08:00 [DBG] Beginning server routines... +2026-02-05 12:13:59.461 -08:00 [DBG] Listening for client events... +2026-02-05 12:13:59.478 -08:00 [DBG] Finished: Routing Notification initialized in 43ms +2026-02-05 12:13:59.479 -08:00 [DBG] Finished: Processing notification initialized in 45ms +2026-02-05 12:13:59.496 -08:00 [ERR] Unable to get configuration from client! +OmniSharp.Extensions.JsonRpc.Server.MethodNotSupportedException: Method not found: 'workspace/configuration'. + at OmniSharp.Extensions.JsonRpc.ResponseRouter.ResponseRouterReturnsImpl.Returning[TResponse](CancellationToken cancellationToken) +2026-02-05 12:13:59.516 -08:00 [ERR] Unable to get configuration from client! +OmniSharp.Extensions.JsonRpc.Server.MethodNotSupportedException: Method not found: 'workspace/configuration'. + at OmniSharp.Extensions.JsonRpc.ResponseRouter.ResponseRouterReturnsImpl.Returning[TResponse](CancellationToken cancellationToken) +2026-02-05 12:14:03.026 -08:00 [DBG] Finding descriptors for devskim/setSettings +2026-02-05 12:14:03.030 -08:00 [DBG] Swapping from "Serial" to "Parallel" +2026-02-05 12:14:03.030 -08:00 [DBG] Completing existing request process type "Serial" +2026-02-05 12:14:03.032 -08:00 [DBG] Queueing "Parallel":devskim/setSettings request for processing +2026-02-05 12:14:03.032 -08:00 [DBG] Starting: Processing notification devskim/setSettings +2026-02-05 12:14:03.032 -08:00 [DBG] Starting: Routing Notification devskim/setSettings +2026-02-05 12:14:03.032 -08:00 [VRB] Converting params for Notification devskim/setSettings to DevSkim.LanguageServer.DevSkimSetLanguageServerSettingsParams +2026-02-05 12:14:03.077 -08:00 [DBG] Finished: Routing Notification devskim/setSettings in 45ms +2026-02-05 12:14:03.078 -08:00 [DBG] Finished: Processing notification devskim/setSettings in 45ms +2026-02-05 12:14:03.078 -08:00 [DBG] Finding descriptors for textDocument/didOpen +2026-02-05 12:14:03.083 -08:00 [VRB] Created attribute csharp::file:///c:/Users/gstocco/Repos/DevSkim/DevSkim-DotNet/Microsoft.DevSkim.LanguageProtoInterop/PortableScannerSettings.cs +2026-02-05 12:14:03.084 -08:00 [VRB] Looking for handler for descriptors textDocument/didOpen +2026-02-05 12:14:03.084 -08:00 [VRB] Checking handler textDocument/didOpen:DevSkim.LanguageServer.TextDocumentSyncHandler +2026-02-05 12:14:03.084 -08:00 [VRB] Registration options OmniSharp.Extensions.LanguageServer.Protocol.Models.TextDocumentOpenRegistrationOptions +2026-02-05 12:14:03.084 -08:00 [VRB] Document Selector [batch], [c], [cpp], [csharp], [vb], [python], [javascript], [javascriptreact], [typescript], [typescriptreact], [coffeescript], [java], [objective-c], [swift], [perl], [perl6], [ruby], [lua], [groovy], [go], [rust], [jade], [clojure], [r], [yaml], [fsharp], [php], [powershell], [shellscript], [sql], [plaintext], [.config], [packages.config], [CSharp Project], [cobol], [json], [xml] +2026-02-05 12:14:03.085 -08:00 [VRB] Handler Selected: DevSkim.LanguageServer.TextDocumentSyncHandler via [batch], [c], [cpp], [csharp], [vb], [python], [javascript], [javascriptreact], [typescript], [typescriptreact], [coffeescript], [java], [objective-c], [swift], [perl], [perl6], [ruby], [lua], [groovy], [go], [rust], [jade], [clojure], [r], [yaml], [fsharp], [php], [powershell], [shellscript], [sql], [plaintext], [.config], [packages.config], [CSharp Project], [cobol], [json], [xml] (targeting OmniSharp.Extensions.JsonRpc.IJsonRpcNotificationHandler`1[[OmniSharp.Extensions.LanguageServer.Protocol.Models.DidOpenTextDocumentParams, OmniSharp.Extensions.LanguageProtocol, Version=0.19.0.0, Culture=neutral, PublicKeyToken=6d868dff454e6022]]) +2026-02-05 12:14:03.085 -08:00 [DBG] Swapping from "Parallel" to "Serial" +2026-02-05 12:14:03.085 -08:00 [DBG] Cancelling any outstanding requests (switch from parallel to serial) +2026-02-05 12:14:03.086 -08:00 [DBG] Completing existing request process type "Parallel" +2026-02-05 12:14:03.086 -08:00 [DBG] Queueing "Serial":textDocument/didOpen request for processing +2026-02-05 12:14:03.086 -08:00 [DBG] Starting: Processing notification textDocument/didOpen +2026-02-05 12:14:03.086 -08:00 [DBG] Starting: Routing Notification textDocument/didOpen +2026-02-05 12:14:03.086 -08:00 [VRB] Converting params for Notification textDocument/didOpen to OmniSharp.Extensions.LanguageServer.Protocol.Models.DidOpenTextDocumentParams +2026-02-05 12:14:03.090 -08:00 [DBG] TextDocumentSyncHandler.cs: DidOpenTextDocumentParams +2026-02-05 12:14:03.095 -08:00 [DBG] Processing document: /C:/Users/gstocco/Repos/DevSkim/DevSkim-DotNet/Microsoft.DevSkim.LanguageProtoInterop/PortableScannerSettings.cs +2026-02-05 12:14:03.138 -08:00 [DBG] Adding 0 issues to diagnostics +2026-02-05 12:14:03.139 -08:00 [DBG] Publishing diagnostics... +2026-02-05 12:14:03.152 -08:00 [DBG] Finished: Routing Notification textDocument/didOpen in 66ms +2026-02-05 12:14:03.153 -08:00 [DBG] Finished: Processing notification textDocument/didOpen in 66ms +2026-02-05 12:14:03.205 -08:00 [DBG] Finding descriptors for NotificationReceived +2026-02-05 12:14:03.205 -08:00 [DBG] Unable to find NotificationReceived, methods found include $/setTrace:OmniSharp.Extensions.LanguageServer.Server.Logging.LanguageServerLoggingManager, textDocument/didChange:DevSkim.LanguageServer.TextDocumentSyncHandler, devskim/setSettings:DevSkim.LanguageServer.VisualStudioConfigurationHandler, workspace/didChangeConfiguration:DevSkim.LanguageServer.DidChangeConfigurationHandler, window/workDoneProgress/cancel:OmniSharp.Extensions.LanguageServer.Protocol.Server.WorkDone.LanguageServerWorkDoneManager, workspace/didChangeWorkspaceFolders:OmniSharp.Extensions.LanguageServer.Server.LanguageServerWorkspaceFolderManager, exit:OmniSharp.Extensions.LanguageServer.Server.LanguageServer, initialize:OmniSharp.Extensions.LanguageServer.Server.LanguageServer, $/progress:OmniSharp.Extensions.LanguageServer.Protocol.Progress.ProgressManager, initialized:OmniSharp.Extensions.LanguageServer.Server.LanguageServer, textDocument/didSave:DevSkim.LanguageServer.TextDocumentSyncHandler, shutdown:OmniSharp.Extensions.LanguageServer.Server.LanguageServer, textDocument/didOpen:DevSkim.LanguageServer.TextDocumentSyncHandler, textDocument/didClose:DevSkim.LanguageServer.TextDocumentSyncHandler +2026-02-05 12:14:03.205 -08:00 [DBG] Notification handler was not found (or not setup) NotificationReceived +2026-02-05 12:14:15.683 -08:00 [DBG] Finding descriptors for textDocument/didSave +2026-02-05 12:14:15.689 -08:00 [VRB] Found attributes 1, ["csharp::file:///c:/Users/gstocco/Repos/DevSkim/DevSkim-DotNet/Microsoft.DevSkim.LanguageProtoInterop/PortableScannerSettings.cs"] +2026-02-05 12:14:15.690 -08:00 [VRB] Looking for handler for descriptors textDocument/didSave +2026-02-05 12:14:15.690 -08:00 [VRB] Checking handler textDocument/didSave:DevSkim.LanguageServer.TextDocumentSyncHandler +2026-02-05 12:14:15.690 -08:00 [VRB] Registration options OmniSharp.Extensions.LanguageServer.Protocol.Models.TextDocumentSaveRegistrationOptions +2026-02-05 12:14:15.690 -08:00 [VRB] Document Selector [batch], [c], [cpp], [csharp], [vb], [python], [javascript], [javascriptreact], [typescript], [typescriptreact], [coffeescript], [java], [objective-c], [swift], [perl], [perl6], [ruby], [lua], [groovy], [go], [rust], [jade], [clojure], [r], [yaml], [fsharp], [php], [powershell], [shellscript], [sql], [plaintext], [.config], [packages.config], [CSharp Project], [cobol], [json], [xml] +2026-02-05 12:14:15.690 -08:00 [VRB] Handler Selected: DevSkim.LanguageServer.TextDocumentSyncHandler via [batch], [c], [cpp], [csharp], [vb], [python], [javascript], [javascriptreact], [typescript], [typescriptreact], [coffeescript], [java], [objective-c], [swift], [perl], [perl6], [ruby], [lua], [groovy], [go], [rust], [jade], [clojure], [r], [yaml], [fsharp], [php], [powershell], [shellscript], [sql], [plaintext], [.config], [packages.config], [CSharp Project], [cobol], [json], [xml] (targeting OmniSharp.Extensions.JsonRpc.IJsonRpcNotificationHandler`1[[OmniSharp.Extensions.LanguageServer.Protocol.Models.DidSaveTextDocumentParams, OmniSharp.Extensions.LanguageProtocol, Version=0.19.0.0, Culture=neutral, PublicKeyToken=6d868dff454e6022]]) +2026-02-05 12:14:15.690 -08:00 [DBG] Queueing "Serial":textDocument/didSave request for processing +2026-02-05 12:14:15.691 -08:00 [DBG] Starting: Processing notification textDocument/didSave +2026-02-05 12:14:15.691 -08:00 [DBG] Starting: Routing Notification textDocument/didSave +2026-02-05 12:14:15.691 -08:00 [VRB] Converting params for Notification textDocument/didSave to OmniSharp.Extensions.LanguageServer.Protocol.Models.DidSaveTextDocumentParams +2026-02-05 12:14:15.693 -08:00 [DBG] TextDocumentSyncHandler.cs: DidSaveTextDocumentParams +2026-02-05 12:14:15.693 -08:00 [DBG] No content found +2026-02-05 12:14:15.693 -08:00 [DBG] Finished: Routing Notification textDocument/didSave in 2ms +2026-02-05 12:14:15.693 -08:00 [DBG] Finished: Processing notification textDocument/didSave in 2ms +2026-02-05 12:14:23.823 -08:00 [DBG] Finding descriptors for textDocument/didSave +2026-02-05 12:14:23.823 -08:00 [VRB] Found attributes 1, ["csharp::file:///c:/Users/gstocco/Repos/DevSkim/DevSkim-DotNet/Microsoft.DevSkim.LanguageProtoInterop/PortableScannerSettings.cs"] +2026-02-05 12:14:23.823 -08:00 [VRB] Looking for handler for descriptors textDocument/didSave +2026-02-05 12:14:23.823 -08:00 [VRB] Checking handler textDocument/didSave:DevSkim.LanguageServer.TextDocumentSyncHandler +2026-02-05 12:14:23.823 -08:00 [VRB] Registration options OmniSharp.Extensions.LanguageServer.Protocol.Models.TextDocumentSaveRegistrationOptions +2026-02-05 12:14:23.823 -08:00 [VRB] Document Selector [batch], [c], [cpp], [csharp], [vb], [python], [javascript], [javascriptreact], [typescript], [typescriptreact], [coffeescript], [java], [objective-c], [swift], [perl], [perl6], [ruby], [lua], [groovy], [go], [rust], [jade], [clojure], [r], [yaml], [fsharp], [php], [powershell], [shellscript], [sql], [plaintext], [.config], [packages.config], [CSharp Project], [cobol], [json], [xml] +2026-02-05 12:14:23.823 -08:00 [VRB] Handler Selected: DevSkim.LanguageServer.TextDocumentSyncHandler via [batch], [c], [cpp], [csharp], [vb], [python], [javascript], [javascriptreact], [typescript], [typescriptreact], [coffeescript], [java], [objective-c], [swift], [perl], [perl6], [ruby], [lua], [groovy], [go], [rust], [jade], [clojure], [r], [yaml], [fsharp], [php], [powershell], [shellscript], [sql], [plaintext], [.config], [packages.config], [CSharp Project], [cobol], [json], [xml] (targeting OmniSharp.Extensions.JsonRpc.IJsonRpcNotificationHandler`1[[OmniSharp.Extensions.LanguageServer.Protocol.Models.DidSaveTextDocumentParams, OmniSharp.Extensions.LanguageProtocol, Version=0.19.0.0, Culture=neutral, PublicKeyToken=6d868dff454e6022]]) +2026-02-05 12:14:23.823 -08:00 [DBG] Queueing "Serial":textDocument/didSave request for processing +2026-02-05 12:14:23.823 -08:00 [DBG] Starting: Processing notification textDocument/didSave +2026-02-05 12:14:23.823 -08:00 [DBG] Starting: Routing Notification textDocument/didSave +2026-02-05 12:14:23.824 -08:00 [VRB] Converting params for Notification textDocument/didSave to OmniSharp.Extensions.LanguageServer.Protocol.Models.DidSaveTextDocumentParams +2026-02-05 12:14:23.828 -08:00 [DBG] TextDocumentSyncHandler.cs: DidSaveTextDocumentParams +2026-02-05 12:14:23.828 -08:00 [DBG] No content found +2026-02-05 12:14:23.828 -08:00 [DBG] Finished: Routing Notification textDocument/didSave in 4ms +2026-02-05 12:14:23.829 -08:00 [DBG] Finished: Processing notification textDocument/didSave in 5ms +2026-02-05 12:14:26.054 -08:00 [DBG] Finding descriptors for textDocument/didClose +2026-02-05 12:14:26.055 -08:00 [VRB] Found attributes 1, ["csharp::file:///c:/Users/gstocco/Repos/DevSkim/DevSkim-DotNet/Microsoft.DevSkim.LanguageProtoInterop/PortableScannerSettings.cs"] +2026-02-05 12:14:26.055 -08:00 [VRB] Looking for handler for descriptors textDocument/didClose +2026-02-05 12:14:26.055 -08:00 [VRB] Checking handler textDocument/didClose:DevSkim.LanguageServer.TextDocumentSyncHandler +2026-02-05 12:14:26.055 -08:00 [VRB] Registration options OmniSharp.Extensions.LanguageServer.Protocol.Models.TextDocumentCloseRegistrationOptions +2026-02-05 12:14:26.055 -08:00 [VRB] Document Selector [batch], [c], [cpp], [csharp], [vb], [python], [javascript], [javascriptreact], [typescript], [typescriptreact], [coffeescript], [java], [objective-c], [swift], [perl], [perl6], [ruby], [lua], [groovy], [go], [rust], [jade], [clojure], [r], [yaml], [fsharp], [php], [powershell], [shellscript], [sql], [plaintext], [.config], [packages.config], [CSharp Project], [cobol], [json], [xml] +2026-02-05 12:14:26.055 -08:00 [VRB] Handler Selected: DevSkim.LanguageServer.TextDocumentSyncHandler via [batch], [c], [cpp], [csharp], [vb], [python], [javascript], [javascriptreact], [typescript], [typescriptreact], [coffeescript], [java], [objective-c], [swift], [perl], [perl6], [ruby], [lua], [groovy], [go], [rust], [jade], [clojure], [r], [yaml], [fsharp], [php], [powershell], [shellscript], [sql], [plaintext], [.config], [packages.config], [CSharp Project], [cobol], [json], [xml] (targeting OmniSharp.Extensions.JsonRpc.IJsonRpcNotificationHandler`1[[OmniSharp.Extensions.LanguageServer.Protocol.Models.DidCloseTextDocumentParams, OmniSharp.Extensions.LanguageProtocol, Version=0.19.0.0, Culture=neutral, PublicKeyToken=6d868dff454e6022]]) +2026-02-05 12:14:26.055 -08:00 [DBG] Swapping from "Serial" to "Parallel" +2026-02-05 12:14:26.055 -08:00 [DBG] Completing existing request process type "Serial" +2026-02-05 12:14:26.055 -08:00 [DBG] Queueing "Parallel":textDocument/didClose request for processing +2026-02-05 12:14:26.055 -08:00 [DBG] Starting: Processing notification textDocument/didClose +2026-02-05 12:14:26.055 -08:00 [DBG] Starting: Routing Notification textDocument/didClose +2026-02-05 12:14:26.056 -08:00 [VRB] Converting params for Notification textDocument/didClose to OmniSharp.Extensions.LanguageServer.Protocol.Models.DidCloseTextDocumentParams +2026-02-05 12:14:26.057 -08:00 [DBG] TextDocumentSyncHandler.cs: DidCloseTextDocumentParams +2026-02-05 12:14:26.058 -08:00 [DBG] Finished: Routing Notification textDocument/didClose in 2ms +2026-02-05 12:14:26.058 -08:00 [DBG] Finished: Processing notification textDocument/didClose in 2ms +2026-02-05 12:14:26.059 -08:00 [DBG] Finding descriptors for NotificationReceived +2026-02-05 12:14:26.059 -08:00 [DBG] Unable to find NotificationReceived, methods found include $/setTrace:OmniSharp.Extensions.LanguageServer.Server.Logging.LanguageServerLoggingManager, textDocument/didChange:DevSkim.LanguageServer.TextDocumentSyncHandler, devskim/setSettings:DevSkim.LanguageServer.VisualStudioConfigurationHandler, workspace/didChangeConfiguration:DevSkim.LanguageServer.DidChangeConfigurationHandler, window/workDoneProgress/cancel:OmniSharp.Extensions.LanguageServer.Protocol.Server.WorkDone.LanguageServerWorkDoneManager, workspace/didChangeWorkspaceFolders:OmniSharp.Extensions.LanguageServer.Server.LanguageServerWorkspaceFolderManager, exit:OmniSharp.Extensions.LanguageServer.Server.LanguageServer, initialize:OmniSharp.Extensions.LanguageServer.Server.LanguageServer, $/progress:OmniSharp.Extensions.LanguageServer.Protocol.Progress.ProgressManager, initialized:OmniSharp.Extensions.LanguageServer.Server.LanguageServer, textDocument/didSave:DevSkim.LanguageServer.TextDocumentSyncHandler, shutdown:OmniSharp.Extensions.LanguageServer.Server.LanguageServer, textDocument/didOpen:DevSkim.LanguageServer.TextDocumentSyncHandler, textDocument/didClose:DevSkim.LanguageServer.TextDocumentSyncHandler +2026-02-05 12:14:26.059 -08:00 [DBG] Notification handler was not found (or not setup) NotificationReceived +2026-02-05 12:19:32.845 -08:00 [DBG] Configuring server... +2026-02-05 12:19:33.489 -08:00 [DBG] Finding descriptors for initialize +2026-02-05 12:19:33.593 -08:00 [DBG] Queueing "Serial":initialize:2 request for processing +2026-02-05 12:19:33.609 -08:00 [DBG] Starting: Processing request initialize 2 +2026-02-05 12:19:33.614 -08:00 [DBG] Starting: Routing Request (2) initialize +2026-02-05 12:19:33.619 -08:00 [VRB] Converting params for Request (2) initialize to OmniSharp.Extensions.LanguageServer.Protocol.Models.InternalInitializeParams +2026-02-05 12:19:33.620 -08:00 [VRB] Converting params for Notification initialize to OmniSharp.Extensions.LanguageServer.Protocol.Models.InternalInitializeParams +2026-02-05 12:19:33.940 -08:00 [DBG] Server is starting... +2026-02-05 12:19:33.976 -08:00 [DBG] Server started +2026-02-05 12:19:33.979 -08:00 [VRB] Response value was OmniSharp.Extensions.LanguageServer.Protocol.Models.InitializeResult +2026-02-05 12:19:33.981 -08:00 [DBG] Finished: Routing Request (2) initialize in 367ms +2026-02-05 12:19:33.981 -08:00 [DBG] Finished: Processing request initialize 2 in 370ms +2026-02-05 12:19:34.028 -08:00 [DBG] Finding descriptors for initialized +2026-02-05 12:19:34.029 -08:00 [DBG] Queueing "Serial":initialized request for processing +2026-02-05 12:19:34.033 -08:00 [DBG] Starting: Processing notification initialized +2026-02-05 12:19:34.036 -08:00 [DBG] Starting: Routing Notification initialized +2026-02-05 12:19:34.036 -08:00 [VRB] Converting params for Notification initialized to OmniSharp.Extensions.LanguageServer.Protocol.Models.InitializedParams +2026-02-05 12:19:34.076 -08:00 [DBG] Beginning server routines... +2026-02-05 12:19:34.077 -08:00 [DBG] Listening for client events... +2026-02-05 12:19:34.101 -08:00 [DBG] Finished: Routing Notification initialized in 65ms +2026-02-05 12:19:34.102 -08:00 [DBG] Finished: Processing notification initialized in 68ms +2026-02-05 12:19:34.103 -08:00 [DBG] Finding descriptors for devskim/setSettings +2026-02-05 12:19:34.106 -08:00 [DBG] Swapping from "Serial" to "Parallel" +2026-02-05 12:19:34.106 -08:00 [DBG] Completing existing request process type "Serial" +2026-02-05 12:19:34.109 -08:00 [DBG] Queueing "Parallel":devskim/setSettings request for processing +2026-02-05 12:19:34.109 -08:00 [DBG] Starting: Processing notification devskim/setSettings +2026-02-05 12:19:34.109 -08:00 [DBG] Starting: Routing Notification devskim/setSettings +2026-02-05 12:19:34.109 -08:00 [VRB] Converting params for Notification devskim/setSettings to DevSkim.LanguageServer.DevSkimSetLanguageServerSettingsParams +2026-02-05 12:19:34.159 -08:00 [DBG] Finished: Routing Notification devskim/setSettings in 49ms +2026-02-05 12:19:34.159 -08:00 [DBG] Finished: Processing notification devskim/setSettings in 49ms +2026-02-05 12:19:34.159 -08:00 [DBG] Finding descriptors for textDocument/didOpen +2026-02-05 12:19:34.164 -08:00 [VRB] Created attribute csharp::file:///c:/Users/gstocco/Repos/DevSkim/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/StaticScannerSettings.cs +2026-02-05 12:19:34.165 -08:00 [VRB] Looking for handler for descriptors textDocument/didOpen +2026-02-05 12:19:34.166 -08:00 [VRB] Checking handler textDocument/didOpen:DevSkim.LanguageServer.TextDocumentSyncHandler +2026-02-05 12:19:34.166 -08:00 [VRB] Registration options OmniSharp.Extensions.LanguageServer.Protocol.Models.TextDocumentOpenRegistrationOptions +2026-02-05 12:19:34.166 -08:00 [VRB] Document Selector [batch], [c], [cpp], [csharp], [vb], [python], [javascript], [javascriptreact], [typescript], [typescriptreact], [coffeescript], [java], [objective-c], [swift], [perl], [perl6], [ruby], [lua], [groovy], [go], [rust], [jade], [clojure], [r], [yaml], [fsharp], [php], [powershell], [shellscript], [sql], [plaintext], [.config], [packages.config], [CSharp Project], [cobol], [json], [xml] +2026-02-05 12:19:34.166 -08:00 [VRB] Handler Selected: DevSkim.LanguageServer.TextDocumentSyncHandler via [batch], [c], [cpp], [csharp], [vb], [python], [javascript], [javascriptreact], [typescript], [typescriptreact], [coffeescript], [java], [objective-c], [swift], [perl], [perl6], [ruby], [lua], [groovy], [go], [rust], [jade], [clojure], [r], [yaml], [fsharp], [php], [powershell], [shellscript], [sql], [plaintext], [.config], [packages.config], [CSharp Project], [cobol], [json], [xml] (targeting OmniSharp.Extensions.JsonRpc.IJsonRpcNotificationHandler`1[[OmniSharp.Extensions.LanguageServer.Protocol.Models.DidOpenTextDocumentParams, OmniSharp.Extensions.LanguageProtocol, Version=0.19.0.0, Culture=neutral, PublicKeyToken=6d868dff454e6022]]) +2026-02-05 12:19:34.167 -08:00 [DBG] Swapping from "Parallel" to "Serial" +2026-02-05 12:19:34.167 -08:00 [DBG] Cancelling any outstanding requests (switch from parallel to serial) +2026-02-05 12:19:34.167 -08:00 [DBG] Completing existing request process type "Parallel" +2026-02-05 12:19:34.167 -08:00 [DBG] Queueing "Serial":textDocument/didOpen request for processing +2026-02-05 12:19:34.167 -08:00 [DBG] Starting: Processing notification textDocument/didOpen +2026-02-05 12:19:34.167 -08:00 [DBG] Starting: Routing Notification textDocument/didOpen +2026-02-05 12:19:34.167 -08:00 [VRB] Converting params for Notification textDocument/didOpen to OmniSharp.Extensions.LanguageServer.Protocol.Models.DidOpenTextDocumentParams +2026-02-05 12:19:34.170 -08:00 [DBG] TextDocumentSyncHandler.cs: DidOpenTextDocumentParams +2026-02-05 12:19:34.175 -08:00 [DBG] Processing document: /C:/Users/gstocco/Repos/DevSkim/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/StaticScannerSettings.cs +2026-02-05 12:19:34.194 -08:00 [ERR] Unable to get configuration from client! +OmniSharp.Extensions.JsonRpc.Server.MethodNotSupportedException: Method not found: 'workspace/configuration'. + at OmniSharp.Extensions.JsonRpc.ResponseRouter.ResponseRouterReturnsImpl.Returning[TResponse](CancellationToken cancellationToken) +2026-02-05 12:19:34.220 -08:00 [ERR] Unable to get configuration from client! +OmniSharp.Extensions.JsonRpc.Server.MethodNotSupportedException: Method not found: 'workspace/configuration'. + at OmniSharp.Extensions.JsonRpc.ResponseRouter.ResponseRouterReturnsImpl.Returning[TResponse](CancellationToken cancellationToken) +2026-02-05 12:19:34.220 -08:00 [DBG] Adding 0 issues to diagnostics +2026-02-05 12:19:34.220 -08:00 [DBG] Publishing diagnostics... +2026-02-05 12:19:34.232 -08:00 [DBG] Finished: Routing Notification textDocument/didOpen in 64ms +2026-02-05 12:19:34.232 -08:00 [DBG] Finished: Processing notification textDocument/didOpen in 65ms +2026-02-05 12:19:34.247 -08:00 [DBG] Finding descriptors for NotificationReceived +2026-02-05 12:19:34.248 -08:00 [DBG] Unable to find NotificationReceived, methods found include exit:OmniSharp.Extensions.LanguageServer.Server.LanguageServer, initialize:OmniSharp.Extensions.LanguageServer.Server.LanguageServer, textDocument/didSave:DevSkim.LanguageServer.TextDocumentSyncHandler, textDocument/didOpen:DevSkim.LanguageServer.TextDocumentSyncHandler, textDocument/didClose:DevSkim.LanguageServer.TextDocumentSyncHandler, window/workDoneProgress/cancel:OmniSharp.Extensions.LanguageServer.Protocol.Server.WorkDone.LanguageServerWorkDoneManager, shutdown:OmniSharp.Extensions.LanguageServer.Server.LanguageServer, $/progress:OmniSharp.Extensions.LanguageServer.Protocol.Progress.ProgressManager, workspace/didChangeConfiguration:DevSkim.LanguageServer.DidChangeConfigurationHandler, workspace/didChangeWorkspaceFolders:OmniSharp.Extensions.LanguageServer.Server.LanguageServerWorkspaceFolderManager, textDocument/didChange:DevSkim.LanguageServer.TextDocumentSyncHandler, $/setTrace:OmniSharp.Extensions.LanguageServer.Server.Logging.LanguageServerLoggingManager, devskim/setSettings:DevSkim.LanguageServer.VisualStudioConfigurationHandler, initialized:OmniSharp.Extensions.LanguageServer.Server.LanguageServer +2026-02-05 12:19:34.249 -08:00 [DBG] Notification handler was not found (or not setup) NotificationReceived +2026-02-05 12:19:47.195 -08:00 [DBG] Finding descriptors for textDocument/didSave +2026-02-05 12:19:47.202 -08:00 [VRB] Found attributes 1, ["csharp::file:///c:/Users/gstocco/Repos/DevSkim/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/StaticScannerSettings.cs"] +2026-02-05 12:19:47.203 -08:00 [VRB] Looking for handler for descriptors textDocument/didSave +2026-02-05 12:19:47.203 -08:00 [VRB] Checking handler textDocument/didSave:DevSkim.LanguageServer.TextDocumentSyncHandler +2026-02-05 12:19:47.203 -08:00 [VRB] Registration options OmniSharp.Extensions.LanguageServer.Protocol.Models.TextDocumentSaveRegistrationOptions +2026-02-05 12:19:47.203 -08:00 [VRB] Document Selector [batch], [c], [cpp], [csharp], [vb], [python], [javascript], [javascriptreact], [typescript], [typescriptreact], [coffeescript], [java], [objective-c], [swift], [perl], [perl6], [ruby], [lua], [groovy], [go], [rust], [jade], [clojure], [r], [yaml], [fsharp], [php], [powershell], [shellscript], [sql], [plaintext], [.config], [packages.config], [CSharp Project], [cobol], [json], [xml] +2026-02-05 12:19:47.203 -08:00 [VRB] Handler Selected: DevSkim.LanguageServer.TextDocumentSyncHandler via [batch], [c], [cpp], [csharp], [vb], [python], [javascript], [javascriptreact], [typescript], [typescriptreact], [coffeescript], [java], [objective-c], [swift], [perl], [perl6], [ruby], [lua], [groovy], [go], [rust], [jade], [clojure], [r], [yaml], [fsharp], [php], [powershell], [shellscript], [sql], [plaintext], [.config], [packages.config], [CSharp Project], [cobol], [json], [xml] (targeting OmniSharp.Extensions.JsonRpc.IJsonRpcNotificationHandler`1[[OmniSharp.Extensions.LanguageServer.Protocol.Models.DidSaveTextDocumentParams, OmniSharp.Extensions.LanguageProtocol, Version=0.19.0.0, Culture=neutral, PublicKeyToken=6d868dff454e6022]]) +2026-02-05 12:19:47.203 -08:00 [DBG] Queueing "Serial":textDocument/didSave request for processing +2026-02-05 12:19:47.203 -08:00 [DBG] Starting: Processing notification textDocument/didSave +2026-02-05 12:19:47.203 -08:00 [DBG] Starting: Routing Notification textDocument/didSave +2026-02-05 12:19:47.203 -08:00 [VRB] Converting params for Notification textDocument/didSave to OmniSharp.Extensions.LanguageServer.Protocol.Models.DidSaveTextDocumentParams +2026-02-05 12:19:47.206 -08:00 [DBG] TextDocumentSyncHandler.cs: DidSaveTextDocumentParams +2026-02-05 12:19:47.206 -08:00 [DBG] No content found +2026-02-05 12:19:47.206 -08:00 [DBG] Finished: Routing Notification textDocument/didSave in 2ms +2026-02-05 12:19:47.206 -08:00 [DBG] Finished: Processing notification textDocument/didSave in 2ms +2026-02-05 12:20:02.278 -08:00 [DBG] Finding descriptors for textDocument/didClose +2026-02-05 12:20:02.281 -08:00 [VRB] Found attributes 1, ["csharp::file:///c:/Users/gstocco/Repos/DevSkim/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/StaticScannerSettings.cs"] +2026-02-05 12:20:02.281 -08:00 [VRB] Looking for handler for descriptors textDocument/didClose +2026-02-05 12:20:02.281 -08:00 [VRB] Checking handler textDocument/didClose:DevSkim.LanguageServer.TextDocumentSyncHandler +2026-02-05 12:20:02.281 -08:00 [VRB] Registration options OmniSharp.Extensions.LanguageServer.Protocol.Models.TextDocumentCloseRegistrationOptions +2026-02-05 12:20:02.281 -08:00 [VRB] Document Selector [batch], [c], [cpp], [csharp], [vb], [python], [javascript], [javascriptreact], [typescript], [typescriptreact], [coffeescript], [java], [objective-c], [swift], [perl], [perl6], [ruby], [lua], [groovy], [go], [rust], [jade], [clojure], [r], [yaml], [fsharp], [php], [powershell], [shellscript], [sql], [plaintext], [.config], [packages.config], [CSharp Project], [cobol], [json], [xml] +2026-02-05 12:20:02.281 -08:00 [VRB] Handler Selected: DevSkim.LanguageServer.TextDocumentSyncHandler via [batch], [c], [cpp], [csharp], [vb], [python], [javascript], [javascriptreact], [typescript], [typescriptreact], [coffeescript], [java], [objective-c], [swift], [perl], [perl6], [ruby], [lua], [groovy], [go], [rust], [jade], [clojure], [r], [yaml], [fsharp], [php], [powershell], [shellscript], [sql], [plaintext], [.config], [packages.config], [CSharp Project], [cobol], [json], [xml] (targeting OmniSharp.Extensions.JsonRpc.IJsonRpcNotificationHandler`1[[OmniSharp.Extensions.LanguageServer.Protocol.Models.DidCloseTextDocumentParams, OmniSharp.Extensions.LanguageProtocol, Version=0.19.0.0, Culture=neutral, PublicKeyToken=6d868dff454e6022]]) +2026-02-05 12:20:02.281 -08:00 [DBG] Swapping from "Serial" to "Parallel" +2026-02-05 12:20:02.281 -08:00 [DBG] Completing existing request process type "Serial" +2026-02-05 12:20:02.281 -08:00 [DBG] Queueing "Parallel":textDocument/didClose request for processing +2026-02-05 12:20:02.281 -08:00 [DBG] Starting: Processing notification textDocument/didClose +2026-02-05 12:20:02.281 -08:00 [DBG] Starting: Routing Notification textDocument/didClose +2026-02-05 12:20:02.281 -08:00 [VRB] Converting params for Notification textDocument/didClose to OmniSharp.Extensions.LanguageServer.Protocol.Models.DidCloseTextDocumentParams +2026-02-05 12:20:02.283 -08:00 [DBG] TextDocumentSyncHandler.cs: DidCloseTextDocumentParams +2026-02-05 12:20:02.284 -08:00 [DBG] Finished: Routing Notification textDocument/didClose in 2ms +2026-02-05 12:20:02.284 -08:00 [DBG] Finished: Processing notification textDocument/didClose in 2ms +2026-02-05 12:20:02.286 -08:00 [DBG] Finding descriptors for NotificationReceived +2026-02-05 12:20:02.286 -08:00 [DBG] Unable to find NotificationReceived, methods found include exit:OmniSharp.Extensions.LanguageServer.Server.LanguageServer, initialize:OmniSharp.Extensions.LanguageServer.Server.LanguageServer, textDocument/didSave:DevSkim.LanguageServer.TextDocumentSyncHandler, textDocument/didOpen:DevSkim.LanguageServer.TextDocumentSyncHandler, textDocument/didClose:DevSkim.LanguageServer.TextDocumentSyncHandler, window/workDoneProgress/cancel:OmniSharp.Extensions.LanguageServer.Protocol.Server.WorkDone.LanguageServerWorkDoneManager, shutdown:OmniSharp.Extensions.LanguageServer.Server.LanguageServer, $/progress:OmniSharp.Extensions.LanguageServer.Protocol.Progress.ProgressManager, workspace/didChangeConfiguration:DevSkim.LanguageServer.DidChangeConfigurationHandler, workspace/didChangeWorkspaceFolders:OmniSharp.Extensions.LanguageServer.Server.LanguageServerWorkspaceFolderManager, textDocument/didChange:DevSkim.LanguageServer.TextDocumentSyncHandler, $/setTrace:OmniSharp.Extensions.LanguageServer.Server.Logging.LanguageServerLoggingManager, devskim/setSettings:DevSkim.LanguageServer.VisualStudioConfigurationHandler, initialized:OmniSharp.Extensions.LanguageServer.Server.LanguageServer +2026-02-05 12:20:02.286 -08:00 [DBG] Notification handler was not found (or not setup) NotificationReceived From 5ea212b1ff5eb0beccd440f14525a360d4727977 Mon Sep 17 00:00:00 2001 From: Giulia Stocco Date: Thu, 5 Feb 2026 14:33:04 -0800 Subject: [PATCH 04/19] Fix code fixes + suppressions. --- .../CodeActionHandler.cs | 50 ++++++++++++++---- .../TextDocumentSyncHandler.cs | 23 ++++---- .../DevSkimLanguageServerProvider.cs | 52 +++++++++++++------ 3 files changed, 91 insertions(+), 34 deletions(-) diff --git a/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/CodeActionHandler.cs b/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/CodeActionHandler.cs index cdc3224e..6908be8a 100644 --- a/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/CodeActionHandler.cs +++ b/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/CodeActionHandler.cs @@ -23,6 +23,9 @@ internal class CodeActionHandler : ICodeActionHandler // Store code fixes keyed by document URI and diagnostic key private static readonly ConcurrentDictionary>> _codeFixCache = new(); + + // Store line lengths per document so we can compute exact end-of-line positions for suppressions + private static readonly ConcurrentDictionary _lineLengthCache = new(); public CodeActionHandler(ILogger logger) { @@ -56,7 +59,6 @@ public CodeActionRegistrationOptions GetRegistrationOptions(CodeActionCapability } var diagnosticKey = CreateDiagnosticKey(documentUri, diagnostic); - _logger.LogDebug($"CodeActionHandler: Looking for fixes for diagnostic key: {diagnosticKey}"); if (_codeFixCache.TryGetValue(documentUri, out var documentFixes) && documentFixes.TryGetValue(diagnosticKey, out var fixes)) @@ -82,20 +84,26 @@ public CodeActionRegistrationOptions GetRegistrationOptions(CodeActionCapability private static WorkspaceEdit CreateWorkspaceEdit(DocumentUri uri, Diagnostic diagnostic, CodeFixMapping fix) { - var textEdit = fix.isSuppression - ? new TextEdit + TextEdit textEdit; + if (fix.isSuppression) + { + // For suppressions, insert at the actual end of the line + int line = diagnostic.Range.End.Line; + int lineLength = GetLineLength(uri, line); + textEdit = new TextEdit { - // For suppressions, insert at the end of the line - Range = new OmniSharp.Extensions.LanguageServer.Protocol.Models.Range( - diagnostic.Range.End.Line, int.MaxValue, - diagnostic.Range.End.Line, int.MaxValue), + Range = new OmniSharp.Extensions.LanguageServer.Protocol.Models.Range(line, lineLength, line, lineLength), NewText = fix.replacement - } - : new TextEdit + }; + } + else + { + textEdit = new TextEdit { Range = diagnostic.Range, NewText = fix.replacement }; + } return new WorkspaceEdit { @@ -106,6 +114,29 @@ private static WorkspaceEdit CreateWorkspaceEdit(DocumentUri uri, Diagnostic dia }; } + /// + /// Store line lengths for a document, computed from the document text we already have during scanning. + /// + public static void SetLineLengths(DocumentUri uri, string text) + { + var lines = text.Split('\n'); + var lengths = new int[lines.Length]; + for (int i = 0; i < lines.Length; i++) + { + lengths[i] = lines[i].TrimEnd('\r').Length; + } + _lineLengthCache[uri.ToString()] = lengths; + } + + private static int GetLineLength(DocumentUri uri, int line) + { + if (_lineLengthCache.TryGetValue(uri.ToString(), out var lengths) && line < lengths.Length) + { + return lengths[line]; + } + return 0; + } + /// /// Register code fixes for a diagnostic. Called by TextDocumentSyncHandler when processing documents. /// @@ -129,6 +160,7 @@ public static void RegisterCodeFix(DocumentUri uri, Diagnostic diagnostic, CodeF public static void ClearCodeFixes(DocumentUri uri) { _codeFixCache.TryRemove(uri.ToString(), out _); + _lineLengthCache.TryRemove(uri.ToString(), out _); } private static string CreateDiagnosticKey(string documentUri, Diagnostic diagnostic) diff --git a/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/TextDocumentSyncHandler.cs b/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/TextDocumentSyncHandler.cs index 2f06df4d..5a57551d 100644 --- a/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/TextDocumentSyncHandler.cs +++ b/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/TextDocumentSyncHandler.cs @@ -110,6 +110,9 @@ private async Task GenerateDiagnosticsForTextDocumentAsync(string text, in // Clear previous code fixes for this document and register new ones CodeActionHandler.ClearCodeFixes(uri); + // Store line lengths so CodeActionHandler can compute exact end-of-line positions for suppressions + CodeActionHandler.SetLineLengths(uri, text); + _logger.LogDebug("\tPublishing diagnostics..."); _facade.TextDocument.PublishDiagnostics(new PublishDiagnosticsParams() { @@ -118,18 +121,18 @@ private async Task GenerateDiagnosticsForTextDocumentAsync(string text, in Version = version }); - // Register code fixes with the CodeActionHandler for standard LSP code action requests + // Send custom notifications for VS Code backward compatibility + _facade.TextDocument.SendNotification(DevSkimMessages.FileVersion, new MappingsVersion() { version = version, fileName = uri.ToUri() }); + foreach (var mapping in codeFixes) + { + _facade.TextDocument.SendNotification(DevSkimMessages.CodeFixMapping, mapping); + } + + // Register code fixes with CodeActionHandler for standard LSP textDocument/codeAction (used by VS) _logger.LogDebug($"\tRegistering {codeFixes.Count} code fixes..."); - for (int i = 0; i < diagnostics.Count; i++) + foreach (var mapping in codeFixes) { - var diag = diagnostics[i]; - // Find matching code fixes for each diagnostic by comparing the string representation of the code - foreach (var mapping in codeFixes.Where(cf => - cf.diagnostic.Code?.String == diag.Code?.String && - cf.diagnostic.Range.Start.Line == diag.Range.Start.Line)) - { - CodeActionHandler.RegisterCodeFix(uri, diag, mapping); - } + CodeActionHandler.RegisterCodeFix(uri, mapping.diagnostic, mapping); } return Unit.Value; diff --git a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/DevSkimLanguageServerProvider.cs b/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/DevSkimLanguageServerProvider.cs index 39bf23ef..9078c625 100644 --- a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/DevSkimLanguageServerProvider.cs +++ b/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/DevSkimLanguageServerProvider.cs @@ -20,35 +20,33 @@ namespace Microsoft.DevSkim.VisualStudio; [VisualStudioContribution] internal class DevSkimLanguageServerProvider : LanguageServerProvider { + private Process? _serverProcess; + /// public override LanguageServerProviderConfiguration LanguageServerProviderConfiguration => new( "%DevSkim.LanguageServerProvider.DisplayName%", [ - // Try using "text" base document type to activate for all text files - // The language server itself determines which files it can analyze DocumentFilter.FromDocumentType("text"), ]); /// public override Task CreateServerConnectionAsync(CancellationToken cancellationToken) { - // Log to a file for debugging since Debug.WriteLine may not be visible var logPath = Path.Combine(Path.GetTempPath(), "devskim-vs-extension.log"); File.AppendAllText(logPath, $"[{DateTime.Now}] CreateServerConnectionAsync called\n"); + // Kill any leftover process from a previous activation + StopServerProcess(); + var serverPath = GetLanguageServerPath(); File.AppendAllText(logPath, $"[{DateTime.Now}] Server path: {serverPath}\n"); - File.AppendAllText(logPath, $"[{DateTime.Now}] Assembly location: {Assembly.GetExecutingAssembly().Location}\n"); if (string.IsNullOrEmpty(serverPath) || !File.Exists(serverPath)) { File.AppendAllText(logPath, $"[{DateTime.Now}] ERROR: Language server not found at: {serverPath}\n"); - Debug.WriteLine($"DevSkim: Language server not found at: {serverPath}"); return Task.FromResult(null); } - File.AppendAllText(logPath, $"[{DateTime.Now}] Server exists, starting process...\n"); - var startInfo = new ProcessStartInfo { FileName = serverPath, @@ -60,11 +58,8 @@ internal class DevSkimLanguageServerProvider : LanguageServerProvider WorkingDirectory = Path.GetDirectoryName(serverPath), }; -#pragma warning disable CA2000 // The process is disposed after Visual Studio sends the stop command. var process = new Process { StartInfo = startInfo }; -#pragma warning restore CA2000 - // Log stderr for debugging process.ErrorDataReceived += (sender, e) => { if (!string.IsNullOrEmpty(e.Data)) @@ -75,9 +70,9 @@ internal class DevSkimLanguageServerProvider : LanguageServerProvider if (process.Start()) { + _serverProcess = process; process.BeginErrorReadLine(); File.AppendAllText(logPath, $"[{DateTime.Now}] Language server started (PID: {process.Id})\n"); - Debug.WriteLine($"DevSkim: Language server started (PID: {process.Id})"); return Task.FromResult(new DuplexPipe( PipeReader.Create(process.StandardOutput.BaseStream), @@ -85,7 +80,6 @@ internal class DevSkimLanguageServerProvider : LanguageServerProvider } File.AppendAllText(logPath, $"[{DateTime.Now}] ERROR: Failed to start language server process\n"); - Debug.WriteLine("DevSkim: Failed to start language server process"); return Task.FromResult(null); } @@ -100,19 +94,47 @@ public override Task OnServerInitializationResultAsync( if (serverInitializationResult == ServerInitializationResult.Failed) { File.AppendAllText(logPath, $"[{DateTime.Now}] ERROR: Language server initialization failed: {initializationFailureInfo?.StatusMessage}\n"); - Debug.WriteLine($"DevSkim: Language server initialization failed: {initializationFailureInfo?.StatusMessage}"); - // Disable the server from being activated again this.Enabled = false; } else { File.AppendAllText(logPath, $"[{DateTime.Now}] Language server initialized successfully\n"); - Debug.WriteLine("DevSkim: Language server initialized successfully"); } return base.OnServerInitializationResultAsync(serverInitializationResult, initializationFailureInfo, cancellationToken); } + /// + protected override void Dispose(bool isDisposing) + { + if (isDisposing) + { + StopServerProcess(); + } + + base.Dispose(isDisposing); + } + + private void StopServerProcess() + { + try + { + if (_serverProcess is { HasExited: false }) + { + _serverProcess.Kill(); + _serverProcess.Dispose(); + } + } + catch + { + // Best effort cleanup + } + finally + { + _serverProcess = null; + } + } + private static string GetLanguageServerPath() { var extensionDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); From 4572df24bf983f201dcec56de1565752ff8f48cf Mon Sep 17 00:00:00 2001 From: Giulia Stocco Date: Thu, 5 Feb 2026 14:42:31 -0800 Subject: [PATCH 05/19] Clean up language server process --- .../DevSkimLanguageServerProvider.cs | 111 ++++++++++++++++++ 1 file changed, 111 insertions(+) diff --git a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/DevSkimLanguageServerProvider.cs b/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/DevSkimLanguageServerProvider.cs index 9078c625..c90b23d7 100644 --- a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/DevSkimLanguageServerProvider.cs +++ b/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/DevSkimLanguageServerProvider.cs @@ -3,13 +3,16 @@ namespace Microsoft.DevSkim.VisualStudio; +using System.ComponentModel; using System.Diagnostics; using System.IO.Pipelines; using System.Reflection; +using System.Runtime.InteropServices; using global::Microsoft.VisualStudio.Extensibility; using global::Microsoft.VisualStudio.Extensibility.Editor; using global::Microsoft.VisualStudio.Extensibility.LanguageServer; using global::Microsoft.VisualStudio.RpcContracts.LanguageServerProvider; +using Microsoft.Win32.SafeHandles; using Nerdbank.Streams; /// @@ -21,6 +24,7 @@ namespace Microsoft.DevSkim.VisualStudio; internal class DevSkimLanguageServerProvider : LanguageServerProvider { private Process? _serverProcess; + private SafeHandle? _jobHandle; /// public override LanguageServerProviderConfiguration LanguageServerProviderConfiguration => new( @@ -47,6 +51,9 @@ internal class DevSkimLanguageServerProvider : LanguageServerProvider return Task.FromResult(null); } + // Create a Windows Job Object so the server process is killed when the host process exits + EnsureJobObject(); + var startInfo = new ProcessStartInfo { FileName = serverPath, @@ -71,6 +78,7 @@ internal class DevSkimLanguageServerProvider : LanguageServerProvider if (process.Start()) { _serverProcess = process; + AssignProcessToJobObject(process); process.BeginErrorReadLine(); File.AppendAllText(logPath, $"[{DateTime.Now}] Language server started (PID: {process.Id})\n"); @@ -110,6 +118,8 @@ protected override void Dispose(bool isDisposing) if (isDisposing) { StopServerProcess(); + _jobHandle?.Dispose(); + _jobHandle = null; } base.Dispose(isDisposing); @@ -135,6 +145,59 @@ private void StopServerProcess() } } + private void EnsureJobObject() + { + if (_jobHandle != null) + { + return; + } + + try + { + string jobName = "DevSkimLanguageServer" + Environment.ProcessId; + _jobHandle = NativeMethods.CreateJobObject(IntPtr.Zero, jobName); + + var extendedInfo = new NativeMethods.JOBOBJECT_EXTENDED_LIMIT_INFORMATION + { + BasicLimitInformation = new NativeMethods.JOBOBJECT_BASIC_LIMIT_INFORMATION + { + LimitFlags = 0x2000 /* JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE */ + } + }; + + int length = Marshal.SizeOf(extendedInfo); + IntPtr pExtendedInfo = Marshal.AllocHGlobal(length); + try + { + Marshal.StructureToPtr(extendedInfo, pExtendedInfo, false); + NativeMethods.SetInformationJobObject(_jobHandle, 9 /* JobObjectExtendedLimitInformation */, pExtendedInfo, (uint)length); + } + finally + { + Marshal.FreeHGlobal(pExtendedInfo); + } + } + catch + { + // Non-fatal: process cleanup will fall back to Dispose/Kill + } + } + + private void AssignProcessToJobObject(Process process) + { + try + { + if (_jobHandle != null && !_jobHandle.IsInvalid) + { + NativeMethods.AssignProcessToJobObject(_jobHandle, process.Handle); + } + } + catch + { + // Non-fatal + } + } + private static string GetLanguageServerPath() { var extensionDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); @@ -145,5 +208,53 @@ private static string GetLanguageServerPath() return Path.Combine(extensionDirectory, "Server", "Microsoft.DevSkim.LanguageServer.exe"); } + + private static class NativeMethods + { + [DllImport("kernel32.dll", CharSet = CharSet.Unicode)] + public static extern SafeWaitHandle CreateJobObject(IntPtr lpJobAttributes, string? lpName); + + [DllImport("kernel32.dll")] + public static extern bool SetInformationJobObject(SafeHandle hJob, int jobObjectInfoClass, IntPtr lpJobObjectInfo, uint cbJobObjectInfoLength); + + [DllImport("kernel32.dll")] + public static extern bool AssignProcessToJobObject(SafeHandle hJob, IntPtr hProcess); + + [StructLayout(LayoutKind.Sequential)] + public struct JOBOBJECT_BASIC_LIMIT_INFORMATION + { + public long PerProcessUserTimeLimit; + public long PerJobUserTimeLimit; + public uint LimitFlags; + public UIntPtr MinimumWorkingSetSize; + public UIntPtr MaximumWorkingSetSize; + public uint ActiveProcessLimit; + public UIntPtr Affinity; + public uint PriorityClass; + public uint SchedulingClass; + } + + [StructLayout(LayoutKind.Sequential)] + public struct IO_COUNTERS + { + public ulong ReadOperationCount; + public ulong WriteOperationCount; + public ulong OtherOperationCount; + public ulong ReadTransferCount; + public ulong WriteTransferCount; + public ulong OtherTransferCount; + } + + [StructLayout(LayoutKind.Sequential)] + public struct JOBOBJECT_EXTENDED_LIMIT_INFORMATION + { + public JOBOBJECT_BASIC_LIMIT_INFORMATION BasicLimitInformation; + public IO_COUNTERS IoInfo; + public UIntPtr ProcessMemoryLimit; + public UIntPtr JobMemoryLimit; + public UIntPtr PeakProcessMemoryUsed; + public UIntPtr PeakJobMemoryUsed; + } + } } #pragma warning restore VSEXTPREVIEW_LSP From 21d8566e6d9a1eeed934b76c3c634f4cd4a38a17 Mon Sep 17 00:00:00 2001 From: Giulia Stocco Date: Thu, 5 Feb 2026 16:17:20 -0800 Subject: [PATCH 06/19] Fix settings --- .../Program.cs | 28 +- .../.vsextension/string-resources.json | 89 +++++- .../DevSkimLanguageServerProvider.cs | 265 ++++++++++++++++-- .../DevSkimSettingDefinitions.cs | 223 +++++++++++++++ .../Microsoft.DevSkim.VisualStudio.csproj | 5 + 5 files changed, 580 insertions(+), 30 deletions(-) create mode 100644 DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/DevSkimSettingDefinitions.cs diff --git a/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/Program.cs b/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/Program.cs index 6b4be26f..4d953a37 100644 --- a/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/Program.cs +++ b/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/Program.cs @@ -5,6 +5,7 @@ using OmniSharp.Extensions.LanguageServer.Protocol.Server.Capabilities; using OmniSharp.Extensions.LanguageServer.Server; using Serilog; +using System.Security.Cryptography; namespace DevSkim.LanguageServer; @@ -39,7 +40,8 @@ static async Task Main(string[] args) Log.Logger.Debug("Configuring server..."); IObserver workDone = null!; - + var thing = "http://test.com"; + MD5 mD5 = MD5.Create(); OmniSharp.Extensions.LanguageServer.Server.LanguageServer server = await OmniSharp.Extensions.LanguageServer.Server.LanguageServer.From( options => options @@ -62,11 +64,25 @@ static async Task Main(string[] args) { Log.Logger.Debug("Server is starting..."); - // Initialize with default settings immediately - // This ensures rules are enabled even if the client - // doesn't push settings via workspace/configuration - StaticScannerSettings.UpdateWith(new Microsoft.DevSkim.LanguageProtoInterop.PortableScannerSettings()); - Log.Logger.Debug("Default settings applied"); + // Check if the client sent settings via initializationOptions + // (VS extension passes PortableScannerSettings here) + Microsoft.DevSkim.LanguageProtoInterop.PortableScannerSettings? clientSettings = null; + try + { + if (request.InitializationOptions is Newtonsoft.Json.Linq.JToken initOptions) + { + clientSettings = initOptions.ToObject(); + Log.Logger.Debug("Received settings from initializationOptions"); + } + } + catch (Exception ex) + { + Log.Logger.Warning(ex, "Failed to parse initializationOptions as settings"); + } + + // Apply client settings if provided, otherwise use defaults + StaticScannerSettings.UpdateWith(clientSettings ?? new Microsoft.DevSkim.LanguageProtoInterop.PortableScannerSettings()); + Log.Logger.Debug("Settings applied"); OmniSharp.Extensions.LanguageServer.Protocol.Server.WorkDone.IWorkDoneObserver manager = server.WorkDoneManager.For( request, new WorkDoneProgressBegin diff --git a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/.vsextension/string-resources.json b/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/.vsextension/string-resources.json index faa21d49..8ac5db47 100644 --- a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/.vsextension/string-resources.json +++ b/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/.vsextension/string-resources.json @@ -1,3 +1,90 @@ { - "DevSkim.LanguageServerProvider.DisplayName": "DevSkim Security Analyzer" + "DevSkim.LanguageServerProvider.DisplayName": "DevSkim Security Analyzer", + + "devskim.DisplayName": "DevSkim", + "devskim.Description": "DevSkim security analyzer settings.", + + "devskim.rules.DisplayName": "Rules", + "devskim.rules.Description": "Settings for controlling which DevSkim rules are enabled and custom rule paths.", + + "devskim.suppressions.DisplayName": "Suppressions", + "devskim.suppressions.Description": "Settings for controlling how DevSkim suppressions are created and managed.", + + "devskim.triggers.DisplayName": "Triggers", + "devskim.triggers.Description": "Settings for controlling when DevSkim scans are triggered.", + + "devskim.ignores.DisplayName": "Ignores", + "devskim.ignores.Description": "Settings for ignoring specific rules or files.", + + "devskim.rules.enableCriticalSeverityRules.DisplayName": "Enable Critical Severity Rules", + "devskim.rules.enableCriticalSeverityRules.Description": "Enable rules with critical severity.", + + "devskim.rules.enableImportantSeverityRules.DisplayName": "Enable Important Severity Rules", + "devskim.rules.enableImportantSeverityRules.Description": "Enable rules with important severity.", + + "devskim.rules.enableModerateSeverityRules.DisplayName": "Enable Moderate Severity Rules", + "devskim.rules.enableModerateSeverityRules.Description": "Enable rules with moderate severity.", + + "devskim.rules.enableManualReviewSeverityRules.DisplayName": "Enable Manual Review Severity Rules", + "devskim.rules.enableManualReviewSeverityRules.Description": "Enable rules that require manual review.", + + "devskim.rules.enableBestPracticeSeverityRules.DisplayName": "Enable Best Practice Severity Rules", + "devskim.rules.enableBestPracticeSeverityRules.Description": "Enable rules for best practice recommendations.", + + "devskim.rules.enableHighConfidenceRules.DisplayName": "Enable High Confidence Rules", + "devskim.rules.enableHighConfidenceRules.Description": "Enable rules with high confidence findings.", + + "devskim.rules.enableMediumConfidenceRules.DisplayName": "Enable Medium Confidence Rules", + "devskim.rules.enableMediumConfidenceRules.Description": "Enable rules with medium confidence findings.", + + "devskim.rules.enableLowConfidenceRules.DisplayName": "Enable Low Confidence Rules", + "devskim.rules.enableLowConfidenceRules.Description": "Enable rules with low confidence findings.", + + "devskim.rules.ignoreDefaultRules.DisplayName": "Ignore Default Rules", + "devskim.rules.ignoreDefaultRules.Description": "When enabled, the built-in default rules are not loaded. Only custom rules will be used.", + + "devskim.rules.customRulesPaths.DisplayName": "Custom Rules Paths", + "devskim.rules.customRulesPaths.Description": "Semicolon-separated list of paths to directories containing custom DevSkim rules.", + + "devskim.rules.customLanguagesPath.DisplayName": "Custom Languages Path", + "devskim.rules.customLanguagesPath.Description": "Path to a custom language definitions file.", + + "devskim.rules.customCommentsPath.DisplayName": "Custom Comments Path", + "devskim.rules.customCommentsPath.Description": "Path to a custom comment definitions file.", + + "devskim.rules.guidanceBaseURL.DisplayName": "Guidance Base URL", + "devskim.rules.guidanceBaseURL.Description": "Base URL for rule guidance documentation.", + + "devskim.suppressions.suppressionCommentStyle.DisplayName": "Suppression Comment Style", + "devskim.suppressions.suppressionCommentStyle.Description": "Comment style used for suppression comments. Valid values: Line, Block.", + + "devskim.suppressions.manualReviewerName.DisplayName": "Manual Reviewer Name", + "devskim.suppressions.manualReviewerName.Description": "Name used to populate the reviewer field in suppression comments.", + + "devskim.suppressions.suppressionDurationInDays.DisplayName": "Suppression Duration (Days)", + "devskim.suppressions.suppressionDurationInDays.Description": "Default number of days before a suppression expires.", + + "devskim.triggers.scanOnOpen.DisplayName": "Scan on Open", + "devskim.triggers.scanOnOpen.Description": "Run DevSkim analysis when a file is opened.", + + "devskim.triggers.scanOnSave.DisplayName": "Scan on Save", + "devskim.triggers.scanOnSave.Description": "Run DevSkim analysis when a file is saved.", + + "devskim.triggers.scanOnChange.DisplayName": "Scan on Change", + "devskim.triggers.scanOnChange.Description": "Run DevSkim analysis when a file is modified.", + + "devskim.triggers.removeFindingsOnClose.DisplayName": "Remove Findings on Close", + "devskim.triggers.removeFindingsOnClose.Description": "Remove DevSkim findings when a file is closed.", + + "devskim.ignores.ignoreRulesList.DisplayName": "Ignore Rules List", + "devskim.ignores.ignoreRulesList.Description": "Comma-separated list of DevSkim rule IDs to ignore.", + + "devskim.ignores.ignoreFiles.DisplayName": "Ignore Files", + "devskim.ignores.ignoreFiles.Description": "Comma-separated list of file glob patterns to exclude from scanning.", + + "devskim.diagnostics.DisplayName": "Diagnostics", + "devskim.diagnostics.Description": "Settings for DevSkim extension diagnostics and logging.", + + "devskim.diagnostics.enableFileLogging.DisplayName": "Enable File Logging", + "devskim.diagnostics.enableFileLogging.Description": "Write extension logs to a file in the temp directory (devskim-vs-extension.log). Useful for troubleshooting." } diff --git a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/DevSkimLanguageServerProvider.cs b/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/DevSkimLanguageServerProvider.cs index c90b23d7..6ea3c1bb 100644 --- a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/DevSkimLanguageServerProvider.cs +++ b/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/DevSkimLanguageServerProvider.cs @@ -3,28 +3,38 @@ namespace Microsoft.DevSkim.VisualStudio; -using System.ComponentModel; using System.Diagnostics; using System.IO.Pipelines; using System.Reflection; using System.Runtime.InteropServices; +using global::Microsoft.DevSkim.LanguageProtoInterop; using global::Microsoft.VisualStudio.Extensibility; using global::Microsoft.VisualStudio.Extensibility.Editor; using global::Microsoft.VisualStudio.Extensibility.LanguageServer; +using global::Microsoft.VisualStudio.Extensibility.Settings; using global::Microsoft.VisualStudio.RpcContracts.LanguageServerProvider; using Microsoft.Win32.SafeHandles; using Nerdbank.Streams; +using Newtonsoft.Json.Linq; +using Serilog; +using Serilog.Core; /// /// DevSkim Language Server Provider. /// Activates the DevSkim language server for security analysis when supported files are opened. /// #pragma warning disable VSEXTPREVIEW_LSP // Type is for evaluation purposes only and is subject to change or removal in future updates. +#pragma warning disable VSEXTPREVIEW_SETTINGS [VisualStudioContribution] internal class DevSkimLanguageServerProvider : LanguageServerProvider { + private static readonly string LogFilePath = Path.Combine(Path.GetTempPath(), "devskim-vs-extension.log"); + private Process? _serverProcess; private SafeHandle? _jobHandle; + private readonly List _settingsSubscriptions = []; + private bool _initialPushDone; + private CancellationTokenSource? _restartDebounce; /// public override LanguageServerProviderConfiguration LanguageServerProviderConfiguration => new( @@ -34,23 +44,34 @@ internal class DevSkimLanguageServerProvider : LanguageServerProvider ]); /// - public override Task CreateServerConnectionAsync(CancellationToken cancellationToken) + public override async Task CreateServerConnectionAsync(CancellationToken cancellationToken) { - var logPath = Path.Combine(Path.GetTempPath(), "devskim-vs-extension.log"); - File.AppendAllText(logPath, $"[{DateTime.Now}] CreateServerConnectionAsync called\n"); - + // Configure logging on each server start (file logging may have changed) + ConfigureLogging(await ReadFileLoggingSettingAsync(cancellationToken)); + + Log.Debug("CreateServerConnectionAsync called"); + // Kill any leftover process from a previous activation StopServerProcess(); - + var serverPath = GetLanguageServerPath(); - File.AppendAllText(logPath, $"[{DateTime.Now}] Server path: {serverPath}\n"); - + Log.Debug("Server path: {ServerPath}", serverPath); + if (string.IsNullOrEmpty(serverPath) || !File.Exists(serverPath)) { - File.AppendAllText(logPath, $"[{DateTime.Now}] ERROR: Language server not found at: {serverPath}\n"); - return Task.FromResult(null); + Log.Error("Language server not found at: {ServerPath}", serverPath); + return null; } + // Read current settings and pass them as LSP initializationOptions + // so the server applies them during the initialize handshake. + var currentSettings = await ReadAllSettingsAsync(cancellationToken); + LanguageServerOptions = new LanguageServerOptions + { + InitializationOptions = JToken.FromObject(currentSettings), + }; + Log.Debug("InitializationOptions set with current settings"); + // Create a Windows Job Object so the server process is killed when the host process exits EnsureJobObject(); @@ -71,7 +92,7 @@ internal class DevSkimLanguageServerProvider : LanguageServerProvider { if (!string.IsNullOrEmpty(e.Data)) { - Debug.WriteLine($"DevSkim Server: {e.Data}"); + Log.Debug("Server stderr: {Data}", e.Data); } }; @@ -80,36 +101,42 @@ internal class DevSkimLanguageServerProvider : LanguageServerProvider _serverProcess = process; AssignProcessToJobObject(process); process.BeginErrorReadLine(); - File.AppendAllText(logPath, $"[{DateTime.Now}] Language server started (PID: {process.Id})\n"); + Log.Information("Language server started (PID: {ProcessId})", process.Id); - return Task.FromResult(new DuplexPipe( + return new DuplexPipe( PipeReader.Create(process.StandardOutput.BaseStream), - PipeWriter.Create(process.StandardInput.BaseStream))); + PipeWriter.Create(process.StandardInput.BaseStream)); } - File.AppendAllText(logPath, $"[{DateTime.Now}] ERROR: Failed to start language server process\n"); - return Task.FromResult(null); + Log.Error("Failed to start language server process"); + return null; } /// - public override Task OnServerInitializationResultAsync( + public override async Task OnServerInitializationResultAsync( ServerInitializationResult serverInitializationResult, LanguageServerInitializationFailureInfo? initializationFailureInfo, CancellationToken cancellationToken) { - var logPath = Path.Combine(Path.GetTempPath(), "devskim-vs-extension.log"); - if (serverInitializationResult == ServerInitializationResult.Failed) { - File.AppendAllText(logPath, $"[{DateTime.Now}] ERROR: Language server initialization failed: {initializationFailureInfo?.StatusMessage}\n"); - this.Enabled = false; + Log.Error("Language server initialization failed: {Message}", initializationFailureInfo?.StatusMessage); + Enabled = false; } else { - File.AppendAllText(logPath, $"[{DateTime.Now}] Language server initialized successfully\n"); + Log.Information("Language server initialized successfully"); + SubscribeToSettingsChanges(); + // Delay enabling change detection so SubscribeAsync initial callbacks are ignored + _ = Task.Run(async () => + { + await Task.Delay(5000); + _initialPushDone = true; + Log.Debug("Settings change detection enabled"); + }); } - return base.OnServerInitializationResultAsync(serverInitializationResult, initializationFailureInfo, cancellationToken); + await base.OnServerInitializationResultAsync(serverInitializationResult, initializationFailureInfo, cancellationToken); } /// @@ -117,6 +144,13 @@ protected override void Dispose(bool isDisposing) { if (isDisposing) { + foreach (var sub in _settingsSubscriptions) + { + sub.Dispose(); + } + _settingsSubscriptions.Clear(); + _restartDebounce?.Cancel(); + _restartDebounce?.Dispose(); StopServerProcess(); _jobHandle?.Dispose(); _jobHandle = null; @@ -125,6 +159,189 @@ protected override void Dispose(bool isDisposing) base.Dispose(isDisposing); } + #region Logging + + private static void ConfigureLogging(bool enableFileLogging) + { + var config = new LoggerConfiguration() + .Enrich.FromLogContext() + .WriteTo.Debug(outputTemplate: "[DevSkim] {Message:lj}{NewLine}{Exception}"); + +#if DEBUG + // Always log to file in debug builds + config = config + .WriteTo.File(LogFilePath, rollingInterval: RollingInterval.Day) + .MinimumLevel.Verbose(); +#else + if (enableFileLogging) + { + config = config.WriteTo.File(LogFilePath, rollingInterval: RollingInterval.Day); + } + + config = config.MinimumLevel.Debug(); +#endif + + Log.Logger = config.CreateLogger(); + } + + private async Task ReadFileLoggingSettingAsync(CancellationToken cancellationToken) + { + try + { + return (await Extensibility.Settings() + .ReadEffectiveValueAsync(DevSkimSettingDefinitions.EnableFileLogging, cancellationToken)) + .ValueOrDefault(false); + } + catch + { + return false; + } + } + + #endregion + + #region Settings + + /// + /// Subscribes to all settings changes. On change, restarts the server so it picks up + /// new settings via initializationOptions during the LSP handshake. + /// + private void SubscribeToSettingsChanges() + { + SubscribeSetting(DevSkimSettingDefinitions.EnableCriticalSeverityRules); + SubscribeSetting(DevSkimSettingDefinitions.EnableImportantSeverityRules); + SubscribeSetting(DevSkimSettingDefinitions.EnableModerateSeverityRules); + SubscribeSetting(DevSkimSettingDefinitions.EnableManualReviewSeverityRules); + SubscribeSetting(DevSkimSettingDefinitions.EnableBestPracticeSeverityRules); + SubscribeSetting(DevSkimSettingDefinitions.EnableHighConfidenceRules); + SubscribeSetting(DevSkimSettingDefinitions.EnableMediumConfidenceRules); + SubscribeSetting(DevSkimSettingDefinitions.EnableLowConfidenceRules); + SubscribeSetting(DevSkimSettingDefinitions.IgnoreDefaultRules); + SubscribeSetting(DevSkimSettingDefinitions.ScanOnOpen); + SubscribeSetting(DevSkimSettingDefinitions.ScanOnSave); + SubscribeSetting(DevSkimSettingDefinitions.ScanOnChange); + SubscribeSetting(DevSkimSettingDefinitions.RemoveFindingsOnClose); + SubscribeStringSetting(DevSkimSettingDefinitions.CustomRulesPaths); + SubscribeStringSetting(DevSkimSettingDefinitions.CustomLanguagesPath); + SubscribeStringSetting(DevSkimSettingDefinitions.CustomCommentsPath); + SubscribeStringSetting(DevSkimSettingDefinitions.GuidanceBaseURL); + SubscribeStringSetting(DevSkimSettingDefinitions.SuppressionCommentStyle); + SubscribeStringSetting(DevSkimSettingDefinitions.ManualReviewerName); + SubscribeStringSetting(DevSkimSettingDefinitions.IgnoreRulesList); + SubscribeStringSetting(DevSkimSettingDefinitions.IgnoreFiles); + SubscribeIntSetting(DevSkimSettingDefinitions.SuppressionDurationInDays); + } + + private void SubscribeSetting(Setting.Boolean setting) + { + _ = Task.Run(async () => + { + var sub = await Extensibility.Settings().SubscribeAsync( + setting, + CancellationToken.None, + changeHandler: _ => OnSettingChanged()); + _settingsSubscriptions.Add(sub); + }); + } + + private void SubscribeStringSetting(Setting.String setting) + { + _ = Task.Run(async () => + { + var sub = await Extensibility.Settings().SubscribeAsync( + setting, + CancellationToken.None, + changeHandler: _ => OnSettingChanged()); + _settingsSubscriptions.Add(sub); + }); + } + + private void SubscribeIntSetting(Setting.Integer setting) + { + _ = Task.Run(async () => + { + var sub = await Extensibility.Settings().SubscribeAsync( + setting, + CancellationToken.None, + changeHandler: _ => OnSettingChanged()); + _settingsSubscriptions.Add(sub); + }); + } + + private void OnSettingChanged() + { + if (!_initialPushDone) + { + return; + } + + // Debounce: cancel any pending restart and start a new 2-second timer. + // This way rapid changes (e.g. toggling multiple settings) cause only one restart. + _restartDebounce?.Cancel(); + _restartDebounce = new CancellationTokenSource(); + var token = _restartDebounce.Token; + + _ = Task.Run(async () => + { + try + { + await Task.Delay(2000, token); + Log.Information("Settings changed, restarting server"); + Enabled = false; + await Task.Delay(500, CancellationToken.None); + Enabled = true; + } + catch (OperationCanceledException) + { + // Debounced — a newer change superseded this one + } + }); + } + + /// + /// Reads all DevSkim settings from VS and maps them to a . + /// + private async Task ReadAllSettingsAsync(CancellationToken cancellationToken) + { + var api = Extensibility.Settings(); + + var suppressionStyle = (await api.ReadEffectiveValueAsync(DevSkimSettingDefinitions.SuppressionCommentStyle, cancellationToken)) + .ValueOrDefault("Line"); + var parsedStyle = Enum.TryParse(suppressionStyle, ignoreCase: true, out var style) + ? style + : CommentStylesEnum.Line; + + return new PortableScannerSettings + { + EnableCriticalSeverityRules = (await api.ReadEffectiveValueAsync(DevSkimSettingDefinitions.EnableCriticalSeverityRules, cancellationToken)).ValueOrDefault(true), + EnableImportantSeverityRules = (await api.ReadEffectiveValueAsync(DevSkimSettingDefinitions.EnableImportantSeverityRules, cancellationToken)).ValueOrDefault(true), + EnableModerateSeverityRules = (await api.ReadEffectiveValueAsync(DevSkimSettingDefinitions.EnableModerateSeverityRules, cancellationToken)).ValueOrDefault(true), + EnableManualReviewSeverityRules = (await api.ReadEffectiveValueAsync(DevSkimSettingDefinitions.EnableManualReviewSeverityRules, cancellationToken)).ValueOrDefault(true), + EnableBestPracticeSeverityRules = (await api.ReadEffectiveValueAsync(DevSkimSettingDefinitions.EnableBestPracticeSeverityRules, cancellationToken)).ValueOrDefault(true), + EnableHighConfidenceRules = (await api.ReadEffectiveValueAsync(DevSkimSettingDefinitions.EnableHighConfidenceRules, cancellationToken)).ValueOrDefault(true), + EnableMediumConfidenceRules = (await api.ReadEffectiveValueAsync(DevSkimSettingDefinitions.EnableMediumConfidenceRules, cancellationToken)).ValueOrDefault(true), + EnableLowConfidenceRules = (await api.ReadEffectiveValueAsync(DevSkimSettingDefinitions.EnableLowConfidenceRules, cancellationToken)).ValueOrDefault(false), + IgnoreDefaultRules = (await api.ReadEffectiveValueAsync(DevSkimSettingDefinitions.IgnoreDefaultRules, cancellationToken)).ValueOrDefault(false), + ScanOnOpen = (await api.ReadEffectiveValueAsync(DevSkimSettingDefinitions.ScanOnOpen, cancellationToken)).ValueOrDefault(true), + ScanOnSave = (await api.ReadEffectiveValueAsync(DevSkimSettingDefinitions.ScanOnSave, cancellationToken)).ValueOrDefault(true), + ScanOnChange = (await api.ReadEffectiveValueAsync(DevSkimSettingDefinitions.ScanOnChange, cancellationToken)).ValueOrDefault(true), + RemoveFindingsOnClose = (await api.ReadEffectiveValueAsync(DevSkimSettingDefinitions.RemoveFindingsOnClose, cancellationToken)).ValueOrDefault(true), + CustomRulesPathsString = (await api.ReadEffectiveValueAsync(DevSkimSettingDefinitions.CustomRulesPaths, cancellationToken)).ValueOrDefault(""), + CustomLanguagesPath = (await api.ReadEffectiveValueAsync(DevSkimSettingDefinitions.CustomLanguagesPath, cancellationToken)).ValueOrDefault(""), + CustomCommentsPath = (await api.ReadEffectiveValueAsync(DevSkimSettingDefinitions.CustomCommentsPath, cancellationToken)).ValueOrDefault(""), + GuidanceBaseURL = (await api.ReadEffectiveValueAsync(DevSkimSettingDefinitions.GuidanceBaseURL, cancellationToken)).ValueOrDefault("https://github.com/microsoft/devskim/tree/main/guidance"), + SuppressionCommentStyle = parsedStyle, + ManualReviewerName = (await api.ReadEffectiveValueAsync(DevSkimSettingDefinitions.ManualReviewerName, cancellationToken)).ValueOrDefault(""), + SuppressionDurationInDays = (await api.ReadEffectiveValueAsync(DevSkimSettingDefinitions.SuppressionDurationInDays, cancellationToken)).ValueOrDefault(30), + IgnoreRulesListString = (await api.ReadEffectiveValueAsync(DevSkimSettingDefinitions.IgnoreRulesList, cancellationToken)).ValueOrDefault(""), + IgnoreFilesString = (await api.ReadEffectiveValueAsync(DevSkimSettingDefinitions.IgnoreFiles, cancellationToken)).ValueOrDefault(""), + }; + } + + #endregion + + #region Process Management + private void StopServerProcess() { try @@ -256,5 +473,7 @@ public struct JOBOBJECT_EXTENDED_LIMIT_INFORMATION public UIntPtr PeakJobMemoryUsed; } } + + #endregion } #pragma warning restore VSEXTPREVIEW_LSP diff --git a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/DevSkimSettingDefinitions.cs b/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/DevSkimSettingDefinitions.cs new file mode 100644 index 00000000..934042c5 --- /dev/null +++ b/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/DevSkimSettingDefinitions.cs @@ -0,0 +1,223 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +namespace Microsoft.DevSkim.VisualStudio; + +using Microsoft.VisualStudio.Extensibility; +using Microsoft.VisualStudio.Extensibility.Settings; + +#pragma warning disable VSEXTPREVIEW_SETTINGS + +/// +/// Defines the settings for the DevSkim Visual Studio extension using the VS Extensibility SDK settings API. +/// Settings mirror properties. +/// +internal static class DevSkimSettingDefinitions +{ + #region Categories + + [VisualStudioContribution] + internal static SettingCategory DevSkimCategory { get; } = new("devskim", "%devskim.DisplayName%") + { + Description = "%devskim.Description%", + GenerateObserverClass = true, + }; + + [VisualStudioContribution] + internal static SettingCategory RulesCategory { get; } = new("devskimRules", "%devskim.rules.DisplayName%", DevSkimCategory) + { + Description = "%devskim.rules.Description%", + }; + + [VisualStudioContribution] + internal static SettingCategory SuppressionsCategory { get; } = new("devskimSuppressions", "%devskim.suppressions.DisplayName%", DevSkimCategory) + { + Description = "%devskim.suppressions.Description%", + }; + + [VisualStudioContribution] + internal static SettingCategory TriggersCategory { get; } = new("devskimTriggers", "%devskim.triggers.DisplayName%", DevSkimCategory) + { + Description = "%devskim.triggers.Description%", + }; + + [VisualStudioContribution] + internal static SettingCategory IgnoresCategory { get; } = new("devskimIgnores", "%devskim.ignores.DisplayName%", DevSkimCategory) + { + Description = "%devskim.ignores.Description%", + }; + + #endregion + + #region Rules Settings - Severity + + [VisualStudioContribution] + internal static Setting.Boolean EnableCriticalSeverityRules { get; } = new("devskimEnableCriticalSeverityRules", "%devskim.rules.enableCriticalSeverityRules.DisplayName%", RulesCategory, defaultValue: true) + { + Description = "%devskim.rules.enableCriticalSeverityRules.Description%", + }; + + [VisualStudioContribution] + internal static Setting.Boolean EnableImportantSeverityRules { get; } = new("devskimEnableImportantSeverityRules", "%devskim.rules.enableImportantSeverityRules.DisplayName%", RulesCategory, defaultValue: true) + { + Description = "%devskim.rules.enableImportantSeverityRules.Description%", + }; + + [VisualStudioContribution] + internal static Setting.Boolean EnableModerateSeverityRules { get; } = new("devskimEnableModerateSeverityRules", "%devskim.rules.enableModerateSeverityRules.DisplayName%", RulesCategory, defaultValue: true) + { + Description = "%devskim.rules.enableModerateSeverityRules.Description%", + }; + + [VisualStudioContribution] + internal static Setting.Boolean EnableManualReviewSeverityRules { get; } = new("devskimEnableManualReviewSeverityRules", "%devskim.rules.enableManualReviewSeverityRules.DisplayName%", RulesCategory, defaultValue: true) + { + Description = "%devskim.rules.enableManualReviewSeverityRules.Description%", + }; + + [VisualStudioContribution] + internal static Setting.Boolean EnableBestPracticeSeverityRules { get; } = new("devskimEnableBestPracticeSeverityRules", "%devskim.rules.enableBestPracticeSeverityRules.DisplayName%", RulesCategory, defaultValue: true) + { + Description = "%devskim.rules.enableBestPracticeSeverityRules.Description%", + }; + + #endregion + + #region Rules Settings - Confidence + + [VisualStudioContribution] + internal static Setting.Boolean EnableHighConfidenceRules { get; } = new("devskimEnableHighConfidenceRules", "%devskim.rules.enableHighConfidenceRules.DisplayName%", RulesCategory, defaultValue: true) + { + Description = "%devskim.rules.enableHighConfidenceRules.Description%", + }; + + [VisualStudioContribution] + internal static Setting.Boolean EnableMediumConfidenceRules { get; } = new("devskimEnableMediumConfidenceRules", "%devskim.rules.enableMediumConfidenceRules.DisplayName%", RulesCategory, defaultValue: true) + { + Description = "%devskim.rules.enableMediumConfidenceRules.Description%", + }; + + [VisualStudioContribution] + internal static Setting.Boolean EnableLowConfidenceRules { get; } = new("devskimEnableLowConfidenceRules", "%devskim.rules.enableLowConfidenceRules.DisplayName%", RulesCategory, defaultValue: false) + { + Description = "%devskim.rules.enableLowConfidenceRules.Description%", + }; + + #endregion + + #region Rules Settings - Paths and Configuration + + [VisualStudioContribution] + internal static Setting.Boolean IgnoreDefaultRules { get; } = new("devskimIgnoreDefaultRules", "%devskim.rules.ignoreDefaultRules.DisplayName%", RulesCategory, defaultValue: false) + { + Description = "%devskim.rules.ignoreDefaultRules.Description%", + }; + + [VisualStudioContribution] + internal static Setting.String CustomRulesPaths { get; } = new("devskimCustomRulesPaths", "%devskim.rules.customRulesPaths.DisplayName%", RulesCategory, defaultValue: "") + { + Description = "%devskim.rules.customRulesPaths.Description%", + }; + + [VisualStudioContribution] + internal static Setting.String CustomLanguagesPath { get; } = new("devskimCustomLanguagesPath", "%devskim.rules.customLanguagesPath.DisplayName%", RulesCategory, defaultValue: "") + { + Description = "%devskim.rules.customLanguagesPath.Description%", + }; + + [VisualStudioContribution] + internal static Setting.String CustomCommentsPath { get; } = new("devskimCustomCommentsPath", "%devskim.rules.customCommentsPath.DisplayName%", RulesCategory, defaultValue: "") + { + Description = "%devskim.rules.customCommentsPath.Description%", + }; + + [VisualStudioContribution] + internal static Setting.String GuidanceBaseURL { get; } = new("devskimGuidanceBaseURL", "%devskim.rules.guidanceBaseURL.DisplayName%", RulesCategory, defaultValue: "https://github.com/microsoft/devskim/tree/main/guidance") + { + Description = "%devskim.rules.guidanceBaseURL.Description%", + }; + + #endregion + + #region Suppressions Settings + + [VisualStudioContribution] + internal static Setting.String SuppressionCommentStyle { get; } = new("devskimSuppressionCommentStyle", "%devskim.suppressions.suppressionCommentStyle.DisplayName%", SuppressionsCategory, defaultValue: "Line") + { + Description = "%devskim.suppressions.suppressionCommentStyle.Description%", + }; + + [VisualStudioContribution] + internal static Setting.String ManualReviewerName { get; } = new("devskimManualReviewerName", "%devskim.suppressions.manualReviewerName.DisplayName%", SuppressionsCategory, defaultValue: "") + { + Description = "%devskim.suppressions.manualReviewerName.Description%", + }; + + [VisualStudioContribution] + internal static Setting.Integer SuppressionDurationInDays { get; } = new("devskimSuppressionDurationInDays", "%devskim.suppressions.suppressionDurationInDays.DisplayName%", SuppressionsCategory, defaultValue: 30) + { + Description = "%devskim.suppressions.suppressionDurationInDays.Description%", + }; + + #endregion + + #region Triggers Settings + + [VisualStudioContribution] + internal static Setting.Boolean ScanOnOpen { get; } = new("devskimScanOnOpen", "%devskim.triggers.scanOnOpen.DisplayName%", TriggersCategory, defaultValue: true) + { + Description = "%devskim.triggers.scanOnOpen.Description%", + }; + + [VisualStudioContribution] + internal static Setting.Boolean ScanOnSave { get; } = new("devskimScanOnSave", "%devskim.triggers.scanOnSave.DisplayName%", TriggersCategory, defaultValue: true) + { + Description = "%devskim.triggers.scanOnSave.Description%", + }; + + [VisualStudioContribution] + internal static Setting.Boolean ScanOnChange { get; } = new("devskimScanOnChange", "%devskim.triggers.scanOnChange.DisplayName%", TriggersCategory, defaultValue: true) + { + Description = "%devskim.triggers.scanOnChange.Description%", + }; + + [VisualStudioContribution] + internal static Setting.Boolean RemoveFindingsOnClose { get; } = new("devskimRemoveFindingsOnClose", "%devskim.triggers.removeFindingsOnClose.DisplayName%", TriggersCategory, defaultValue: true) + { + Description = "%devskim.triggers.removeFindingsOnClose.Description%", + }; + + #endregion + + #region Ignores Settings + + [VisualStudioContribution] + internal static Setting.String IgnoreRulesList { get; } = new("devskimIgnoreRulesList", "%devskim.ignores.ignoreRulesList.DisplayName%", IgnoresCategory, defaultValue: "") + { + Description = "%devskim.ignores.ignoreRulesList.Description%", + }; + + [VisualStudioContribution] + internal static Setting.String IgnoreFiles { get; } = new("devskimIgnoreFiles", "%devskim.ignores.ignoreFiles.DisplayName%", IgnoresCategory, defaultValue: "") + { + Description = "%devskim.ignores.ignoreFiles.Description%", + }; + + #endregion + + #region Diagnostics Settings + + [VisualStudioContribution] + internal static SettingCategory DiagnosticsCategory { get; } = new("devskimDiagnostics", "%devskim.diagnostics.DisplayName%", DevSkimCategory) + { + Description = "%devskim.diagnostics.Description%", + }; + + [VisualStudioContribution] + internal static Setting.Boolean EnableFileLogging { get; } = new("devskimEnableFileLogging", "%devskim.diagnostics.enableFileLogging.DisplayName%", DiagnosticsCategory, defaultValue: false) + { + Description = "%devskim.diagnostics.enableFileLogging.Description%", + }; + + #endregion +} diff --git a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/Microsoft.DevSkim.VisualStudio.csproj b/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/Microsoft.DevSkim.VisualStudio.csproj index 30a2d0ed..fe6e3bf6 100644 --- a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/Microsoft.DevSkim.VisualStudio.csproj +++ b/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/Microsoft.DevSkim.VisualStudio.csproj @@ -18,6 +18,11 @@ + + + + + From b5cb8080048afeee61e337325fb42cf8d735d196 Mon Sep 17 00:00:00 2001 From: Giulia Stocco <98900+gfs@users.noreply.github.com> Date: Thu, 5 Feb 2026 16:21:08 -0800 Subject: [PATCH 07/19] Delete DevSkim-DotNet/devskim-server-log20260205.txt --- DevSkim-DotNet/devskim-server-log20260205.txt | 201 ------------------ 1 file changed, 201 deletions(-) delete mode 100644 DevSkim-DotNet/devskim-server-log20260205.txt diff --git a/DevSkim-DotNet/devskim-server-log20260205.txt b/DevSkim-DotNet/devskim-server-log20260205.txt deleted file mode 100644 index dbafad2f..00000000 --- a/DevSkim-DotNet/devskim-server-log20260205.txt +++ /dev/null @@ -1,201 +0,0 @@ -2026-02-05 12:13:58.280 -08:00 [DBG] Configuring server... -2026-02-05 12:13:58.971 -08:00 [DBG] Finding descriptors for initialize -2026-02-05 12:13:59.087 -08:00 [DBG] Queueing "Serial":initialize:2 request for processing -2026-02-05 12:13:59.101 -08:00 [DBG] Starting: Processing request initialize 2 -2026-02-05 12:13:59.106 -08:00 [DBG] Starting: Routing Request (2) initialize -2026-02-05 12:13:59.111 -08:00 [VRB] Converting params for Request (2) initialize to OmniSharp.Extensions.LanguageServer.Protocol.Models.InternalInitializeParams -2026-02-05 12:13:59.112 -08:00 [VRB] Converting params for Notification initialize to OmniSharp.Extensions.LanguageServer.Protocol.Models.InternalInitializeParams -2026-02-05 12:13:59.335 -08:00 [DBG] Server is starting... -2026-02-05 12:13:59.380 -08:00 [DBG] Server started -2026-02-05 12:13:59.383 -08:00 [VRB] Response value was OmniSharp.Extensions.LanguageServer.Protocol.Models.InitializeResult -2026-02-05 12:13:59.384 -08:00 [DBG] Finished: Routing Request (2) initialize in 278ms -2026-02-05 12:13:59.385 -08:00 [DBG] Finished: Processing request initialize 2 in 281ms -2026-02-05 12:13:59.430 -08:00 [DBG] Finding descriptors for initialized -2026-02-05 12:13:59.431 -08:00 [DBG] Queueing "Serial":initialized request for processing -2026-02-05 12:13:59.433 -08:00 [DBG] Starting: Processing notification initialized -2026-02-05 12:13:59.435 -08:00 [DBG] Starting: Routing Notification initialized -2026-02-05 12:13:59.435 -08:00 [VRB] Converting params for Notification initialized to OmniSharp.Extensions.LanguageServer.Protocol.Models.InitializedParams -2026-02-05 12:13:59.460 -08:00 [DBG] Beginning server routines... -2026-02-05 12:13:59.461 -08:00 [DBG] Listening for client events... -2026-02-05 12:13:59.478 -08:00 [DBG] Finished: Routing Notification initialized in 43ms -2026-02-05 12:13:59.479 -08:00 [DBG] Finished: Processing notification initialized in 45ms -2026-02-05 12:13:59.496 -08:00 [ERR] Unable to get configuration from client! -OmniSharp.Extensions.JsonRpc.Server.MethodNotSupportedException: Method not found: 'workspace/configuration'. - at OmniSharp.Extensions.JsonRpc.ResponseRouter.ResponseRouterReturnsImpl.Returning[TResponse](CancellationToken cancellationToken) -2026-02-05 12:13:59.516 -08:00 [ERR] Unable to get configuration from client! -OmniSharp.Extensions.JsonRpc.Server.MethodNotSupportedException: Method not found: 'workspace/configuration'. - at OmniSharp.Extensions.JsonRpc.ResponseRouter.ResponseRouterReturnsImpl.Returning[TResponse](CancellationToken cancellationToken) -2026-02-05 12:14:03.026 -08:00 [DBG] Finding descriptors for devskim/setSettings -2026-02-05 12:14:03.030 -08:00 [DBG] Swapping from "Serial" to "Parallel" -2026-02-05 12:14:03.030 -08:00 [DBG] Completing existing request process type "Serial" -2026-02-05 12:14:03.032 -08:00 [DBG] Queueing "Parallel":devskim/setSettings request for processing -2026-02-05 12:14:03.032 -08:00 [DBG] Starting: Processing notification devskim/setSettings -2026-02-05 12:14:03.032 -08:00 [DBG] Starting: Routing Notification devskim/setSettings -2026-02-05 12:14:03.032 -08:00 [VRB] Converting params for Notification devskim/setSettings to DevSkim.LanguageServer.DevSkimSetLanguageServerSettingsParams -2026-02-05 12:14:03.077 -08:00 [DBG] Finished: Routing Notification devskim/setSettings in 45ms -2026-02-05 12:14:03.078 -08:00 [DBG] Finished: Processing notification devskim/setSettings in 45ms -2026-02-05 12:14:03.078 -08:00 [DBG] Finding descriptors for textDocument/didOpen -2026-02-05 12:14:03.083 -08:00 [VRB] Created attribute csharp::file:///c:/Users/gstocco/Repos/DevSkim/DevSkim-DotNet/Microsoft.DevSkim.LanguageProtoInterop/PortableScannerSettings.cs -2026-02-05 12:14:03.084 -08:00 [VRB] Looking for handler for descriptors textDocument/didOpen -2026-02-05 12:14:03.084 -08:00 [VRB] Checking handler textDocument/didOpen:DevSkim.LanguageServer.TextDocumentSyncHandler -2026-02-05 12:14:03.084 -08:00 [VRB] Registration options OmniSharp.Extensions.LanguageServer.Protocol.Models.TextDocumentOpenRegistrationOptions -2026-02-05 12:14:03.084 -08:00 [VRB] Document Selector [batch], [c], [cpp], [csharp], [vb], [python], [javascript], [javascriptreact], [typescript], [typescriptreact], [coffeescript], [java], [objective-c], [swift], [perl], [perl6], [ruby], [lua], [groovy], [go], [rust], [jade], [clojure], [r], [yaml], [fsharp], [php], [powershell], [shellscript], [sql], [plaintext], [.config], [packages.config], [CSharp Project], [cobol], [json], [xml] -2026-02-05 12:14:03.085 -08:00 [VRB] Handler Selected: DevSkim.LanguageServer.TextDocumentSyncHandler via [batch], [c], [cpp], [csharp], [vb], [python], [javascript], [javascriptreact], [typescript], [typescriptreact], [coffeescript], [java], [objective-c], [swift], [perl], [perl6], [ruby], [lua], [groovy], [go], [rust], [jade], [clojure], [r], [yaml], [fsharp], [php], [powershell], [shellscript], [sql], [plaintext], [.config], [packages.config], [CSharp Project], [cobol], [json], [xml] (targeting OmniSharp.Extensions.JsonRpc.IJsonRpcNotificationHandler`1[[OmniSharp.Extensions.LanguageServer.Protocol.Models.DidOpenTextDocumentParams, OmniSharp.Extensions.LanguageProtocol, Version=0.19.0.0, Culture=neutral, PublicKeyToken=6d868dff454e6022]]) -2026-02-05 12:14:03.085 -08:00 [DBG] Swapping from "Parallel" to "Serial" -2026-02-05 12:14:03.085 -08:00 [DBG] Cancelling any outstanding requests (switch from parallel to serial) -2026-02-05 12:14:03.086 -08:00 [DBG] Completing existing request process type "Parallel" -2026-02-05 12:14:03.086 -08:00 [DBG] Queueing "Serial":textDocument/didOpen request for processing -2026-02-05 12:14:03.086 -08:00 [DBG] Starting: Processing notification textDocument/didOpen -2026-02-05 12:14:03.086 -08:00 [DBG] Starting: Routing Notification textDocument/didOpen -2026-02-05 12:14:03.086 -08:00 [VRB] Converting params for Notification textDocument/didOpen to OmniSharp.Extensions.LanguageServer.Protocol.Models.DidOpenTextDocumentParams -2026-02-05 12:14:03.090 -08:00 [DBG] TextDocumentSyncHandler.cs: DidOpenTextDocumentParams -2026-02-05 12:14:03.095 -08:00 [DBG] Processing document: /C:/Users/gstocco/Repos/DevSkim/DevSkim-DotNet/Microsoft.DevSkim.LanguageProtoInterop/PortableScannerSettings.cs -2026-02-05 12:14:03.138 -08:00 [DBG] Adding 0 issues to diagnostics -2026-02-05 12:14:03.139 -08:00 [DBG] Publishing diagnostics... -2026-02-05 12:14:03.152 -08:00 [DBG] Finished: Routing Notification textDocument/didOpen in 66ms -2026-02-05 12:14:03.153 -08:00 [DBG] Finished: Processing notification textDocument/didOpen in 66ms -2026-02-05 12:14:03.205 -08:00 [DBG] Finding descriptors for NotificationReceived -2026-02-05 12:14:03.205 -08:00 [DBG] Unable to find NotificationReceived, methods found include $/setTrace:OmniSharp.Extensions.LanguageServer.Server.Logging.LanguageServerLoggingManager, textDocument/didChange:DevSkim.LanguageServer.TextDocumentSyncHandler, devskim/setSettings:DevSkim.LanguageServer.VisualStudioConfigurationHandler, workspace/didChangeConfiguration:DevSkim.LanguageServer.DidChangeConfigurationHandler, window/workDoneProgress/cancel:OmniSharp.Extensions.LanguageServer.Protocol.Server.WorkDone.LanguageServerWorkDoneManager, workspace/didChangeWorkspaceFolders:OmniSharp.Extensions.LanguageServer.Server.LanguageServerWorkspaceFolderManager, exit:OmniSharp.Extensions.LanguageServer.Server.LanguageServer, initialize:OmniSharp.Extensions.LanguageServer.Server.LanguageServer, $/progress:OmniSharp.Extensions.LanguageServer.Protocol.Progress.ProgressManager, initialized:OmniSharp.Extensions.LanguageServer.Server.LanguageServer, textDocument/didSave:DevSkim.LanguageServer.TextDocumentSyncHandler, shutdown:OmniSharp.Extensions.LanguageServer.Server.LanguageServer, textDocument/didOpen:DevSkim.LanguageServer.TextDocumentSyncHandler, textDocument/didClose:DevSkim.LanguageServer.TextDocumentSyncHandler -2026-02-05 12:14:03.205 -08:00 [DBG] Notification handler was not found (or not setup) NotificationReceived -2026-02-05 12:14:15.683 -08:00 [DBG] Finding descriptors for textDocument/didSave -2026-02-05 12:14:15.689 -08:00 [VRB] Found attributes 1, ["csharp::file:///c:/Users/gstocco/Repos/DevSkim/DevSkim-DotNet/Microsoft.DevSkim.LanguageProtoInterop/PortableScannerSettings.cs"] -2026-02-05 12:14:15.690 -08:00 [VRB] Looking for handler for descriptors textDocument/didSave -2026-02-05 12:14:15.690 -08:00 [VRB] Checking handler textDocument/didSave:DevSkim.LanguageServer.TextDocumentSyncHandler -2026-02-05 12:14:15.690 -08:00 [VRB] Registration options OmniSharp.Extensions.LanguageServer.Protocol.Models.TextDocumentSaveRegistrationOptions -2026-02-05 12:14:15.690 -08:00 [VRB] Document Selector [batch], [c], [cpp], [csharp], [vb], [python], [javascript], [javascriptreact], [typescript], [typescriptreact], [coffeescript], [java], [objective-c], [swift], [perl], [perl6], [ruby], [lua], [groovy], [go], [rust], [jade], [clojure], [r], [yaml], [fsharp], [php], [powershell], [shellscript], [sql], [plaintext], [.config], [packages.config], [CSharp Project], [cobol], [json], [xml] -2026-02-05 12:14:15.690 -08:00 [VRB] Handler Selected: DevSkim.LanguageServer.TextDocumentSyncHandler via [batch], [c], [cpp], [csharp], [vb], [python], [javascript], [javascriptreact], [typescript], [typescriptreact], [coffeescript], [java], [objective-c], [swift], [perl], [perl6], [ruby], [lua], [groovy], [go], [rust], [jade], [clojure], [r], [yaml], [fsharp], [php], [powershell], [shellscript], [sql], [plaintext], [.config], [packages.config], [CSharp Project], [cobol], [json], [xml] (targeting OmniSharp.Extensions.JsonRpc.IJsonRpcNotificationHandler`1[[OmniSharp.Extensions.LanguageServer.Protocol.Models.DidSaveTextDocumentParams, OmniSharp.Extensions.LanguageProtocol, Version=0.19.0.0, Culture=neutral, PublicKeyToken=6d868dff454e6022]]) -2026-02-05 12:14:15.690 -08:00 [DBG] Queueing "Serial":textDocument/didSave request for processing -2026-02-05 12:14:15.691 -08:00 [DBG] Starting: Processing notification textDocument/didSave -2026-02-05 12:14:15.691 -08:00 [DBG] Starting: Routing Notification textDocument/didSave -2026-02-05 12:14:15.691 -08:00 [VRB] Converting params for Notification textDocument/didSave to OmniSharp.Extensions.LanguageServer.Protocol.Models.DidSaveTextDocumentParams -2026-02-05 12:14:15.693 -08:00 [DBG] TextDocumentSyncHandler.cs: DidSaveTextDocumentParams -2026-02-05 12:14:15.693 -08:00 [DBG] No content found -2026-02-05 12:14:15.693 -08:00 [DBG] Finished: Routing Notification textDocument/didSave in 2ms -2026-02-05 12:14:15.693 -08:00 [DBG] Finished: Processing notification textDocument/didSave in 2ms -2026-02-05 12:14:23.823 -08:00 [DBG] Finding descriptors for textDocument/didSave -2026-02-05 12:14:23.823 -08:00 [VRB] Found attributes 1, ["csharp::file:///c:/Users/gstocco/Repos/DevSkim/DevSkim-DotNet/Microsoft.DevSkim.LanguageProtoInterop/PortableScannerSettings.cs"] -2026-02-05 12:14:23.823 -08:00 [VRB] Looking for handler for descriptors textDocument/didSave -2026-02-05 12:14:23.823 -08:00 [VRB] Checking handler textDocument/didSave:DevSkim.LanguageServer.TextDocumentSyncHandler -2026-02-05 12:14:23.823 -08:00 [VRB] Registration options OmniSharp.Extensions.LanguageServer.Protocol.Models.TextDocumentSaveRegistrationOptions -2026-02-05 12:14:23.823 -08:00 [VRB] Document Selector [batch], [c], [cpp], [csharp], [vb], [python], [javascript], [javascriptreact], [typescript], [typescriptreact], [coffeescript], [java], [objective-c], [swift], [perl], [perl6], [ruby], [lua], [groovy], [go], [rust], [jade], [clojure], [r], [yaml], [fsharp], [php], [powershell], [shellscript], [sql], [plaintext], [.config], [packages.config], [CSharp Project], [cobol], [json], [xml] -2026-02-05 12:14:23.823 -08:00 [VRB] Handler Selected: DevSkim.LanguageServer.TextDocumentSyncHandler via [batch], [c], [cpp], [csharp], [vb], [python], [javascript], [javascriptreact], [typescript], [typescriptreact], [coffeescript], [java], [objective-c], [swift], [perl], [perl6], [ruby], [lua], [groovy], [go], [rust], [jade], [clojure], [r], [yaml], [fsharp], [php], [powershell], [shellscript], [sql], [plaintext], [.config], [packages.config], [CSharp Project], [cobol], [json], [xml] (targeting OmniSharp.Extensions.JsonRpc.IJsonRpcNotificationHandler`1[[OmniSharp.Extensions.LanguageServer.Protocol.Models.DidSaveTextDocumentParams, OmniSharp.Extensions.LanguageProtocol, Version=0.19.0.0, Culture=neutral, PublicKeyToken=6d868dff454e6022]]) -2026-02-05 12:14:23.823 -08:00 [DBG] Queueing "Serial":textDocument/didSave request for processing -2026-02-05 12:14:23.823 -08:00 [DBG] Starting: Processing notification textDocument/didSave -2026-02-05 12:14:23.823 -08:00 [DBG] Starting: Routing Notification textDocument/didSave -2026-02-05 12:14:23.824 -08:00 [VRB] Converting params for Notification textDocument/didSave to OmniSharp.Extensions.LanguageServer.Protocol.Models.DidSaveTextDocumentParams -2026-02-05 12:14:23.828 -08:00 [DBG] TextDocumentSyncHandler.cs: DidSaveTextDocumentParams -2026-02-05 12:14:23.828 -08:00 [DBG] No content found -2026-02-05 12:14:23.828 -08:00 [DBG] Finished: Routing Notification textDocument/didSave in 4ms -2026-02-05 12:14:23.829 -08:00 [DBG] Finished: Processing notification textDocument/didSave in 5ms -2026-02-05 12:14:26.054 -08:00 [DBG] Finding descriptors for textDocument/didClose -2026-02-05 12:14:26.055 -08:00 [VRB] Found attributes 1, ["csharp::file:///c:/Users/gstocco/Repos/DevSkim/DevSkim-DotNet/Microsoft.DevSkim.LanguageProtoInterop/PortableScannerSettings.cs"] -2026-02-05 12:14:26.055 -08:00 [VRB] Looking for handler for descriptors textDocument/didClose -2026-02-05 12:14:26.055 -08:00 [VRB] Checking handler textDocument/didClose:DevSkim.LanguageServer.TextDocumentSyncHandler -2026-02-05 12:14:26.055 -08:00 [VRB] Registration options OmniSharp.Extensions.LanguageServer.Protocol.Models.TextDocumentCloseRegistrationOptions -2026-02-05 12:14:26.055 -08:00 [VRB] Document Selector [batch], [c], [cpp], [csharp], [vb], [python], [javascript], [javascriptreact], [typescript], [typescriptreact], [coffeescript], [java], [objective-c], [swift], [perl], [perl6], [ruby], [lua], [groovy], [go], [rust], [jade], [clojure], [r], [yaml], [fsharp], [php], [powershell], [shellscript], [sql], [plaintext], [.config], [packages.config], [CSharp Project], [cobol], [json], [xml] -2026-02-05 12:14:26.055 -08:00 [VRB] Handler Selected: DevSkim.LanguageServer.TextDocumentSyncHandler via [batch], [c], [cpp], [csharp], [vb], [python], [javascript], [javascriptreact], [typescript], [typescriptreact], [coffeescript], [java], [objective-c], [swift], [perl], [perl6], [ruby], [lua], [groovy], [go], [rust], [jade], [clojure], [r], [yaml], [fsharp], [php], [powershell], [shellscript], [sql], [plaintext], [.config], [packages.config], [CSharp Project], [cobol], [json], [xml] (targeting OmniSharp.Extensions.JsonRpc.IJsonRpcNotificationHandler`1[[OmniSharp.Extensions.LanguageServer.Protocol.Models.DidCloseTextDocumentParams, OmniSharp.Extensions.LanguageProtocol, Version=0.19.0.0, Culture=neutral, PublicKeyToken=6d868dff454e6022]]) -2026-02-05 12:14:26.055 -08:00 [DBG] Swapping from "Serial" to "Parallel" -2026-02-05 12:14:26.055 -08:00 [DBG] Completing existing request process type "Serial" -2026-02-05 12:14:26.055 -08:00 [DBG] Queueing "Parallel":textDocument/didClose request for processing -2026-02-05 12:14:26.055 -08:00 [DBG] Starting: Processing notification textDocument/didClose -2026-02-05 12:14:26.055 -08:00 [DBG] Starting: Routing Notification textDocument/didClose -2026-02-05 12:14:26.056 -08:00 [VRB] Converting params for Notification textDocument/didClose to OmniSharp.Extensions.LanguageServer.Protocol.Models.DidCloseTextDocumentParams -2026-02-05 12:14:26.057 -08:00 [DBG] TextDocumentSyncHandler.cs: DidCloseTextDocumentParams -2026-02-05 12:14:26.058 -08:00 [DBG] Finished: Routing Notification textDocument/didClose in 2ms -2026-02-05 12:14:26.058 -08:00 [DBG] Finished: Processing notification textDocument/didClose in 2ms -2026-02-05 12:14:26.059 -08:00 [DBG] Finding descriptors for NotificationReceived -2026-02-05 12:14:26.059 -08:00 [DBG] Unable to find NotificationReceived, methods found include $/setTrace:OmniSharp.Extensions.LanguageServer.Server.Logging.LanguageServerLoggingManager, textDocument/didChange:DevSkim.LanguageServer.TextDocumentSyncHandler, devskim/setSettings:DevSkim.LanguageServer.VisualStudioConfigurationHandler, workspace/didChangeConfiguration:DevSkim.LanguageServer.DidChangeConfigurationHandler, window/workDoneProgress/cancel:OmniSharp.Extensions.LanguageServer.Protocol.Server.WorkDone.LanguageServerWorkDoneManager, workspace/didChangeWorkspaceFolders:OmniSharp.Extensions.LanguageServer.Server.LanguageServerWorkspaceFolderManager, exit:OmniSharp.Extensions.LanguageServer.Server.LanguageServer, initialize:OmniSharp.Extensions.LanguageServer.Server.LanguageServer, $/progress:OmniSharp.Extensions.LanguageServer.Protocol.Progress.ProgressManager, initialized:OmniSharp.Extensions.LanguageServer.Server.LanguageServer, textDocument/didSave:DevSkim.LanguageServer.TextDocumentSyncHandler, shutdown:OmniSharp.Extensions.LanguageServer.Server.LanguageServer, textDocument/didOpen:DevSkim.LanguageServer.TextDocumentSyncHandler, textDocument/didClose:DevSkim.LanguageServer.TextDocumentSyncHandler -2026-02-05 12:14:26.059 -08:00 [DBG] Notification handler was not found (or not setup) NotificationReceived -2026-02-05 12:19:32.845 -08:00 [DBG] Configuring server... -2026-02-05 12:19:33.489 -08:00 [DBG] Finding descriptors for initialize -2026-02-05 12:19:33.593 -08:00 [DBG] Queueing "Serial":initialize:2 request for processing -2026-02-05 12:19:33.609 -08:00 [DBG] Starting: Processing request initialize 2 -2026-02-05 12:19:33.614 -08:00 [DBG] Starting: Routing Request (2) initialize -2026-02-05 12:19:33.619 -08:00 [VRB] Converting params for Request (2) initialize to OmniSharp.Extensions.LanguageServer.Protocol.Models.InternalInitializeParams -2026-02-05 12:19:33.620 -08:00 [VRB] Converting params for Notification initialize to OmniSharp.Extensions.LanguageServer.Protocol.Models.InternalInitializeParams -2026-02-05 12:19:33.940 -08:00 [DBG] Server is starting... -2026-02-05 12:19:33.976 -08:00 [DBG] Server started -2026-02-05 12:19:33.979 -08:00 [VRB] Response value was OmniSharp.Extensions.LanguageServer.Protocol.Models.InitializeResult -2026-02-05 12:19:33.981 -08:00 [DBG] Finished: Routing Request (2) initialize in 367ms -2026-02-05 12:19:33.981 -08:00 [DBG] Finished: Processing request initialize 2 in 370ms -2026-02-05 12:19:34.028 -08:00 [DBG] Finding descriptors for initialized -2026-02-05 12:19:34.029 -08:00 [DBG] Queueing "Serial":initialized request for processing -2026-02-05 12:19:34.033 -08:00 [DBG] Starting: Processing notification initialized -2026-02-05 12:19:34.036 -08:00 [DBG] Starting: Routing Notification initialized -2026-02-05 12:19:34.036 -08:00 [VRB] Converting params for Notification initialized to OmniSharp.Extensions.LanguageServer.Protocol.Models.InitializedParams -2026-02-05 12:19:34.076 -08:00 [DBG] Beginning server routines... -2026-02-05 12:19:34.077 -08:00 [DBG] Listening for client events... -2026-02-05 12:19:34.101 -08:00 [DBG] Finished: Routing Notification initialized in 65ms -2026-02-05 12:19:34.102 -08:00 [DBG] Finished: Processing notification initialized in 68ms -2026-02-05 12:19:34.103 -08:00 [DBG] Finding descriptors for devskim/setSettings -2026-02-05 12:19:34.106 -08:00 [DBG] Swapping from "Serial" to "Parallel" -2026-02-05 12:19:34.106 -08:00 [DBG] Completing existing request process type "Serial" -2026-02-05 12:19:34.109 -08:00 [DBG] Queueing "Parallel":devskim/setSettings request for processing -2026-02-05 12:19:34.109 -08:00 [DBG] Starting: Processing notification devskim/setSettings -2026-02-05 12:19:34.109 -08:00 [DBG] Starting: Routing Notification devskim/setSettings -2026-02-05 12:19:34.109 -08:00 [VRB] Converting params for Notification devskim/setSettings to DevSkim.LanguageServer.DevSkimSetLanguageServerSettingsParams -2026-02-05 12:19:34.159 -08:00 [DBG] Finished: Routing Notification devskim/setSettings in 49ms -2026-02-05 12:19:34.159 -08:00 [DBG] Finished: Processing notification devskim/setSettings in 49ms -2026-02-05 12:19:34.159 -08:00 [DBG] Finding descriptors for textDocument/didOpen -2026-02-05 12:19:34.164 -08:00 [VRB] Created attribute csharp::file:///c:/Users/gstocco/Repos/DevSkim/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/StaticScannerSettings.cs -2026-02-05 12:19:34.165 -08:00 [VRB] Looking for handler for descriptors textDocument/didOpen -2026-02-05 12:19:34.166 -08:00 [VRB] Checking handler textDocument/didOpen:DevSkim.LanguageServer.TextDocumentSyncHandler -2026-02-05 12:19:34.166 -08:00 [VRB] Registration options OmniSharp.Extensions.LanguageServer.Protocol.Models.TextDocumentOpenRegistrationOptions -2026-02-05 12:19:34.166 -08:00 [VRB] Document Selector [batch], [c], [cpp], [csharp], [vb], [python], [javascript], [javascriptreact], [typescript], [typescriptreact], [coffeescript], [java], [objective-c], [swift], [perl], [perl6], [ruby], [lua], [groovy], [go], [rust], [jade], [clojure], [r], [yaml], [fsharp], [php], [powershell], [shellscript], [sql], [plaintext], [.config], [packages.config], [CSharp Project], [cobol], [json], [xml] -2026-02-05 12:19:34.166 -08:00 [VRB] Handler Selected: DevSkim.LanguageServer.TextDocumentSyncHandler via [batch], [c], [cpp], [csharp], [vb], [python], [javascript], [javascriptreact], [typescript], [typescriptreact], [coffeescript], [java], [objective-c], [swift], [perl], [perl6], [ruby], [lua], [groovy], [go], [rust], [jade], [clojure], [r], [yaml], [fsharp], [php], [powershell], [shellscript], [sql], [plaintext], [.config], [packages.config], [CSharp Project], [cobol], [json], [xml] (targeting OmniSharp.Extensions.JsonRpc.IJsonRpcNotificationHandler`1[[OmniSharp.Extensions.LanguageServer.Protocol.Models.DidOpenTextDocumentParams, OmniSharp.Extensions.LanguageProtocol, Version=0.19.0.0, Culture=neutral, PublicKeyToken=6d868dff454e6022]]) -2026-02-05 12:19:34.167 -08:00 [DBG] Swapping from "Parallel" to "Serial" -2026-02-05 12:19:34.167 -08:00 [DBG] Cancelling any outstanding requests (switch from parallel to serial) -2026-02-05 12:19:34.167 -08:00 [DBG] Completing existing request process type "Parallel" -2026-02-05 12:19:34.167 -08:00 [DBG] Queueing "Serial":textDocument/didOpen request for processing -2026-02-05 12:19:34.167 -08:00 [DBG] Starting: Processing notification textDocument/didOpen -2026-02-05 12:19:34.167 -08:00 [DBG] Starting: Routing Notification textDocument/didOpen -2026-02-05 12:19:34.167 -08:00 [VRB] Converting params for Notification textDocument/didOpen to OmniSharp.Extensions.LanguageServer.Protocol.Models.DidOpenTextDocumentParams -2026-02-05 12:19:34.170 -08:00 [DBG] TextDocumentSyncHandler.cs: DidOpenTextDocumentParams -2026-02-05 12:19:34.175 -08:00 [DBG] Processing document: /C:/Users/gstocco/Repos/DevSkim/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/StaticScannerSettings.cs -2026-02-05 12:19:34.194 -08:00 [ERR] Unable to get configuration from client! -OmniSharp.Extensions.JsonRpc.Server.MethodNotSupportedException: Method not found: 'workspace/configuration'. - at OmniSharp.Extensions.JsonRpc.ResponseRouter.ResponseRouterReturnsImpl.Returning[TResponse](CancellationToken cancellationToken) -2026-02-05 12:19:34.220 -08:00 [ERR] Unable to get configuration from client! -OmniSharp.Extensions.JsonRpc.Server.MethodNotSupportedException: Method not found: 'workspace/configuration'. - at OmniSharp.Extensions.JsonRpc.ResponseRouter.ResponseRouterReturnsImpl.Returning[TResponse](CancellationToken cancellationToken) -2026-02-05 12:19:34.220 -08:00 [DBG] Adding 0 issues to diagnostics -2026-02-05 12:19:34.220 -08:00 [DBG] Publishing diagnostics... -2026-02-05 12:19:34.232 -08:00 [DBG] Finished: Routing Notification textDocument/didOpen in 64ms -2026-02-05 12:19:34.232 -08:00 [DBG] Finished: Processing notification textDocument/didOpen in 65ms -2026-02-05 12:19:34.247 -08:00 [DBG] Finding descriptors for NotificationReceived -2026-02-05 12:19:34.248 -08:00 [DBG] Unable to find NotificationReceived, methods found include exit:OmniSharp.Extensions.LanguageServer.Server.LanguageServer, initialize:OmniSharp.Extensions.LanguageServer.Server.LanguageServer, textDocument/didSave:DevSkim.LanguageServer.TextDocumentSyncHandler, textDocument/didOpen:DevSkim.LanguageServer.TextDocumentSyncHandler, textDocument/didClose:DevSkim.LanguageServer.TextDocumentSyncHandler, window/workDoneProgress/cancel:OmniSharp.Extensions.LanguageServer.Protocol.Server.WorkDone.LanguageServerWorkDoneManager, shutdown:OmniSharp.Extensions.LanguageServer.Server.LanguageServer, $/progress:OmniSharp.Extensions.LanguageServer.Protocol.Progress.ProgressManager, workspace/didChangeConfiguration:DevSkim.LanguageServer.DidChangeConfigurationHandler, workspace/didChangeWorkspaceFolders:OmniSharp.Extensions.LanguageServer.Server.LanguageServerWorkspaceFolderManager, textDocument/didChange:DevSkim.LanguageServer.TextDocumentSyncHandler, $/setTrace:OmniSharp.Extensions.LanguageServer.Server.Logging.LanguageServerLoggingManager, devskim/setSettings:DevSkim.LanguageServer.VisualStudioConfigurationHandler, initialized:OmniSharp.Extensions.LanguageServer.Server.LanguageServer -2026-02-05 12:19:34.249 -08:00 [DBG] Notification handler was not found (or not setup) NotificationReceived -2026-02-05 12:19:47.195 -08:00 [DBG] Finding descriptors for textDocument/didSave -2026-02-05 12:19:47.202 -08:00 [VRB] Found attributes 1, ["csharp::file:///c:/Users/gstocco/Repos/DevSkim/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/StaticScannerSettings.cs"] -2026-02-05 12:19:47.203 -08:00 [VRB] Looking for handler for descriptors textDocument/didSave -2026-02-05 12:19:47.203 -08:00 [VRB] Checking handler textDocument/didSave:DevSkim.LanguageServer.TextDocumentSyncHandler -2026-02-05 12:19:47.203 -08:00 [VRB] Registration options OmniSharp.Extensions.LanguageServer.Protocol.Models.TextDocumentSaveRegistrationOptions -2026-02-05 12:19:47.203 -08:00 [VRB] Document Selector [batch], [c], [cpp], [csharp], [vb], [python], [javascript], [javascriptreact], [typescript], [typescriptreact], [coffeescript], [java], [objective-c], [swift], [perl], [perl6], [ruby], [lua], [groovy], [go], [rust], [jade], [clojure], [r], [yaml], [fsharp], [php], [powershell], [shellscript], [sql], [plaintext], [.config], [packages.config], [CSharp Project], [cobol], [json], [xml] -2026-02-05 12:19:47.203 -08:00 [VRB] Handler Selected: DevSkim.LanguageServer.TextDocumentSyncHandler via [batch], [c], [cpp], [csharp], [vb], [python], [javascript], [javascriptreact], [typescript], [typescriptreact], [coffeescript], [java], [objective-c], [swift], [perl], [perl6], [ruby], [lua], [groovy], [go], [rust], [jade], [clojure], [r], [yaml], [fsharp], [php], [powershell], [shellscript], [sql], [plaintext], [.config], [packages.config], [CSharp Project], [cobol], [json], [xml] (targeting OmniSharp.Extensions.JsonRpc.IJsonRpcNotificationHandler`1[[OmniSharp.Extensions.LanguageServer.Protocol.Models.DidSaveTextDocumentParams, OmniSharp.Extensions.LanguageProtocol, Version=0.19.0.0, Culture=neutral, PublicKeyToken=6d868dff454e6022]]) -2026-02-05 12:19:47.203 -08:00 [DBG] Queueing "Serial":textDocument/didSave request for processing -2026-02-05 12:19:47.203 -08:00 [DBG] Starting: Processing notification textDocument/didSave -2026-02-05 12:19:47.203 -08:00 [DBG] Starting: Routing Notification textDocument/didSave -2026-02-05 12:19:47.203 -08:00 [VRB] Converting params for Notification textDocument/didSave to OmniSharp.Extensions.LanguageServer.Protocol.Models.DidSaveTextDocumentParams -2026-02-05 12:19:47.206 -08:00 [DBG] TextDocumentSyncHandler.cs: DidSaveTextDocumentParams -2026-02-05 12:19:47.206 -08:00 [DBG] No content found -2026-02-05 12:19:47.206 -08:00 [DBG] Finished: Routing Notification textDocument/didSave in 2ms -2026-02-05 12:19:47.206 -08:00 [DBG] Finished: Processing notification textDocument/didSave in 2ms -2026-02-05 12:20:02.278 -08:00 [DBG] Finding descriptors for textDocument/didClose -2026-02-05 12:20:02.281 -08:00 [VRB] Found attributes 1, ["csharp::file:///c:/Users/gstocco/Repos/DevSkim/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/StaticScannerSettings.cs"] -2026-02-05 12:20:02.281 -08:00 [VRB] Looking for handler for descriptors textDocument/didClose -2026-02-05 12:20:02.281 -08:00 [VRB] Checking handler textDocument/didClose:DevSkim.LanguageServer.TextDocumentSyncHandler -2026-02-05 12:20:02.281 -08:00 [VRB] Registration options OmniSharp.Extensions.LanguageServer.Protocol.Models.TextDocumentCloseRegistrationOptions -2026-02-05 12:20:02.281 -08:00 [VRB] Document Selector [batch], [c], [cpp], [csharp], [vb], [python], [javascript], [javascriptreact], [typescript], [typescriptreact], [coffeescript], [java], [objective-c], [swift], [perl], [perl6], [ruby], [lua], [groovy], [go], [rust], [jade], [clojure], [r], [yaml], [fsharp], [php], [powershell], [shellscript], [sql], [plaintext], [.config], [packages.config], [CSharp Project], [cobol], [json], [xml] -2026-02-05 12:20:02.281 -08:00 [VRB] Handler Selected: DevSkim.LanguageServer.TextDocumentSyncHandler via [batch], [c], [cpp], [csharp], [vb], [python], [javascript], [javascriptreact], [typescript], [typescriptreact], [coffeescript], [java], [objective-c], [swift], [perl], [perl6], [ruby], [lua], [groovy], [go], [rust], [jade], [clojure], [r], [yaml], [fsharp], [php], [powershell], [shellscript], [sql], [plaintext], [.config], [packages.config], [CSharp Project], [cobol], [json], [xml] (targeting OmniSharp.Extensions.JsonRpc.IJsonRpcNotificationHandler`1[[OmniSharp.Extensions.LanguageServer.Protocol.Models.DidCloseTextDocumentParams, OmniSharp.Extensions.LanguageProtocol, Version=0.19.0.0, Culture=neutral, PublicKeyToken=6d868dff454e6022]]) -2026-02-05 12:20:02.281 -08:00 [DBG] Swapping from "Serial" to "Parallel" -2026-02-05 12:20:02.281 -08:00 [DBG] Completing existing request process type "Serial" -2026-02-05 12:20:02.281 -08:00 [DBG] Queueing "Parallel":textDocument/didClose request for processing -2026-02-05 12:20:02.281 -08:00 [DBG] Starting: Processing notification textDocument/didClose -2026-02-05 12:20:02.281 -08:00 [DBG] Starting: Routing Notification textDocument/didClose -2026-02-05 12:20:02.281 -08:00 [VRB] Converting params for Notification textDocument/didClose to OmniSharp.Extensions.LanguageServer.Protocol.Models.DidCloseTextDocumentParams -2026-02-05 12:20:02.283 -08:00 [DBG] TextDocumentSyncHandler.cs: DidCloseTextDocumentParams -2026-02-05 12:20:02.284 -08:00 [DBG] Finished: Routing Notification textDocument/didClose in 2ms -2026-02-05 12:20:02.284 -08:00 [DBG] Finished: Processing notification textDocument/didClose in 2ms -2026-02-05 12:20:02.286 -08:00 [DBG] Finding descriptors for NotificationReceived -2026-02-05 12:20:02.286 -08:00 [DBG] Unable to find NotificationReceived, methods found include exit:OmniSharp.Extensions.LanguageServer.Server.LanguageServer, initialize:OmniSharp.Extensions.LanguageServer.Server.LanguageServer, textDocument/didSave:DevSkim.LanguageServer.TextDocumentSyncHandler, textDocument/didOpen:DevSkim.LanguageServer.TextDocumentSyncHandler, textDocument/didClose:DevSkim.LanguageServer.TextDocumentSyncHandler, window/workDoneProgress/cancel:OmniSharp.Extensions.LanguageServer.Protocol.Server.WorkDone.LanguageServerWorkDoneManager, shutdown:OmniSharp.Extensions.LanguageServer.Server.LanguageServer, $/progress:OmniSharp.Extensions.LanguageServer.Protocol.Progress.ProgressManager, workspace/didChangeConfiguration:DevSkim.LanguageServer.DidChangeConfigurationHandler, workspace/didChangeWorkspaceFolders:OmniSharp.Extensions.LanguageServer.Server.LanguageServerWorkspaceFolderManager, textDocument/didChange:DevSkim.LanguageServer.TextDocumentSyncHandler, $/setTrace:OmniSharp.Extensions.LanguageServer.Server.Logging.LanguageServerLoggingManager, devskim/setSettings:DevSkim.LanguageServer.VisualStudioConfigurationHandler, initialized:OmniSharp.Extensions.LanguageServer.Server.LanguageServer -2026-02-05 12:20:02.286 -08:00 [DBG] Notification handler was not found (or not setup) NotificationReceived From 461db4d2dc88098566e9bdba294ef7fa8460a564 Mon Sep 17 00:00:00 2001 From: Giulia Stocco Date: Thu, 5 Feb 2026 16:23:52 -0800 Subject: [PATCH 08/19] Simplify diagnostic key - alraedy mapped in dictionary by uri no need to include in the key too --- .../Microsoft.DevSkim.LanguageServer/CodeActionHandler.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/CodeActionHandler.cs b/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/CodeActionHandler.cs index 6908be8a..fdc2b5ce 100644 --- a/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/CodeActionHandler.cs +++ b/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/CodeActionHandler.cs @@ -165,7 +165,7 @@ public static void ClearCodeFixes(DocumentUri uri) private static string CreateDiagnosticKey(string documentUri, Diagnostic diagnostic) { - return $"{documentUri}: {diagnostic.Message}, {diagnostic.Code}, {diagnostic.Range.Start.Line}, {diagnostic.Range.Start.Character}, {diagnostic.Range.End.Line}, {diagnostic.Range.End.Character}"; + return $"{diagnostic.Code}:{diagnostic.Range.Start.Line}:{diagnostic.Range.Start.Character}:{diagnostic.Range.End.Line}:{diagnostic.Range.End.Character}"; } } } From 61c2fc3ab4f0be9affb3b45485f277c07557b794 Mon Sep 17 00:00:00 2001 From: Giulia Stocco Date: Thu, 5 Feb 2026 16:29:08 -0800 Subject: [PATCH 09/19] Fix version stamping extension --- .../Microsoft.DevSkim.VisualStudio/DevSkimExtension.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/DevSkimExtension.cs b/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/DevSkimExtension.cs index fc6b1860..2d3317cd 100644 --- a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/DevSkimExtension.cs +++ b/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/DevSkimExtension.cs @@ -5,7 +5,6 @@ namespace Microsoft.DevSkim.VisualStudio; using global::Microsoft.Extensions.DependencyInjection; using global::Microsoft.VisualStudio.Extensibility; -using System.Security.Cryptography; /// /// Extension entry point for the DevSkim Visual Studio extension. @@ -18,7 +17,7 @@ internal class DevSkimExtension : Extension { Metadata = new( id: "Microsoft.DevSkim.VisualStudio.f3a2c5e8-7d9b-4a1c-8e6f-2b3d4c5e6f7a", - version: this.ExtensionAssemblyVersion, + version: new Version(ThisAssembly.AssemblyFileVersion), publisherName: "Microsoft DevLabs", displayName: "Microsoft DevSkim", description: "Security-focused static analysis tool for identifying vulnerabilities in source code."), From c9824e2fe37329a45e69e0a49e5eb6d67cba4811 Mon Sep 17 00:00:00 2001 From: Giulia Stocco Date: Thu, 5 Feb 2026 16:29:45 -0800 Subject: [PATCH 10/19] Remove custom fix handler (now redundant) --- .../TextDocumentSyncHandler.cs | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/TextDocumentSyncHandler.cs b/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/TextDocumentSyncHandler.cs index 5a57551d..50484fd3 100644 --- a/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/TextDocumentSyncHandler.cs +++ b/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/TextDocumentSyncHandler.cs @@ -121,14 +121,8 @@ private async Task GenerateDiagnosticsForTextDocumentAsync(string text, in Version = version }); - // Send custom notifications for VS Code backward compatibility - _facade.TextDocument.SendNotification(DevSkimMessages.FileVersion, new MappingsVersion() { version = version, fileName = uri.ToUri() }); - foreach (var mapping in codeFixes) - { - _facade.TextDocument.SendNotification(DevSkimMessages.CodeFixMapping, mapping); - } - - // Register code fixes with CodeActionHandler for standard LSP textDocument/codeAction (used by VS) + // Register code fixes with CodeActionHandler for standard LSP textDocument/codeAction + // This works for both VS and VS Code — no custom notifications needed _logger.LogDebug($"\tRegistering {codeFixes.Count} code fixes..."); foreach (var mapping in codeFixes) { From 8b9871dfacb3191b10041c6d5cdb1780e9a9bede Mon Sep 17 00:00:00 2001 From: Giulia Stocco Date: Thu, 5 Feb 2026 16:31:58 -0800 Subject: [PATCH 11/19] Fix metadata in VS Extension --- .../Microsoft.DevSkim.VisualStudio/DevSkimExtension.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/DevSkimExtension.cs b/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/DevSkimExtension.cs index 2d3317cd..e3fa50e4 100644 --- a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/DevSkimExtension.cs +++ b/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/DevSkimExtension.cs @@ -20,7 +20,11 @@ internal class DevSkimExtension : Extension version: new Version(ThisAssembly.AssemblyFileVersion), publisherName: "Microsoft DevLabs", displayName: "Microsoft DevSkim", - description: "Security-focused static analysis tool for identifying vulnerabilities in source code."), + description: "DevSkim is a highly configurable security linter with a default ruleset focused on common security related issues.") + { + MoreInfo = "https://github.com/Microsoft/DevSkim", + Tags = ["linter", "linters", "coding", "security", "static analysis"], + }, }; /// From 07325b3c10c5ed243d744114e20f6c3685e23dc0 Mon Sep 17 00:00:00 2001 From: Giulia Stocco <98900+gfs@users.noreply.github.com> Date: Thu, 5 Feb 2026 16:33:58 -0800 Subject: [PATCH 12/19] Update DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/Program.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/Program.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/Program.cs b/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/Program.cs index 4d953a37..ae700bb3 100644 --- a/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/Program.cs +++ b/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/Program.cs @@ -5,7 +5,6 @@ using OmniSharp.Extensions.LanguageServer.Protocol.Server.Capabilities; using OmniSharp.Extensions.LanguageServer.Server; using Serilog; -using System.Security.Cryptography; namespace DevSkim.LanguageServer; From f7e548e0a9668ad8db706000a36a6f1657a6595d Mon Sep 17 00:00:00 2001 From: Giulia Stocco Date: Thu, 5 Feb 2026 16:35:17 -0800 Subject: [PATCH 13/19] Remove inadvertent detection test change. --- DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/Program.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/Program.cs b/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/Program.cs index 4d953a37..a77d89e5 100644 --- a/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/Program.cs +++ b/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/Program.cs @@ -40,8 +40,6 @@ static async Task Main(string[] args) Log.Logger.Debug("Configuring server..."); IObserver workDone = null!; - var thing = "http://test.com"; - MD5 mD5 = MD5.Create(); OmniSharp.Extensions.LanguageServer.Server.LanguageServer server = await OmniSharp.Extensions.LanguageServer.Server.LanguageServer.From( options => options From 3d185d96d77e416a8e2ce77f44ee40b39ee72912 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 6 Feb 2026 00:36:53 +0000 Subject: [PATCH 14/19] Address code review feedback: use Select() and remove unused code - Replace foreach loop with .Select() in CodeActionHandler.cs - Remove unused MD5 and test code from Program.cs Co-authored-by: gfs <98900+gfs@users.noreply.github.com> --- .../CodeActionHandler.cs | 17 +++++++---------- .../Microsoft.DevSkim.LanguageServer/Program.cs | 2 -- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/CodeActionHandler.cs b/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/CodeActionHandler.cs index fdc2b5ce..b0c0d73a 100644 --- a/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/CodeActionHandler.cs +++ b/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/CodeActionHandler.cs @@ -64,17 +64,14 @@ public CodeActionRegistrationOptions GetRegistrationOptions(CodeActionCapability documentFixes.TryGetValue(diagnosticKey, out var fixes)) { _logger.LogDebug($"CodeActionHandler: Found {fixes.Count} fixes"); - foreach (var fix in fixes) + var codeActions = fixes.Select(fix => new CodeAction { - var codeAction = new CodeAction - { - Title = fix.friendlyString, - Kind = CodeActionKind.QuickFix, - Diagnostics = new Container(diagnostic), - Edit = CreateWorkspaceEdit(request.TextDocument.Uri, diagnostic, fix) - }; - result.Add(codeAction); - } + Title = fix.friendlyString, + Kind = CodeActionKind.QuickFix, + Diagnostics = new Container(diagnostic), + Edit = CreateWorkspaceEdit(request.TextDocument.Uri, diagnostic, fix) + }); + result.AddRange(codeActions); } } diff --git a/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/Program.cs b/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/Program.cs index ae700bb3..881273d2 100644 --- a/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/Program.cs +++ b/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/Program.cs @@ -39,8 +39,6 @@ static async Task Main(string[] args) Log.Logger.Debug("Configuring server..."); IObserver workDone = null!; - var thing = "http://test.com"; - MD5 mD5 = MD5.Create(); OmniSharp.Extensions.LanguageServer.Server.LanguageServer server = await OmniSharp.Extensions.LanguageServer.Server.LanguageServer.From( options => options From ed6cf52b612a74b3b6868b2cc07a713196f509fa Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 6 Feb 2026 00:41:05 +0000 Subject: [PATCH 15/19] Add documentation for P/Invoke usage in Job Object code - Added XML documentation explaining why native interop is necessary - Added code analysis suppression with justification - Changed method visibility to internal for better encapsulation Co-authored-by: gfs <98900+gfs@users.noreply.github.com> --- .../DevSkimLanguageServerProvider.cs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/DevSkimLanguageServerProvider.cs b/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/DevSkimLanguageServerProvider.cs index 6ea3c1bb..094b02d9 100644 --- a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/DevSkimLanguageServerProvider.cs +++ b/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/DevSkimLanguageServerProvider.cs @@ -426,16 +426,23 @@ private static string GetLanguageServerPath() return Path.Combine(extensionDirectory, "Server", "Microsoft.DevSkim.LanguageServer.exe"); } + /// + /// Native Windows API declarations for Job Object functionality. + /// Job Objects are required to ensure the language server child process is automatically + /// terminated when Visual Studio exits (even if killed unexpectedly). There is no managed + /// .NET equivalent for this Windows kernel feature, so P/Invoke is necessary. + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Interoperability", "SYSLIB1054:Use 'LibraryImportAttribute' instead of 'DllImportAttribute'", Justification = "DllImport is simpler for these few calls and works correctly")] private static class NativeMethods { [DllImport("kernel32.dll", CharSet = CharSet.Unicode)] - public static extern SafeWaitHandle CreateJobObject(IntPtr lpJobAttributes, string? lpName); + internal static extern SafeWaitHandle CreateJobObject(IntPtr lpJobAttributes, string? lpName); [DllImport("kernel32.dll")] - public static extern bool SetInformationJobObject(SafeHandle hJob, int jobObjectInfoClass, IntPtr lpJobObjectInfo, uint cbJobObjectInfoLength); + internal static extern bool SetInformationJobObject(SafeHandle hJob, int jobObjectInfoClass, IntPtr lpJobObjectInfo, uint cbJobObjectInfoLength); [DllImport("kernel32.dll")] - public static extern bool AssignProcessToJobObject(SafeHandle hJob, IntPtr hProcess); + internal static extern bool AssignProcessToJobObject(SafeHandle hJob, IntPtr hProcess); [StructLayout(LayoutKind.Sequential)] public struct JOBOBJECT_BASIC_LIMIT_INFORMATION From 331529ccdbf053d000a9f89c639f4ae57f2a6ee6 Mon Sep 17 00:00:00 2001 From: Giulia Stocco Date: Thu, 5 Feb 2026 16:49:18 -0800 Subject: [PATCH 16/19] Code review improvements/cleanup. --- .../CodeActionHandler.cs | 2 +- .../ConfigHelpers.cs | 8 ++++---- .../Microsoft.DevSkim.LanguageServer.csproj | 1 - .../Microsoft.DevSkim.LanguageServer/Program.cs | 17 +---------------- .../StaticScannerSettings.cs | 8 +++++--- .../DevSkimLanguageServerProvider.cs | 4 ++-- 6 files changed, 13 insertions(+), 27 deletions(-) diff --git a/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/CodeActionHandler.cs b/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/CodeActionHandler.cs index b0c0d73a..dd020737 100644 --- a/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/CodeActionHandler.cs +++ b/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/CodeActionHandler.cs @@ -71,7 +71,7 @@ public CodeActionRegistrationOptions GetRegistrationOptions(CodeActionCapability Diagnostics = new Container(diagnostic), Edit = CreateWorkspaceEdit(request.TextDocument.Uri, diagnostic, fix) }); - result.AddRange(codeActions); + result.AddRange(codeActions.Select(ca => new CommandOrCodeAction(ca))); } } diff --git a/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/ConfigHelpers.cs b/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/ConfigHelpers.cs index 747b069f..e715a3fe 100644 --- a/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/ConfigHelpers.cs +++ b/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/ConfigHelpers.cs @@ -50,9 +50,9 @@ internal static void SetScannerSettings(IConfiguration configuration) { fileIgnoreRegexes.Add(new Glob(potentialRegex)); } - catch (Exception e) + catch (Exception) { - // TODO: Log issue with provided regex + // Invalid glob pattern — skip } } StaticScannerSettings.IgnoreFiles = fileIgnoreRegexes; @@ -72,9 +72,9 @@ internal static void SetScannerSettings(IConfiguration configuration) { ruleSet.AddPath(path); } - catch (Exception e) + catch (Exception) { - // TODO: Log issue with provided path + // Invalid rule path — skip } } ruleSet = ruleSet.WithoutIds(StaticScannerSettings.IgnoreRuleIds); diff --git a/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/Microsoft.DevSkim.LanguageServer.csproj b/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/Microsoft.DevSkim.LanguageServer.csproj index 37ecea17..da5505c3 100644 --- a/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/Microsoft.DevSkim.LanguageServer.csproj +++ b/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/Microsoft.DevSkim.LanguageServer.csproj @@ -12,7 +12,6 @@ - diff --git a/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/Program.cs b/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/Program.cs index 881273d2..c6db08dd 100644 --- a/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/Program.cs +++ b/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/Program.cs @@ -1,5 +1,4 @@ -using CommandLine; -using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using OmniSharp.Extensions.LanguageServer.Protocol.Models; using OmniSharp.Extensions.LanguageServer.Protocol.Server.Capabilities; @@ -10,17 +9,9 @@ namespace DevSkim.LanguageServer; internal class Program { - public class Options - { - } - static async Task Main(string[] args) { #if DEBUG - //while (!Debugger.IsAttached) - //{ - // await Task.Delay(100); - //} Log.Logger = new LoggerConfiguration() .Enrich.FromLogContext() .WriteTo.File("devskim-server-log.txt", rollingInterval: RollingInterval.Day) @@ -30,12 +21,6 @@ static async Task Main(string[] args) // Creates a "silent" logger Log.Logger = new LoggerConfiguration().CreateLogger(); #endif - Options _options = new Options(); - Parser.Default.ParseArguments(args) - .WithParsed(o => - { - _options = o; - }); Log.Logger.Debug("Configuring server..."); IObserver workDone = null!; diff --git a/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/StaticScannerSettings.cs b/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/StaticScannerSettings.cs index 4f794853..c008d808 100644 --- a/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/StaticScannerSettings.cs +++ b/DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/StaticScannerSettings.cs @@ -43,9 +43,11 @@ private static DevSkimRuleProcessorOptions CreateDefaultOptions() public static void UpdateWith(PortableScannerSettings request) { SuppressionStyle = ToSuppressionStyle(request.SuppressionCommentStyle); - CustomRulePaths = request.CustomRulesPathsString.Split(','); - IgnoreRuleIds = request.IgnoreRulesListString.Split(','); - IgnoreFiles = request.IgnoreFilesString.Split(',').Select(x => new Glob(x)).ToArray(); + CustomRulePaths = request.CustomRulesPathsString.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries); + IgnoreRuleIds = request.IgnoreRulesListString.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries); + IgnoreFiles = request.IgnoreFilesString + .Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries) + .Select(x => new Glob(x)).ToArray(); ReviewerName = request.ManualReviewerName; SuppressionDuration = request.SuppressionDurationInDays; IgnoreDefaultRuleSet = request.IgnoreDefaultRules; diff --git a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/DevSkimLanguageServerProvider.cs b/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/DevSkimLanguageServerProvider.cs index 6ea3c1bb..6349a059 100644 --- a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/DevSkimLanguageServerProvider.cs +++ b/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/DevSkimLanguageServerProvider.cs @@ -32,7 +32,7 @@ internal class DevSkimLanguageServerProvider : LanguageServerProvider private Process? _serverProcess; private SafeHandle? _jobHandle; - private readonly List _settingsSubscriptions = []; + private readonly System.Collections.Concurrent.ConcurrentBag _settingsSubscriptions = []; private bool _initialPushDone; private CancellationTokenSource? _restartDebounce; @@ -148,7 +148,7 @@ protected override void Dispose(bool isDisposing) { sub.Dispose(); } - _settingsSubscriptions.Clear(); + while (_settingsSubscriptions.TryTake(out _)) { } _restartDebounce?.Cancel(); _restartDebounce?.Dispose(); StopServerProcess(); From 2d8c0a7ba9774d8aea810267bce66c81708fe3de Mon Sep 17 00:00:00 2001 From: Giulia Stocco Date: Thu, 5 Feb 2026 16:53:05 -0800 Subject: [PATCH 17/19] Update ESLint ecosystem to v9, resolving 6 of 8 npm deprecation warnings (eslint, @humanwhocodes/config-array, @humanwhocodes/object-schema, rimraf, glob@7, inflight). Remaining 2 warnings are transitive deps of @vscode/vsce. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Upgrade eslint ^8.8.0 → ^9.0.0 - Upgrade @typescript-eslint/eslint-plugin and parser ^5.10.1 → ^8.0.0 - Add typescript-eslint package for flat config support - Replace .eslintrc.js + .eslintignore with eslint.config.mjs - Update lint script to remove deprecated --ext flag - Auto-fix lint errors in client/devSkimFixer.ts (var→const, missing semicolon) - Remove stale eslint-disable directive in devskimSettings.ts --- DevSkim-VSCode-Plugin/.eslintignore | 5 - DevSkim-VSCode-Plugin/.eslintrc.js | 20 - .../client/common/devskimSettings.ts | 2 +- DevSkim-VSCode-Plugin/client/devSkimFixer.ts | 6 +- DevSkim-VSCode-Plugin/eslint.config.mjs | 19 + DevSkim-VSCode-Plugin/package-lock.json | 1611 ++++++++--------- DevSkim-VSCode-Plugin/package.json | 11 +- 7 files changed, 812 insertions(+), 862 deletions(-) delete mode 100644 DevSkim-VSCode-Plugin/.eslintignore delete mode 100644 DevSkim-VSCode-Plugin/.eslintrc.js create mode 100644 DevSkim-VSCode-Plugin/eslint.config.mjs diff --git a/DevSkim-VSCode-Plugin/.eslintignore b/DevSkim-VSCode-Plugin/.eslintignore deleted file mode 100644 index 63239eaf..00000000 --- a/DevSkim-VSCode-Plugin/.eslintignore +++ /dev/null @@ -1,5 +0,0 @@ -node_modules/** -client/node_modules/** -client/out/** -server/node_modules/** -server/out/** \ No newline at end of file diff --git a/DevSkim-VSCode-Plugin/.eslintrc.js b/DevSkim-VSCode-Plugin/.eslintrc.js deleted file mode 100644 index f660e395..00000000 --- a/DevSkim-VSCode-Plugin/.eslintrc.js +++ /dev/null @@ -1,20 +0,0 @@ -/**@type {import('eslint').Linter.Config} */ -// eslint-disable-next-line no-undef -module.exports = { - root: true, - parser: '@typescript-eslint/parser', - plugins: [ - '@typescript-eslint', - ], - extends: [ - 'eslint:recommended', - 'plugin:@typescript-eslint/recommended', - ], - rules: { - 'semi': [2, "always"], - '@typescript-eslint/no-unused-vars': 0, - '@typescript-eslint/no-explicit-any': 0, - '@typescript-eslint/explicit-module-boundary-types': 0, - '@typescript-eslint/no-non-null-assertion': 0, - } -}; \ No newline at end of file diff --git a/DevSkim-VSCode-Plugin/client/common/devskimSettings.ts b/DevSkim-VSCode-Plugin/client/common/devskimSettings.ts index 7635c4c7..6d766f84 100644 --- a/DevSkim-VSCode-Plugin/client/common/devskimSettings.ts +++ b/DevSkim-VSCode-Plugin/client/common/devskimSettings.ts @@ -1,4 +1,4 @@ -/* eslint-disable @typescript-eslint/no-inferrable-types */ + // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. diff --git a/DevSkim-VSCode-Plugin/client/devSkimFixer.ts b/DevSkim-VSCode-Plugin/client/devSkimFixer.ts index 95fcf040..dfe29100 100644 --- a/DevSkim-VSCode-Plugin/client/devSkimFixer.ts +++ b/DevSkim-VSCode-Plugin/client/devSkimFixer.ts @@ -16,8 +16,8 @@ export class DevSkimFixer implements vscode.CodeActionProvider { removeFindingsForOtherVersions(fileVersion: FileVersion) { - var keyNames = this.fixMapping.get(fileVersion.fileName)?.keys() ?? new Array(); - for(let key of keyNames) + const keyNames = this.fixMapping.get(fileVersion.fileName)?.keys() ?? new Array(); + for(const key of keyNames) { if (key != fileVersion.version) { @@ -68,7 +68,7 @@ export class DevSkimFixer implements vscode.CodeActionProvider { else { const line = document.lineAt(diagnostic.range.end.line); - fix.edit.insert(document.uri, line.range.end, codeFix.replacement) + fix.edit.insert(document.uri, line.range.end, codeFix.replacement); } return fix; } diff --git a/DevSkim-VSCode-Plugin/eslint.config.mjs b/DevSkim-VSCode-Plugin/eslint.config.mjs new file mode 100644 index 00000000..12c115df --- /dev/null +++ b/DevSkim-VSCode-Plugin/eslint.config.mjs @@ -0,0 +1,19 @@ +import eslint from "@eslint/js"; +import tseslint from "typescript-eslint"; + +export default tseslint.config( + eslint.configs.recommended, + ...tseslint.configs.recommended, + { + files: ["client/**/*.ts"], + rules: { + "semi": [2, "always"], + "@typescript-eslint/no-unused-vars": "off", + "@typescript-eslint/no-explicit-any": "off", + "@typescript-eslint/no-non-null-assertion": "off", + }, + }, + { + ignores: ["**/out/**", "**/node_modules/**", "scripts/**"], + } +); diff --git a/DevSkim-VSCode-Plugin/package-lock.json b/DevSkim-VSCode-Plugin/package-lock.json index 97fe023b..b7e69950 100644 --- a/DevSkim-VSCode-Plugin/package-lock.json +++ b/DevSkim-VSCode-Plugin/package-lock.json @@ -11,13 +11,14 @@ "license": "MIT", "devDependencies": { "@types/node": "^14.x", - "@typescript-eslint/eslint-plugin": "^5.10.1", - "@typescript-eslint/parser": "^5.10.1", + "@typescript-eslint/eslint-plugin": "^8.0.0", + "@typescript-eslint/parser": "^8.0.0", "@vscode/vsce": "^3.7.1", "esbuild": "^0.25.2", - "eslint": "^8.8.0", + "eslint": "^9.0.0", "nerdbank-gitversioning": "^3.4.255", - "typescript": "^4.5.5" + "typescript": "^4.5.5", + "typescript-eslint": "^8.54.0" }, "engines": { "vscode": "^1.63.0" @@ -660,10 +661,11 @@ } }, "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", - "integrity": "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==", + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", + "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", "dev": true, + "license": "MIT", "dependencies": { "eslint-visitor-keys": "^3.4.3" }, @@ -678,59 +680,149 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", - "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", "dev": true, + "license": "MIT", "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, + "node_modules/@eslint/config-array": { + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz", + "integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.7", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", + "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", + "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, "node_modules/@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.3.tgz", + "integrity": "sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ==", "dev": true, + "license": "MIT", "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", + "espree": "^10.0.1", + "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", + "js-yaml": "^4.1.1", "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, + "node_modules/@eslint/eslintrc/node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, "node_modules/@eslint/js": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", - "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", + "version": "9.39.2", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.2.tgz", + "integrity": "sha512-q1mjIoW1VX4IvSocvM/vbTiveKC4k9eLrajNEuSsmjymSDEbpGddtpfOoN7YGAqBK3NG+uqo8ia4PDTt8buCYA==", "dev": true, + "license": "MIT", "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" } }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", - "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", - "deprecated": "Use @eslint/config-array instead", + "node_modules/@eslint/object-schema": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", + "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", + "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@humanwhocodes/object-schema": "^2.0.3", - "debug": "^4.3.1", - "minimatch": "^3.0.5" + "@eslint/core": "^0.17.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.7", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", + "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.4.0" }, "engines": { - "node": ">=10.10.0" + "node": ">=18.18.0" } }, "node_modules/@humanwhocodes/module-importer": { @@ -738,6 +830,7 @@ "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=12.22" }, @@ -746,12 +839,19 @@ "url": "https://github.com/sponsors/nzakas" } }, - "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", - "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", - "deprecated": "Use @eslint/object-schema instead", - "dev": true + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } }, "node_modules/@isaacs/balanced-match": { "version": "4.0.1", @@ -777,75 +877,13 @@ } }, "node_modules/@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", - "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-9.0.0.tgz", + "integrity": "sha512-AokJm4tuBHillT+FpMtxQ60n8ObyXBatq7jD2/JA9dxbDDokKQm8KMht5ibGzLVU9IJDIKK4TPKgMHEYMn3lMg==", "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true, - "license": "MIT" - }, - "node_modules/@isaacs/cliui/node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, - "license": "MIT", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@isaacs/cliui/node_modules/strip-ansi": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", - "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, + "license": "BlueOak-1.0.0", "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" + "node": ">=18" } }, "node_modules/@nodelib/fs.scandir": { @@ -853,6 +891,7 @@ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" @@ -866,6 +905,7 @@ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true, + "license": "MIT", "engines": { "node": ">= 8" } @@ -875,6 +915,7 @@ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" @@ -977,19 +1018,6 @@ "node": ">=20.0.0" } }, - "node_modules/@secretlint/formatter/node_modules/ansi-regex": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", - "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, "node_modules/@secretlint/formatter/node_modules/chalk": { "version": "5.6.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", @@ -1003,22 +1031,6 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/@secretlint/formatter/node_modules/strip-ansi": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", - "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, "node_modules/@secretlint/node": { "version": "10.2.2", "resolved": "https://registry.npmjs.org/@secretlint/node/-/node-10.2.2.tgz", @@ -1153,6 +1165,16 @@ "text-table": "^0.2.0" } }, + "node_modules/@textlint/linter-formatter/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/@textlint/linter-formatter/node_modules/pluralize": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-2.0.0.tgz", @@ -1160,6 +1182,19 @@ "dev": true, "license": "MIT" }, + "node_modules/@textlint/linter-formatter/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/@textlint/module-interop": { "version": "15.5.1", "resolved": "https://registry.npmjs.org/@textlint/module-interop/-/module-interop-15.5.1.tgz", @@ -1184,11 +1219,19 @@ "@textlint/ast-node-types": "15.5.1" } }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/node": { "version": "14.18.63", @@ -1210,124 +1253,151 @@ "dev": true, "license": "MIT" }, - "node_modules/@types/semver": { - "version": "7.5.8", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", - "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", - "dev": true - }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz", - "integrity": "sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==", + "version": "8.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.54.0.tgz", + "integrity": "sha512-hAAP5io/7csFStuOmR782YmTthKBJ9ND3WVL60hcOjvtGFb+HJxH4O5huAcmcZ9v9G8P+JETiZ/G1B8MALnWZQ==", "dev": true, + "license": "MIT", "dependencies": { - "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/type-utils": "5.62.0", - "@typescript-eslint/utils": "5.62.0", - "debug": "^4.3.4", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "natural-compare-lite": "^1.4.0", - "semver": "^7.3.7", - "tsutils": "^3.21.0" + "@eslint-community/regexpp": "^4.12.2", + "@typescript-eslint/scope-manager": "8.54.0", + "@typescript-eslint/type-utils": "8.54.0", + "@typescript-eslint/utils": "8.54.0", + "@typescript-eslint/visitor-keys": "8.54.0", + "ignore": "^7.0.5", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.4.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^5.0.0", - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "@typescript-eslint/parser": "^8.54.0", + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/parser": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz", - "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==", + "version": "8.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.54.0.tgz", + "integrity": "sha512-BtE0k6cjwjLZoZixN0t5AKP0kSzlGu7FctRXYuPAm//aaiZhmfq1JwdYpYr1brzEspYyFeF+8XF5j2VK6oalrA==", "dev": true, + "license": "MIT", + "peer": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/typescript-estree": "5.62.0", - "debug": "^4.3.4" + "@typescript-eslint/scope-manager": "8.54.0", + "@typescript-eslint/types": "8.54.0", + "@typescript-eslint/typescript-estree": "8.54.0", + "@typescript-eslint/visitor-keys": "8.54.0", + "debug": "^4.4.3" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/project-service": { + "version": "8.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.54.0.tgz", + "integrity": "sha512-YPf+rvJ1s7MyiWM4uTRhE4DvBXrEV+d8oC3P9Y2eT7S+HBS0clybdMIPnhiATi9vZOYDc7OQ1L/i6ga6NFYK/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.54.0", + "@typescript-eslint/types": "^8.54.0", + "debug": "^4.4.3" }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", - "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", + "version": "8.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.54.0.tgz", + "integrity": "sha512-27rYVQku26j/PbHYcVfRPonmOlVI6gihHtXFbTdB5sb6qA0wdAQAbyXFVarQ5t4HRojIz64IV90YtsjQSSGlQg==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0" + "@typescript-eslint/types": "8.54.0", + "@typescript-eslint/visitor-keys": "8.54.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.54.0.tgz", + "integrity": "sha512-dRgOyT2hPk/JwxNMZDsIXDgyl9axdJI3ogZ2XWhBPsnZUv+hPesa5iuhdYt2gzwA9t8RE5ytOJ6xB0moV0Ujvw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/type-utils": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz", - "integrity": "sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==", + "version": "8.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.54.0.tgz", + "integrity": "sha512-hiLguxJWHjjwL6xMBwD903ciAwd7DmK30Y9Axs/etOkftC3ZNN9K44IuRD/EB08amu+Zw6W37x9RecLkOo3pMA==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "5.62.0", - "@typescript-eslint/utils": "5.62.0", - "debug": "^4.3.4", - "tsutils": "^3.21.0" + "@typescript-eslint/types": "8.54.0", + "@typescript-eslint/typescript-estree": "8.54.0", + "@typescript-eslint/utils": "8.54.0", + "debug": "^4.4.3", + "ts-api-utils": "^2.4.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "*" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/types": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", - "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", + "version": "8.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.54.0.tgz", + "integrity": "sha512-PDUI9R1BVjqu7AUDsRBbKMtwmjWcn4J3le+5LpcFgWULN3LvHC5rkc9gCVxbrsrGmO1jfPybN5s6h4Jy+OnkAA==", "dev": true, + "license": "MIT", "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -1335,79 +1405,118 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", - "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", + "version": "8.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.54.0.tgz", + "integrity": "sha512-BUwcskRaPvTk6fzVWgDPdUndLjB87KYDrN5EYGetnktoeAvPtO4ONHlAZDnj5VFnUANg0Sjm7j4usBlnoVMHwA==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" + "@typescript-eslint/project-service": "8.54.0", + "@typescript-eslint/tsconfig-utils": "8.54.0", + "@typescript-eslint/types": "8.54.0", + "@typescript-eslint/visitor-keys": "8.54.0", + "debug": "^4.4.3", + "minimatch": "^9.0.5", + "semver": "^7.7.3", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.4.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/@typescript-eslint/utils": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz", - "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==", + "version": "8.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.54.0.tgz", + "integrity": "sha512-9Cnda8GS57AQakvRyG0PTejJNlA2xhvyNtEVIMlDWOOeEyBkYWhGPnfrIAnqxLMTSTo6q8g12XVjjev5l1NvMA==", "dev": true, + "license": "MIT", "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@types/json-schema": "^7.0.9", - "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/typescript-estree": "5.62.0", - "eslint-scope": "^5.1.1", - "semver": "^7.3.7" + "@eslint-community/eslint-utils": "^4.9.1", + "@typescript-eslint/scope-manager": "8.54.0", + "@typescript-eslint/types": "8.54.0", + "@typescript-eslint/typescript-estree": "8.54.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", - "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", + "version": "8.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.54.0.tgz", + "integrity": "sha512-VFlhGSl4opC0bprJiItPQ1RfUhGDIBokcPwaFH4yiBCaNPeld/9VeXbiPO1cLyorQi1G1vL+ecBk1x8o1axORA==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "5.62.0", - "eslint-visitor-keys": "^3.3.0" + "@typescript-eslint/types": "8.54.0", + "eslint-visitor-keys": "^4.2.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, "node_modules/@typespec/ts-http-runtime": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@typespec/ts-http-runtime/-/ts-http-runtime-0.3.2.tgz", - "integrity": "sha512-IlqQ/Gv22xUC1r/WQm4StLkYQmaaTsXAhUVsNE0+xiyf0yRFiH5++q78U3bw6bLKDCTmh0uqKB9eG9+Bt75Dkg==", + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@typespec/ts-http-runtime/-/ts-http-runtime-0.3.3.tgz", + "integrity": "sha512-91fp6CAAJSRtH5ja95T1FHSKa8aPW9/Zw6cta81jlZTUw/+Vq8jM/AfF/14h2b71wwR84JUTW/3Y8QPhDAawFA==", "dev": true, "license": "MIT", "dependencies": { @@ -1419,12 +1528,6 @@ "node": ">=20.0.0" } }, - "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "dev": true - }, "node_modules/@vscode/vsce": { "version": "3.7.1", "resolved": "https://registry.npmjs.org/@vscode/vsce/-/vsce-3.7.1.tgz", @@ -1617,52 +1720,13 @@ "win32" ] }, - "node_modules/@vscode/vsce/node_modules/glob": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-11.1.0.tgz", - "integrity": "sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw==", - "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "foreground-child": "^3.3.1", - "jackspeak": "^4.1.1", - "minimatch": "^10.1.1", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^2.0.0" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@vscode/vsce/node_modules/glob/node_modules/minimatch": { - "version": "10.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.2.tgz", - "integrity": "sha512-fu656aJ0n2kcXwsnwnv9g24tkU5uSmOlTjd6WyyaKm2Z+h1qmY6bAjrcaIxF/BslFqbZ8UBtbJi7KgQOZD2PTw==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/brace-expansion": "^5.0.1" - }, - "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/acorn": { - "version": "8.14.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", - "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, + "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -1675,6 +1739,7 @@ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, + "license": "MIT", "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } @@ -1694,6 +1759,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -1706,9 +1772,9 @@ } }, "node_modules/ansi-escapes": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.2.0.tgz", - "integrity": "sha512-g6LhBsl+GBPRWGWsBtutpzBYuIIdBkLEvad5C/va/74Db018+5TZiyA26cZJAr3Rft5lprVqOIPxf5Vid6tqAw==", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.3.0.tgz", + "integrity": "sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg==", "dev": true, "license": "MIT", "dependencies": { @@ -1722,12 +1788,16 @@ } }, "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", "dev": true, + "license": "MIT", "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, "node_modules/ansi-styles": { @@ -1752,15 +1822,6 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/astral-regex": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", @@ -1876,6 +1937,7 @@ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, + "license": "MIT", "dependencies": { "fill-range": "^7.1.1" }, @@ -1978,6 +2040,7 @@ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -2214,7 +2277,8 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/default-browser": { "version": "5.5.0", @@ -2280,30 +2344,6 @@ "node": ">=8" } }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/dom-serializer": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", @@ -2378,13 +2418,6 @@ "node": ">= 0.4" } }, - "node_modules/eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "dev": true, - "license": "MIT" - }, "node_modules/ecdsa-sig-formatter": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", @@ -2560,73 +2593,95 @@ "@esbuild/win32-x64": "0.25.2" } }, - "node_modules/eslint": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", - "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", - "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.1", - "@humanwhocodes/config-array": "^0.13.0", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "9.39.2", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.2.tgz", + "integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.21.1", + "@eslint/config-helpers": "^0.4.2", + "@eslint/core": "^0.17.0", + "@eslint/eslintrc": "^3.3.1", + "@eslint/js": "9.39.2", + "@eslint/plugin-kit": "^0.4.1", + "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", "ajv": "^6.12.4", "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", + "cross-spawn": "^7.0.6", "debug": "^4.3.2", - "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", + "eslint-scope": "^8.4.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.0", + "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", + "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" + "optionator": "^0.9.3" }, "bin": { "eslint": "bin/eslint.js" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://opencollective.com/eslint" + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } } }, "node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", + "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" + "estraverse": "^5.2.0" }, "engines": { - "node": ">=8.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/eslint-visitor-keys": { @@ -2634,6 +2689,7 @@ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, + "license": "Apache-2.0", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -2641,65 +2697,66 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint/node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "node_modules/eslint/node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, + "license": "Apache-2.0", "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "node_modules/eslint/node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, + "license": "MIT", "engines": { - "node": ">=4.0" + "node": ">= 4" } }, "node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "acorn": "^8.9.0", + "acorn": "^8.15.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" + "eslint-visitor-keys": "^4.2.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree/node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, "node_modules/esquery": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", - "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", + "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "estraverse": "^5.1.0" }, @@ -2707,20 +2764,12 @@ "node": ">=0.10" } }, - "node_modules/esquery/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, "node_modules/esrecurse": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "estraverse": "^5.2.0" }, @@ -2728,20 +2777,12 @@ "node": ">=4.0" } }, - "node_modules/esrecurse/node_modules/estraverse": { + "node_modules/estraverse": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } @@ -2751,6 +2792,7 @@ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=0.10.0" } @@ -2794,6 +2836,7 @@ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, + "license": "ISC", "dependencies": { "is-glob": "^4.0.1" }, @@ -2805,13 +2848,15 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fast-uri": { "version": "3.1.0", @@ -2831,10 +2876,11 @@ "license": "BSD-3-Clause" }, "node_modules/fastq": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", - "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", + "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", "dev": true, + "license": "ISC", "dependencies": { "reusify": "^1.0.4" } @@ -2850,15 +2896,16 @@ } }, "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", "dev": true, + "license": "MIT", "dependencies": { - "flat-cache": "^3.0.4" + "flat-cache": "^4.0.0" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=16.0.0" } }, "node_modules/fill-range": { @@ -2866,6 +2913,7 @@ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, + "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -2878,6 +2926,7 @@ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, + "license": "MIT", "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" @@ -2890,24 +2939,25 @@ } }, "node_modules/flat-cache": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", - "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", "dev": true, + "license": "MIT", "dependencies": { "flatted": "^3.2.9", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" + "keyv": "^4.5.4" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=16" } }, "node_modules/flatted": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.2.tgz", - "integrity": "sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==", - "dev": true + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "dev": true, + "license": "ISC" }, "node_modules/foreground-child": { "version": "3.3.1", @@ -2966,12 +3016,6 @@ "node": ">=14.14" } }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", @@ -3030,21 +3074,25 @@ "optional": true }, "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-11.1.0.tgz", + "integrity": "sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", "dev": true, + "license": "BlueOak-1.0.0", "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "foreground-child": "^3.3.1", + "jackspeak": "^4.1.1", + "minimatch": "^10.1.1", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^2.0.0" + }, + "bin": { + "glob": "dist/esm/bin.mjs" }, "engines": { - "node": "*" + "node": "20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -3055,6 +3103,7 @@ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, + "license": "ISC", "dependencies": { "is-glob": "^4.0.3" }, @@ -3062,36 +3111,51 @@ "node": ">=10.13.0" } }, - "node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "node_modules/glob/node_modules/minimatch": { + "version": "10.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.2.tgz", + "integrity": "sha512-fu656aJ0n2kcXwsnwnv9g24tkU5uSmOlTjd6WyyaKm2Z+h1qmY6bAjrcaIxF/BslFqbZ8UBtbJi7KgQOZD2PTw==", "dev": true, + "license": "BlueOak-1.0.0", "dependencies": { - "type-fest": "^0.20.2" + "@isaacs/brace-expansion": "^5.0.1" }, "engines": { - "node": ">=8" + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-14.1.0.tgz", + "integrity": "sha512-0Ia46fDOaT7k4og1PDW4YbodWWr3scS2vAr2lTbsplOt2WkKp0vQbkI9wKis/T5LV/dqPjO3bpS/z6GTJB82LA==", "dev": true, + "license": "MIT", "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" + "@sindresorhus/merge-streams": "^2.1.0", + "fast-glob": "^3.3.3", + "ignore": "^7.0.3", + "path-type": "^6.0.0", + "slash": "^5.1.0", + "unicorn-magic": "^0.3.0" }, "engines": { - "node": ">=10" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -3117,12 +3181,6 @@ "dev": true, "license": "ISC" }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true - }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -3285,19 +3343,21 @@ "optional": true }, "node_modules/ignore": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 4" } }, "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", "dev": true, + "license": "MIT", "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -3314,6 +3374,7 @@ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8.19" } @@ -3331,22 +3392,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", - "dev": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true + "dev": true, + "license": "ISC", + "optional": true }, "node_modules/ini": { "version": "1.3.8", @@ -3427,19 +3479,11 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.12.0" } }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/is-wsl": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", @@ -3481,13 +3525,13 @@ } }, "node_modules/jackspeak": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.1.1.tgz", - "integrity": "sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.2.1.tgz", + "integrity": "sha512-GPBXyfcZSGujjddPeA+V34bW70ZJT7jzCEbloVasSH4yjiqWqXHX8iZQtZdVbOhc5esSeAIuiSmMutRZQB/olg==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { - "@isaacs/cliui": "^8.0.2" + "@isaacs/cliui": "^9.0.0" }, "engines": { "node": "20 || >=22" @@ -3520,19 +3564,22 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json5": { "version": "2.2.3", @@ -3631,6 +3678,7 @@ "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", "dev": true, + "license": "MIT", "dependencies": { "json-buffer": "3.0.1" } @@ -3650,6 +3698,7 @@ "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, + "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" @@ -3673,6 +3722,7 @@ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, + "license": "MIT", "dependencies": { "p-locate": "^5.0.0" }, @@ -3736,7 +3786,8 @@ "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/lodash.once": { "version": "4.1.1", @@ -3814,6 +3865,7 @@ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 8" } @@ -3823,6 +3875,7 @@ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, + "license": "MIT", "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" @@ -3947,13 +4000,8 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true - }, - "node_modules/natural-compare-lite": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", - "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/nerdbank-gitversioning": { "version": "3.6.146", @@ -4080,6 +4128,8 @@ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, + "license": "ISC", + "optional": true, "dependencies": { "wrappy": "1" } @@ -4108,6 +4158,7 @@ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "dev": true, + "license": "MIT", "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", @@ -4125,6 +4176,7 @@ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, + "license": "MIT", "dependencies": { "yocto-queue": "^0.1.0" }, @@ -4140,6 +4192,7 @@ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, + "license": "MIT", "dependencies": { "p-limit": "^3.0.2" }, @@ -4175,6 +4228,7 @@ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, + "license": "MIT", "dependencies": { "callsites": "^3.0.0" }, @@ -4200,19 +4254,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/parse-json/node_modules/type-fest": { - "version": "4.41.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", - "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/parse-semver": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/parse-semver/-/parse-semver-1.1.1.tgz", @@ -4301,19 +4342,11 @@ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", @@ -4351,12 +4384,16 @@ } }, "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-6.0.0.tgz", + "integrity": "sha512-Vj7sf++t5pBD637NSfkxpHSMfWaeig5+DKWLhcqIYx6mWQz5hdJTGDVMQiJcw1ZYkhs7AazKDGpRVji1LJCZUQ==", "dev": true, + "license": "MIT", "engines": { - "node": ">=8" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/pend": { @@ -4378,6 +4415,7 @@ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, + "license": "MIT", "engines": { "node": ">=8.6" }, @@ -4428,6 +4466,7 @@ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8.0" } @@ -4449,6 +4488,7 @@ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -4497,7 +4537,8 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/rc": { "version": "1.2.8", @@ -4573,14 +4614,14 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/read-pkg/node_modules/type-fest": { - "version": "4.41.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", - "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "node_modules/read-pkg/node_modules/unicorn-magic": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", + "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==", "dev": true, - "license": "(MIT OR CC0-1.0)", + "license": "MIT", "engines": { - "node": ">=16" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -4617,36 +4658,22 @@ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", "dev": true, + "license": "MIT", "engines": { "iojs": ">=1.0.0", "node": ">=0.10.0" } }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/run-applescript": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.1.0.tgz", @@ -4679,6 +4706,7 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "dependencies": { "queue-microtask": "^1.2.2" } @@ -4706,118 +4734,49 @@ }, "node_modules/safer-buffer": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true, - "license": "MIT" - }, - "node_modules/sax": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.4.tgz", - "integrity": "sha512-1n3r/tGXO6b6VXMdFT54SHzT9ytu9yr7TaELowdYpMqY/Ao7EnlQGmAQ1+RatX7Tkkdm6hONI2owqNx2aZj5Sw==", - "dev": true, - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=11.0.0" - } - }, - "node_modules/secretlint": { - "version": "10.2.2", - "resolved": "https://registry.npmjs.org/secretlint/-/secretlint-10.2.2.tgz", - "integrity": "sha512-xVpkeHV/aoWe4vP4TansF622nBEImzCY73y/0042DuJ29iKIaqgoJ8fGxre3rVSHHbxar4FdJobmTnLp9AU0eg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@secretlint/config-creator": "^10.2.2", - "@secretlint/formatter": "^10.2.2", - "@secretlint/node": "^10.2.2", - "@secretlint/profiler": "^10.2.2", - "debug": "^4.4.1", - "globby": "^14.1.0", - "read-pkg": "^9.0.1" - }, - "bin": { - "secretlint": "bin/secretlint.js" - }, - "engines": { - "node": ">=20.0.0" - } - }, - "node_modules/secretlint/node_modules/globby": { - "version": "14.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-14.1.0.tgz", - "integrity": "sha512-0Ia46fDOaT7k4og1PDW4YbodWWr3scS2vAr2lTbsplOt2WkKp0vQbkI9wKis/T5LV/dqPjO3bpS/z6GTJB82LA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@sindresorhus/merge-streams": "^2.1.0", - "fast-glob": "^3.3.3", - "ignore": "^7.0.3", - "path-type": "^6.0.0", - "slash": "^5.1.0", - "unicorn-magic": "^0.3.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/secretlint/node_modules/ignore": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", - "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/secretlint/node_modules/path-type": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-6.0.0.tgz", - "integrity": "sha512-Vj7sf++t5pBD637NSfkxpHSMfWaeig5+DKWLhcqIYx6mWQz5hdJTGDVMQiJcw1ZYkhs7AazKDGpRVji1LJCZUQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true, + "license": "MIT" }, - "node_modules/secretlint/node_modules/slash": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", - "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", + "node_modules/sax": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.4.tgz", + "integrity": "sha512-1n3r/tGXO6b6VXMdFT54SHzT9ytu9yr7TaELowdYpMqY/Ao7EnlQGmAQ1+RatX7Tkkdm6hONI2owqNx2aZj5Sw==", "dev": true, - "license": "MIT", + "license": "BlueOak-1.0.0", "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=11.0.0" } }, - "node_modules/secretlint/node_modules/unicorn-magic": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz", - "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==", + "node_modules/secretlint": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/secretlint/-/secretlint-10.2.2.tgz", + "integrity": "sha512-xVpkeHV/aoWe4vP4TansF622nBEImzCY73y/0042DuJ29iKIaqgoJ8fGxre3rVSHHbxar4FdJobmTnLp9AU0eg==", "dev": true, "license": "MIT", - "engines": { - "node": ">=18" + "dependencies": { + "@secretlint/config-creator": "^10.2.2", + "@secretlint/formatter": "^10.2.2", + "@secretlint/node": "^10.2.2", + "@secretlint/profiler": "^10.2.2", + "debug": "^4.4.1", + "globby": "^14.1.0", + "read-pkg": "^9.0.1" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "bin": { + "secretlint": "bin/secretlint.js" + }, + "engines": { + "node": ">=20.0.0" } }, "node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -4985,12 +4944,16 @@ } }, "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", + "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", "dev": true, + "license": "MIT", "engines": { - "node": ">=8" + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/slice-ansi": { @@ -5073,27 +5036,22 @@ "node": ">=8" } }, - "node_modules/string-width-cjs": { - "name": "string-width", - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "node_modules/string-width/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, "engines": { "node": ">=8" } }, - "node_modules/strip-ansi": { + "node_modules/string-width/node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -5101,18 +5059,20 @@ "node": ">=8" } }, - "node_modules/strip-ansi-cjs": { - "name": "strip-ansi", - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", "dev": true, "license": "MIT", "dependencies": { - "ansi-regex": "^5.0.1" + "ansi-regex": "^6.0.1" }, "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, "node_modules/strip-json-comments": { @@ -5120,6 +5080,7 @@ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" }, @@ -5201,6 +5162,16 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/table/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/table/node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", @@ -5208,6 +5179,19 @@ "dev": true, "license": "MIT" }, + "node_modules/table/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/tar-fs": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.4.tgz", @@ -5261,7 +5245,8 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/textextensions": { "version": "6.11.0", @@ -5279,6 +5264,55 @@ "url": "https://bevry.me/fund" } }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/tmp": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.5.tgz", @@ -5294,6 +5328,7 @@ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, + "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, @@ -5301,31 +5336,23 @@ "node": ">=8.0" } }, - "node_modules/tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "dev": true - }, - "node_modules/tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "node_modules/ts-api-utils": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.4.0.tgz", + "integrity": "sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==", "dev": true, - "dependencies": { - "tslib": "^1.8.1" - }, + "license": "MIT", "engines": { - "node": ">= 6" + "node": ">=18.12" }, "peerDependencies": { - "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + "typescript": ">=4.8.4" } }, - "node_modules/tsutils/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "dev": true }, "node_modules/tunnel": { @@ -5357,6 +5384,7 @@ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, + "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1" }, @@ -5365,12 +5393,13 @@ } }, "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { - "node": ">=10" + "node": ">=16" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -5393,6 +5422,7 @@ "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", "dev": true, + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -5401,6 +5431,30 @@ "node": ">=4.2.0" } }, + "node_modules/typescript-eslint": { + "version": "8.54.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.54.0.tgz", + "integrity": "sha512-CKsJ+g53QpsNPqbzUsfKVgd3Lny4yKZ1pP4qN3jdMOg/sisIDLGyDMezycquXLE5JsEU0wp3dGNdzig0/fmSVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/eslint-plugin": "8.54.0", + "@typescript-eslint/parser": "8.54.0", + "@typescript-eslint/typescript-estree": "8.54.0", + "@typescript-eslint/utils": "8.54.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, "node_modules/uc.micro": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", @@ -5426,9 +5480,9 @@ } }, "node_modules/unicorn-magic": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", - "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==", + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz", + "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==", "dev": true, "license": "MIT", "engines": { @@ -5453,6 +5507,7 @@ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "punycode": "^2.1.0" } @@ -5550,119 +5605,18 @@ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs": { - "name": "wrap-ansi", - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-regex": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", - "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-styles": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", - "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true, - "license": "MIT" - }, - "node_modules/wrap-ansi/node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, - "license": "MIT", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/wrap-ansi/node_modules/strip-ansi": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", - "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", - "dev": true, "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" + "node": ">=0.10.0" } }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true + "dev": true, + "license": "ISC", + "optional": true }, "node_modules/wsl-utils": { "version": "0.1.0", @@ -5737,6 +5691,7 @@ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, diff --git a/DevSkim-VSCode-Plugin/package.json b/DevSkim-VSCode-Plugin/package.json index d681c745..5c966393 100644 --- a/DevSkim-VSCode-Plugin/package.json +++ b/DevSkim-VSCode-Plugin/package.json @@ -299,7 +299,7 @@ "compile": "tsc -b", "build": "npm run setup && npm run compile", "watch": "tsc -b -w", - "lint": "eslint ./client --ext .ts,.tsx", + "lint": "eslint ./client", "postinstall": "cd client && npm install && cd .. && npm uninstall @vscode/vsce && npm install --save-dev @vscode/vsce", "vscode:prepublish": "npm run esbuild-base -- --minify", "esbuild-base": "esbuild ./client/extension.ts --bundle --outfile=client/out/extension.js --external:vscode --format=cjs --platform=node", @@ -322,12 +322,13 @@ }, "devDependencies": { "@types/node": "^14.x", - "@typescript-eslint/eslint-plugin": "^5.10.1", - "@typescript-eslint/parser": "^5.10.1", + "@typescript-eslint/eslint-plugin": "^8.0.0", + "@typescript-eslint/parser": "^8.0.0", "@vscode/vsce": "^3.7.1", "esbuild": "^0.25.2", - "eslint": "^8.8.0", + "eslint": "^9.0.0", "nerdbank-gitversioning": "^3.4.255", - "typescript": "^4.5.5" + "typescript": "^4.5.5", + "typescript-eslint": "^8.54.0" } } From 2fc2b722a15ad1f0e34e4a166d16c5851efd3c2e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 6 Feb 2026 02:02:15 +0000 Subject: [PATCH 18/19] Add CancellationTokenSource for graceful subscription cancellation - Added class-level _disposeCts that is cancelled in Dispose method - Updated SubscribeAsync calls to use _disposeCts.Token instead of CancellationToken.None - Added try/catch for OperationCanceledException to handle disposal during initialization Co-authored-by: gfs <98900+gfs@users.noreply.github.com> --- .../DevSkimLanguageServerProvider.cs | 56 ++++++++++++++----- 1 file changed, 41 insertions(+), 15 deletions(-) diff --git a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/DevSkimLanguageServerProvider.cs b/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/DevSkimLanguageServerProvider.cs index 1e059cf1..f267306f 100644 --- a/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/DevSkimLanguageServerProvider.cs +++ b/DevSkim-DotNet/Microsoft.DevSkim.VisualStudio/DevSkimLanguageServerProvider.cs @@ -35,6 +35,7 @@ internal class DevSkimLanguageServerProvider : LanguageServerProvider private readonly System.Collections.Concurrent.ConcurrentBag _settingsSubscriptions = []; private bool _initialPushDone; private CancellationTokenSource? _restartDebounce; + private readonly CancellationTokenSource _disposeCts = new(); /// public override LanguageServerProviderConfiguration LanguageServerProviderConfiguration => new( @@ -144,6 +145,10 @@ protected override void Dispose(bool isDisposing) { if (isDisposing) { + // Cancel pending subscription operations first + _disposeCts.Cancel(); + _disposeCts.Dispose(); + foreach (var sub in _settingsSubscriptions) { sub.Dispose(); @@ -236,11 +241,18 @@ private void SubscribeSetting(Setting.Boolean setting) { _ = Task.Run(async () => { - var sub = await Extensibility.Settings().SubscribeAsync( - setting, - CancellationToken.None, - changeHandler: _ => OnSettingChanged()); - _settingsSubscriptions.Add(sub); + try + { + var sub = await Extensibility.Settings().SubscribeAsync( + setting, + _disposeCts.Token, + changeHandler: _ => OnSettingChanged()); + _settingsSubscriptions.Add(sub); + } + catch (OperationCanceledException) + { + // Provider is being disposed, ignore + } }); } @@ -248,11 +260,18 @@ private void SubscribeStringSetting(Setting.String setting) { _ = Task.Run(async () => { - var sub = await Extensibility.Settings().SubscribeAsync( - setting, - CancellationToken.None, - changeHandler: _ => OnSettingChanged()); - _settingsSubscriptions.Add(sub); + try + { + var sub = await Extensibility.Settings().SubscribeAsync( + setting, + _disposeCts.Token, + changeHandler: _ => OnSettingChanged()); + _settingsSubscriptions.Add(sub); + } + catch (OperationCanceledException) + { + // Provider is being disposed, ignore + } }); } @@ -260,11 +279,18 @@ private void SubscribeIntSetting(Setting.Integer setting) { _ = Task.Run(async () => { - var sub = await Extensibility.Settings().SubscribeAsync( - setting, - CancellationToken.None, - changeHandler: _ => OnSettingChanged()); - _settingsSubscriptions.Add(sub); + try + { + var sub = await Extensibility.Settings().SubscribeAsync( + setting, + _disposeCts.Token, + changeHandler: _ => OnSettingChanged()); + _settingsSubscriptions.Add(sub); + } + catch (OperationCanceledException) + { + // Provider is being disposed, ignore + } }); } From 31b13f86856f162f8c24e9cfdf424ba466cdb0dc Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 6 Feb 2026 23:42:04 +0000 Subject: [PATCH 19/19] Add changelog entry for VS extension rewrite using VisualStudio.Extensibility SDK Co-authored-by: gfs <98900+gfs@users.noreply.github.com> --- Changelog.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Changelog.md b/Changelog.md index 4d112400..06c398ff 100644 --- a/Changelog.md +++ b/Changelog.md @@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [1.0.76] - 2026-02-06 +### Changed +- Rewrote Visual Studio extension using VisualStudio.Extensibility SDK for VS2022/2026 compatibility +- Replaced legacy MEF-based ILanguageClient with LanguageServerProvider from new VS Extensibility SDK +- Implemented Windows Job Object for reliable language server process cleanup when VS exits +- Added settings management using VS Extensibility SDK settings API with localized string resources +- Enhanced code actions and fixes handling for better VS compatibility + ## [1.0.75] - 2026-02-06 ### Changed - Removed unnecessary uninstall/reinstall of @vscode/vsce from postinstall script in VSCode plugin