Files
EugeneTes e6b09fef1e feat(mcp): extension project and configuration
McpOptions/McpServerConfig/PlaywrightOptions with ApplyEnvironment (PLAYWRIGHT_* variables, quote-aware ExtraArgs split) and Validate; ShellWords; mcpServers from the user settings.json. New project in the solution and referenced by the extension tests.
2026-09-26 20:13:50 +02:00

44 lines
1.5 KiB
C#

using System.Text;
namespace Volcanic.AgenticCore.Extensions.Mcp;
/// <summary>Splits a command-line fragment into argv the way a POSIX shell would, without expansion.</summary>
internal static class ShellWords
{
/// <summary>Whitespace separates words; '…' is literal; "…" allows \" and \\. Backslashes elsewhere are kept (Windows paths).</summary>
public static IReadOnlyList<string> Split(string text)
{
var words = new List<string>();
var current = new StringBuilder();
var inWord = false;
char? quote = null;
for (var i = 0; i < text.Length; i++)
{
var c = text[i];
if (quote == '\'')
{
if (c == '\'') quote = null; else current.Append(c);
continue;
}
if (quote == '"')
{
if (c == '"') quote = null;
else if (c == '\\' && i + 1 < text.Length && text[i + 1] is '"' or '\\') current.Append(text[++i]);
else current.Append(c);
continue;
}
if (char.IsWhiteSpace(c))
{
if (inWord) { words.Add(current.ToString()); current.Clear(); inWord = false; }
continue;
}
inWord = true;
if (c is '"' or '\'') quote = c;
else current.Append(c);
}
if (quote is { } open) throw new FormatException($"unterminated {open} quote");
if (inWord) words.Add(current.ToString());
return words;
}
}