코드 탭 작업 폴더 동기화 불일치 수정 및 빠른 전송 안정화

작업 폴더 선택 시 현재 대화가 없더라도 Code/Cowork 대화를 즉시 확보하고 WorkFolder를 먼저 기록하도록 보강했다.

새 Code/Cowork 대화가 탭별 최근 작업 폴더를 기본으로 승계하도록 ChatSessionStateService를 조정하고, 현재 폴더 표시도 CodeWorkFolder/CoworkWorkFolder를 우선 사용하도록 맞췄다.

작업 폴더 해제 시 대화 메타데이터와 탭별 저장 폴더를 함께 초기화하도록 정리했다.

검증: dotnet build src/AxCopilot/AxCopilot.csproj -c Release -v minimal -p:OutputPath=bin\\verify_workfolder_sync\\ -p:IntermediateOutputPath=obj\\verify_workfolder_sync\\ / dotnet test src/AxCopilot.Tests/AxCopilot.Tests.csproj -c Release -v minimal --filter ChatSessionStateServiceTests -p:OutputPath=bin\\verify_workfolder_sync_tests\\ -p:IntermediateOutputPath=obj\\verify_workfolder_sync_tests\
This commit is contained in:
2026-04-15 14:18:14 +09:00
parent d58cf2c093
commit b260008663
5 changed files with 77 additions and 2 deletions

View File

@@ -168,7 +168,7 @@ public sealed class ChatSessionStateService
if (string.Equals(normalizedTab, "Code", StringComparison.OrdinalIgnoreCase)
|| string.Equals(normalizedTab, "Cowork", StringComparison.OrdinalIgnoreCase))
{
created.WorkFolder = "";
created.WorkFolder = ResolveDefaultWorkFolderForTab(normalizedTab, settings);
try
{
var currentPerm = AxCopilot.Services.Agent.PermissionModeCatalog.NormalizeGlobalMode(
@@ -187,6 +187,24 @@ public sealed class ChatSessionStateService
return created;
}
private static string ResolveDefaultWorkFolderForTab(string normalizedTab, ISettingsService settings)
{
var llm = settings.Settings.Llm;
var tabFolder = normalizedTab switch
{
"Code" => llm.CodeWorkFolder,
"Cowork" => llm.CoworkWorkFolder,
_ => "",
};
if (!string.IsNullOrWhiteSpace(tabFolder))
return tabFolder;
return string.Equals(normalizedTab, "Chat", StringComparison.OrdinalIgnoreCase)
? ""
: llm.WorkFolder ?? "";
}
public ChatConversation CreateBranchConversation(
ChatConversation source,
int atIndex,

View File

@@ -2187,6 +2187,9 @@ public partial class ChatWindow : Window
ChatConversation? convToPersist = null;
lock (_convLock)
{
if (_currentConversation == null && (_activeTab is "Cowork" or "Code"))
_currentConversation = ChatSession?.EnsureCurrentConversation(_activeTab) ?? new ChatConversation { Tab = _activeTab };
if (_currentConversation != null)
{
var session = ChatSession;
@@ -2240,6 +2243,15 @@ public partial class ChatWindow : Window
if (_currentConversation != null && !string.IsNullOrEmpty(_currentConversation.WorkFolder))
return _currentConversation.WorkFolder;
}
if (string.Equals(_activeTab, "Code", StringComparison.OrdinalIgnoreCase)
&& !string.IsNullOrWhiteSpace(_settings.Settings.Llm.CodeWorkFolder))
return _settings.Settings.Llm.CodeWorkFolder;
if (string.Equals(_activeTab, "Cowork", StringComparison.OrdinalIgnoreCase)
&& !string.IsNullOrWhiteSpace(_settings.Settings.Llm.CoworkWorkFolder))
return _settings.Settings.Llm.CoworkWorkFolder;
return _settings.Settings.Llm.WorkFolder;
}
@@ -2331,6 +2343,7 @@ public partial class ChatWindow : Window
private void BtnFolderClear_Click(object sender, RoutedEventArgs e)
{
var currentFolder = GetCurrentWorkFolder();
ViewModel.WorkFolder = "";
lock (_convLock)
{
@@ -2343,6 +2356,21 @@ public partial class ChatWindow : Window
_currentConversation.WorkFolder = "";
}
}
if (string.Equals(_activeTab, "Code", StringComparison.OrdinalIgnoreCase))
_settings.Settings.Llm.CodeWorkFolder = "";
else if (string.Equals(_activeTab, "Cowork", StringComparison.OrdinalIgnoreCase))
_settings.Settings.Llm.CoworkWorkFolder = "";
if (!string.IsNullOrWhiteSpace(currentFolder)
&& string.Equals(_settings.Settings.Llm.WorkFolder, currentFolder, StringComparison.OrdinalIgnoreCase))
_settings.Settings.Llm.WorkFolder = "";
ScheduleSettingsSave();
RefreshContextUsageVisual();
RefreshInputWatermarkText();
UpdateFolderSelectButtonStyle();
UpdateConditionalSkillActivation(reset: true, reloadSkillSources: true);
}
/// <summary>현재 대화의 개별 설정을 로드합니다. null이면 전역 기본값 사용.</summary>