154 lines
4.7 KiB
Python
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())
|