mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-07-13 22:35:16 +03:00
feat(switch): support claude-code install, smart runtime warnings, .gitignore propagation
- switch.py v1.2: `claude-code --project-dir` now copies skills (was error before)
- Skip runtime conversion for single-runtime skills (e.g. img-grid stays python)
- Distinguish info ("Python-версия не предусмотрена") from real missing-file warnings
- Print .gitignore recommendations for target project on install
- Copy root-level .gitignore from skills dir during install
- Interactive mode asks project path for all platforms, not just claude-code
- Add .gitignore in skills root (__pycache__/) and web-test/ (node_modules, *.png, *.mp4)
- Sync root .gitignore with all 13 platforms from PLATFORMS registry
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1 @@
|
|||||||
|
__pycache__/
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
scripts/node_modules/
|
||||||
|
.browser-session.json
|
||||||
|
*.png
|
||||||
|
*.mp4
|
||||||
+9
-2
@@ -34,8 +34,15 @@ __pycache__/
|
|||||||
*.mp4
|
*.mp4
|
||||||
|
|
||||||
# Навыки, скопированные для других AI-платформ (генерируются scripts/switch.py)
|
# Навыки, скопированные для других AI-платформ (генерируются scripts/switch.py)
|
||||||
|
.agents/
|
||||||
|
.augment/
|
||||||
|
.cline/
|
||||||
.codex/
|
.codex/
|
||||||
.cursor/skills/
|
.cursor/
|
||||||
.github/skills/
|
|
||||||
.gemini/
|
.gemini/
|
||||||
|
.github/skills/
|
||||||
|
.kilocode/
|
||||||
|
.kiro/
|
||||||
.opencode/
|
.opencode/
|
||||||
|
.roo/
|
||||||
|
.windsurf/
|
||||||
|
|||||||
+221
-71
@@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# switch.py v1.1 — Переключение навыков 1С между AI-платформами и рантаймами
|
# switch.py v1.2 — Переключение навыков 1С между AI-платформами и рантаймами
|
||||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
"""
|
"""
|
||||||
Копирует навыки из .claude/skills/ на другие AI-платформы (Cursor, Codex, Copilot,
|
Копирует навыки из .claude/skills/ на другие AI-платформы (Cursor, Codex, Copilot,
|
||||||
@@ -7,11 +7,12 @@ Kiro, Gemini CLI, OpenCode, Windsurf, Kilo Code, Cline, Roo Code, Augment и д
|
|||||||
с перезаписью путей, и/или переключает рантайм (PowerShell ↔ Python).
|
с перезаписью путей, и/или переключает рантайм (PowerShell ↔ Python).
|
||||||
|
|
||||||
Использование:
|
Использование:
|
||||||
python scripts/switch.py # интерактивный режим
|
python scripts/switch.py # интерактивный режим
|
||||||
python scripts/switch.py cursor # скопировать на Cursor
|
python scripts/switch.py cursor # скопировать на Cursor
|
||||||
python scripts/switch.py cursor --runtime python # скопировать + Python
|
python scripts/switch.py cursor --runtime python # скопировать + Python
|
||||||
python scripts/switch.py --undo cursor # удалить копию
|
python scripts/switch.py claude-code --project-dir /my/proj # установить в проект
|
||||||
python scripts/switch.py --runtime python # сменить runtime in-place
|
python scripts/switch.py --undo cursor # удалить копию
|
||||||
|
python scripts/switch.py --runtime python # сменить runtime in-place
|
||||||
"""
|
"""
|
||||||
import argparse
|
import argparse
|
||||||
import glob
|
import glob
|
||||||
@@ -41,6 +42,16 @@ PLATFORMS = {
|
|||||||
|
|
||||||
SOURCE_PREFIX = '.claude/skills'
|
SOURCE_PREFIX = '.claude/skills'
|
||||||
|
|
||||||
|
# Рекомендуемые записи для .gitignore целевого проекта
|
||||||
|
GITIGNORE_RECOMMENDATIONS = [
|
||||||
|
'.v8-project.json',
|
||||||
|
'build/',
|
||||||
|
'base/',
|
||||||
|
'*.epf',
|
||||||
|
'*.erf',
|
||||||
|
'*.log',
|
||||||
|
]
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# Runtime regex patterns (from switch-to-python.py / switch-to-powershell.py)
|
# Runtime regex patterns (from switch-to-python.py / switch-to-powershell.py)
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
@@ -72,6 +83,52 @@ def collect_md_files(skill_dir):
|
|||||||
return sorted(glob.glob(os.path.join(skill_dir, '*.md')))
|
return sorted(glob.glob(os.path.join(skill_dir, '*.md')))
|
||||||
|
|
||||||
|
|
||||||
|
def classify_skill_runtime(skill_dir):
|
||||||
|
"""Classify skill runtime based on invocations in .md files.
|
||||||
|
|
||||||
|
Returns 'ps', 'py', 'both', or 'none'.
|
||||||
|
"""
|
||||||
|
has_ps = has_py = False
|
||||||
|
for md_path in collect_md_files(skill_dir):
|
||||||
|
with open(md_path, 'r', encoding='utf-8') as f:
|
||||||
|
content = f.read()
|
||||||
|
if RX_PS.search(content):
|
||||||
|
has_ps = True
|
||||||
|
if RX_PY.search(content):
|
||||||
|
has_py = True
|
||||||
|
if has_ps and has_py:
|
||||||
|
return 'both'
|
||||||
|
return 'ps' if has_ps else ('py' if has_py else 'none')
|
||||||
|
|
||||||
|
|
||||||
|
def check_missing_files(skill_dir, target_runtime, root):
|
||||||
|
"""Check if target runtime script files exist for a skill.
|
||||||
|
|
||||||
|
Returns list of missing file paths (relative to root).
|
||||||
|
"""
|
||||||
|
missing = []
|
||||||
|
for md_path in collect_md_files(skill_dir):
|
||||||
|
with open(md_path, 'r', encoding='utf-8') as f:
|
||||||
|
content = f.read()
|
||||||
|
if target_runtime == 'python':
|
||||||
|
for m in RX_PS.findall(content):
|
||||||
|
py_path = m.lstrip("'") + '.py'
|
||||||
|
if not os.path.isfile(os.path.join(root, py_path)):
|
||||||
|
missing.append(py_path)
|
||||||
|
elif target_runtime == 'powershell':
|
||||||
|
for m in RX_PY.findall(content):
|
||||||
|
ps1_path = m.lstrip("'") + '.ps1'
|
||||||
|
if not os.path.isfile(os.path.join(root, ps1_path)):
|
||||||
|
missing.append(ps1_path)
|
||||||
|
return missing
|
||||||
|
|
||||||
|
|
||||||
|
def is_different_dir(dir1, dir2):
|
||||||
|
"""Check if two directories are different (resolved)."""
|
||||||
|
return os.path.normcase(os.path.realpath(dir1)) != \
|
||||||
|
os.path.normcase(os.path.realpath(dir2))
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# Transformations
|
# Transformations
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
@@ -91,27 +148,59 @@ def switch_runtime_content(content, target_runtime):
|
|||||||
return new, new != content
|
return new, new != content
|
||||||
|
|
||||||
|
|
||||||
def check_runtime_files(skills_dir, target_runtime, root):
|
def print_gitignore_recommendations(project_dir):
|
||||||
"""Check that target runtime script files exist. Returns list of warnings."""
|
"""Print .gitignore recommendations for the target project."""
|
||||||
warnings = []
|
gitignore_path = os.path.join(project_dir, '.gitignore')
|
||||||
for skill_name in scan_skills(skills_dir):
|
existing = set()
|
||||||
for md_path in collect_md_files(os.path.join(skills_dir, skill_name)):
|
if os.path.isfile(gitignore_path):
|
||||||
with open(md_path, 'r', encoding='utf-8') as f:
|
with open(gitignore_path, 'r', encoding='utf-8') as f:
|
||||||
content = f.read()
|
for line in f:
|
||||||
|
existing.add(line.strip())
|
||||||
|
|
||||||
if target_runtime == 'python':
|
missing = [r for r in GITIGNORE_RECOMMENDATIONS if r not in existing]
|
||||||
matches = RX_PS.findall(content)
|
if missing:
|
||||||
for m in matches:
|
print(f"\nРекомендуется добавить в .gitignore проекта:")
|
||||||
py_path = m.lstrip("'") + '.py'
|
for r in missing:
|
||||||
if not os.path.isfile(os.path.join(root, py_path)):
|
print(f" {r}")
|
||||||
warnings.append(f" {py_path} не найден")
|
|
||||||
elif target_runtime == 'powershell':
|
|
||||||
matches = RX_PY.findall(content)
|
def collect_runtime_messages(skill_name, skill_dir, target_runtime, root):
|
||||||
for m in matches:
|
"""Check runtime compatibility for a skill.
|
||||||
ps1_path = m.lstrip("'") + '.ps1'
|
|
||||||
if not os.path.isfile(os.path.join(root, ps1_path)):
|
Returns (info_list, warning_list).
|
||||||
warnings.append(f" {ps1_path} не найден")
|
"""
|
||||||
return warnings
|
info = []
|
||||||
|
warnings = []
|
||||||
|
src_rt = classify_skill_runtime(skill_dir)
|
||||||
|
|
||||||
|
if target_runtime == 'python' and src_rt in ('ps', 'none'):
|
||||||
|
missing = check_missing_files(skill_dir, 'python', root)
|
||||||
|
if missing:
|
||||||
|
info.append(f" {skill_name} — только PowerShell "
|
||||||
|
f"(Python-версия не предусмотрена)")
|
||||||
|
elif target_runtime == 'powershell' and src_rt in ('py', 'none'):
|
||||||
|
missing = check_missing_files(skill_dir, 'powershell', root)
|
||||||
|
if missing:
|
||||||
|
info.append(f" {skill_name} — только Python "
|
||||||
|
f"(PowerShell-версия не предусмотрена)")
|
||||||
|
else:
|
||||||
|
missing = check_missing_files(skill_dir, target_runtime, root)
|
||||||
|
for m in missing:
|
||||||
|
warnings.append(f" {m} не найден ({skill_name})")
|
||||||
|
|
||||||
|
return info, warnings
|
||||||
|
|
||||||
|
|
||||||
|
def print_runtime_messages(info, warnings):
|
||||||
|
"""Print collected info and warning messages."""
|
||||||
|
if info:
|
||||||
|
print(f"\nИнформация:")
|
||||||
|
for i in info:
|
||||||
|
print(i)
|
||||||
|
if warnings:
|
||||||
|
print(f"\nПредупреждения (отсутствующие файлы):")
|
||||||
|
for w in warnings:
|
||||||
|
print(w)
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
@@ -136,8 +225,15 @@ def cmd_install(platform, runtime, project_dir):
|
|||||||
|
|
||||||
os.makedirs(target_dir, exist_ok=True)
|
os.makedirs(target_dir, exist_ok=True)
|
||||||
|
|
||||||
|
# Copy root-level files from source skills dir (.gitignore, etc.)
|
||||||
|
for name in os.listdir(src_dir):
|
||||||
|
src_path = os.path.join(src_dir, name)
|
||||||
|
if os.path.isfile(src_path):
|
||||||
|
shutil.copy2(src_path, os.path.join(target_dir, name))
|
||||||
|
|
||||||
installed = 0
|
installed = 0
|
||||||
warnings = []
|
all_info = []
|
||||||
|
all_warnings = []
|
||||||
|
|
||||||
print(f"\nКопирование {len(skills)} навыков в {target_prefix}/ ...")
|
print(f"\nКопирование {len(skills)} навыков в {target_prefix}/ ...")
|
||||||
|
|
||||||
@@ -145,6 +241,15 @@ def cmd_install(platform, runtime, project_dir):
|
|||||||
src_skill = os.path.join(src_dir, skill_name)
|
src_skill = os.path.join(src_dir, skill_name)
|
||||||
dst_skill = os.path.join(target_dir, skill_name)
|
dst_skill = os.path.join(target_dir, skill_name)
|
||||||
|
|
||||||
|
# Skip runtime conversion for single-runtime skills where
|
||||||
|
# target files don't exist (e.g. img-grid has only .py)
|
||||||
|
src_rt = classify_skill_runtime(src_skill)
|
||||||
|
missing = check_missing_files(src_skill, runtime, repo_root())
|
||||||
|
skip_runtime = bool(missing) and (
|
||||||
|
(runtime == 'python' and src_rt in ('ps', 'none'))
|
||||||
|
or (runtime == 'powershell' and src_rt in ('py', 'none'))
|
||||||
|
)
|
||||||
|
|
||||||
# Copy entire skill directory
|
# Copy entire skill directory
|
||||||
shutil.copytree(src_skill, dst_skill)
|
shutil.copytree(src_skill, dst_skill)
|
||||||
|
|
||||||
@@ -155,30 +260,34 @@ def cmd_install(platform, runtime, project_dir):
|
|||||||
|
|
||||||
new_content = rewrite_paths(content, SOURCE_PREFIX, target_prefix)
|
new_content = rewrite_paths(content, SOURCE_PREFIX, target_prefix)
|
||||||
|
|
||||||
# Apply runtime switch if requested
|
# Apply runtime switch (skip for single-runtime skills
|
||||||
if runtime == 'python':
|
# where target runtime is not available)
|
||||||
new_content, _ = switch_runtime_content(new_content, 'python')
|
if not skip_runtime:
|
||||||
|
if runtime == 'python':
|
||||||
# Check .py files exist in source repo
|
new_content, _ = switch_runtime_content(new_content, 'python')
|
||||||
for m in RX_PS.findall(content):
|
elif runtime == 'powershell':
|
||||||
clean = m.lstrip("'").replace(SOURCE_PREFIX, target_prefix)
|
new_content, _ = switch_runtime_content(new_content, 'powershell')
|
||||||
original_py = m.lstrip("'") + '.py'
|
|
||||||
if not os.path.isfile(os.path.join(repo_root(), original_py)):
|
|
||||||
warnings.append(f" {original_py} не найден ({skill_name})")
|
|
||||||
|
|
||||||
if new_content != content:
|
if new_content != content:
|
||||||
with open(md_path, 'w', encoding='utf-8') as f:
|
with open(md_path, 'w', encoding='utf-8') as f:
|
||||||
f.write(new_content)
|
f.write(new_content)
|
||||||
|
|
||||||
|
# Check runtime compatibility (against source)
|
||||||
|
info, warnings = collect_runtime_messages(
|
||||||
|
skill_name, src_skill, runtime, repo_root())
|
||||||
|
all_info.extend(info)
|
||||||
|
all_warnings.extend(warnings)
|
||||||
|
|
||||||
print(f" [OK] {skill_name}")
|
print(f" [OK] {skill_name}")
|
||||||
installed += 1
|
installed += 1
|
||||||
|
|
||||||
print(f"\nГотово! {installed} навыков установлено в {target_prefix}/")
|
print(f"\nГотово! {installed} навыков установлено в {target_prefix}/")
|
||||||
if warnings:
|
|
||||||
print("\nПредупреждения (отсутствующие .py файлы):")
|
print_runtime_messages(all_info, all_warnings)
|
||||||
for w in warnings:
|
print_gitignore_recommendations(project_dir)
|
||||||
print(w)
|
|
||||||
print(f"\nДля удаления: python scripts/switch.py --undo {platform}")
|
if platform != 'claude-code':
|
||||||
|
print(f"\nДля удаления: python scripts/switch.py --undo {platform}")
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
||||||
@@ -221,34 +330,37 @@ def cmd_switch_runtime(runtime, project_dir):
|
|||||||
|
|
||||||
skills = scan_skills(skills_dir)
|
skills = scan_skills(skills_dir)
|
||||||
switched = 0
|
switched = 0
|
||||||
warnings = []
|
all_info = []
|
||||||
|
all_warnings = []
|
||||||
|
|
||||||
print(f"\nПереключение на {runtime} в {PLATFORMS[platform_name]}/ ...")
|
print(f"\nПереключение на {runtime} в {PLATFORMS[platform_name]}/ ...")
|
||||||
|
|
||||||
for skill_name in skills:
|
for skill_name in skills:
|
||||||
skill_path = os.path.join(skills_dir, skill_name)
|
skill_path = os.path.join(skills_dir, skill_name)
|
||||||
|
|
||||||
|
# Skip runtime conversion for single-runtime skills where
|
||||||
|
# target files don't exist (e.g. img-grid has only .py)
|
||||||
|
cur_rt = classify_skill_runtime(skill_path)
|
||||||
|
missing = check_missing_files(skill_path, runtime, repo_root())
|
||||||
|
skip_runtime = bool(missing) and (
|
||||||
|
(runtime == 'python' and cur_rt in ('ps', 'none'))
|
||||||
|
or (runtime == 'powershell' and cur_rt in ('py', 'none'))
|
||||||
|
)
|
||||||
|
|
||||||
|
info, warnings = collect_runtime_messages(
|
||||||
|
skill_name, skill_path, runtime, repo_root())
|
||||||
|
all_info.extend(info)
|
||||||
|
all_warnings.extend(warnings)
|
||||||
|
|
||||||
|
if skip_runtime:
|
||||||
|
continue
|
||||||
|
|
||||||
for md_path in collect_md_files(skill_path):
|
for md_path in collect_md_files(skill_path):
|
||||||
with open(md_path, 'r', encoding='utf-8') as f:
|
with open(md_path, 'r', encoding='utf-8') as f:
|
||||||
content = f.read()
|
content = f.read()
|
||||||
|
|
||||||
new_content, changed = switch_runtime_content(content, runtime)
|
new_content, changed = switch_runtime_content(content, runtime)
|
||||||
|
|
||||||
# Check target files exist
|
|
||||||
if runtime == 'python':
|
|
||||||
for m in RX_PS.findall(content):
|
|
||||||
py_path = m.lstrip("'") + '.py'
|
|
||||||
full = os.path.join(repo_root(), py_path)
|
|
||||||
if not os.path.isfile(full):
|
|
||||||
md_name = os.path.basename(md_path)
|
|
||||||
warnings.append(f" {py_path} не найден ({skill_name}/{md_name})")
|
|
||||||
elif runtime == 'powershell':
|
|
||||||
for m in RX_PY.findall(content):
|
|
||||||
ps1_path = m.lstrip("'") + '.ps1'
|
|
||||||
full = os.path.join(repo_root(), ps1_path)
|
|
||||||
if not os.path.isfile(full):
|
|
||||||
md_name = os.path.basename(md_path)
|
|
||||||
warnings.append(f" {ps1_path} не найден ({skill_name}/{md_name})")
|
|
||||||
|
|
||||||
if changed:
|
if changed:
|
||||||
with open(md_path, 'w', encoding='utf-8') as f:
|
with open(md_path, 'w', encoding='utf-8') as f:
|
||||||
f.write(new_content)
|
f.write(new_content)
|
||||||
@@ -257,10 +369,7 @@ def cmd_switch_runtime(runtime, project_dir):
|
|||||||
switched += 1
|
switched += 1
|
||||||
|
|
||||||
print(f"\nПереключено {switched} файлов на {runtime}.")
|
print(f"\nПереключено {switched} файлов на {runtime}.")
|
||||||
if warnings:
|
print_runtime_messages(all_info, all_warnings)
|
||||||
print(f"\nПредупреждения (отсутствующие файлы):")
|
|
||||||
for w in warnings:
|
|
||||||
print(w)
|
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
||||||
@@ -289,6 +398,17 @@ def ask_choice(prompt, options, default=1):
|
|||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
|
|
||||||
|
def ask_path(prompt, default=''):
|
||||||
|
"""Ask user for a directory path."""
|
||||||
|
hint = f" [{default}]" if default else ""
|
||||||
|
try:
|
||||||
|
raw = input(f"\n{prompt}{hint}: ").strip()
|
||||||
|
return raw if raw else default
|
||||||
|
except (EOFError, KeyboardInterrupt):
|
||||||
|
print("\nОтмена.")
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
|
||||||
def interactive_mode():
|
def interactive_mode():
|
||||||
"""Run interactive setup wizard."""
|
"""Run interactive setup wizard."""
|
||||||
print("Навыки 1С — настройка платформы")
|
print("Навыки 1С — настройка платформы")
|
||||||
@@ -317,12 +437,32 @@ def interactive_mode():
|
|||||||
choice = ask_choice("Для какой платформы настроить навыки?", platform_options)
|
choice = ask_choice("Для какой платформы настроить навыки?", platform_options)
|
||||||
platform = platform_keys[choice - 1]
|
platform = platform_keys[choice - 1]
|
||||||
|
|
||||||
# Check if already installed — offer update or remove
|
|
||||||
project_dir = os.getcwd()
|
project_dir = os.getcwd()
|
||||||
|
install_mode = True
|
||||||
|
|
||||||
|
# For claude-code in repo root, offer runtime switch as alternative
|
||||||
|
if platform == 'claude-code' and not is_different_dir(project_dir, repo_root()):
|
||||||
|
mode_options = [
|
||||||
|
("Переключить runtime", "сменить PowerShell \u2194 Python в текущем проекте"),
|
||||||
|
("Установить в проект", "скопировать навыки в другой проект"),
|
||||||
|
]
|
||||||
|
mode = ask_choice("Что сделать?", mode_options)
|
||||||
|
install_mode = (mode == 2)
|
||||||
|
|
||||||
|
# Ask for project directory when installing
|
||||||
|
if install_mode:
|
||||||
|
default_dir = project_dir
|
||||||
|
project_dir = ask_path("Путь к целевому проекту", default_dir)
|
||||||
|
if not project_dir or not os.path.isdir(project_dir):
|
||||||
|
print(f"Ошибка: директория '{project_dir}' не найдена.",
|
||||||
|
file=sys.stderr)
|
||||||
|
return 1
|
||||||
|
|
||||||
|
# Check if already installed — offer update or remove
|
||||||
target_prefix = PLATFORMS[platform]
|
target_prefix = PLATFORMS[platform]
|
||||||
target_dir = os.path.join(project_dir, target_prefix.replace('/', os.sep))
|
target_dir = os.path.join(project_dir, target_prefix.replace('/', os.sep))
|
||||||
|
|
||||||
if platform != 'claude-code' and os.path.isdir(target_dir):
|
if install_mode and os.path.isdir(target_dir):
|
||||||
existing = scan_skills(target_dir)
|
existing = scan_skills(target_dir)
|
||||||
if existing:
|
if existing:
|
||||||
action_options = [
|
action_options = [
|
||||||
@@ -347,10 +487,10 @@ def interactive_mode():
|
|||||||
rt_choice = ask_choice("Какой рантайм скриптов?", runtime_options)
|
rt_choice = ask_choice("Какой рантайм скриптов?", runtime_options)
|
||||||
runtime = 'powershell' if rt_choice == 1 else 'python'
|
runtime = 'powershell' if rt_choice == 1 else 'python'
|
||||||
|
|
||||||
if platform == 'claude-code':
|
if install_mode:
|
||||||
return cmd_switch_runtime(runtime, project_dir)
|
|
||||||
else:
|
|
||||||
return cmd_install(platform, runtime, project_dir)
|
return cmd_install(platform, runtime, project_dir)
|
||||||
|
else:
|
||||||
|
return cmd_switch_runtime(runtime, project_dir)
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
@@ -365,6 +505,7 @@ def main():
|
|||||||
epilog='Примеры:\n'
|
epilog='Примеры:\n'
|
||||||
' python scripts/switch.py cursor\n'
|
' python scripts/switch.py cursor\n'
|
||||||
' python scripts/switch.py cursor --runtime python\n'
|
' python scripts/switch.py cursor --runtime python\n'
|
||||||
|
' python scripts/switch.py claude-code --project-dir /my/proj\n'
|
||||||
' python scripts/switch.py --undo cursor\n'
|
' python scripts/switch.py --undo cursor\n'
|
||||||
' python scripts/switch.py --runtime python\n',
|
' python scripts/switch.py --runtime python\n',
|
||||||
formatter_class=argparse.RawDescriptionHelpFormatter
|
formatter_class=argparse.RawDescriptionHelpFormatter
|
||||||
@@ -384,8 +525,10 @@ def main():
|
|||||||
if args.undo:
|
if args.undo:
|
||||||
if not args.platform:
|
if not args.platform:
|
||||||
parser.error("--undo требует указания платформы")
|
parser.error("--undo требует указания платформы")
|
||||||
if args.platform == 'claude-code':
|
if args.platform == 'claude-code' \
|
||||||
parser.error("--undo не применим к claude-code (это исходная платформа)")
|
and not is_different_dir(args.project_dir, repo_root()):
|
||||||
|
parser.error(
|
||||||
|
"--undo не применим к claude-code в исходном репозитории")
|
||||||
return cmd_undo(args.platform, args.project_dir)
|
return cmd_undo(args.platform, args.project_dir)
|
||||||
|
|
||||||
# --runtime without platform = in-place switch
|
# --runtime without platform = in-place switch
|
||||||
@@ -395,10 +538,17 @@ def main():
|
|||||||
# platform specified
|
# platform specified
|
||||||
if args.platform:
|
if args.platform:
|
||||||
if args.platform == 'claude-code':
|
if args.platform == 'claude-code':
|
||||||
|
# claude-code + different project-dir → install
|
||||||
|
if is_different_dir(args.project_dir, repo_root()):
|
||||||
|
runtime = args.runtime or 'powershell'
|
||||||
|
return cmd_install(args.platform, runtime, args.project_dir)
|
||||||
|
# claude-code in repo root → runtime switch only
|
||||||
if args.runtime:
|
if args.runtime:
|
||||||
return cmd_switch_runtime(args.runtime, args.project_dir)
|
return cmd_switch_runtime(args.runtime, args.project_dir)
|
||||||
else:
|
else:
|
||||||
parser.error("для claude-code укажите --runtime python или --runtime powershell")
|
parser.error(
|
||||||
|
"для claude-code без --project-dir укажите "
|
||||||
|
"--runtime python или --runtime powershell")
|
||||||
runtime = args.runtime or 'powershell'
|
runtime = args.runtime or 'powershell'
|
||||||
return cmd_install(args.platform, runtime, args.project_dir)
|
return cmd_install(args.platform, runtime, args.project_dir)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user