Clover/main.py
opencode fde9ab9b39 fix: replace sys.path.insert(0) with safe sys.path.append (issue #7)
- Append project root instead of inserting at position 0
- Prevents import shadowing of system packages
- Check for duplicates before adding to sys.path
- Add __init__.py to models package
2026-07-05 07:02:43 +00:00

182 lines
6.7 KiB
Python

#!/usr/bin/env python3
"""
Clover - A CLI tool for working with AI models to build and manage projects.
Interactive mode where you can run commands without prefixing 'clover'.
"""
import argparse
import os
import sys
# Ensure project root is in path for direct execution (python main.py)
# Use a set to avoid duplicates and don't insert at position 0 to avoid shadowing
_project_root = os.path.dirname(os.path.abspath(__file__))
if _project_root not in sys.path:
sys.path.append(_project_root)
from cli.commands import handle_command
from cli.parser import parse_args, print_help
def interactive_mode():
"""Run Clover in interactive mode"""
print("🍀 Clover Interactive AI Development Assistant")
print("=" * 60)
print("Welcome to Clover! An AI-powered development assistant that can:")
print(" • Create, edit, and manage files")
print(" • Execute commands and test code")
print(" • Work through problems step-by-step")
print(" • Use tools to solve complex development tasks")
print("")
print("🔧 Available Commands:")
print("- /init : Initialize project summary file")
print("- /list : List available AI models")
print("- /timeout SECS : Set timeout duration")
print("- /threads N : Set thread limit")
print("- /git_status : Check Git repository status")
print("- /lint_file FILE : Lint a specific file")
print("- /reset : Reset AI conversation history")
print("- /summary : Show AI conversation summary")
print("- /help : Show this help")
print("- /quit or /exit: Exit interactive mode")
print("")
print("💡 Just describe what you want to build and the AI will:")
print(" → Break down the task into steps")
print(" → Create and test files as needed")
print(" → Continue until the task is complete")
print("=" * 60)
print("🚀 Ready! Enter your development request below:")
while True:
try:
# Get user input
user_input = input("\n🍀 > ").strip()
# Handle exit commands
if user_input.lower() in ["/quit", "/exit", "exit", "quit"]:
print("\n👋 Thanks for using Clover! Goodbye!")
break
# Handle help command
if user_input.lower() == "/help":
print_help()
continue
# If input is empty, continue
if not user_input:
continue
# Parse and handle the command (prefix with clover for parsing)
# We'll create a fake args object for command handling in interactive mode
if user_input.startswith("/"):
# This is already a special command - no prefix needed
args = argparse.Namespace()
if user_input == "/init":
args.init = True
args.list = False
args.timeout = None
args.threads = None
args.prompt = None
elif user_input == "/list":
args.init = False
args.list = True
args.timeout = None
args.threads = None
args.prompt = None
elif user_input.startswith("/timeout "):
try:
seconds = int(user_input.split()[1])
args.init = False
args.list = False
args.timeout = seconds
args.threads = None
args.prompt = None
except (ValueError, IndexError):
print("Usage: /timeout <seconds>")
continue
elif user_input.startswith("/threads "):
try:
count = int(user_input.split()[1])
args.init = False
args.list = False
args.timeout = None
args.threads = count
args.prompt = None
except (ValueError, IndexError):
print("Usage: /threads <count>")
continue
elif user_input == "/git_status":
# For git commands we might need to handle differently
args.init = False
args.list = False
args.timeout = None
args.threads = None
args.prompt = "/git_status"
elif user_input.startswith("/lint_file "):
args.init = False
args.list = False
args.timeout = None
args.threads = None
args.prompt = user_input
elif user_input == "/reset":
args.init = False
args.list = False
args.timeout = None
args.threads = None
args.prompt = "/reset"
elif user_input == "/summary":
args.init = False
args.list = False
args.timeout = None
args.threads = None
args.prompt = "/summary"
else:
# Treat as regular command for now
args = argparse.Namespace()
args.init = False
args.list = False
args.timeout = None
args.threads = None
args.prompt = user_input
try:
handle_command(args)
except Exception as e:
print(f"Error executing command: {e}")
else:
# Treat as regular query
args = argparse.Namespace()
args.init = False
args.list = False
args.timeout = None
args.threads = None
args.prompt = user_input
try:
handle_command(args)
except Exception as e:
print(f"Error executing command: {e}")
except KeyboardInterrupt:
print("\n\n🛑 Session interrupted. Thanks for using Clover!")
break
except EOFError:
print("\n👋 Thanks for using Clover! Goodbye!")
break
def main():
"""Main entry point"""
# Parse arguments
args = parse_args()
# Check if running in interactive mode (no arguments provided)
if len(sys.argv) == 1:
interactive_mode()
else:
# Run single command mode
handle_command(args)
if __name__ == "__main__":
main()