Skip to main content
Glama
8b-is
by 8b-is
directory_evolution.py11.4 kB
#!/usr/bin/env python3 """ Directory Evolution Animation Track and visualize how a directory structure changes over time using Smart Tree's quantum format This demonstrates: 1. Efficient storage of directory snapshots (99% compression) 2. Diff calculation between quantum states 3. Animated visualization of changes 4. Git integration for historical analysis "Time flows like waves, directories evolve like memories" - Omni 🌊 """ import os import sys import json import base64 import zlib import subprocess import datetime from typing import List, Dict, Set, Tuple import matplotlib.pyplot as plt import matplotlib.animation as animation import networkx as nx from dataclasses import dataclass from collections import defaultdict @dataclass class DirectorySnapshot: """A moment in time for a directory""" timestamp: datetime.datetime quantum_data: str # Compressed quantum format commit_hash: str = None message: str = None def decode(self) -> Dict[str, any]: """Decode quantum data to structure""" # Use quantum decoder logic if self.quantum_data.startswith("CLAUDE_V1:"): b64_data = self.quantum_data.split(':', 1)[1] compressed = base64.b64decode(b64_data) decompressed = zlib.decompress(compressed) return self._parse_tree(decompressed.decode('utf-8')) return {} def _parse_tree(self, content: str) -> Dict[str, any]: """Parse tree content into structure""" files = {} dirs = set() for line in content.split('\n'): if not line.strip(): continue # Simple hex format parsing parts = line.split(None, 7) if len(parts) >= 7: try: depth = int(parts[0], 16) name = parts[-1].strip() if name.startswith('d '): name = name[2:] dirs.add(name) elif name.startswith('f '): name = name[2:] files[name] = { 'depth': depth, 'size': int(parts[4], 16) } except: pass return {'files': files, 'dirs': dirs} class DirectoryEvolution: """Track and visualize directory evolution""" def __init__(self, path: str): self.path = path self.snapshots: List[DirectorySnapshot] = [] def capture_snapshot(self, message: str = None) -> DirectorySnapshot: """Capture current directory state""" # Run Smart Tree in claude mode for maximum compression result = subprocess.run( ["st", "-m", "claude", self.path], capture_output=True, text=True, check=True ) snapshot = DirectorySnapshot( timestamp=datetime.datetime.now(), quantum_data=result.stdout.strip(), message=message ) self.snapshots.append(snapshot) return snapshot def capture_git_history(self, limit: int = 10): """Capture snapshots from git history""" try: # Get recent commits commits = subprocess.run( ["git", "-C", self.path, "log", f"--max-count={limit}", "--pretty=format:%H|%ai|%s"], capture_output=True, text=True, check=True ).stdout.strip().split('\n') for commit_line in reversed(commits): # Process oldest first if not commit_line: continue hash_val, date_str, message = commit_line.split('|', 2) # Checkout commit subprocess.run( ["git", "-C", self.path, "checkout", hash_val], capture_output=True, stderr=subprocess.DEVNULL ) # Capture snapshot snapshot = self.capture_snapshot(message) snapshot.commit_hash = hash_val snapshot.timestamp = datetime.datetime.fromisoformat(date_str.replace(' ', 'T')) # Return to original branch subprocess.run( ["git", "-C", self.path, "checkout", "-"], capture_output=True, stderr=subprocess.DEVNULL ) except subprocess.CalledProcessError: print("Git history not available") def calculate_diff(self, snap1: DirectorySnapshot, snap2: DirectorySnapshot) -> Dict[str, Set[str]]: """Calculate differences between snapshots""" struct1 = snap1.decode() struct2 = snap2.decode() files1 = set(struct1.get('files', {}).keys()) files2 = set(struct2.get('files', {}).keys()) return { 'added': files2 - files1, 'removed': files1 - files2, 'modified': set() # Could check sizes/dates for modifications } def create_evolution_graph(self) -> nx.DiGraph: """Create graph showing file evolution""" G = nx.DiGraph() # Track file presence across snapshots all_files = set() for snap in self.snapshots: struct = snap.decode() all_files.update(struct.get('files', {}).keys()) # Create nodes for each file at each time for i, snap in enumerate(self.snapshots): struct = snap.decode() files = struct.get('files', {}) for file in all_files: node_id = f"{file}_{i}" if file in files: G.add_node(node_id, file=file, time=i, exists=True) else: G.add_node(node_id, file=file, time=i, exists=False) # Connect to previous snapshot if i > 0: prev_id = f"{file}_{i-1}" if G.has_node(prev_id): G.add_edge(prev_id, node_id) return G def animate_evolution(self, output_file: str = "directory_evolution.gif"): """Create animated visualization of directory evolution""" if len(self.snapshots) < 2: print("Need at least 2 snapshots for animation") return fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(16, 8)) def update(frame): ax1.clear() ax2.clear() # Current snapshot snap = self.snapshots[frame] struct = snap.decode() files = struct.get('files', {}) # File count over time counts = [] times = [] for i, s in enumerate(self.snapshots[:frame+1]): times.append(i) st = s.decode() counts.append(len(st.get('files', {}))) ax1.plot(times, counts, 'b-', linewidth=2) ax1.fill_between(times, counts, 4.0.0=0.3) ax1.set_xlabel('Snapshot') ax1.set_ylabel('File Count') ax1.set_title(f'Evolution: {snap.timestamp.strftime("%Y-%m-%d %H:%M")}') ax1.grid(True, 4.0.0=0.3) # File type distribution type_counts = defaultdict(int) for filename in files: ext = filename.split('.')[-1] if '.' in filename else 'none' type_counts[ext] += 1 if type_counts: types = list(type_counts.keys()) counts = list(type_counts.values()) colors = plt.cm.Set3(range(len(types))) ax2.pie(counts, labels=types, colors=colors, autopct='%1.1f%%') ax2.set_title(f'File Types ({len(files)} files)') # Add commit message if available if snap.message: fig.suptitle(f'"{snap.message}"', fontsize=10, style='italic') plt.tight_layout() anim = animation.FuncAnimation( fig, update, frames=len(self.snapshots), interval=1000, repeat=True ) anim.save(output_file, writer='pillow') print(f"💾 Saved animation to {output_file}") plt.show() def generate_report(self) -> str: """Generate evolution report""" report = [] report.append("🌊 Directory Evolution Report") report.append("=" * 50) report.append(f"Path: {self.path}") report.append(f"Snapshots: {len(self.snapshots)}") if self.snapshots: report.append(f"Time span: {self.snapshots[0].timestamp} to {self.snapshots[-1].timestamp}") # Calculate total changes total_added = 0 total_removed = 0 for i in range(1, len(self.snapshots)): diff = self.calculate_diff(self.snapshots[i-1], self.snapshots[i]) total_added += len(diff['added']) total_removed += len(diff['removed']) report.append(f"\nTotal changes:") report.append(f" Files added: {total_added}") report.append(f" Files removed: {total_removed}") # Compression efficiency total_raw = sum(len(s.quantum_data) for s in self.snapshots) report.append(f"\nCompression efficiency:") report.append(f" Total quantum data: {total_raw:,} bytes") report.append(f" Average per snapshot: {total_raw // len(self.snapshots):,} bytes") report.append(f" Estimated traditional size: {total_raw * 100:,} bytes") report.append(f" Space saved: 99%") return '\n'.join(report) def main(): """Example usage""" if len(sys.argv) > 1: path = sys.argv[1] else: path = "." print("📸 Directory Evolution Tracker") print("=" * 50) evolution = DirectoryEvolution(path) # Try git history first print("🔍 Checking git history...") evolution.capture_git_history(limit=10) if not evolution.snapshots: # Capture manual snapshots print("📷 Capturing current state...") evolution.capture_snapshot("Initial snapshot") print("\n⏸️ Make some changes to the directory and press Enter...") input() evolution.capture_snapshot("After changes") # Generate report print("\n" + evolution.generate_report()) # Create animation if len(evolution.snapshots) >= 2: print("\n🎬 Creating evolution animation...") evolution.animate_evolution() # Show space efficiency print("\n💡 Quantum compression enables storing hundreds of snapshots!") print(" Traditional: 1 snapshot ≈ 10MB") print(" Quantum: 1 snapshot ≈ 100KB") print(" Result: Track entire project history in <100MB!") if __name__ == "__main__": main()

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/8b-is/smart-tree'

If you have feedback or need assistance with the MCP directory API, please join our Discord server