136 lines
4.9 KiB
C#
136 lines
4.9 KiB
C#
using MarketAlly.AIPlugin;
|
|
|
|
namespace MarketAlly.GitCommitEditor.Plugins;
|
|
|
|
/// <summary>
|
|
/// Valid conventional commit types
|
|
/// </summary>
|
|
public enum CommitType
|
|
{
|
|
/// <summary>New feature</summary>
|
|
feat,
|
|
/// <summary>Bug fix</summary>
|
|
fix,
|
|
/// <summary>Documentation only</summary>
|
|
docs,
|
|
/// <summary>Formatting, whitespace (no code change)</summary>
|
|
style,
|
|
/// <summary>Code change that neither fixes a bug nor adds a feature</summary>
|
|
refactor,
|
|
/// <summary>Performance improvement</summary>
|
|
perf,
|
|
/// <summary>Adding or updating tests</summary>
|
|
test,
|
|
/// <summary>Build system or dependencies</summary>
|
|
build,
|
|
/// <summary>CI/CD configuration</summary>
|
|
ci,
|
|
/// <summary>Maintenance tasks, logging, tooling</summary>
|
|
chore
|
|
}
|
|
|
|
/// <summary>
|
|
/// Result model for the commit message generation
|
|
/// </summary>
|
|
public class CommitMessageResult
|
|
{
|
|
public CommitType Type { get; set; } = CommitType.chore;
|
|
public string? Scope { get; set; }
|
|
public string Description { get; set; } = string.Empty;
|
|
public string Body { get; set; } = string.Empty;
|
|
|
|
/// <summary>
|
|
/// Gets the formatted subject line: type(scope): description
|
|
/// </summary>
|
|
public string Subject => string.IsNullOrEmpty(Scope)
|
|
? $"{Type}: {Description}"
|
|
: $"{Type}({Scope}): {Description}";
|
|
}
|
|
|
|
/// <summary>
|
|
/// AI Plugin for generating improved commit messages following conventional commit format
|
|
/// </summary>
|
|
[AIPlugin("GenerateCommitMessage", "Generates an improved git commit message based on the original message, changed files, and diff content. Returns a structured result with subject line and optional body.")]
|
|
public class GenerateCommitMessagePlugin : IAIPlugin
|
|
{
|
|
[AIParameter("The original commit message to improve", required: true)]
|
|
public string OriginalMessage { get; set; } = string.Empty;
|
|
|
|
[AIParameter("List of file paths that were changed in the commit", required: true)]
|
|
public List<string> FilesChanged { get; set; } = new();
|
|
|
|
[AIParameter("Number of lines added in the commit", required: true)]
|
|
public int LinesAdded { get; set; }
|
|
|
|
[AIParameter("Number of lines deleted in the commit", required: true)]
|
|
public int LinesDeleted { get; set; }
|
|
|
|
[AIParameter("Summary of the diff/changes (truncated)", required: false)]
|
|
public string? DiffSummary { get; set; }
|
|
|
|
[AIParameter("List of quality issues detected in the original message", required: false)]
|
|
public List<string>? QualityIssues { get; set; }
|
|
|
|
public IReadOnlyDictionary<string, Type> SupportedParameters => new Dictionary<string, Type>
|
|
{
|
|
["originalMessage"] = typeof(string),
|
|
["filesChanged"] = typeof(List<string>),
|
|
["linesAdded"] = typeof(int),
|
|
["linesDeleted"] = typeof(int),
|
|
["diffSummary"] = typeof(string),
|
|
["qualityIssues"] = typeof(List<string>)
|
|
};
|
|
|
|
public Task<AIPluginResult> ExecuteAsync(IReadOnlyDictionary<string, object> parameters)
|
|
{
|
|
var result = new CommitMessageResult
|
|
{
|
|
Type = CommitType.chore,
|
|
Description = OriginalMessage,
|
|
Body = string.Empty
|
|
};
|
|
|
|
return Task.FromResult(new AIPluginResult(result, "Commit message generated"));
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// AI Plugin that the AI calls to return the generated commit message
|
|
/// </summary>
|
|
[AIPlugin("ReturnCommitMessage", "Returns the generated commit message. Call this after analyzing the commit to provide the improved message in conventional commit format.")]
|
|
public class ReturnCommitMessagePlugin : IAIPlugin
|
|
{
|
|
[AIParameter("The commit type", required: true)]
|
|
public CommitType Type { get; set; } = CommitType.chore;
|
|
|
|
[AIParameter("Optional scope/area of the codebase affected (e.g., 'api', 'ui', 'auth'). Omit if not applicable.", required: false)]
|
|
public string? Scope { get; set; }
|
|
|
|
[AIParameter("Short description of the change (max 60 chars, imperative mood, no period). Example: 'add user authentication'", required: true)]
|
|
public string Description { get; set; } = string.Empty;
|
|
|
|
[AIParameter("Optional extended description explaining what changed and why. Leave empty if the subject is self-explanatory.", required: false)]
|
|
public string Body { get; set; } = string.Empty;
|
|
|
|
public IReadOnlyDictionary<string, Type> SupportedParameters => new Dictionary<string, Type>
|
|
{
|
|
["type"] = typeof(CommitType),
|
|
["scope"] = typeof(string),
|
|
["description"] = typeof(string),
|
|
["body"] = typeof(string)
|
|
};
|
|
|
|
public Task<AIPluginResult> ExecuteAsync(IReadOnlyDictionary<string, object> parameters)
|
|
{
|
|
var result = new CommitMessageResult
|
|
{
|
|
Type = Type,
|
|
Scope = Scope,
|
|
Description = Description,
|
|
Body = Body ?? string.Empty
|
|
};
|
|
|
|
return Task.FromResult(new AIPluginResult(result, "Commit message returned"));
|
|
}
|
|
}
|