@@ -22,6 +22,22 @@ public class McpSettingsSection
2222 private Toggle debugLogsToggle ;
2323 private EnumField validationLevelField ;
2424 private Label validationDescription ;
25+ private Foldout advancedSettingsFoldout ;
26+ private TextField uvxPathOverride ;
27+ private Button browseUvxButton ;
28+ private Button clearUvxButton ;
29+ private VisualElement uvxPathStatus ;
30+ private TextField gitUrlOverride ;
31+ private Button browseGitUrlButton ;
32+ private Button clearGitUrlButton ;
33+ private TextField deploySourcePath ;
34+ private Button browseDeploySourceButton ;
35+ private Button clearDeploySourceButton ;
36+ private Button deployButton ;
37+ private Button deployRestoreButton ;
38+ private Label deployTargetLabel ;
39+ private Label deployBackupLabel ;
40+ private Label deployStatusLabel ;
2541
2642 // Data
2743 private ValidationLevel currentValidationLevel = ValidationLevel . Standard ;
@@ -55,6 +71,22 @@ private void CacheUIElements()
5571 debugLogsToggle = Root . Q < Toggle > ( "debug-logs-toggle" ) ;
5672 validationLevelField = Root . Q < EnumField > ( "validation-level" ) ;
5773 validationDescription = Root . Q < Label > ( "validation-description" ) ;
74+ advancedSettingsFoldout = Root . Q < Foldout > ( "advanced-settings-foldout" ) ;
75+ uvxPathOverride = Root . Q < TextField > ( "uv-path-override" ) ;
76+ browseUvxButton = Root . Q < Button > ( "browse-uv-button" ) ;
77+ clearUvxButton = Root . Q < Button > ( "clear-uv-button" ) ;
78+ uvxPathStatus = Root . Q < VisualElement > ( "uv-path-status" ) ;
79+ gitUrlOverride = Root . Q < TextField > ( "git-url-override" ) ;
80+ browseGitUrlButton = Root . Q < Button > ( "browse-git-url-button" ) ;
81+ clearGitUrlButton = Root . Q < Button > ( "clear-git-url-button" ) ;
82+ deploySourcePath = Root . Q < TextField > ( "deploy-source-path" ) ;
83+ browseDeploySourceButton = Root . Q < Button > ( "browse-deploy-source-button" ) ;
84+ clearDeploySourceButton = Root . Q < Button > ( "clear-deploy-source-button" ) ;
85+ deployButton = Root . Q < Button > ( "deploy-button" ) ;
86+ deployRestoreButton = Root . Q < Button > ( "deploy-restore-button" ) ;
87+ deployTargetLabel = Root . Q < Label > ( "deploy-target-label" ) ;
88+ deployBackupLabel = Root . Q < Label > ( "deploy-backup-label" ) ;
89+ deployStatusLabel = Root . Q < Label > ( "deploy-status-label" ) ;
5890 }
5991
6092 private void InitializeUI ( )
@@ -85,6 +117,58 @@ private void RegisterCallbacks()
85117 EditorPrefs . SetInt ( EditorPrefKeys . ValidationLevel , ( int ) currentValidationLevel ) ;
86118 UpdateValidationDescription ( ) ;
87119 } ) ;
120+
121+ browseUvxButton . clicked += OnBrowseUvxClicked ;
122+ clearUvxButton . clicked += OnClearUvxClicked ;
123+
124+ browseGitUrlButton . clicked += OnBrowseGitUrlClicked ;
125+
126+ gitUrlOverride . RegisterValueChangedCallback ( evt =>
127+ {
128+ string url = evt . newValue ? . Trim ( ) ;
129+ if ( string . IsNullOrEmpty ( url ) )
130+ {
131+ EditorPrefs . DeleteKey ( EditorPrefKeys . GitUrlOverride ) ;
132+ }
133+ else
134+ {
135+ EditorPrefs . SetString ( EditorPrefKeys . GitUrlOverride , url ) ;
136+ }
137+ OnGitUrlChanged ? . Invoke ( ) ;
138+ OnHttpServerCommandUpdateRequested ? . Invoke ( ) ;
139+ } ) ;
140+
141+ clearGitUrlButton . clicked += ( ) =>
142+ {
143+ gitUrlOverride . value = string . Empty ;
144+ EditorPrefs . DeleteKey ( EditorPrefKeys . GitUrlOverride ) ;
145+ OnGitUrlChanged ? . Invoke ( ) ;
146+ OnHttpServerCommandUpdateRequested ? . Invoke ( ) ;
147+ } ;
148+
149+ deploySourcePath . RegisterValueChangedCallback ( evt =>
150+ {
151+ string path = evt . newValue ? . Trim ( ) ;
152+ if ( string . IsNullOrEmpty ( path ) || path == "Not set" )
153+ {
154+ return ;
155+ }
156+
157+ try
158+ {
159+ MCPServiceLocator . Deployment . SetStoredSourcePath ( path ) ;
160+ }
161+ catch ( Exception ex )
162+ {
163+ EditorUtility . DisplayDialog ( "Invalid Source" , ex . Message , "OK" ) ;
164+ UpdateDeploymentSection ( ) ;
165+ }
166+ } ) ;
167+
168+ browseDeploySourceButton . clicked += OnBrowseDeploySourceClicked ;
169+ clearDeploySourceButton . clicked += OnClearDeploySourceClicked ;
170+ deployButton . clicked += OnDeployClicked ;
171+ deployRestoreButton . clicked += OnRestoreBackupClicked ;
88172 }
89173
90174 public void UpdatePathOverrides ( )
@@ -131,5 +215,144 @@ private string GetValidationLevelDescription(int index)
131215 _ => "Standard validation"
132216 } ;
133217 }
218+
219+ private void OnBrowseUvxClicked ( )
220+ {
221+ string suggested = RuntimeInformation . IsOSPlatform ( OSPlatform . OSX )
222+ ? "/opt/homebrew/bin"
223+ : Environment . GetFolderPath ( Environment . SpecialFolder . ProgramFiles ) ;
224+ string picked = EditorUtility . OpenFilePanel ( "Select uv Executable" , suggested , "" ) ;
225+ if ( ! string . IsNullOrEmpty ( picked ) )
226+ {
227+ try
228+ {
229+ MCPServiceLocator . Paths . SetUvxPathOverride ( picked ) ;
230+ UpdatePathOverrides ( ) ;
231+ McpLog . Info ( $ "uv path override set to: { picked } ") ;
232+ }
233+ catch ( Exception ex )
234+ {
235+ EditorUtility . DisplayDialog ( "Invalid Path" , ex . Message , "OK" ) ;
236+ }
237+ }
238+ }
239+
240+ private void OnClearUvxClicked ( )
241+ {
242+ MCPServiceLocator . Paths . ClearUvxPathOverride ( ) ;
243+ UpdatePathOverrides ( ) ;
244+ McpLog . Info ( "uv path override cleared" ) ;
245+ }
246+
247+ private void OnBrowseGitUrlClicked ( )
248+ {
249+ string picked = EditorUtility . OpenFolderPanel ( "Select Server folder" , string . Empty , string . Empty ) ;
250+ if ( ! string . IsNullOrEmpty ( picked ) )
251+ {
252+ gitUrlOverride . value = picked ;
253+ EditorPrefs . SetString ( EditorPrefKeys . GitUrlOverride , picked ) ;
254+ OnGitUrlChanged ? . Invoke ( ) ;
255+ OnHttpServerCommandUpdateRequested ? . Invoke ( ) ;
256+ McpLog . Info ( $ "Server source override set to: { picked } ") ;
257+ }
258+ }
259+
260+ private void UpdateDeploymentSection ( )
261+ {
262+ var deployService = MCPServiceLocator . Deployment ;
263+
264+ string sourcePath = deployService . GetStoredSourcePath ( ) ;
265+ deploySourcePath . value = sourcePath ?? string . Empty ;
266+
267+ deployTargetLabel . text = $ "Target: { deployService . GetTargetDisplayPath ( ) } ";
268+
269+ string backupPath = deployService . GetLastBackupPath ( ) ;
270+ if ( deployService . HasBackup ( ) )
271+ {
272+ deployBackupLabel . text = $ "Last backup: { backupPath } ";
273+ }
274+ else
275+ {
276+ deployBackupLabel . text = "Last backup: none" ;
277+ }
278+
279+ deployRestoreButton ? . SetEnabled ( deployService . HasBackup ( ) ) ;
280+ }
281+
282+ private void OnBrowseDeploySourceClicked ( )
283+ {
284+ string picked = EditorUtility . OpenFolderPanel ( "Select MCPForUnity folder" , string . Empty , string . Empty ) ;
285+ if ( string . IsNullOrEmpty ( picked ) )
286+ {
287+ return ;
288+ }
289+
290+ try
291+ {
292+ MCPServiceLocator . Deployment . SetStoredSourcePath ( picked ) ;
293+ SetDeployStatus ( $ "Source set: { picked } ") ;
294+ }
295+ catch ( Exception ex )
296+ {
297+ EditorUtility . DisplayDialog ( "Invalid Source" , ex . Message , "OK" ) ;
298+ SetDeployStatus ( "Source selection failed" ) ;
299+ }
300+
301+ UpdateDeploymentSection ( ) ;
302+ }
303+
304+ private void OnClearDeploySourceClicked ( )
305+ {
306+ MCPServiceLocator . Deployment . ClearStoredSourcePath ( ) ;
307+ UpdateDeploymentSection ( ) ;
308+ SetDeployStatus ( "Source cleared" ) ;
309+ }
310+
311+ private void OnDeployClicked ( )
312+ {
313+ var result = MCPServiceLocator . Deployment . DeployFromStoredSource ( ) ;
314+ SetDeployStatus ( result . Message , ! result . Success ) ;
315+
316+ if ( ! result . Success )
317+ {
318+ EditorUtility . DisplayDialog ( "Deployment Failed" , result . Message , "OK" ) ;
319+ }
320+ else
321+ {
322+ EditorUtility . DisplayDialog ( "Deployment Complete" , result . Message + ( string . IsNullOrEmpty ( result . BackupPath ) ? string . Empty : $ "\n Backup: { result . BackupPath } ") , "OK" ) ;
323+ }
324+
325+ UpdateDeploymentSection ( ) ;
326+ }
327+
328+ private void OnRestoreBackupClicked ( )
329+ {
330+ var result = MCPServiceLocator . Deployment . RestoreLastBackup ( ) ;
331+ SetDeployStatus ( result . Message , ! result . Success ) ;
332+
333+ if ( ! result . Success )
334+ {
335+ EditorUtility . DisplayDialog ( "Restore Failed" , result . Message , "OK" ) ;
336+ }
337+ else
338+ {
339+ EditorUtility . DisplayDialog ( "Restore Complete" , result . Message , "OK" ) ;
340+ }
341+
342+ UpdateDeploymentSection ( ) ;
343+ }
344+
345+ private void SetDeployStatus ( string message , bool isError = false )
346+ {
347+ if ( deployStatusLabel == null )
348+ {
349+ return ;
350+ }
351+
352+ deployStatusLabel . text = message ;
353+ deployStatusLabel . style . color = isError
354+ ? new StyleColor ( new Color ( 0.85f , 0.2f , 0.2f ) )
355+ : StyleKeyword . Null ;
356+ }
134357 }
135358}
0 commit comments