orchestrated-discussions/.venv/lib/python3.12/site-packages/artifact_editor/cli.py

154 lines
4.7 KiB
Python

"""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())