diff --git a/src/PRDigest.NET/HtmlGenerator.cs b/src/PRDigest.NET/HtmlGenerator.cs index 8ad1682..3bb8632 100644 --- a/src/PRDigest.NET/HtmlGenerator.cs +++ b/src/PRDigest.NET/HtmlGenerator.cs @@ -82,15 +82,25 @@ public static string GenerateIndex(string archivesDir, string outputsDir)
{analyzerResult.PullRequestTotalCount}
-
マージされたPR
+
PR 数(Total)
-
{analyzerResult.PullRequestCountForBot}
-
マージされたPR(Bot)
+
{analyzerResult.PullRequestCountForCommunity}
+
PR 数(Community)
+
+
+
{analyzerResult.PullRequestCountForAiAgent}
+
PR 数(AI Agent)
+
{analyzerResult.PullRequestCountForBot}
+
PR 数(Bot)
+
+
+
+
{analyzerResult.LabelCount}
-
ラベル種類
+
ラベルタイプ数
"""; @@ -218,6 +228,7 @@ private static string GenerateCategorizedTocHtml(PullRequestAnalyzer.AnalysisRes var builder = new DefaultInterpolatedStringHandler(0, 0); builder.AppendLiteral($"

カテゴリ別PR一覧

"); builder.AppendLiteral(Environment.NewLine); + // Community PRs (expanded) var communityCount = analyzerResult.CommunityPullRequestMetadataSpan.Length; builder.AppendLiteral($"
"); @@ -239,6 +250,25 @@ private static string GenerateCategorizedTocHtml(PullRequestAnalyzer.AnalysisRes builder.AppendLiteral("
"); builder.AppendLiteral(Environment.NewLine); + // AI Agent PRs (collapsed) + var aiAgentCount = analyzerResult.AiAgentPullRequestMetadataSpan.Length; + builder.AppendLiteral("
"); + builder.AppendLiteral(Environment.NewLine); + builder.AppendLiteral(" AI Agent PRs ("); + builder.AppendFormatted(aiAgentCount); + builder.AppendLiteral(" PRs)"); + builder.AppendLiteral(Environment.NewLine); + builder.AppendLiteral("
    "); + builder.AppendLiteral(Environment.NewLine); + foreach (var heading in analyzerResult.AiAgentPullRequestMetadataSpan) + { + AppendHeadingListItem(ref builder, heading); + } + builder.AppendLiteral("
"); + builder.AppendLiteral(Environment.NewLine); + builder.AppendLiteral("
"); + builder.AppendLiteral(Environment.NewLine); + // Bot PRs (collapsed) var botCount = analyzerResult.BotPullRequestMetadataSpan.Length; builder.AppendLiteral("
"); @@ -647,9 +677,16 @@ footer p { .stats-grid { display: grid; - grid-template-columns: repeat(3, 1fr); + grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 16px; - margin: 16px 0 24px 0; + margin: 16px 0 8px 0; + } + + .stats-label-row { + display: grid; + grid-template-columns: repeat(4, minmax(0, 1fr)); + gap: 16px; + margin: 0 0 24px 0; } .stat-card { @@ -658,6 +695,7 @@ footer p { border-radius: 8px; padding: 24px; text-align: center; + min-width: 0; } .stat-value { @@ -672,6 +710,7 @@ footer p { font-size: 14px; color: #6b7280; margin-top: 4px; + overflow-wrap: break-word; } .view-tabs { @@ -812,6 +851,11 @@ pre code { font-size: 16px; } + .stats-grid, + .stats-label-row { + grid-template-columns: repeat(2, minmax(0, 1fr)); + } + .stat-value { font-size: 28px; } diff --git a/src/PRDigest.NET/PullRequestAnalyzer.cs b/src/PRDigest.NET/PullRequestAnalyzer.cs index c3c0617..a2dae2d 100644 --- a/src/PRDigest.NET/PullRequestAnalyzer.cs +++ b/src/PRDigest.NET/PullRequestAnalyzer.cs @@ -28,13 +28,13 @@ public static AnalysisResults Analyze(MarkdownDocument document) var currentPosition = PullRequestPosition.None; var tableOfContents = false; var pullRequestTotalCount = 0; - var pullRequestCountForBot = 0; HeadingBlock? nextPullRequestNumber = null; HashSet? pullRequestNumberTable = null; Dictionary> labelTable = []; Dictionary labelColorMap = []; List botPullRequestHeadings = []; List communityPrHeadings = []; + List aiAgentPullRequestHeadings = []; Metadata currentMetadata = default; Dictionary pullRequestInfoTable = []; @@ -132,18 +132,20 @@ public static AnalysisResults Analyze(MarkdownDocument document) prList.Add(currentMetadata); } - var user = metadataList[0]?.Descendants().Skip(1).FirstOrDefault(); - if (user is not null) + var userLiteralInlines = metadataList[0]?.Descendants(); + if (userLiteralInlines is not null && userLiteralInlines.Any()) { - var userName = user.Content.ToString().Trim(); + var userName = string.Concat(userLiteralInlines.Select(literal => literal.Content.ToString())).Trim(); - // check ..[bot].. or @Copilot to count bot PRs - if (userName.EndsWith("[bot]", StringComparison.OrdinalIgnoreCase) || - userName.IndexOf("@Copilot", StringComparison.OrdinalIgnoreCase) > -1) + // check ..[bot].. to count bot PRs, @Copilot to count AI agent PRs + if (userName.EndsWith("[bot]", StringComparison.OrdinalIgnoreCase)) { - pullRequestCountForBot++; botPullRequestHeadings.Add(currentMetadata); } + else if (userName.IndexOf("@Copilot", StringComparison.OrdinalIgnoreCase) > -1) + { + aiAgentPullRequestHeadings.Add(currentMetadata); + } else { communityPrHeadings.Add(currentMetadata); @@ -184,11 +186,11 @@ public static AnalysisResults Analyze(MarkdownDocument document) return new AnalysisResults( pullRequestTotalCount, - pullRequestCountForBot, labelTable.ToFrozenDictionary(kvp => kvp.Key, kvp => kvp.Value.ToImmutableArray()), labelColorMap.ToFrozenDictionary(), botPullRequestHeadings, communityPrHeadings, + aiAgentPullRequestHeadings, pullRequestInfoTable.ToFrozenDictionary()); } @@ -294,20 +296,24 @@ private static string GetOverview(ContainerInline? inline) public sealed class AnalysisResults( int pullRequestTotalCount, - int pullRequestCountForBot, FrozenDictionary> labelMap, FrozenDictionary labelColorMap, List botPullRequestMetadata, List communityPullRequestMetadata, + List aiAgentPullRequestMetadata, FrozenDictionary summaryMap) { public int PullRequestTotalCount => pullRequestTotalCount; - public int PullRequestCountForBot => pullRequestCountForBot; + + public int PullRequestCountForCommunity => communityPullRequestMetadata.Count; + public int PullRequestCountForBot => botPullRequestMetadata.Count; + public int PullRequestCountForAiAgent => aiAgentPullRequestMetadata.Count; public FrozenDictionary> LabelMap => labelMap; public FrozenDictionary LabelColorGroups => labelColorMap; public int LabelCount => LabelMap.Count; public ReadOnlySpan CommunityPullRequestMetadataSpan => CollectionsMarshal.AsSpan(communityPullRequestMetadata); public ReadOnlySpan BotPullRequestMetadataSpan => CollectionsMarshal.AsSpan(botPullRequestMetadata); + public ReadOnlySpan AiAgentPullRequestMetadataSpan => CollectionsMarshal.AsSpan(aiAgentPullRequestMetadata); public FrozenDictionary SummaryMap => summaryMap; }