From 646c805b8e55e8fe813af104c081d1ddfcd2396f Mon Sep 17 00:00:00 2001 From: Gordon Beeming Date: Thu, 19 Feb 2026 20:28:02 +1000 Subject: [PATCH] refactor: Update BuildCmdWrapper to use args splatting and add unit tests --- .worktrees/issue-65 | 1 - app/Infrastructure/ShellIntegration.cs | 9 +++--- .../ShellIntegrationTests.cs | 29 +++++++++++++++++++ 3 files changed, 34 insertions(+), 5 deletions(-) delete mode 160000 .worktrees/issue-65 create mode 100644 tests/CopilotHere.UnitTests/ShellIntegrationTests.cs diff --git a/.worktrees/issue-65 b/.worktrees/issue-65 deleted file mode 160000 index ac8dac8..0000000 --- a/.worktrees/issue-65 +++ /dev/null @@ -1 +0,0 @@ -Subproject commit ac8dac8f322549067b27faba84f8350fd6e809e0 diff --git a/app/Infrastructure/ShellIntegration.cs b/app/Infrastructure/ShellIntegration.cs index 2ad6fc2..91b1528 100644 --- a/app/Infrastructure/ShellIntegration.cs +++ b/app/Infrastructure/ShellIntegration.cs @@ -331,18 +331,19 @@ private static void EnsureCmdWrappers(string userHome, string psPath) File.WriteAllText(yoloCmd, BuildCmdWrapper("copilot_yolo", psPath)); } - private static string BuildCmdWrapper(string functionName, string psPath) + internal static string BuildCmdWrapper(string functionName, string psPath) { // Prefer pwsh, fall back to powershell. - // Keep wrapper simple and rely on PowerShell script for all logic. + // Pass arguments after `--` and forward via PowerShell `@args` so quoted + // values (for example --prompt "What is 1 + 1 ?") stay as a single arg. return "@echo off\r\n" + "setlocal\r\n" + "set \"SCRIPT=%USERPROFILE%\\.copilot_here.ps1\"\r\n" + "where pwsh >nul 2>nul\r\n" + "if %ERRORLEVEL%==0 (\r\n" + - $" pwsh -NoProfile -ExecutionPolicy Bypass -Command \". '%USERPROFILE%\\.copilot_here.ps1'; {functionName} %*\"\r\n" + + $" pwsh -NoProfile -ExecutionPolicy Bypass -Command \"& {{ . '%USERPROFILE%\\.copilot_here.ps1'; {functionName} @args }}\" -- %*\r\n" + ") else (\r\n" + - $" powershell -NoProfile -ExecutionPolicy Bypass -Command \". '%USERPROFILE%\\.copilot_here.ps1'; {functionName} %*\"\r\n" + + $" powershell -NoProfile -ExecutionPolicy Bypass -Command \"& {{ . '%USERPROFILE%\\.copilot_here.ps1'; {functionName} @args }}\" -- %*\r\n" + ")\r\n" + "endlocal\r\n"; } diff --git a/tests/CopilotHere.UnitTests/ShellIntegrationTests.cs b/tests/CopilotHere.UnitTests/ShellIntegrationTests.cs new file mode 100644 index 0000000..5730d9c --- /dev/null +++ b/tests/CopilotHere.UnitTests/ShellIntegrationTests.cs @@ -0,0 +1,29 @@ +using CopilotHere.Infrastructure; +using TUnit.Core; + +namespace CopilotHere.Tests; + +public class ShellIntegrationTests +{ + [Test] + public async Task BuildCmdWrapper_UsesArgsSplatForForwarding() + { + // Act + var wrapper = ShellIntegration.BuildCmdWrapper("copilot_yolo", "ignored"); + + // Assert + await Assert.That(wrapper).Contains("copilot_yolo @args"); + await Assert.That(wrapper).Contains(" -- %*"); + } + + [Test] + public async Task BuildCmdWrapper_UsesArgsSplatForBothPwshAndWindowsPowerShell() + { + // Act + var wrapper = ShellIntegration.BuildCmdWrapper("copilot_here", "ignored"); + + // Assert + var occurrences = wrapper.Split("copilot_here @args").Length - 1; + await Assert.That(occurrences).IsEqualTo(2); + } +}