"""Install selected repository skills into Codex or another skill directory.""" import argparse import os from pathlib import Path import re import shutil SOURCE = Path(__file__).resolve().parents[1] def linked(path): return path.is_symlink() or getattr(path, 'is_junction', lambda: False)() def main(): parser = argparse.ArgumentParser(description=__doc__) parser.add_argument('names', nargs='*', help='Skill folder names; defaults to handycontrol-wpf') parser.add_argument('--all', action='store_true', help='Install all component skills') parser.add_argument('--dest', type=Path, default=Path(os.environ.get('CODEX_HOME', str(Path.home() / '.codex'))) / 'skills') parser.add_argument('--force', action='store_true', help='Replace files in existing skill folders') parser.add_argument('--list', action='store_true') args = parser.parse_args() available = sorted(p.parent.name for p in SOURCE.glob('*/SKILL.md')) if args.list: print('\n'.join(available)) return if args.all and args.names: parser.error('Use names or --all, not both') names = available if args.all else list(dict.fromkeys(args.names or ['handycontrol-wpf'])) destination = args.dest.expanduser().resolve() # Preflight every selection before copying anything. No deletes, no shell execution. for name in names: if not re.fullmatch(r'handycontrol-wpf(?:-[a-z0-9]+)*', name) or name not in available: parser.error(f'Unknown skill: {name}') target = destination / name if target.resolve().is_relative_to(SOURCE.resolve()) or SOURCE.resolve().is_relative_to(target.resolve()): parser.error(f'Destination overlaps repository skills: {target}') if linked(target): parser.error(f'Destination must not be a link: {target}') if target.exists() and not args.force: parser.error(f'Already exists: {target}; use --force to update files') if target.exists() and not target.is_dir(): parser.error(f'Not a directory: {target}') # Refuse linked descendants too, including when updating an existing skill. if target.exists() and any(linked(p) for p in target.rglob('*')): parser.error(f'Destination contains links: {target}') for name in names: shutil.copytree(SOURCE / name, destination / name, dirs_exist_ok=args.force) print(f'Installed {name} -> {destination / name}') if __name__ == '__main__': main()