File size: 7,521 Bytes
494c89b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
"""
Централизованное управление путями
Все пути в одном месте для удобства
"""

import os
import platform
from pathlib import Path
from typing import Optional


class Paths:
    """Singleton для управления всеми путями в системе"""
    
    _instance: Optional['Paths'] = None
    
    def __new__(cls):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
            cls._instance._init_paths()
        return cls._instance
    
    def _init_paths(self):
        """Инициализация всех путей"""
        self.os_type = platform.system().lower()
        self.home = Path.home()
        
        # =====================================================================
        # Project paths
        # =====================================================================
        self.autoreg_dir = Path(__file__).parent.parent
        self.project_dir = self.autoreg_dir.parent
        
        # =====================================================================
        # User data paths (~/.kiro-manager-wb/)
        # =====================================================================
        self.user_data_dir = self.home / '.kiro-manager-wb'
        self.tokens_dir = self.user_data_dir / 'tokens'
        self.backups_dir = self.user_data_dir / 'backups'
        self.logs_dir = self.user_data_dir / 'logs'
        self.cache_dir = self.user_data_dir / 'cache'
        self.debug_sessions_dir = self.user_data_dir / 'debug_sessions'
        
        # Files
        self.accounts_file = self.user_data_dir / 'accounts.json'
        self.settings_file = self.user_data_dir / 'settings.json'
        self.log_file = self.logs_dir / 'autoreg.log'
        
        # =====================================================================
        # AWS SSO cache (~/.aws/sso/cache/)
        # =====================================================================
        self.aws_dir = self.home / '.aws'
        self.aws_sso_cache = self.aws_dir / 'sso' / 'cache'
        self.kiro_token_file = self.aws_sso_cache / 'kiro-auth-token.json'
        
        # =====================================================================
        # Kiro IDE paths
        # =====================================================================
        if self.os_type == 'windows':
            appdata = os.environ.get('APPDATA', '')
            self.kiro_data_dir = Path(appdata) / 'Kiro' if appdata else None
        elif self.os_type == 'darwin':  # macOS
            self.kiro_data_dir = self.home / 'Library' / 'Application Support' / 'Kiro'
        else:  # Linux
            self.kiro_data_dir = self.home / '.config' / 'Kiro'
        
        if self.kiro_data_dir:
            self.kiro_user_dir = self.kiro_data_dir / 'User'
            self.kiro_global_storage = self.kiro_user_dir / 'globalStorage'
            self.kiro_storage_json = self.kiro_global_storage / 'storage.json'
            self.kiro_state_db = self.kiro_global_storage / 'state.vscdb'
            self.kiro_agent_storage = self.kiro_global_storage / 'kiro.kiroagent'
        else:
            self.kiro_user_dir = None
            self.kiro_global_storage = None
            self.kiro_storage_json = None
            self.kiro_state_db = None
            self.kiro_agent_storage = None
        
        # =====================================================================
        # Kiro installation path
        # =====================================================================
        self.kiro_install_path: Optional[Path] = None
        if self.os_type == 'windows':
            possible_paths = [
                Path(os.environ.get('LOCALAPPDATA', '')) / 'Programs' / 'kiro',
                Path(os.environ.get('PROGRAMFILES', '')) / 'Kiro',
            ]
            # Additional paths for non-standard installations
            for drive in ['C:', 'D:', 'E:', 'S:', 'F:', 'G:']:
                possible_paths.append(Path(drive) / 'Kiro')
                possible_paths.append(Path(drive) / 'Programs' / 'Kiro')
                possible_paths.append(Path(drive) / 'kiro')
        elif self.os_type == 'darwin':
            possible_paths = [
                Path('/Applications/Kiro.app/Contents/Resources/app'),
                self.home / 'Applications' / 'Kiro.app' / 'Contents' / 'Resources' / 'app',
            ]
        else:  # Linux
            possible_paths = [
                Path('/usr/share/kiro'),
                Path('/opt/kiro'),
                self.home / '.local' / 'share' / 'kiro',
            ]
        
        for path in possible_paths:
            if path.exists():
                self.kiro_install_path = path
                break
        
        # =====================================================================
        # Kiro settings (~/.kiro/)
        # =====================================================================
        self.kiro_settings_dir = self.home / '.kiro' / 'settings'
        self.kiro_mcp_config = self.kiro_settings_dir / 'mcp.json'
        
        # Ensure directories exist
        self._ensure_dirs()
    
    def _ensure_dirs(self):
        """Создаёт необходимые директории"""
        dirs_to_create = [
            self.user_data_dir,
            self.tokens_dir,
            self.backups_dir,
            self.logs_dir,
            self.cache_dir,
            self.debug_sessions_dir,
            self.aws_sso_cache,
        ]
        
        for dir_path in dirs_to_create:
            dir_path.mkdir(parents=True, exist_ok=True)
    
    # =========================================================================
    # Helper methods
    # =========================================================================
    
    def is_kiro_installed(self) -> bool:
        """Проверяет установлен ли Kiro"""
        return self.kiro_data_dir is not None and self.kiro_data_dir.exists()
    
    def get_token_file(self, name: str) -> Path:
        """Возвращает путь к файлу токена"""
        if not name.endswith('.json'):
            name = f"token-{name}.json"
        return self.tokens_dir / name
    
    def get_backup_file(self, prefix: str, ext: str = 'json') -> Path:
        """Генерирует путь для нового бэкапа с timestamp"""
        from datetime import datetime
        timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
        return self.backups_dir / f"{prefix}-{timestamp}.{ext}"
    
    def get_client_registration_file(self, client_id_hash: str) -> Path:
        """Возвращает путь к файлу регистрации клиента"""
        return self.aws_sso_cache / f"{client_id_hash}.json"
    
    def list_tokens(self) -> list[Path]:
        """Возвращает список всех файлов токенов"""
        return list(self.tokens_dir.glob('token-*.json'))
    
    def list_backups(self, prefix: str = None) -> list[Path]:
        """Возвращает список бэкапов"""
        pattern = f"{prefix}-*.json" if prefix else "*.json"
        return sorted(self.backups_dir.glob(pattern), reverse=True)


# Singleton instance
_paths: Optional[Paths] = None


def get_paths() -> Paths:
    """Получить singleton instance Paths"""
    global _paths
    if _paths is None:
        _paths = Paths()
    return _paths