namespace Sdt.Cli; public static class CliParser { private static readonly HashSet SubcommandRoots = new(StringComparer.OrdinalIgnoreCase) { "workspace", "bridge", "setup", "doctor", "env", "favorite", "config", }; public static CliInvocation Parse(IReadOnlyList args) { if (args.Count == 0) return new CliInvocation("interactive", null, [], new Dictionary(StringComparer.OrdinalIgnoreCase)); if (args.Any(a => string.Equals(a, "--plain", StringComparison.OrdinalIgnoreCase))) ApplyPlainOutputMode(); if (args.Count == 1 && (string.Equals(args[0], "--help", StringComparison.OrdinalIgnoreCase) || string.Equals(args[0], "-h", StringComparison.OrdinalIgnoreCase) || string.Equals(args[0], "help", StringComparison.OrdinalIgnoreCase))) { return new CliInvocation("help", null, [], new Dictionary(StringComparer.OrdinalIgnoreCase)); } if (args.Count == 1 && (string.Equals(args[0], "init", StringComparison.OrdinalIgnoreCase) || string.Equals(args[0], "--init", StringComparison.OrdinalIgnoreCase))) { return new CliInvocation("init", null, [], new Dictionary(StringComparer.OrdinalIgnoreCase)); } var command = args[0]; string? subcommand = null; var optionStart = args.Count; if (SubcommandRoots.Contains(command) && args.Count > 1 && !args[1].StartsWith("-", StringComparison.Ordinal)) { subcommand = args[1]; optionStart = 2; } else { optionStart = 1; } var tail = args.Skip(optionStart).ToArray(); var options = ParseOptions(tail, out var positional); return new CliInvocation(command, subcommand, positional, options); } private static Dictionary ParseOptions(string[] args, out List positional) { var options = new Dictionary(StringComparer.OrdinalIgnoreCase); positional = []; for (var i = 0; i < args.Length; i++) { var token = args[i]; if (!token.StartsWith("-", StringComparison.Ordinal)) { positional.Add(token); continue; } if (i + 1 < args.Length && !args[i + 1].StartsWith("-", StringComparison.Ordinal)) { options[token] = args[i + 1]; i++; } else { options[token] = null; } } return options; } private static void ApplyPlainOutputMode() { Environment.SetEnvironmentVariable("NO_COLOR", "1"); Environment.SetEnvironmentVariable("SDT_NO_COLOR", "1"); Environment.SetEnvironmentVariable("SDT_NO_UNICODE", "1"); } }