AX Agent 내부 설정 MCP 서버 관리와 대화 스타일 섹션 복구
Some checks failed
Release Gate / gate (push) Has been cancelled

- AX Agent 내부 설정 공통 탭에 대화 스타일 섹션 제목을 복구해 문서 형태/디자인 스타일 저장 항목을 명확히 노출

- 스킬 탭 MCP 서버 영역에 서버 추가 버튼을 복원하고 목록 카드에서 활성화 전환과 삭제를 바로 처리하도록 보강

- 오버레이 저장 경로를 그대로 사용해 내부 설정에서 변경 즉시 저장되도록 유지

- README와 DEVELOPMENT 문서에 2026-04-06 00:45 (KST) 기준 이력 반영 및 Release 빌드 경고 0 오류 0 확인
This commit is contained in:
2026-04-05 22:09:29 +09:00
parent 1948af3cc4
commit d0fa54f10e
4 changed files with 195 additions and 22 deletions

View File

@@ -7,6 +7,10 @@ Windows 전용 시맨틱 런처 & 워크스페이스 매니저
개발 참고: Claw Code 동등성 작업 추적 문서
`docs/claw-code-parity-plan.md`
- 업데이트: 2026-04-06 00:45 (KST)
- AX Agent 내부 설정 공통 탭에 `대화 스타일` 섹션 제목을 복구해, `문서 형태``디자인 스타일` 저장 항목이 명확히 보이도록 정리했습니다.
- AX Agent 내부 설정 스킬 탭의 `MCP 서버` 영역에 `서버 추가` 버튼을 복원했고, 목록 카드 안에서 `활성화/비활성화``삭제`까지 바로 관리할 수 있게 옮겼습니다.
- 업데이트: 2026-04-05 19:04 (KST)
- AX Agent transcript와 작업 요약에서 도구/스킬 이름을 사람이 읽기 쉬운 표시명으로 정리했습니다. raw snake_case 도구명 대신 `파일 읽기`, `빌드/실행`, `Git`, `/bug-hunt` 같은 표시명 중심으로 보입니다.
- 도구/스킬 이벤트 배지는 역할 중심(`도구`, `도구 결과`, `스킬`)으로 단순화하고, 실제 도구명은 본문 보조 텍스트로만 노출되게 바꿨습니다.

View File

@@ -4851,3 +4851,5 @@ ow + toggle ?쒓컖 ?몄뼱濡??ㅼ떆 ?뺣젹?덈떎.
- [PermissionRequestWindow.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/PermissionRequestWindow.cs) 의 `BuildPreviewCard`, `BuildFileEditPreviewCard`, `BuildFileWriteTwoColumnPreviewCard`는 이 helper를 쓰도록 정리해 권한 승인 프리뷰가 같은 preview 언어를 따르도록 맞췄다.
- [ChatWindow.xaml](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.xaml) 의 우측 프리뷰 패널 헤더를 `파일명 / 경로 / 형식·크기 메타` 구조로 재배치하고, [ChatWindow.xaml.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.xaml.cs) 에 `SetPreviewHeader`, `SetPreviewHeaderState`를 추가해 현재 탭 파일 메타를 표시하도록 했다.
- 텍스트 프리뷰 본문도 bordered preview box 안에 렌더되게 바꿔, AX Agent 파일 프리뷰와 transcript/승인 프리뷰 사이 시각 언어를 더 가깝게 맞췄다.
- Document update: 2026-04-06 00:45 (KST) - Restored the missing AX Agent internal-settings UX for conversation-style persistence by adding a visible `대화 스타일` section header above the existing `문서 형태` and `디자인 스타일` controls. The underlying save path already existed in `CmbOverlayDefaultOutputFormat_SelectionChanged` and `CmbOverlayDefaultMood_SelectionChanged`; this pass makes that persisted behavior explicit again in the overlay.
- Document update: 2026-04-06 00:45 (KST) - Restored MCP server management inside the AX Agent internal settings overlay. The skill tab now exposes `+ 서버 추가`, and overlay MCP cards support inline enable/disable and delete actions with immediate persistence through `PersistOverlaySettingsState(...)`.

View File

@@ -3111,6 +3111,16 @@
Checked="ChkOverlayAiEnabled_Changed"
Unchecked="ChkOverlayAiEnabled_Changed"/>
</Grid>
<StackPanel Margin="0,4,0,12">
<TextBlock Text="대화 스타일"
FontSize="13"
FontWeight="SemiBold"
Foreground="{DynamicResource PrimaryText}"/>
<TextBlock Text="응답 결과물의 기본 형태와 문서 분위기를 여기서 저장합니다."
Margin="0,4,0,0"
FontSize="11"
Foreground="{DynamicResource SecondaryText}"/>
</StackPanel>
<Grid x:Name="OverlayDefaultOutputFormatRow" Margin="0,0,0,8">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
@@ -5187,10 +5197,39 @@
<StackPanel x:Name="OverlayFallbackModelsPanel"/>
</Border>
<TextBlock Text="MCP 서버"
FontSize="12.5"
FontWeight="SemiBold"
Foreground="{DynamicResource PrimaryText}"/>
<Grid Margin="0,0,0,4">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<StackPanel>
<TextBlock Text="MCP 서버"
FontSize="12.5"
FontWeight="SemiBold"
Foreground="{DynamicResource PrimaryText}"/>
<TextBlock Text="외부 도구 서버를 등록하면 AX Agent가 연결된 기능을 사용할 수 있습니다."
Margin="0,4,0,0"
FontSize="11"
Foreground="{DynamicResource SecondaryText}"/>
</StackPanel>
<Button x:Name="BtnOverlayAddMcpServer"
Grid.Column="1"
Padding="12,6"
Cursor="Hand"
Click="BtnOverlayAddMcpServer_Click">
<StackPanel Orientation="Horizontal">
<TextBlock Text="&#xE710;"
FontFamily="Segoe MDL2 Assets"
FontSize="11"
Margin="0,0,5,0"
VerticalAlignment="Center"/>
<TextBlock Text="서버 추가"
FontSize="11.5"
Foreground="{DynamicResource AccentColor}"
VerticalAlignment="Center"/>
</StackPanel>
</Button>
</Grid>
<Border Background="{DynamicResource ItemBackground}"
BorderBrush="{DynamicResource BorderColor}"
BorderThickness="1"

View File

@@ -15656,49 +15656,177 @@ public partial class ChatWindow : Window
OverlayMcpServerListPanel.Children.Clear();
var servers = _settings.Settings.Llm.McpServers;
var primaryText = TryFindResource("PrimaryText") as Brush ?? Brushes.Black;
var secondaryText = TryFindResource("SecondaryText") as Brush ?? Brushes.Gray;
var accentBrush = TryFindResource("AccentColor") as Brush ?? Brushes.DodgerBlue;
var borderBrush = TryFindResource("BorderColor") as Brush ?? Brushes.LightGray;
var itemBackground = TryFindResource("ItemBackground") as Brush ?? Brushes.White;
var cardBackground = TryFindResource("LauncherBackground") as Brush ?? Brushes.White;
if (servers == null || servers.Count == 0)
{
OverlayMcpServerListPanel.Children.Add(new TextBlock
{
Text = "등록된 MCP 서버가 없습니다.",
FontSize = 11,
Foreground = TryFindResource("SecondaryText") as Brush ?? Brushes.Gray
Foreground = secondaryText
});
return;
}
foreach (var server in servers)
Border CreateActionChip(string text, Brush foreground, Action onClick)
{
var card = new Border
var border = new Border
{
Background = TryFindResource("LauncherBackground") as Brush ?? Brushes.White,
BorderBrush = TryFindResource("BorderColor") as Brush ?? Brushes.LightGray,
Background = Brushes.Transparent,
BorderBrush = Brushes.Transparent,
BorderThickness = new Thickness(1),
CornerRadius = new CornerRadius(8),
Padding = new Thickness(10, 8, 10, 8),
Padding = new Thickness(8, 4, 8, 4),
Margin = new Thickness(6, 0, 0, 0),
Cursor = Cursors.Hand,
};
var label = new TextBlock
{
Text = text,
FontSize = 11,
FontWeight = FontWeights.SemiBold,
Foreground = foreground,
VerticalAlignment = VerticalAlignment.Center,
};
border.Child = label;
border.MouseEnter += (_, _) =>
{
border.Background = TryFindResource("HintBackground") as Brush ?? new SolidColorBrush(Color.FromArgb(20, 0, 0, 0));
border.BorderBrush = borderBrush;
};
border.MouseLeave += (_, _) =>
{
border.Background = Brushes.Transparent;
border.BorderBrush = Brushes.Transparent;
};
border.MouseLeftButtonUp += (_, _) => onClick();
return border;
}
for (int index = 0; index < servers.Count; index++)
{
var server = servers[index];
var card = new Border
{
Background = cardBackground,
BorderBrush = borderBrush,
BorderThickness = new Thickness(1),
CornerRadius = new CornerRadius(8),
Padding = new Thickness(12, 10, 12, 10),
Margin = new Thickness(0, 0, 0, 6)
};
var stack = new StackPanel();
stack.Children.Add(new TextBlock
var root = new StackPanel();
var header = new Grid();
header.ColumnDefinitions.Add(new ColumnDefinition());
header.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
var title = new TextBlock
{
Text = server.Name,
FontSize = 12,
FontWeight = FontWeights.SemiBold,
Foreground = TryFindResource("PrimaryText") as Brush ?? Brushes.Black
});
stack.Children.Add(new TextBlock
Foreground = primaryText,
VerticalAlignment = VerticalAlignment.Center
};
header.Children.Add(title);
var actions = new StackPanel
{
Text = $"{server.Command} {(server.Enabled ? "· " : "· ")}",
Margin = new Thickness(0, 3, 0, 0),
FontSize = 10.5,
TextWrapping = TextWrapping.Wrap,
Foreground = TryFindResource("SecondaryText") as Brush ?? Brushes.Gray
});
card.Child = stack;
Orientation = Orientation.Horizontal,
HorizontalAlignment = HorizontalAlignment.Right,
};
actions.Children.Add(CreateActionChip(server.Enabled ? "비활성화" : "활성화", accentBrush, () =>
{
_settings.Settings.Llm.McpServers[index].Enabled = !_settings.Settings.Llm.McpServers[index].Enabled;
PersistOverlaySettingsState(refreshOverlayDeferredInputs: false);
BuildOverlayMcpServerCards();
}));
actions.Children.Add(CreateActionChip("삭제", BrushFromHex("#DC2626"), () =>
{
var result = CustomMessageBox.Show($"'{server.Name}' 서버를 삭제하시겠습니까?", "MCP 서버 삭제",
MessageBoxButton.YesNo, MessageBoxImage.Question);
if (result != MessageBoxResult.Yes)
return;
_settings.Settings.Llm.McpServers.RemoveAt(index);
PersistOverlaySettingsState(refreshOverlayDeferredInputs: false);
BuildOverlayMcpServerCards();
}));
Grid.SetColumn(actions, 1);
header.Children.Add(actions);
root.Children.Add(header);
var commandCard = new Border
{
Background = itemBackground,
BorderBrush = borderBrush,
BorderThickness = new Thickness(1),
CornerRadius = new CornerRadius(8),
Padding = new Thickness(10, 8, 10, 8),
Margin = new Thickness(0, 8, 0, 0),
Child = new StackPanel
{
Children =
{
new TextBlock
{
Text = server.Command,
FontSize = 10.8,
TextWrapping = TextWrapping.Wrap,
Foreground = primaryText,
},
new TextBlock
{
Text = server.Enabled ? "활성 상태" : "비활성 상태",
Margin = new Thickness(0, 4, 0, 0),
FontSize = 10.5,
Foreground = secondaryText,
}
}
}
};
root.Children.Add(commandCard);
card.Child = root;
OverlayMcpServerListPanel.Children.Add(card);
}
}
private void BtnOverlayAddMcpServer_Click(object sender, RoutedEventArgs e)
{
var nameDialog = new InputDialog("MCP 서버 추가", "서버 이름:", placeholder: "예: my-mcp-server")
{
Owner = this
};
if (nameDialog.ShowDialog() != true || string.IsNullOrWhiteSpace(nameDialog.ResponseText))
return;
var commandDialog = new InputDialog("MCP 서버 추가", "실행 명령:", placeholder: "예: npx -y @modelcontextprotocol/server-filesystem")
{
Owner = this
};
if (commandDialog.ShowDialog() != true || string.IsNullOrWhiteSpace(commandDialog.ResponseText))
return;
_settings.Settings.Llm.McpServers.Add(new Models.McpServerEntry
{
Name = nameDialog.ResponseText.Trim(),
Command = commandDialog.ResponseText.Trim(),
Enabled = true,
});
PersistOverlaySettingsState(refreshOverlayDeferredInputs: false);
BuildOverlayMcpServerCards();
}
private void BuildOverlayToolRegistryPanel()
{
if (OverlayToolRegistryPanel == null)