From 6e5edfe0e553e6a5e928143f8018aa57ea85a645 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sat, 17 Jan 2026 08:06:08 +0000
Subject: [PATCH 1/8] Initial plan
From 85250289136073486f97ed97062d8832f6706f74 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sat, 17 Jan 2026 08:13:37 +0000
Subject: [PATCH 2/8] Fix extra logging in non-root commands by filtering
plugin messages
Co-authored-by: waldekmastykarz <11164679+waldekmastykarz@users.noreply.github.com>
---
DevProxy/Commands/DevProxyCommand.cs | 19 ++++++++++++++++++
.../Extensions/ILoggingBuilderExtensions.cs | 20 +++++++++++++++++++
2 files changed, 39 insertions(+)
diff --git a/DevProxy/Commands/DevProxyCommand.cs b/DevProxy/Commands/DevProxyCommand.cs
index e3db039b..61d292fc 100644
--- a/DevProxy/Commands/DevProxyCommand.cs
+++ b/DevProxy/Commands/DevProxyCommand.cs
@@ -40,9 +40,12 @@ sealed class DevProxyCommand : RootCommand
private static readonly string[] globalOptions = ["--version"];
private static readonly string[] helpOptions = ["--help", "-h", "/h", "-?", "/?"];
+ // Built-in subcommands
+ private static readonly string[] subCommands = ["msgraphdb", "config", "outdated", "jwt", "cert", "stdio"];
private static bool _hasGlobalOptionsResolved;
private static bool _isStdioCommandResolved;
+ private static bool _isSubCommandResolved;
private static bool _stdioLogFilePathResolved;
public static bool HasGlobalOptions
@@ -78,6 +81,22 @@ public static bool IsStdioCommand
}
}
+ public static bool IsSubCommand
+ {
+ get
+ {
+ if (_isSubCommandResolved)
+ {
+ return field;
+ }
+
+ var args = Environment.GetCommandLineArgs();
+ field = args.Any(arg => subCommands.Contains(arg));
+ _isSubCommandResolved = true;
+ return field;
+ }
+ }
+
public static string StdioLogFilePath
{
get
diff --git a/DevProxy/Extensions/ILoggingBuilderExtensions.cs b/DevProxy/Extensions/ILoggingBuilderExtensions.cs
index 00735f24..3537d12d 100644
--- a/DevProxy/Extensions/ILoggingBuilderExtensions.cs
+++ b/DevProxy/Extensions/ILoggingBuilderExtensions.cs
@@ -39,6 +39,26 @@ public static ILoggingBuilder ConfigureDevProxyLogging(
return builder;
}
+ // For subcommands (except stdio), use simple console logging without rich formatting
+ // to avoid interfering with the command's output. Filter out plugin messages.
+ if (DevProxyCommand.IsSubCommand)
+ {
+ _ = builder
+ .ClearProviders()
+ .AddFilter("Microsoft.Hosting.*", LogLevel.None)
+ .AddFilter("Microsoft.AspNetCore.*", LogLevel.None)
+ .AddFilter("Microsoft.Extensions.*", LogLevel.None)
+ .AddFilter("System.*", LogLevel.None)
+ .AddFilter("DevProxy.Plugins.*", LogLevel.None)
+ .AddSimpleConsole(options =>
+ {
+ options.SingleLine = true;
+ options.IncludeScopes = false;
+ })
+ .SetMinimumLevel(configuredLogLevel);
+ return builder;
+ }
+
_ = builder
.AddFilter("Microsoft.Hosting.*", LogLevel.Error)
.AddFilter("Microsoft.AspNetCore.*", LogLevel.Error)
From ccf902b993e8ebcd83d29aea7e26583d8bfdc112 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sat, 17 Jan 2026 10:40:49 +0000
Subject: [PATCH 3/8] Refactor: Use IsRootCommand instead of listing subcommand
names
Co-authored-by: waldekmastykarz <11164679+waldekmastykarz@users.noreply.github.com>
---
DevProxy/Commands/DevProxyCommand.cs | 21 ++++++++++++-------
.../Extensions/ILoggingBuilderExtensions.cs | 12 ++++-------
2 files changed, 18 insertions(+), 15 deletions(-)
diff --git a/DevProxy/Commands/DevProxyCommand.cs b/DevProxy/Commands/DevProxyCommand.cs
index 61d292fc..13e61269 100644
--- a/DevProxy/Commands/DevProxyCommand.cs
+++ b/DevProxy/Commands/DevProxyCommand.cs
@@ -40,12 +40,10 @@ sealed class DevProxyCommand : RootCommand
private static readonly string[] globalOptions = ["--version"];
private static readonly string[] helpOptions = ["--help", "-h", "/h", "-?", "/?"];
- // Built-in subcommands
- private static readonly string[] subCommands = ["msgraphdb", "config", "outdated", "jwt", "cert", "stdio"];
private static bool _hasGlobalOptionsResolved;
private static bool _isStdioCommandResolved;
- private static bool _isSubCommandResolved;
+ private static bool _isRootCommandResolved;
private static bool _stdioLogFilePathResolved;
public static bool HasGlobalOptions
@@ -81,18 +79,27 @@ public static bool IsStdioCommand
}
}
- public static bool IsSubCommand
+ ///
+ /// Determines if the root command (proxy itself) is being invoked.
+ /// Returns true when no subcommand is specified (only options or no args).
+ /// A subcommand is detected when the first non-program argument doesn't start with '-'.
+ ///
+ public static bool IsRootCommand
{
get
{
- if (_isSubCommandResolved)
+ if (_isRootCommandResolved)
{
return field;
}
var args = Environment.GetCommandLineArgs();
- field = args.Any(arg => subCommands.Contains(arg));
- _isSubCommandResolved = true;
+ // Skip the first argument which is the program name
+ // If there are no more arguments, it's the root command
+ // If the first argument starts with '-', it's an option (root command)
+ // Otherwise, it's a subcommand name
+ field = args.Length <= 1 || args[1].StartsWith('-');
+ _isRootCommandResolved = true;
return field;
}
}
diff --git a/DevProxy/Extensions/ILoggingBuilderExtensions.cs b/DevProxy/Extensions/ILoggingBuilderExtensions.cs
index 3537d12d..31fb1b41 100644
--- a/DevProxy/Extensions/ILoggingBuilderExtensions.cs
+++ b/DevProxy/Extensions/ILoggingBuilderExtensions.cs
@@ -39,9 +39,10 @@ public static ILoggingBuilder ConfigureDevProxyLogging(
return builder;
}
- // For subcommands (except stdio), use simple console logging without rich formatting
- // to avoid interfering with the command's output. Filter out plugin messages.
- if (DevProxyCommand.IsSubCommand)
+ // Only the root command (proxy itself) uses rich logging.
+ // All subcommands use simple logging without rich formatting to avoid
+ // interfering with command output
+ if (!DevProxyCommand.IsRootCommand)
{
_ = builder
.ClearProviders()
@@ -50,11 +51,6 @@ public static ILoggingBuilder ConfigureDevProxyLogging(
.AddFilter("Microsoft.Extensions.*", LogLevel.None)
.AddFilter("System.*", LogLevel.None)
.AddFilter("DevProxy.Plugins.*", LogLevel.None)
- .AddSimpleConsole(options =>
- {
- options.SingleLine = true;
- options.IncludeScopes = false;
- })
.SetMinimumLevel(configuredLogLevel);
return builder;
}
From eb12d79ff2d73721351a5e7592d01c0fa902a71d Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sun, 18 Jan 2026 13:11:47 +0000
Subject: [PATCH 4/8] Handle jwt command separately: no console logging, other
subcommands log
Co-authored-by: waldekmastykarz <11164679+waldekmastykarz@users.noreply.github.com>
---
DevProxy/Commands/DevProxyCommand.cs | 17 +++++
.../Extensions/ILoggingBuilderExtensions.cs | 76 +++++++++++--------
2 files changed, 62 insertions(+), 31 deletions(-)
diff --git a/DevProxy/Commands/DevProxyCommand.cs b/DevProxy/Commands/DevProxyCommand.cs
index 13e61269..4a835871 100644
--- a/DevProxy/Commands/DevProxyCommand.cs
+++ b/DevProxy/Commands/DevProxyCommand.cs
@@ -43,6 +43,7 @@ sealed class DevProxyCommand : RootCommand
private static bool _hasGlobalOptionsResolved;
private static bool _isStdioCommandResolved;
+ private static bool _isJwtCommandResolved;
private static bool _isRootCommandResolved;
private static bool _stdioLogFilePathResolved;
@@ -79,6 +80,22 @@ public static bool IsStdioCommand
}
}
+ public static bool IsJwtCommand
+ {
+ get
+ {
+ if (_isJwtCommandResolved)
+ {
+ return field;
+ }
+
+ var args = Environment.GetCommandLineArgs();
+ field = args.Contains("jwt");
+ _isJwtCommandResolved = true;
+ return field;
+ }
+ }
+
///
/// Determines if the root command (proxy itself) is being invoked.
/// Returns true when no subcommand is specified (only options or no args).
diff --git a/DevProxy/Extensions/ILoggingBuilderExtensions.cs b/DevProxy/Extensions/ILoggingBuilderExtensions.cs
index 31fb1b41..de1774a3 100644
--- a/DevProxy/Extensions/ILoggingBuilderExtensions.cs
+++ b/DevProxy/Extensions/ILoggingBuilderExtensions.cs
@@ -39,45 +39,59 @@ public static ILoggingBuilder ConfigureDevProxyLogging(
return builder;
}
- // Only the root command (proxy itself) uses rich logging.
- // All subcommands use simple logging without rich formatting to avoid
- // interfering with command output
- if (!DevProxyCommand.IsRootCommand)
+ // For jwt command, suppress all logging to console to avoid interfering with token output
+ if (DevProxyCommand.IsJwtCommand)
{
_ = builder
.ClearProviders()
- .AddFilter("Microsoft.Hosting.*", LogLevel.None)
- .AddFilter("Microsoft.AspNetCore.*", LogLevel.None)
- .AddFilter("Microsoft.Extensions.*", LogLevel.None)
- .AddFilter("System.*", LogLevel.None)
- .AddFilter("DevProxy.Plugins.*", LogLevel.None)
+ .SetMinimumLevel(LogLevel.None);
+ return builder;
+ }
+
+ // For root command (proxy itself), use rich logging
+ if (DevProxyCommand.IsRootCommand)
+ {
+ _ = builder
+ .AddFilter("Microsoft.Hosting.*", LogLevel.Error)
+ .AddFilter("Microsoft.AspNetCore.*", LogLevel.Error)
+ .AddFilter("Microsoft.Extensions.*", LogLevel.Error)
+ .AddFilter("System.*", LogLevel.Error)
+ // Only show plugin messages when no global options are set
+ .AddFilter("DevProxy.Plugins.*", level =>
+ level >= configuredLogLevel &&
+ !DevProxyCommand.HasGlobalOptions)
+ .AddConsole(options =>
+ {
+ options.FormatterName = ProxyConsoleFormatter.DefaultCategoryName;
+ options.LogToStandardErrorThreshold = LogLevel.Warning;
+ }
+ )
+ .AddConsoleFormatter(options =>
+ {
+ options.IncludeScopes = true;
+ options.ShowSkipMessages = configuration.GetValue("showSkipMessages", true);
+ options.ShowTimestamps = configuration.GetValue("showTimestamps", true);
+ }
+ )
+ .AddRequestLogger()
.SetMinimumLevel(configuredLogLevel);
return builder;
}
+ // For other subcommands (cert, config, outdated, msgraphdb), use simple console logging
+ // with plugin messages filtered out
_ = builder
- .AddFilter("Microsoft.Hosting.*", LogLevel.Error)
- .AddFilter("Microsoft.AspNetCore.*", LogLevel.Error)
- .AddFilter("Microsoft.Extensions.*", LogLevel.Error)
- .AddFilter("System.*", LogLevel.Error)
- // Only show plugin messages when no global options are set
- .AddFilter("DevProxy.Plugins.*", level =>
- level >= configuredLogLevel &&
- !DevProxyCommand.HasGlobalOptions)
- .AddConsole(options =>
- {
- options.FormatterName = ProxyConsoleFormatter.DefaultCategoryName;
- options.LogToStandardErrorThreshold = LogLevel.Warning;
- }
- )
- .AddConsoleFormatter(options =>
- {
- options.IncludeScopes = true;
- options.ShowSkipMessages = configuration.GetValue("showSkipMessages", true);
- options.ShowTimestamps = configuration.GetValue("showTimestamps", true);
- }
- )
- .AddRequestLogger()
+ .ClearProviders()
+ .AddFilter("Microsoft.Hosting.*", LogLevel.None)
+ .AddFilter("Microsoft.AspNetCore.*", LogLevel.None)
+ .AddFilter("Microsoft.Extensions.*", LogLevel.None)
+ .AddFilter("System.*", LogLevel.None)
+ .AddFilter("DevProxy.Plugins.*", LogLevel.None)
+ .AddSimpleConsole(options =>
+ {
+ options.SingleLine = true;
+ options.IncludeScopes = false;
+ })
.SetMinimumLevel(configuredLogLevel);
return builder;
From 516df64ade9e3957ff5bca7d700064d4b97be758 Mon Sep 17 00:00:00 2001
From: Waldek Mastykarz
Date: Sun, 18 Jan 2026 18:46:48 +0100
Subject: [PATCH 5/8] Apply suggestion from @Copilot
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
---
DevProxy/Commands/DevProxyCommand.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/DevProxy/Commands/DevProxyCommand.cs b/DevProxy/Commands/DevProxyCommand.cs
index 4a835871..b41848f0 100644
--- a/DevProxy/Commands/DevProxyCommand.cs
+++ b/DevProxy/Commands/DevProxyCommand.cs
@@ -90,7 +90,7 @@ public static bool IsJwtCommand
}
var args = Environment.GetCommandLineArgs();
- field = args.Contains("jwt");
+ field = args.Length > 1 && string.Equals(args[1], "jwt", StringComparison.OrdinalIgnoreCase);
_isJwtCommandResolved = true;
return field;
}
From 098c076212a7dca57fdaf7b4107079055e677ff6 Mon Sep 17 00:00:00 2001
From: waldekmastykarz
Date: Sun, 18 Jan 2026 18:49:43 +0100
Subject: [PATCH 6/8] Enhance logging for non-root subcommands by adjusting
filter levels and adding console formatter
---
.../Extensions/ILoggingBuilderExtensions.cs | 33 ++++++++++++-------
1 file changed, 22 insertions(+), 11 deletions(-)
diff --git a/DevProxy/Extensions/ILoggingBuilderExtensions.cs b/DevProxy/Extensions/ILoggingBuilderExtensions.cs
index de1774a3..39b190f9 100644
--- a/DevProxy/Extensions/ILoggingBuilderExtensions.cs
+++ b/DevProxy/Extensions/ILoggingBuilderExtensions.cs
@@ -81,17 +81,28 @@ public static ILoggingBuilder ConfigureDevProxyLogging(
// For other subcommands (cert, config, outdated, msgraphdb), use simple console logging
// with plugin messages filtered out
_ = builder
- .ClearProviders()
- .AddFilter("Microsoft.Hosting.*", LogLevel.None)
- .AddFilter("Microsoft.AspNetCore.*", LogLevel.None)
- .AddFilter("Microsoft.Extensions.*", LogLevel.None)
- .AddFilter("System.*", LogLevel.None)
- .AddFilter("DevProxy.Plugins.*", LogLevel.None)
- .AddSimpleConsole(options =>
- {
- options.SingleLine = true;
- options.IncludeScopes = false;
- })
+ .AddFilter("Microsoft.Hosting.*", LogLevel.Error)
+ .AddFilter("Microsoft.AspNetCore.*", LogLevel.Error)
+ .AddFilter("Microsoft.Extensions.*", LogLevel.Error)
+ .AddFilter("System.*", LogLevel.Error)
+ // Only show plugin messages when no global options are set
+ .AddFilter("DevProxy.Plugins.*", level =>
+ level >= configuredLogLevel &&
+ !DevProxyCommand.HasGlobalOptions)
+ .AddConsole(options =>
+ {
+ options.FormatterName = ProxyConsoleFormatter.DefaultCategoryName;
+ options.LogToStandardErrorThreshold = LogLevel.Warning;
+ }
+ )
+ .AddConsoleFormatter(options =>
+ {
+ options.IncludeScopes = true;
+ options.ShowSkipMessages = configuration.GetValue("showSkipMessages", true);
+ options.ShowTimestamps = configuration.GetValue("showTimestamps", true);
+ }
+ )
+ .AddRequestLogger()
.SetMinimumLevel(configuredLogLevel);
return builder;
From 8ecf3a40e0ded0e8d7287051b1481824b5c67996 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Mon, 19 Jan 2026 10:09:37 +0000
Subject: [PATCH 7/8] Fix subcommands to use simple logging with plugin
messages filtered out
Co-authored-by: waldekmastykarz <11164679+waldekmastykarz@users.noreply.github.com>
---
.../Extensions/ILoggingBuilderExtensions.cs | 33 +++++++------------
1 file changed, 11 insertions(+), 22 deletions(-)
diff --git a/DevProxy/Extensions/ILoggingBuilderExtensions.cs b/DevProxy/Extensions/ILoggingBuilderExtensions.cs
index 39b190f9..97154613 100644
--- a/DevProxy/Extensions/ILoggingBuilderExtensions.cs
+++ b/DevProxy/Extensions/ILoggingBuilderExtensions.cs
@@ -81,28 +81,17 @@ public static ILoggingBuilder ConfigureDevProxyLogging(
// For other subcommands (cert, config, outdated, msgraphdb), use simple console logging
// with plugin messages filtered out
_ = builder
- .AddFilter("Microsoft.Hosting.*", LogLevel.Error)
- .AddFilter("Microsoft.AspNetCore.*", LogLevel.Error)
- .AddFilter("Microsoft.Extensions.*", LogLevel.Error)
- .AddFilter("System.*", LogLevel.Error)
- // Only show plugin messages when no global options are set
- .AddFilter("DevProxy.Plugins.*", level =>
- level >= configuredLogLevel &&
- !DevProxyCommand.HasGlobalOptions)
- .AddConsole(options =>
- {
- options.FormatterName = ProxyConsoleFormatter.DefaultCategoryName;
- options.LogToStandardErrorThreshold = LogLevel.Warning;
- }
- )
- .AddConsoleFormatter(options =>
- {
- options.IncludeScopes = true;
- options.ShowSkipMessages = configuration.GetValue("showSkipMessages", true);
- options.ShowTimestamps = configuration.GetValue("showTimestamps", true);
- }
- )
- .AddRequestLogger()
+ .ClearProviders()
+ .AddSimpleConsole(options =>
+ {
+ options.SingleLine = true;
+ options.IncludeScopes = false;
+ })
+ .AddFilter("Microsoft.Hosting.*", LogLevel.None)
+ .AddFilter("Microsoft.AspNetCore.*", LogLevel.None)
+ .AddFilter("Microsoft.Extensions.*", LogLevel.None)
+ .AddFilter("System.*", LogLevel.None)
+ .AddFilter("DevProxy.Plugins.*", LogLevel.None)
.SetMinimumLevel(configuredLogLevel);
return builder;
From c7c1793c33d3d29c8eed0b1ecdc783956eb8cf57 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Mon, 19 Jan 2026 10:35:23 +0000
Subject: [PATCH 8/8] Keep rich logging for subcommands, only suppress plugin
messages
Co-authored-by: waldekmastykarz <11164679+waldekmastykarz@users.noreply.github.com>
---
.../Extensions/ILoggingBuilderExtensions.cs | 31 ++++++++++++-------
1 file changed, 19 insertions(+), 12 deletions(-)
diff --git a/DevProxy/Extensions/ILoggingBuilderExtensions.cs b/DevProxy/Extensions/ILoggingBuilderExtensions.cs
index 97154613..32c26fe4 100644
--- a/DevProxy/Extensions/ILoggingBuilderExtensions.cs
+++ b/DevProxy/Extensions/ILoggingBuilderExtensions.cs
@@ -78,20 +78,27 @@ public static ILoggingBuilder ConfigureDevProxyLogging(
return builder;
}
- // For other subcommands (cert, config, outdated, msgraphdb), use simple console logging
- // with plugin messages filtered out
+ // For other subcommands (cert, config, outdated, msgraphdb), use rich logging
+ // but with plugin messages filtered out
_ = builder
- .ClearProviders()
- .AddSimpleConsole(options =>
- {
- options.SingleLine = true;
- options.IncludeScopes = false;
- })
- .AddFilter("Microsoft.Hosting.*", LogLevel.None)
- .AddFilter("Microsoft.AspNetCore.*", LogLevel.None)
- .AddFilter("Microsoft.Extensions.*", LogLevel.None)
- .AddFilter("System.*", LogLevel.None)
+ .AddFilter("Microsoft.Hosting.*", LogLevel.Error)
+ .AddFilter("Microsoft.AspNetCore.*", LogLevel.Error)
+ .AddFilter("Microsoft.Extensions.*", LogLevel.Error)
+ .AddFilter("System.*", LogLevel.Error)
.AddFilter("DevProxy.Plugins.*", LogLevel.None)
+ .AddConsole(options =>
+ {
+ options.FormatterName = ProxyConsoleFormatter.DefaultCategoryName;
+ options.LogToStandardErrorThreshold = LogLevel.Warning;
+ }
+ )
+ .AddConsoleFormatter(options =>
+ {
+ options.IncludeScopes = true;
+ options.ShowSkipMessages = configuration.GetValue("showSkipMessages", true);
+ options.ShowTimestamps = configuration.GetValue("showTimestamps", true);
+ }
+ )
.SetMinimumLevel(configuredLogLevel);
return builder;