@@ -770,6 +770,62 @@ def fake_download(project_path, *args, **kwargs):
770770 assert result .exit_code == 0
771771 mock_skills .assert_called_once ()
772772 assert mock_skills .call_args .kwargs .get ("overwrite_existing" ) is True
773+ assert not (target / ".codex" ).exists ()
774+
775+ def test_codex_ai_skills_removes_legacy_codex_dir_after_fallback (self , tmp_path ):
776+ """Codex skills init should not leave legacy .codex prompt directory behind."""
777+ from typer .testing import CliRunner
778+
779+ runner = CliRunner ()
780+ target = tmp_path / "codex-cleanup-new"
781+
782+ def fake_download (project_path , * args , ** kwargs ):
783+ prompts_dir = project_path / ".codex" / "prompts"
784+ prompts_dir .mkdir (parents = True , exist_ok = True )
785+ (prompts_dir / "speckit.specify.md" ).write_text ("---\n description: Legacy prompt\n ---\n \n Body.\n " )
786+
787+ with patch ("specify_cli.download_and_extract_template" , side_effect = fake_download ), \
788+ patch ("specify_cli.ensure_executable_scripts" ), \
789+ patch ("specify_cli.ensure_constitution_from_template" ), \
790+ patch ("specify_cli.install_ai_skills" , return_value = True ), \
791+ patch ("specify_cli.is_git_repo" , return_value = False ), \
792+ patch ("specify_cli.shutil.which" , return_value = "/usr/bin/codex" ):
793+ result = runner .invoke (
794+ app ,
795+ ["init" , str (target ), "--ai" , "codex" , "--ai-skills" , "--script" , "sh" , "--no-git" ],
796+ )
797+
798+ assert result .exit_code == 0
799+ assert not (target / ".codex" ).exists ()
800+
801+ def test_codex_ai_skills_here_mode_removes_legacy_codex_dir (self , tmp_path , monkeypatch ):
802+ """Codex --here skills init should not leave legacy .codex prompt directory behind."""
803+ from typer .testing import CliRunner
804+
805+ runner = CliRunner ()
806+ target = tmp_path / "codex-cleanup-here"
807+ target .mkdir ()
808+ monkeypatch .chdir (target )
809+
810+ def fake_download (project_path , * args , ** kwargs ):
811+ prompts_dir = project_path / ".codex" / "prompts"
812+ prompts_dir .mkdir (parents = True , exist_ok = True )
813+ (prompts_dir / "speckit.specify.md" ).write_text ("---\n description: Legacy prompt\n ---\n \n Body.\n " )
814+
815+ with patch ("specify_cli.download_and_extract_template" , side_effect = fake_download ), \
816+ patch ("specify_cli.ensure_executable_scripts" ), \
817+ patch ("specify_cli.ensure_constitution_from_template" ), \
818+ patch ("specify_cli.install_ai_skills" , return_value = True ), \
819+ patch ("specify_cli.is_git_repo" , return_value = True ), \
820+ patch ("specify_cli.shutil.which" , return_value = "/usr/bin/codex" ):
821+ result = runner .invoke (
822+ app ,
823+ ["init" , "--here" , "--ai" , "codex" , "--ai-skills" , "--script" , "sh" , "--no-git" ],
824+ input = "y\n " ,
825+ )
826+
827+ assert result .exit_code == 0
828+ assert not (target / ".codex" ).exists ()
773829
774830 def test_commands_preserved_when_skills_fail (self , tmp_path ):
775831 """If skills fail, commands should NOT be removed (safety net)."""
0 commit comments