From d2d81f62cbdb51a18bc417e0bc0fc48785745ab0 Mon Sep 17 00:00:00 2001 From: hatayama Date: Mon, 29 Jun 2026 23:46:15 +0900 Subject: [PATCH 1/3] Suppress skill update success dialogs Keep the first-install success dialog while making skill updates rely on the refreshed Installed state instead of showing a completion dialog. --- Assets/Tests/Editor/SetupWizardWindowTests.cs | 35 +++++++++++++++++++ ...nityCliLoopSettingsWindowCliActionTests.cs | 13 +++++++ .../Presentation/Setup/SetupWizardWindow.cs | 13 ++++++- .../UnityCliLoopSettingsWindow.cs | 12 ++++++- 4 files changed, 71 insertions(+), 2 deletions(-) diff --git a/Assets/Tests/Editor/SetupWizardWindowTests.cs b/Assets/Tests/Editor/SetupWizardWindowTests.cs index 95e31b66b..dfa16d331 100644 --- a/Assets/Tests/Editor/SetupWizardWindowTests.cs +++ b/Assets/Tests/Editor/SetupWizardWindowTests.cs @@ -779,6 +779,41 @@ public void GetSkillsButtonTextForSetupWizard_ReturnsExpectedLabel( Assert.That(label, Is.EqualTo(expectedLabel)); } + [Test] + public void ShouldShowSkillsInstalledDialog_WhenTargetsAreMissing_ReturnsTrue() + { + // Verifies that Setup Wizard keeps the success dialog for first install. + List targets = new() + { + CreateSkillTarget( + hasSkillsDirectory: true, + SkillInstallState.Missing) + }; + + bool shouldShowDialog = SetupWizardWindow.ShouldShowSkillsInstalledDialog(targets); + + Assert.That(shouldShowDialog, Is.True); + } + + [Test] + public void ShouldShowSkillsInstalledDialog_WhenAnyTargetIsOutdated_ReturnsFalse() + { + // Verifies that Setup Wizard suppresses the success dialog for skill updates. + List targets = new() + { + CreateSkillTarget( + hasSkillsDirectory: true, + SkillInstallState.Missing), + CreateSkillTarget( + hasSkillsDirectory: true, + SkillInstallState.Outdated) + }; + + bool shouldShowDialog = SetupWizardWindow.ShouldShowSkillsInstalledDialog(targets); + + Assert.That(shouldShowDialog, Is.False); + } + [TestCase(SkillInstallState.Installed, false, true, "setup-target-item__status--installed")] [TestCase(SkillInstallState.Checking, false, true, "setup-target-item__status--checking")] [TestCase(SkillInstallState.Outdated, false, true, "setup-target-item__status--outdated")] diff --git a/Assets/Tests/Editor/UnityCliLoopSettingsWindowCliActionTests.cs b/Assets/Tests/Editor/UnityCliLoopSettingsWindowCliActionTests.cs index 8c8c208dc..47db5dffb 100644 --- a/Assets/Tests/Editor/UnityCliLoopSettingsWindowCliActionTests.cs +++ b/Assets/Tests/Editor/UnityCliLoopSettingsWindowCliActionTests.cs @@ -1,6 +1,7 @@ using NUnit.Framework; using UnityEngine; +using io.github.hatayama.UnityCliLoop.Domain; using io.github.hatayama.UnityCliLoop.Presentation; namespace io.github.hatayama.UnityCliLoop.Tests.Editor @@ -131,6 +132,18 @@ public void IsCliUpdateNeeded_UsesDispatcherMinimumVersion( Assert.That(result, Is.EqualTo(expected)); } + [TestCase(SkillInstallState.Missing, true)] + [TestCase(SkillInstallState.Outdated, false)] + public void ShouldShowSkillsInstalledDialog_ReturnsExpectedValue( + SkillInstallState installState, + bool expected) + { + // Verifies that Settings keeps the success dialog for first install only. + bool result = UnityCliLoopSettingsWindow.ShouldShowSkillsInstalledDialog(installState); + + Assert.That(result, Is.EqualTo(expected)); + } + private static UnityCliLoopSettingsWindow.CliPrimaryButtonAction ParseAction(string action) { return (UnityCliLoopSettingsWindow.CliPrimaryButtonAction) diff --git a/Packages/src/Editor/Presentation/Setup/SetupWizardWindow.cs b/Packages/src/Editor/Presentation/Setup/SetupWizardWindow.cs index 9e8600c8e..271b4fa1d 100644 --- a/Packages/src/Editor/Presentation/Setup/SetupWizardWindow.cs +++ b/Packages/src/Editor/Presentation/Setup/SetupWizardWindow.cs @@ -779,6 +779,13 @@ internal static bool HasSkillUpdateForSetupWizard( || target.HasDifferentLayoutSkills)); } + internal static bool ShouldShowSkillsInstalledDialog( + IEnumerable targets) + { + Debug.Assert(targets != null, "targets must not be null"); + return targets.All(target => target.InstallState != SkillInstallState.Outdated); + } + internal static bool ShouldUseFirstInstallSkillsUi(string lastSeenSetupWizardVersion) { return string.IsNullOrEmpty(lastSeenSetupWizardVersion); @@ -1316,6 +1323,7 @@ private async void HandleInstallSkills() : FilterInstallableSkillTargets(targets); if (installableTargets.Count == 0) return; + bool shouldShowSkillsInstalledDialog = ShouldShowSkillsInstalledDialog(installableTargets); _isInstallingSkills = true; UpdateSkillsStep(true, targets); @@ -1325,7 +1333,10 @@ await _skillSetupUseCase.InstallSkillFilesAsync( installableTargets, !_installSkillsFlat, CancellationToken.None); - EditorDialogHelper.ShowSkillsInstalledDialog(); + if (shouldShowSkillsInstalledDialog) + { + EditorDialogHelper.ShowSkillsInstalledDialog(); + } } finally { diff --git a/Packages/src/Editor/Presentation/UnityCliLoopSettingsWindow.cs b/Packages/src/Editor/Presentation/UnityCliLoopSettingsWindow.cs index 275130f7a..74bc915cd 100644 --- a/Packages/src/Editor/Presentation/UnityCliLoopSettingsWindow.cs +++ b/Packages/src/Editor/Presentation/UnityCliLoopSettingsWindow.cs @@ -967,6 +967,11 @@ internal static bool IsCliUpdateNeeded(string cliVersion, bool cliIsDispatcher) return EvaluateCliSetupCompatibility(cliVersion, cliIsDispatcher).NeedsUpdate; } + internal static bool ShouldShowSkillsInstalledDialog(SkillInstallState installState) + { + return installState != SkillInstallState.Outdated; + } + private static CliSetupCompatibilityState EvaluateCliSetupCompatibility( string cliVersion, bool cliIsDispatcher) @@ -1019,6 +1024,8 @@ private async void HandleInstallSkills() return; } + bool shouldShowSkillsInstalledDialog = + ShouldShowSkillsInstalledDialog(_selectedTargetInstallState); CancelSkillInstallStateRefresh(); _isInstallingSkills = true; RefreshCliSetupSection(); @@ -1040,7 +1047,10 @@ await _skillSetupUseCase.InstallSkillFilesAsync( new List { target }, !_installSkillsFlat, CancellationToken.None); - EditorDialogHelper.ShowSkillsInstalledDialog(); + if (shouldShowSkillsInstalledDialog) + { + EditorDialogHelper.ShowSkillsInstalledDialog(); + } } finally { From 7cb553286a511a59cbd8b17c74a77e0c5f3df70f Mon Sep 17 00:00:00 2001 From: hatayama Date: Mon, 29 Jun 2026 23:56:10 +0900 Subject: [PATCH 2/3] Suppress layout skill update dialogs Treat existing skills in a different layout as an update path so Setup Wizard does not show the first-install success dialog after migrating them. --- Assets/Tests/Editor/SetupWizardWindowTests.cs | 17 +++++++++++++++++ .../Presentation/Setup/SetupWizardWindow.cs | 4 +++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/Assets/Tests/Editor/SetupWizardWindowTests.cs b/Assets/Tests/Editor/SetupWizardWindowTests.cs index dfa16d331..6fcc5febb 100644 --- a/Assets/Tests/Editor/SetupWizardWindowTests.cs +++ b/Assets/Tests/Editor/SetupWizardWindowTests.cs @@ -814,6 +814,23 @@ public void ShouldShowSkillsInstalledDialog_WhenAnyTargetIsOutdated_ReturnsFalse Assert.That(shouldShowDialog, Is.False); } + [Test] + public void ShouldShowSkillsInstalledDialog_WhenAnyTargetUsesDifferentLayout_ReturnsFalse() + { + // Verifies that Setup Wizard suppresses the success dialog for skill layout updates. + List targets = new() + { + CreateSkillTarget( + hasSkillsDirectory: true, + SkillInstallState.Missing, + hasDifferentLayoutSkills: true) + }; + + bool shouldShowDialog = SetupWizardWindow.ShouldShowSkillsInstalledDialog(targets); + + Assert.That(shouldShowDialog, Is.False); + } + [TestCase(SkillInstallState.Installed, false, true, "setup-target-item__status--installed")] [TestCase(SkillInstallState.Checking, false, true, "setup-target-item__status--checking")] [TestCase(SkillInstallState.Outdated, false, true, "setup-target-item__status--outdated")] diff --git a/Packages/src/Editor/Presentation/Setup/SetupWizardWindow.cs b/Packages/src/Editor/Presentation/Setup/SetupWizardWindow.cs index 271b4fa1d..e1fdffff5 100644 --- a/Packages/src/Editor/Presentation/Setup/SetupWizardWindow.cs +++ b/Packages/src/Editor/Presentation/Setup/SetupWizardWindow.cs @@ -783,7 +783,9 @@ internal static bool ShouldShowSkillsInstalledDialog( IEnumerable targets) { Debug.Assert(targets != null, "targets must not be null"); - return targets.All(target => target.InstallState != SkillInstallState.Outdated); + return targets.All(target => + target.InstallState != SkillInstallState.Outdated + && !target.HasDifferentLayoutSkills); } internal static bool ShouldUseFirstInstallSkillsUi(string lastSeenSetupWizardVersion) From bb06526e574e46587e8a6f85e665a95793724d5c Mon Sep 17 00:00:00 2001 From: hatayama Date: Tue, 30 Jun 2026 00:00:44 +0900 Subject: [PATCH 3/3] Suppress Settings layout skill update dialogs Read the selected skill target details before installing so Settings treats existing skills in a different layout as an update instead of a first install. --- ...nityCliLoopSettingsWindowCliActionTests.cs | 24 +++++++++++++++--- .../UnityCliLoopSettingsWindow.cs | 25 +++++++++++++------ 2 files changed, 39 insertions(+), 10 deletions(-) diff --git a/Assets/Tests/Editor/UnityCliLoopSettingsWindowCliActionTests.cs b/Assets/Tests/Editor/UnityCliLoopSettingsWindowCliActionTests.cs index 47db5dffb..756b2eb76 100644 --- a/Assets/Tests/Editor/UnityCliLoopSettingsWindowCliActionTests.cs +++ b/Assets/Tests/Editor/UnityCliLoopSettingsWindowCliActionTests.cs @@ -132,18 +132,36 @@ public void IsCliUpdateNeeded_UsesDispatcherMinimumVersion( Assert.That(result, Is.EqualTo(expected)); } - [TestCase(SkillInstallState.Missing, true)] - [TestCase(SkillInstallState.Outdated, false)] + [TestCase(SkillInstallState.Missing, false, true)] + [TestCase(SkillInstallState.Outdated, false, false)] + [TestCase(SkillInstallState.Missing, true, false)] public void ShouldShowSkillsInstalledDialog_ReturnsExpectedValue( SkillInstallState installState, + bool hasDifferentLayoutSkills, bool expected) { // Verifies that Settings keeps the success dialog for first install only. - bool result = UnityCliLoopSettingsWindow.ShouldShowSkillsInstalledDialog(installState); + SkillSetupTargetInfo targetInfo = CreateSkillTarget(installState, hasDifferentLayoutSkills); + + bool result = UnityCliLoopSettingsWindow.ShouldShowSkillsInstalledDialog(targetInfo); Assert.That(result, Is.EqualTo(expected)); } + private static SkillSetupTargetInfo CreateSkillTarget( + SkillInstallState installState, + bool hasDifferentLayoutSkills) + { + return new SkillSetupTargetInfo( + "Claude Code", + ".claude", + "--claude", + hasSkillsDirectory: true, + hasExistingSkills: true, + hasDifferentLayoutSkills, + installState); + } + private static UnityCliLoopSettingsWindow.CliPrimaryButtonAction ParseAction(string action) { return (UnityCliLoopSettingsWindow.CliPrimaryButtonAction) diff --git a/Packages/src/Editor/Presentation/UnityCliLoopSettingsWindow.cs b/Packages/src/Editor/Presentation/UnityCliLoopSettingsWindow.cs index 74bc915cd..9dc105773 100644 --- a/Packages/src/Editor/Presentation/UnityCliLoopSettingsWindow.cs +++ b/Packages/src/Editor/Presentation/UnityCliLoopSettingsWindow.cs @@ -736,6 +736,16 @@ private SkillInstallState GetSelectedTargetInstallState(bool includeFreshnessChe private SkillInstallState GetSelectedTargetInstallState( string projectRoot, bool includeFreshnessCheck) + { + SkillSetupTargetInfo targetInfo = GetSelectedTargetInfo(projectRoot, includeFreshnessCheck); + return string.IsNullOrEmpty(targetInfo.DirName) + ? SkillInstallState.Missing + : targetInfo.InstallState; + } + + private SkillSetupTargetInfo GetSelectedTargetInfo( + string projectRoot, + bool includeFreshnessCheck) { SkillsTargetSelection selection = SkillsTargetSelectionResolver.Resolve( _skillsTarget, @@ -746,9 +756,7 @@ private SkillInstallState GetSelectedTargetInstallState( SkillSetupTargetInfo targetInfo = targets .FirstOrDefault(target => target.DirName == selection.DirectoryName); - return string.IsNullOrEmpty(targetInfo.DirName) - ? SkillInstallState.Missing - : targetInfo.InstallState; + return targetInfo; } private void CancelSkillInstallStateRefresh() @@ -967,9 +975,10 @@ internal static bool IsCliUpdateNeeded(string cliVersion, bool cliIsDispatcher) return EvaluateCliSetupCompatibility(cliVersion, cliIsDispatcher).NeedsUpdate; } - internal static bool ShouldShowSkillsInstalledDialog(SkillInstallState installState) + internal static bool ShouldShowSkillsInstalledDialog(SkillSetupTargetInfo targetInfo) { - return installState != SkillInstallState.Outdated; + return targetInfo.InstallState != SkillInstallState.Outdated + && !targetInfo.HasDifferentLayoutSkills; } private static CliSetupCompatibilityState EvaluateCliSetupCompatibility( @@ -1024,8 +1033,10 @@ private async void HandleInstallSkills() return; } - bool shouldShowSkillsInstalledDialog = - ShouldShowSkillsInstalledDialog(_selectedTargetInstallState); + string projectRoot = UnityCliLoopPathResolver.GetProjectRoot(); + SkillSetupTargetInfo selectedTargetInfo = + GetSelectedTargetInfo(projectRoot, includeFreshnessCheck: true); + bool shouldShowSkillsInstalledDialog = ShouldShowSkillsInstalledDialog(selectedTargetInfo); CancelSkillInstallStateRefresh(); _isInstallingSkills = true; RefreshCliSetupSection();