Description

Create csharp webapi

Creates a new ASP.NET Core Web API C# project (dotnet new webapi). Requires JSON: name (project name), optional output (folder path).

Included in Version 7

Dynamically extracted tool implementation.
How to register CSharpProjectToolTypescsharp
public sealed class CreateWebApiProjectTool : CSharpProjectTool{    public const string Name = "create_csharp_webapi";    public override string ToolName => Name;    protected override string TemplateShortName => "webapi";    protected override string ProjectKindName => "ASP.NET Core Web API";}
Helper classes for CSharpProjectToolTypescsharp
using System.Diagnostics;using System.Text.Json;using Agent.Core.ToolCalling;namespace Agent.Addons.Tools.CSharpProjects;/// <summary>Base for addon tools that scaffold a C# project with <c>dotnet new</c>.</summary>public abstract class CSharpProjectTool : ICSharpProject{    public abstract string ToolName { get; }    protected abstract string TemplateShortName { get; }    protected abstract string ProjectKindName { get; }    public virtual string ToolDescription =>        $"Creates a new {ProjectKindName} C# project (dotnet new {TemplateShortName}). " +        "Requires JSON: name (project name), optional output (folder path).";    private static object ParametersSchema => new    {        type = "object",        properties = new        {            name = new { type = "string", description = "Project name (also used as the default folder name)." },            output = new { type = "string", description = "Optional output directory. Defaults to a folder named after the project." },        },        required = new[] { "name" },    };    public static void Register<TTool>(ToolRegistry registry)        where TTool : CSharpProjectTool, new()    {        var tool = new TTool();        registry.Register(new AgentTool(            tool.ToolName,            tool.ToolDescription,            tool.Invoke,            ParametersSchema));    }    public static void RegisterAll(ToolRegistry registry)    {        ArgumentNullException.ThrowIfNull(registry);        Register<CreateConsoleProjectTool>(registry);        Register<CreateClassLibraryProjectTool>(registry);        Register<CreateWebEmptyProjectTool>(registry);        Register<CreateGrpcProjectTool>(registry);        Register<CreateWebApiProjectTool>(registry);        Register<CreateWebApiAotProjectTool>(registry);        Register<CreateMvcProjectTool>(registry);        Register<CreateRazorProjectTool>(registry);        Register<CreateBlazorProjectTool>(registry);        Register<CreateBlazorWasmProjectTool>(registry);        Register<CreateRazorClassLibraryProjectTool>(registry);        Register<CreateWorkerProjectTool>(registry);        Register<CreateWinFormsProjectTool>(registry);        Register<CreateWinFormsLibraryProjectTool>(registry);        Register<CreateWinFormsControlLibraryProjectTool>(registry);        Register<CreateWpfProjectTool>(registry);        Register<CreateWpfLibraryProjectTool>(registry);        Register<CreateWpfCustomControlLibraryProjectTool>(registry);        Register<CreateWpfUserControlLibraryProjectTool>(registry);        Register<CreateMstestProjectTool>(registry);        Register<CreateMstestPlaywrightProjectTool>(registry);        Register<CreateNunitProjectTool>(registry);        Register<CreateNunitPlaywrightProjectTool>(registry);        Register<CreateXunitProjectTool>(registry);    }    private string Invoke(string argumentsJson)    {        if (!TryParseArguments(argumentsJson, out string name, out string? output, out string error))        {            return error;        }        return Create(name, output);    }    public string Create(string name, string? outputDirectory = null)    {        string projectName = name.Trim();        if (string.IsNullOrWhiteSpace(projectName))        {            return "Error: Provide a project name (JSON property \"name\").";        }        string outputPath = string.IsNullOrWhiteSpace(outputDirectory)            ? projectName            : outputDirectory.Trim();        try        {            using var process = StartDotNetNew(projectName, outputPath);            string stdout = process.StandardOutput.ReadToEnd();            string stderr = process.StandardError.ReadToEnd();            process.WaitForExit();            if (process.ExitCode == 0)            {                return $"Created {ProjectKindName} '{projectName}' at '{Path.GetFullPath(outputPath)}'.{FormatProcessOutput(stdout)}";            }            return $"Failed to create {ProjectKindName} '{projectName}': {TrimOrDefault(stderr, stdout, "dotnet new returned a non-zero exit code.")}";        }        catch (Exception ex)        {            return $"Failed to create {ProjectKindName} '{projectName}': {ex.Message}";        }    }    private Process StartDotNetNew(string projectName, string outputPath)    {        var startInfo = new ProcessStartInfo        {            FileName = "dotnet",            RedirectStandardOutput = true,            RedirectStandardError = true,            UseShellExecute = false,            CreateNoWindow = true,        };        startInfo.ArgumentList.Add("new");        startInfo.ArgumentList.Add(TemplateShortName);        startInfo.ArgumentList.Add("-n");        startInfo.ArgumentList.Add(projectName);        startInfo.ArgumentList.Add("-o");        startInfo.ArgumentList.Add(outputPath);        startInfo.ArgumentList.Add("--language");        startInfo.ArgumentList.Add("C#");        return Process.Start(startInfo)            ?? throw new InvalidOperationException("Could not start dotnet CLI.");    }    private static bool TryParseArguments(        string argumentsJson,        out string name,        out string? output,        out string error)    {        name = "";        output = null;        error = "";        try        {            using var doc = JsonDocument.Parse(argumentsJson);            var root = doc.RootElement;            if (root.TryGetProperty("name", out var nameProp))            {                name = nameProp.GetString()?.Trim() ?? "";            }            if (root.TryGetProperty("output", out var outputProp))            {                string? outputValue = outputProp.GetString()?.Trim();                if (!string.IsNullOrWhiteSpace(outputValue))                {                    output = outputValue;                }            }            if (string.IsNullOrWhiteSpace(name))            {                error = "Error: Provide a project name (JSON property \"name\").";                return false;            }            return true;        }        catch (JsonException ex)        {            error = $"Error: Invalid JSON arguments — {ex.Message}";            return false;        }    }    private static string FormatProcessOutput(string stdout)    {        string trimmed = stdout.Trim();        return string.IsNullOrWhiteSpace(trimmed) ? "" : $"\n{trimmed}";    }    private static string TrimOrDefault(string primary, string secondary, string fallback)    {        string message = primary.Trim();        if (!string.IsNullOrWhiteSpace(message))        {            return message;        }        message = secondary.Trim();        return string.IsNullOrWhiteSpace(message) ? fallback : message;    }}
Implementation of ICSharpProjectcsharp
namespace Agent.Addons.Tools.CSharpProjects;/// <summary>Creates a C# project via <c>dotnet new</c> when invoked as an agent tool.</summary>public interface ICSharpProject{    string ToolName { get; }    string ToolDescription { get; }    string Create(string name, string? outputDirectory = null);}