-
Notifications
You must be signed in to change notification settings - Fork 62
Expand file tree
/
Copy pathuninstall_command.py
More file actions
89 lines (77 loc) · 2.9 KB
/
uninstall_command.py
File metadata and controls
89 lines (77 loc) · 2.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
"""Uninstall command for AI guardrails hooks."""
from pathlib import Path
from typing import Annotated, Optional
import typer
from cycode.cli.apps.ai_guardrails.command_utils import (
console,
resolve_repo_path,
validate_and_parse_ide,
validate_scope,
)
from cycode.cli.apps.ai_guardrails.consts import IDE_CONFIGS, AIIDEType
from cycode.cli.apps.ai_guardrails.hooks_manager import uninstall_hooks
def uninstall_command(
ctx: typer.Context,
scope: Annotated[
str,
typer.Option(
'--scope',
'-s',
help='Uninstall scope: "user" for user-level hooks, "repo" for repository-level hooks.',
),
] = 'user',
ide: Annotated[
str,
typer.Option(
'--ide',
help='IDE to uninstall hooks from (e.g., "cursor", "claude-code", "all"). Defaults to cursor.',
),
] = AIIDEType.CURSOR.value,
repo_path: Annotated[
Optional[Path],
typer.Option(
'--repo-path',
help='Repository path for repo-scoped uninstallation (defaults to current directory).',
exists=True,
file_okay=False,
dir_okay=True,
resolve_path=True,
),
] = None,
) -> None:
"""Remove AI guardrails hooks from supported IDEs.
This command removes Cycode hooks from the IDE's hooks configuration.
Other hooks (if any) will be preserved.
Examples:
cycode ai-guardrails uninstall # Remove user-level hooks
cycode ai-guardrails uninstall --scope repo # Remove repo-level hooks
cycode ai-guardrails uninstall --ide cursor # Uninstall from Cursor IDE
cycode ai-guardrails uninstall --ide all # Uninstall from all supported IDEs
"""
# Validate inputs
validate_scope(scope)
repo_path = resolve_repo_path(scope, repo_path)
ide_type = validate_and_parse_ide(ide)
ides_to_uninstall: list[AIIDEType] = list(AIIDEType) if ide_type is None else [ide_type]
results: list[tuple[str, bool, str]] = []
for current_ide in ides_to_uninstall:
ide_name = IDE_CONFIGS[current_ide].name
success, message = uninstall_hooks(scope, repo_path, ide=current_ide)
results.append((ide_name, success, message))
# Report results for each IDE
any_success = False
all_success = True
for _ide_name, success, message in results:
if success:
console.print(f'[green]✓[/] {message}')
any_success = True
else:
console.print(f'[red]✗[/] {message}', style='bold red')
all_success = False
if any_success:
console.print()
successful_ides = [name for name, success, _ in results if success]
ide_list = ', '.join(successful_ides)
console.print(f'[dim]Restart {ide_list} for changes to take effect.[/]')
if not all_success:
raise typer.Exit(1)