this repo has no description

feat: improve sync output with status for each skill

- Show all skills with status (+ for added, - for removed, dim for unchanged)
- Clean summary line at the bottom
- Show tip when no skills available

+38 -46
+37 -45
pixi_skills/cli.py
··· 326 326 backend_instance = get_backend(backend_name) 327 327 skills_dir = backend_instance.get_skills_dir(Scope.LOCAL) 328 328 329 - console.print( 330 - f"Syncing to [cyan]{backend_name}[/cyan] -> [dim]{skills_dir}[/dim]\n" 331 - ) 332 - 333 329 # Discover available skills from pixi environment 334 330 available_skills = discover_local_skills(env) 335 331 available_names = {s.name for s in available_skills} ··· 342 338 to_install = [s for s in available_skills if s.name not in installed_names] 343 339 to_remove = [name for name in installed_names if name not in available_names] 344 340 345 - if not to_install and not to_remove: 346 - console.print(f"[dim]Already in sync ({len(available_skills)} skill(s))[/dim]") 347 - raise typer.Exit(0) 341 + # Header 342 + console.print( 343 + f"\n[bold]Syncing[/bold] [cyan]{backend_name}[/cyan] -> {skills_dir}\n" 344 + ) 348 345 349 - # Show summary of changes 350 - if available_skills: 351 - console.print(f"[dim]Available in env: {len(available_skills)} skill(s)[/dim]") 352 - else: 353 - console.print(f"[dim]No skills in .pixi/envs/{env}/share/agent-skills/[/dim]") 354 - 355 - if installed_names: 356 - console.print(f"[dim]Installed: {len(installed_names)} skill(s)[/dim]") 357 - else: 358 - console.print("[dim]Installed: 0 skill(s)[/dim]") 359 - 360 - # Install new skills 361 - installed_count = 0 362 - for skill in sorted(to_install, key=lambda s: s.name): 363 - try: 364 - symlink_path = backend_instance.install(skill) 365 - console.print(f"[green]+[/green] {skill.name} -> {symlink_path}") 366 - installed_count += 1 367 - except ValueError as e: 368 - console.print(f"[red]✗ {skill.name}: {e}[/red]") 346 + # Show all skills with status 347 + all_skill_names = available_names | installed_names 348 + for name in sorted(all_skill_names): 349 + if name in to_remove: 350 + console.print(f" [red]-[/red] {name} [dim](removed)[/dim]") 351 + elif name in {s.name for s in to_install}: 352 + skill = next(s for s in to_install if s.name == name) 353 + try: 354 + backend_instance.install(skill) 355 + console.print(f" [green]+[/green] {name} [dim](installed)[/dim]") 356 + except ValueError as e: 357 + console.print(f" [red]✗[/red] {name} [dim]({e})[/dim]") 358 + else: 359 + console.print(f" [dim] {name}[/dim]") 369 360 370 - # Remove skills no longer available 371 - removed_count = 0 361 + # Handle removals 372 362 for name in sorted(to_remove): 373 - if backend_instance.uninstall(name, Scope.LOCAL): 374 - console.print(f"[red]-[/red] {name}") 375 - removed_count += 1 376 - else: 377 - console.print(f"[yellow]?[/yellow] {name} (not found)") 363 + backend_instance.uninstall(name, Scope.LOCAL) 378 364 379 365 # Summary 380 - changes = [] 381 - if installed_count: 382 - changes.append(f"installed {installed_count}") 383 - if removed_count: 384 - changes.append(f"removed {removed_count}") 385 - 386 - if changes: 387 - console.print(f"\n[green]Synced: {', '.join(changes)} skill(s)[/green]") 366 + console.print() 367 + if to_install or to_remove: 368 + parts = [] 369 + if to_install: 370 + parts.append(f"[green]+{len(to_install)}[/green]") 371 + if to_remove: 372 + parts.append(f"[red]-{len(to_remove)}[/red]") 373 + console.print( 374 + f" [{'/'.join(parts)}] [bold]{len(available_names)} skill(s)[/bold]" 375 + ) 376 + else: 377 + console.print(f" [dim]no changes, {len(available_names)} skill(s)[/dim]") 388 378 389 - # Show final state 390 - final_count = len(available_names) 391 - console.print(f"[dim]Result: {final_count} skill(s) in {skills_dir}[/dim]") 379 + # Show tip if no skills 380 + if not available_skills: 381 + console.print( 382 + f"\n[dim]Add skills to .pixi/envs/{env}/share/agent-skills/ to sync[/dim]" 383 + ) 392 384 393 385 394 386 if __name__ == "__main__":
+1 -1
recipe/recipe.yaml
··· 7 7 path: ../ 8 8 9 9 build: 10 - number: 3 10 + number: 4 11 11 script: 12 12 - pip install . --no-build-isolation --no-deps -vv 13 13