"""CLI entry point for Artifact Editor.""" import argparse import sys from pathlib import Path from . import __version__ # Supported artifact types ARTIFACT_TYPES = [ "mermaid", # Flowcharts, sequence diagrams, ER diagrams "plantuml", # UML diagrams "svg", # Raw SVG graphics "openscad", # 3D CAD (OpenSCAD/SolidPython) "asciiart", # ASCII/box drawing diagrams "code", # Syntax-highlighted code snippets "excalidraw", # Hand-drawn style diagrams (JSON) ] def main(): """Main CLI entry point.""" parser = argparse.ArgumentParser( prog="artifact-editor", description="AI-enhanced editor for creating diagrams, sketches, and 3D models" ) parser.add_argument("--version", action="version", version=f"%(prog)s {__version__}") parser.add_argument( "file", nargs="?", help="File to edit (creates if doesn't exist)" ) parser.add_argument( "-t", "--type", choices=ARTIFACT_TYPES, default=None, help=f"Artifact type: {', '.join(ARTIFACT_TYPES)} (auto-detected from extension)" ) parser.add_argument( "-o", "--output", help="Output file path (alternative to positional argument)" ) parser.add_argument( "-p", "--project", default="", help="Project name/context for AI assistance" ) parser.add_argument( "-i", "--initial", default="", help="Initial content to pre-populate editor" ) parser.add_argument( "--initial-file", help="File containing initial content" ) parser.add_argument( "--headless", action="store_true", help="Run without UI (for AI-only generation)" ) parser.add_argument( "--prompt", help="AI prompt for headless generation" ) args = parser.parse_args() # Determine output path from positional arg or --output file_path = args.file or args.output if not file_path: parser.error("Please specify a file to edit: artifact-editor FILE or artifact-editor -o FILE") output_path = Path(file_path).expanduser().resolve() # Load initial content from existing file or --initial-file initial_content = args.initial if args.initial_file: initial_path = Path(args.initial_file) if initial_path.exists(): initial_content = initial_path.read_text() else: print(f"Error: Initial file not found: {args.initial_file}", file=sys.stderr) return 1 elif output_path.exists() and not initial_content: # Load existing file content initial_content = output_path.read_text() # Auto-detect type from extension if not specified artifact_type = args.type if not artifact_type: ext_map = { '.puml': 'plantuml', '.plantuml': 'plantuml', '.pu': 'plantuml', '.mmd': 'mermaid', '.mermaid': 'mermaid', '.svg': 'svg', '.scad': 'openscad', '.txt': 'asciiart', } artifact_type = ext_map.get(output_path.suffix.lower(), 'plantuml') if args.headless: # Headless mode: generate via AI without UI if not args.prompt: print("Error: --prompt required for headless mode", file=sys.stderr) return 1 return run_headless( artifact_type=artifact_type, output_path=output_path, prompt=args.prompt, project=args.project, initial=initial_content ) else: # Interactive mode: launch editor UI return run_editor( artifact_type=artifact_type, output_path=output_path, project=args.project, initial=initial_content ) def run_editor(artifact_type: str, output_path: Path, project: str, initial: str) -> int: """Launch the interactive editor UI.""" try: from .gui import run_gui return run_gui( artifact_type=artifact_type, output_path=output_path, project=project, initial_content=initial ) except ImportError as e: print(f"Error: GUI dependencies not installed. Run: pip install artifact-editor[gui]", file=sys.stderr) print(f" Missing: {e}", file=sys.stderr) return 2 def run_headless(artifact_type: str, output_path: Path, prompt: str, project: str, initial: str) -> int: """Generate artifact via AI without UI.""" # TODO: Implement AI generation print(f"[TODO] Headless generation for {artifact_type}") print(f" Prompt: {prompt}") print(f" Output: {output_path}") print("Error: Headless generation not yet implemented", file=sys.stderr) return 1 if __name__ == "__main__": sys.exit(main())