Spaces:
Sleeping
Sleeping
| """ | |
| Test patches incrementally to find which one breaks the extension | |
| """ | |
| import sys | |
| import re | |
| from pathlib import Path | |
| sys.path.insert(0, str(Path(__file__).parent.parent)) | |
| from services.kiro_patcher_service import KiroPatcherService | |
| from core.process_utils import is_kiro_running | |
| class IncrementalPatcher(KiroPatcherService): | |
| """Patcher that can apply patches incrementally""" | |
| def apply_patch_1_only(self, content: str) -> str: | |
| """Apply only PATCH 1: getMachineId() injection (v4.0 approach)""" | |
| patched = content | |
| # === PATCH 1: getMachineId() - добавить проверку файла в начало === | |
| pattern = r'function getMachineId\(\) \{\s+try \{\s+return \(0, import_node_machine_id\.machineIdSync\)\(\);' | |
| if re.search(pattern, patched): | |
| patch_code = f'''function getMachineId() {{ | |
| {self.PATCH_MARKER}{self.PATCH_VERSION}_PATCH1_ONLY | |
| try {{ | |
| const fs = require('fs'); | |
| const path = require('path'); | |
| const customIdFile = path.join(process.env.USERPROFILE || process.env.HOME || '', '.kiro-manager-wb', 'machine-id.txt'); | |
| if (fs.existsSync(customIdFile)) {{ | |
| const customId = fs.readFileSync(customIdFile, 'utf8').trim(); | |
| if (customId && customId.length >= 32) {{ | |
| return customId; | |
| }} | |
| }} | |
| }} catch (_) {{}} | |
| // END_PATCH_v{self.PATCH_VERSION} | |
| try {{ | |
| return (0, import_node_machine_id.machineIdSync)();''' | |
| patched = re.sub(pattern, patch_code, patched) | |
| return patched | |
| return content | |
| def apply_patch_1_and_2(self, content: str) -> str: | |
| """Apply PATCH 1 + PATCH 2: getMachineId() + userAttributes()""" | |
| patched = self.apply_patch_1_only(content) | |
| # Replace marker | |
| patched = patched.replace('_PATCH1_ONLY', '_PATCH1_AND_2') | |
| # === PATCH 2: userAttributes() - вызывать getMachineId() динамически === | |
| ua_pattern = r'(function userAttributes\(\)\s*\{\s*return\s*\{[^}]*machineId:\s*)MACHINE_ID(\s*\})' | |
| ua_match = re.search(ua_pattern, patched) | |
| if ua_match: | |
| patched = re.sub(ua_pattern, r'\1getMachineId()\2', patched) | |
| return patched | |
| def patch_incremental(self, patch_level: int = 1, skip_running_check: bool = False): | |
| """ | |
| Apply patches incrementally | |
| patch_level: 1 = only PATCH 1, 2 = PATCH 1+2, 3 = all patches | |
| """ | |
| if not skip_running_check and is_kiro_running(): | |
| return {'success': False, 'message': 'Kiro is running. Please close it first.'} | |
| js_path = self.extension_js_path | |
| if not js_path: | |
| return {'success': False, 'message': 'extension.js not found'} | |
| # Read original | |
| content = js_path.read_text(encoding='utf-8') | |
| # Create backup | |
| backup_path = self._create_backup(js_path, content) | |
| # Apply patches based on level | |
| if patch_level == 1: | |
| patched = self.apply_patch_1_only(content) | |
| msg = "Applied PATCH 1 only (getMachineId replacement)" | |
| elif patch_level == 2: | |
| patched = self.apply_patch_1_and_2(content) | |
| msg = "Applied PATCH 1 + PATCH 2 (getMachineId + userAttributes)" | |
| elif patch_level == 3: | |
| patched = self._apply_patch(content) | |
| msg = "Applied all patches (PATCH 1 + 2 + 3)" | |
| else: | |
| return {'success': False, 'message': f'Invalid patch level: {patch_level}'} | |
| if patched == content: | |
| return {'success': False, 'message': 'No patches were applied'} | |
| # Write patched file | |
| js_path.write_text(patched, encoding='utf-8') | |
| return { | |
| 'success': True, | |
| 'message': msg, | |
| 'backup_path': str(backup_path), | |
| 'patched_file': str(js_path) | |
| } | |
| if __name__ == '__main__': | |
| import json | |
| patcher = IncrementalPatcher() | |
| # Get patch level from command line | |
| patch_level = int(sys.argv[1]) if len(sys.argv) > 1 else 1 | |
| result = patcher.patch_incremental(patch_level, skip_running_check=True) | |
| print(json.dumps(result, indent=2)) | |