How to Rollback to a Previous Version in Distilly: Complete CLI and Python Guide

Distilly stores every skill's artifacts in a hidden versions/ folder and provides the tools/version_manager.py CLI to restore previous states while automatically backing up your current version before overwriting.

Distilly is an open-source framework for generating and managing AI skills. When you need to revert changes, the built-in Skill Version Manager enables you to rollback to a previous version in Distilly by manipulating versioned archives stored within each skill directory.

Understanding Distilly's Version Archive Structure

Every generated skill maintains a versioned archive inside a hidden versions/ folder located within the skill directory. According to the source code in tools/version_manager.py, this archive preserves the four primary artifacts defined in tools/skill_schema.py: SKILL.md, work.md, persona.md, and manifest.json.

The PRIMARY_ARTIFACTS constant (lines 25-33 of skill_schema.py) defines which files the version manager considers essential. When you archive or rollback, the system only interacts with these specific files, ensuring consistency across skill versions.

How the Rollback Mechanism Works

The rollback process in tools/version_manager.py follows a strict five-step safety protocol:

  1. Locate the skill directory using the supplied slug and character preset.
  2. Resolve the target version via resolve_contained_child() (line 86), which validates that the requested version exists inside skill_dir/versions/<target_version>.
  3. Create a backup of current artifacts in a new sub-directory named <current_version>_before_rollback (lines 103-108). This guarantees you can restore the pre-rollback state if needed.
  4. Copy each artifact listed in PRIMARY_ARTIFACTS from the archived version into the live skill directory (lines 115-119).
  5. Update metadata in meta.json to record the rollback: it stamps a new lifecycle version (<target_version>_restored), saves the original version in rollback_from, and refreshes updated_at (lines 121-124).

CLI Workflow for Rolling Back

The version manager exposes a pure-Python CLI interface. Below are the complete commands for managing versions.

List Archived Versions

Before rolling back, identify available versions using the list action, which invokes list_versions() (lines 41-69):

python -m tools.version_manager \
    --action list \
    --slug my-skill \
    --character colleague

This outputs every stored version with timestamps and artifact names, allowing you to identify the correct target version string (e.g., v1, v2).

Create an Optional Backup

To force a snapshot of the live artifacts before any change, use the backup action, which calls backup_current_version() (lines 33-57):

python -m tools.version_manager \
    --action backup \
    --slug my-skill \
    --character colleague

Execute the Rollback

Perform the restoration using the rollback action. This triggers the core rollback() function and updates your meta.json automatically:

python -m tools.version_manager \
    --action rollback \
    --slug my-skill \
    --version v1 \
    --character colleague

Upon success, the console prints: rolled back to v1: SKILL.md, work.md, persona.md, manifest.json.

Clean Up Old Versions

To prune archives older than MAX_VERSIONS (default 10) and keep storage tidy, run the cleanup action, which invokes cleanup_old_versions() (lines 60-79):

python -m tools.version_manager \
    --action cleanup \
    --slug my-skill \
    --character colleague

This removes excess archives and prints each deletion to stdout.

Programmatic Rollback in Python

Because the version manager is implemented as a Python module, you can import its functions directly into automation scripts without shelling out to the CLI:

from pathlib import Path
from tools.version_manager import (
    resolve_base_dir,
    rollback,
)

# Resolve the skill location using character preset

skill_root = resolve_base_dir(base_dir_arg=None, character="colleague")
skill_dir = skill_root / "my-skill"

target_version = "v1"

if rollback(skill_dir, target_version):
    print(f"Successfully rolled back {skill_dir.name} to {target_version}")
else:
    print("Rollback failed – check the output above for errors")

This approach is useful for CI/CD pipelines or custom skill management dashboards.

Safety Features and Path Validation

The rollback process is secure because all path handling routes through validate_path_segment() and resolve_contained_child() (lines 34-68 of skill_schema.py). These functions prevent directory-traversal attacks and symlink-escape vulnerabilities by validating every path segment before file operations occur.

Additionally, the automatic creation of the <current_version>_before_rollback backup ensures that even if the rollback itself fails or you change your mind, the pre-rollback state remains recoverable.

Summary

  • Distilly stores skill artifacts in a hidden versions/ folder inside each skill directory.
  • The Skill Version Manager in tools/version_manager.py handles all versioning operations.
  • Rollbacks automatically create a safety backup named <current_version>_before_rollback before overwriting files.
  • Only files defined in PRIMARY_ARTIFACTS (SKILL.md, work.md, persona.md, manifest.json) are archived and restored.
  • Path validation via validate_path_segment() and resolve_contained_child() ensures security against directory traversal.

Frequently Asked Questions

Where does Distilly store previous versions?

Distilly stores previous versions in a hidden versions/ sub-directory inside the skill's folder. Each archived version resides in its own folder (e.g., skill_dir/versions/v1/) and contains copies of the four primary artifacts defined in tools/skill_schema.py.

Will I lose my current work when rolling back?

No. Distilly automatically creates a backup of your current version in a folder named <current_version>_before_rollback before copying archived files into the live directory. This safety copy preserves your pre-rollback state indefinitely alongside other archived versions.

Can I rollback without using the command line?

Yes. You can import rollback() and resolve_base_dir() directly from tools.version_manager in your Python scripts. This programmatic approach allows you to trigger rollbacks from within applications, automation scripts, or Jupyter notebooks without invoking the CLI.

How many versions does Distilly retain by default?

The version manager retains a maximum of 10 versions by default, controlled by the MAX_VERSIONS constant. You can remove older archives manually using the --action cleanup command, which prunes everything beyond the most recent 10 versions.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →