@@ -1766,9 +1766,6 @@ def integration_uninstall(
17661766 raise typer .Exit (1 )
17671767
17681768 integration = get_integration (key )
1769- if integration is None :
1770- console .print (f"[red]Error:[/red] Unknown integration '{ key } '" )
1771- raise typer .Exit (1 )
17721769
17731770 manifest_path = project_root / ".specify" / "integrations" / f"{ key } .manifest.json"
17741771 if not manifest_path .exists ():
@@ -1796,7 +1793,7 @@ def integration_uninstall(
17961793 console .print (f"[dim]Details:[/dim] { exc } " )
17971794 raise typer .Exit (1 )
17981795
1799- removed , skipped = integration . teardown (project_root , manifest , force = force )
1796+ removed , skipped = manifest . uninstall (project_root , force = force )
18001797
18011798 _remove_integration_json (project_root )
18021799
@@ -1808,7 +1805,7 @@ def integration_uninstall(
18081805 opts .pop ("ai_skills" , None )
18091806 save_init_options (project_root , opts )
18101807
1811- name = (integration .config or {}).get ("name" , key )
1808+ name = (integration .config or {}).get ("name" , key ) if integration else key
18121809 console .print (f"\n [green]✓[/green] Integration '{ name } ' uninstalled" )
18131810 if removed :
18141811 console .print (f" Removed { len (removed )} file(s)" )
@@ -1871,15 +1868,23 @@ def integration_switch(
18711868 f"run [cyan]specify integration uninstall { installed_key } [/cyan], then retry."
18721869 )
18731870 raise typer .Exit (1 )
1874- removed , skipped = current_integration .teardown (
1875- project_root , old_manifest , force = force ,
1876- )
1871+ removed , skipped = old_manifest .uninstall (project_root , force = force )
18771872 if removed :
18781873 console .print (f" Removed { len (removed )} file(s)" )
18791874 if skipped :
18801875 console .print (f" [yellow]⚠[/yellow] { len (skipped )} modified file(s) preserved" )
1881- elif not current_integration :
1882- console .print (f"[dim]Unknown installed integration '{ installed_key } ' — skipping uninstall phase[/dim]" )
1876+ elif not current_integration and manifest_path .exists ():
1877+ # Integration removed from registry but manifest exists — use manifest-only uninstall
1878+ console .print (f"Uninstalling unknown integration '{ installed_key } ' via manifest" )
1879+ try :
1880+ old_manifest = IntegrationManifest .load (installed_key , project_root )
1881+ removed , skipped = old_manifest .uninstall (project_root , force = force )
1882+ if removed :
1883+ console .print (f" Removed { len (removed )} file(s)" )
1884+ if skipped :
1885+ console .print (f" [yellow]⚠[/yellow] { len (skipped )} modified file(s) preserved" )
1886+ except (ValueError , FileNotFoundError ) as exc :
1887+ console .print (f"[yellow]Warning:[/yellow] Could not read manifest for '{ installed_key } ': { exc } " )
18831888 else :
18841889 console .print (f"[dim]No manifest for '{ installed_key } ' — skipping uninstall phase[/dim]" )
18851890
0 commit comments