#!/usr/bin/env python3 """ Command-line tool to import data from .claude.json file. Usage: python import_claude_data.py [--file path/to/.claude.json] [--preview] """ import asyncio import argparse import sys from pathlib import Path from app.database.connection import async_session_maker, init_database from app.api.importer import ClaudeJsonImporter async def preview_import(file_path: str): """Preview what would be imported.""" print(f"šŸ” Previewing import from: {file_path}") print("=" * 50) try: import json import os if not os.path.exists(file_path): print(f"āŒ File not found: {file_path}") return False with open(file_path, 'r', encoding='utf-8') as f: claude_data = json.load(f) file_size_mb = round(os.path.getsize(file_path) / (1024 * 1024), 2) print(f"šŸ“ File size: {file_size_mb} MB") print(f"šŸš€ Total Claude Code startups: {claude_data.get('numStartups', 0)}") print(f"šŸ“… First start time: {claude_data.get('firstStartTime', 'N/A')}") print(f"šŸ“Š Prompt queue uses: {claude_data.get('promptQueueUseCount', 0)}") if "projects" in claude_data: projects = claude_data["projects"] print(f"šŸ“‚ Projects found: {len(projects)}") # Show first few project paths paths = list(projects.keys())[:5] for path in paths: history_count = len(projects[path].get("history", [])) print(f" • {path} ({history_count} history entries)") if len(projects) > 5: print(f" ... and {len(projects) - 5} more projects") # Count total history entries total_history = sum(len(proj.get("history", [])) for proj in projects.values()) print(f"šŸ’¬ Total conversation history entries: {total_history}") print("\nāœ… Preview completed successfully!") return True except Exception as e: print(f"āŒ Preview failed: {e}") return False async def run_import(file_path: str): """Run the actual import process.""" print(f"šŸ“„ Starting import from: {file_path}") print("=" * 50) # Initialize database tables first print("šŸ”§ Initializing database...") await init_database() print("āœ… Database initialized") async with async_session_maker() as db: try: importer = ClaudeJsonImporter(db) results = await importer.import_from_file(file_path) print("šŸŽ‰ Import completed successfully!") print(f"šŸ“‚ Projects imported: {results['projects_imported']}") print(f"ā±ļø Sessions estimated: {results['sessions_estimated']}") print(f"šŸ’¬ Conversations imported: {results['conversations_imported']}") if results['errors']: print(f"\nāš ļø Warnings/Errors ({len(results['errors'])}):") for error in results['errors']: print(f" • {error}") print("\nšŸš€ You can now view your imported data at: http://localhost:8000") return True except Exception as e: print(f"āŒ Import failed: {e}") return False def main(): """Main entry point.""" parser = argparse.ArgumentParser( description="Import Claude Code data from .claude.json file", formatter_class=argparse.RawDescriptionHelpFormatter, epilog=""" Examples: python import_claude_data.py --preview python import_claude_data.py --file ~/.claude.json python import_claude_data.py --file ~/.claude.json --preview """ ) parser.add_argument( "--file", type=str, default=None, help="Path to .claude.json file (default: ~/.claude.json)" ) parser.add_argument( "--preview", action="store_true", help="Preview what would be imported without actually importing" ) args = parser.parse_args() # Determine file path if args.file: file_path = args.file else: file_path = str(Path.home() / ".claude.json") print("šŸ¤– Claude Code Project Tracker - Data Importer") print("=" * 50) if args.preview: success = asyncio.run(preview_import(file_path)) else: print("āš ļø This will import data into your Claude Code Project Tracker database.") print(" Make sure the tracker server is not running during import.") print() confirm = input("Continue with import? (y/N): ").lower().strip() if confirm != 'y': print("Import cancelled.") sys.exit(0) success = asyncio.run(run_import(file_path)) sys.exit(0 if success else 1) if __name__ == "__main__": main()