Add core context generator module
This commit is contained in:
177
src/contextgen/cli.py
Normal file
177
src/contextgen/cli.py
Normal file
@@ -0,0 +1,177 @@
|
|||||||
|
"""Command-line interface for Project Context Generator."""
|
||||||
|
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
import click
|
||||||
|
|
||||||
|
from contextgen.context_generator import ContextGenerator
|
||||||
|
from contextgen.mcp.server import MCPServer
|
||||||
|
|
||||||
|
|
||||||
|
@click.group()
|
||||||
|
@click.version_option(version="0.1.0")
|
||||||
|
@click.option(
|
||||||
|
"--project",
|
||||||
|
type=click.Path(exists=True, file_okay=False, dir_okay=True, path_type=Path),
|
||||||
|
help="Path to project directory (defaults to current directory)",
|
||||||
|
)
|
||||||
|
@click.pass_context
|
||||||
|
def main(ctx: click.Context, project: Path | None) -> None:
|
||||||
|
"""Project Context Generator - Analyze codebases and generate AI-friendly context."""
|
||||||
|
ctx.ensure_object(dict)
|
||||||
|
ctx.obj["project"] = project or Path.cwd()
|
||||||
|
|
||||||
|
|
||||||
|
@main.command()
|
||||||
|
@click.option(
|
||||||
|
"--output",
|
||||||
|
"-o",
|
||||||
|
type=click.Path(path_type=Path),
|
||||||
|
help="Output file path (prints to stdout if not specified)",
|
||||||
|
)
|
||||||
|
@click.option(
|
||||||
|
"--format",
|
||||||
|
"-f",
|
||||||
|
type=click.Choice(["json", "yaml"]),
|
||||||
|
default="json",
|
||||||
|
help="Output format (default: json)",
|
||||||
|
)
|
||||||
|
@click.pass_context
|
||||||
|
def generate(ctx: click.Context, output: Path | None, format: str) -> None:
|
||||||
|
"""Generate context file for the project."""
|
||||||
|
project_path = ctx.obj["project"]
|
||||||
|
|
||||||
|
click.echo(f"Analyzing project: {project_path}", err=True)
|
||||||
|
|
||||||
|
try:
|
||||||
|
generator = ContextGenerator(project_path)
|
||||||
|
context = generator.generate()
|
||||||
|
|
||||||
|
if output:
|
||||||
|
generator.save(output, format)
|
||||||
|
click.echo(f"Context saved to: {output}", err=True)
|
||||||
|
else:
|
||||||
|
if format == "json":
|
||||||
|
import json
|
||||||
|
click.echo(json.dumps(context, indent=2))
|
||||||
|
else:
|
||||||
|
import yaml
|
||||||
|
click.echo(yaml.dump(context, default_flow_style=False))
|
||||||
|
|
||||||
|
click.echo("Context generated successfully!", err=True)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
click.echo(f"Error: {e}", err=True)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
@main.command()
|
||||||
|
@click.option(
|
||||||
|
"--template",
|
||||||
|
"-t",
|
||||||
|
type=str,
|
||||||
|
default="standard",
|
||||||
|
help="Template to use (minimal, standard, comprehensive)",
|
||||||
|
)
|
||||||
|
@click.option(
|
||||||
|
"--output",
|
||||||
|
"-o",
|
||||||
|
type=click.Path(path_type=Path),
|
||||||
|
help="Output file path (prints to stdout if not specified)",
|
||||||
|
)
|
||||||
|
@click.option(
|
||||||
|
"--template-dir",
|
||||||
|
type=click.Path(exists=True, file_okay=False, dir_okay=True, path_type=Path),
|
||||||
|
help="Directory containing custom templates",
|
||||||
|
)
|
||||||
|
@click.pass_context
|
||||||
|
def render(ctx: click.Context, template: str, output: Path | None, template_dir: Path | None) -> None:
|
||||||
|
"""Render context using a template."""
|
||||||
|
project_path = ctx.obj["project"]
|
||||||
|
|
||||||
|
click.echo(f"Generating context with template: {template}", err=True)
|
||||||
|
|
||||||
|
try:
|
||||||
|
generator = ContextGenerator(project_path)
|
||||||
|
rendered = generator.generate_from_template(template, template_dir)
|
||||||
|
|
||||||
|
if output:
|
||||||
|
output.write_text(rendered, encoding="utf-8")
|
||||||
|
click.echo(f"Context saved to: {output}", err=True)
|
||||||
|
else:
|
||||||
|
click.echo(rendered)
|
||||||
|
|
||||||
|
click.echo("Context rendered successfully!", err=True)
|
||||||
|
|
||||||
|
except ValueError as e:
|
||||||
|
click.echo(f"Template error: {e}", err=True)
|
||||||
|
sys.exit(1)
|
||||||
|
except Exception as e:
|
||||||
|
click.echo(f"Error: {e}", err=True)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
@main.command()
|
||||||
|
@click.pass_context
|
||||||
|
def mcp(ctx: click.Context) -> None:
|
||||||
|
"""Run as MCP server (for AI tool integration)."""
|
||||||
|
project_path = ctx.obj["project"]
|
||||||
|
|
||||||
|
click.echo(f"Starting MCP server for: {project_path}", err=True)
|
||||||
|
|
||||||
|
try:
|
||||||
|
server = MCPServer(project_path)
|
||||||
|
server.run_stdio()
|
||||||
|
except Exception as e:
|
||||||
|
click.echo(f"Error: {e}", err=True)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
@main.command()
|
||||||
|
@click.pass_context
|
||||||
|
def info(ctx: click.Context) -> None:
|
||||||
|
"""Show quick overview of the project."""
|
||||||
|
project_path = ctx.obj["project"]
|
||||||
|
|
||||||
|
try:
|
||||||
|
generator = ContextGenerator(project_path)
|
||||||
|
context = generator.generate()
|
||||||
|
|
||||||
|
click.echo(f"Project: {context['project']['name']}")
|
||||||
|
click.echo(f"Primary Language: {context['analysis'].get('primary_language', 'Unknown')}")
|
||||||
|
|
||||||
|
frameworks = context['analysis'].get('frameworks', [])
|
||||||
|
if frameworks:
|
||||||
|
click.echo(f"Frameworks: {', '.join(f['name'] for f in frameworks[:3])}")
|
||||||
|
|
||||||
|
key_files = context['structure'].get('key_files', {})
|
||||||
|
if key_files:
|
||||||
|
click.echo(f"Key Files: {', '.join(key_files.keys())}")
|
||||||
|
|
||||||
|
conventions = context.get('conventions', {})
|
||||||
|
if conventions:
|
||||||
|
naming = conventions.get('naming', {})
|
||||||
|
click.echo(f"Naming Style: {naming.get('dominant_style', 'Unknown')}")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
click.echo(f"Error: {e}", err=True)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
@main.command()
|
||||||
|
@click.pass_context
|
||||||
|
def templates(ctx: click.Context) -> None:
|
||||||
|
"""List available templates."""
|
||||||
|
from contextgen.templates.engine import TemplateEngine
|
||||||
|
|
||||||
|
engine = TemplateEngine()
|
||||||
|
templates = engine.list_templates()
|
||||||
|
|
||||||
|
click.echo("Available templates:")
|
||||||
|
for template in templates:
|
||||||
|
click.echo(f" - {template}")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
Reference in New Issue
Block a user