AX Agent 코드 메시지 강조와 Git 요약 배너 개선

- Cowork/Code 메시지 마크다운 렌더에 camelCase, PascalCase, snake_case 등 코드 심볼 강조를 추가함

- 코드 탭 입력부 위에 저장소/브랜치/변경 수치 요약 배너를 추가해 claude-code 스타일의 repo context를 빠르게 확인할 수 있게 함

- README와 DEVELOPMENT 문서를 2026-04-06 20:18 (KST) 기준으로 갱신함

- 검증: dotnet build src/AxCopilot/AxCopilot.csproj -c Release -v minimal -p:OutputPath=bin\verify\ -p:IntermediateOutputPath=obj\verify\ (경고 0, 오류 0)
This commit is contained in:
2026-04-06 20:29:33 +09:00
parent 43ee9154a8
commit a19f69b2ff
7 changed files with 229 additions and 6 deletions

View File

@@ -12,6 +12,9 @@ namespace AxCopilot.Services;
/// </summary>
public static class MarkdownRenderer
{
private static readonly Brush FilePathBrush = new SolidColorBrush(Color.FromRgb(0x3B, 0x82, 0xF6));
private static readonly Brush CodeSymbolBrush = new SolidColorBrush(Color.FromRgb(0xF2, 0x8C, 0x79));
public static StackPanel Render(string markdown, Brush textColor, Brush secondaryColor, Brush accentColor, Brush codeBg)
{
var panel = new StackPanel();
@@ -272,19 +275,34 @@ public static class MarkdownRenderer
/// <summary>파일 경로 활성 여부 (설정 연동).</summary>
public static bool EnableFilePathHighlight { get; set; } = true;
/// <summary>코드 심볼 강조 활성 여부 (설정/탭 연동).</summary>
public static bool EnableCodeSymbolHighlight { get; set; } = true;
private static readonly Regex CodeSymbolPattern = new(
@"(?<![\w/\\-])(" +
@"[A-Za-z_][A-Za-z0-9_]*\(\)|" + // Method()
@"[A-Za-z_][A-Za-z0-9_]*\.[A-Za-z_][A-Za-z0-9_]*|" + // object.member
@"[A-Za-z_][A-Za-z0-9_]*_[A-Za-z0-9_]+|" + // snake_case / foo_bar
@"[a-z]+[A-Z][A-Za-z0-9_]*|" + // camelCase
@"(?:[A-Z][a-z0-9]+){2,}" + // PascalCase multi word
@")(?![\w/\\-])",
RegexOptions.Compiled);
/// <summary>일반 텍스트에서 파일 경로 패턴을 감지하여 파란색으로 강조합니다.</summary>
private static void AddPlainTextWithFilePaths(InlineCollection inlines, string text)
{
if (!EnableFilePathHighlight)
if (!EnableFilePathHighlight && !EnableCodeSymbolHighlight)
{
inlines.Add(new Run(text));
return;
}
var matches = FilePathPattern.Matches(text);
if (matches.Count == 0)
MatchCollection? matches = null;
if (EnableFilePathHighlight)
matches = FilePathPattern.Matches(text);
if (matches == null || matches.Count == 0)
{
inlines.Add(new Run(text));
AddPlainTextWithCodeSymbols(inlines, text);
return;
}
@@ -293,18 +311,54 @@ public static class MarkdownRenderer
{
// 매치 전 텍스트
if (pm.Index > lastIndex)
inlines.Add(new Run(text[lastIndex..pm.Index]));
AddPlainTextWithCodeSymbols(inlines, text[lastIndex..pm.Index]);
// 파일 경로 — 파란색 강조
inlines.Add(new Run(pm.Value)
{
Foreground = new SolidColorBrush(Color.FromRgb(0x3B, 0x82, 0xF6)), // #3B82F6
Foreground = FilePathBrush,
FontWeight = FontWeights.Medium,
});
lastIndex = pm.Index + pm.Length;
}
// 남은 텍스트
if (lastIndex < text.Length)
AddPlainTextWithCodeSymbols(inlines, text[lastIndex..]);
}
private static void AddPlainTextWithCodeSymbols(InlineCollection inlines, string text)
{
if (string.IsNullOrEmpty(text))
return;
if (!EnableCodeSymbolHighlight)
{
inlines.Add(new Run(text));
return;
}
var matches = CodeSymbolPattern.Matches(text);
if (matches.Count == 0)
{
inlines.Add(new Run(text));
return;
}
var lastIndex = 0;
foreach (Match match in matches)
{
if (match.Index > lastIndex)
inlines.Add(new Run(text[lastIndex..match.Index]));
inlines.Add(new Run(match.Value)
{
Foreground = CodeSymbolBrush,
FontWeight = FontWeights.SemiBold,
});
lastIndex = match.Index + match.Length;
}
if (lastIndex < text.Length)
inlines.Add(new Run(text[lastIndex..]));
}