Created
December 22, 2024 16:13
-
-
Save zachwill/585a2120b0be5e83318141538a8ba7c4 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
import subprocess | |
import webbrowser | |
import time | |
import pyperclip | |
import tempfile | |
from rich.console import Console | |
from rich.panel import Panel | |
from rich.prompt import Prompt | |
# Configuration | |
O1_GEMINI_URL = "https://aistudio.google.com" | |
IDE_PATH = "/Applications/Visual Studio Code.app" | |
CODEBASE_DIR = ".codebase" | |
IMPLEMENTATION_FILE = os.path.join(CODEBASE_DIR, "IMPLEMENTATION.md") | |
PROGRESS_FILE = os.path.join(CODEBASE_DIR, "PROGRESS.md") | |
CODEBASE_FILE = os.path.join(CODEBASE_DIR, "CODEBASE.txt") | |
console = Console() | |
def open_file(filepath): | |
"""Opens a file in the default macOS application.""" | |
subprocess.run(['open', filepath], check=True) | |
def aggregate_codebase(): | |
"""Aggregates the codebase into a single file.""" | |
os.makedirs(CODEBASE_DIR, exist_ok=True) | |
try: | |
# Create temporary files | |
with tempfile.NamedTemporaryFile(mode='w', encoding='utf-8', delete=False) as tracked_files, \ | |
tempfile.NamedTemporaryFile(mode='w', encoding='utf-8', delete=False) as filtered_files: | |
subprocess.run(['git', 'ls-tree', '-r', 'HEAD', '--name-only'], | |
check=True, text=True, stdout=tracked_files) | |
tracked_files_path = tracked_files.name | |
filtered_files_path = filtered_files.name | |
# Filter tracked files | |
with open(tracked_files_path, 'r', encoding='utf-8') as source, \ | |
open(filtered_files_path, 'w', encoding='utf-8') as dest: | |
for line in source: | |
if not any(excluded in line for excluded in ['.git', CODEBASE_DIR]): | |
dest.write(line) | |
# Aggregate files | |
with open(filtered_files_path, 'r', encoding='utf-8') as file_list, \ | |
open(CODEBASE_FILE, 'w', encoding='utf-8') as outfile: | |
outfile.write("# Project Codebase\n\n") | |
outfile.write("Generated on: " + time.strftime("%Y-%m-%d %H:%M:%S") + "\n\n") | |
for line in file_list: | |
file_path = line.strip() | |
try: | |
with open(file_path, 'r', encoding='utf-8') as infile: | |
outfile.write(f"\n## File: {file_path}\n```{os.path.splitext(file_path)[1][1:]}\n") | |
outfile.write(infile.read()) | |
outfile.write("\n```\n") | |
except UnicodeDecodeError: | |
try: | |
with open(file_path, 'r', encoding='latin-1') as infile: | |
outfile.write(f"\n## File: {file_path}\n```{os.path.splitext(file_path)[1][1:]}\n") | |
outfile.write(infile.read()) | |
outfile.write("\n```\n") | |
except Exception as e: | |
console.print(f"[yellow]Warning: Could not read file {file_path}: {e}[/yellow]") | |
continue | |
# Cleanup | |
os.unlink(tracked_files_path) | |
os.unlink(filtered_files_path) | |
console.print(Panel(f"[bold green]Codebase aggregated to[/bold green] [bold]{CODEBASE_FILE}[/bold]")) | |
return True | |
except Exception as e: | |
console.print(Panel(f"[bold red]An unexpected error occurred:[/bold red] {e}")) | |
return False | |
def create_and_open_files(implementation_content): | |
"""Creates and opens files, and opens the browser/IDE.""" | |
try: | |
os.makedirs(CODEBASE_DIR, exist_ok=True) | |
# Create implementation file | |
with open(IMPLEMENTATION_FILE, "w", encoding='utf-8') as f: | |
f.write(implementation_content) | |
# Create progress file if needed | |
if not os.path.exists(PROGRESS_FILE): | |
with open(PROGRESS_FILE, "w", encoding='utf-8') as f: | |
f.write("# Progress Log\n\n") | |
f.write(f"Started: {time.strftime('%Y-%m-%d %H:%M:%S')}\n\n") | |
# Open .codebase directory in Finder | |
subprocess.run(['open', CODEBASE_DIR], check=True) | |
# Open browser | |
webbrowser.open(O1_GEMINI_URL) | |
# Open and focus VS Code | |
try: | |
subprocess.run([IDE_PATH], check=True) | |
time.sleep(2) | |
subprocess.run(['osascript', '-e', 'tell application "Visual Studio Code" to activate'], check=False) | |
except Exception as e: | |
console.print(Panel(f"[yellow]Warning: Could not open VS Code:[/yellow] {e}")) | |
console.print("Please open VS Code manually.") | |
# Open implementation file | |
open_file(IMPLEMENTATION_FILE) | |
console.print(Panel("[bold green]Files created and opened. Browser and VS Code launched.[/bold green]")) | |
return True | |
except Exception as e: | |
console.print(Panel(f"[bold red]An unexpected error occurred:[/bold red] {e}")) | |
return False | |
def update_file(content, filepath): | |
"""Updates a file with new content.""" | |
try: | |
os.makedirs(CODEBASE_DIR, exist_ok=True) | |
with open(filepath, "w", encoding='utf-8') as f: | |
f.write(content) | |
console.print(Panel(f"[bold green]{os.path.basename(filepath)} updated.[/bold green]")) | |
open_file(filepath) | |
return True | |
except Exception as e: | |
console.print(Panel(f"[bold red]Error updating {os.path.basename(filepath)}:[/bold red] {e}")) | |
return False | |
def main(): | |
"""Main function to handle user input and workflow.""" | |
console.print(Panel("[bold blue]AI-Assisted Development Workflow[/bold blue]")) | |
# Step 1: Aggregate Codebase | |
if not aggregate_codebase(): | |
console.print(Panel("[bold red]Codebase aggregation failed. Exiting.[/bold red]")) | |
return | |
# Copy codebase to clipboard | |
try: | |
with open(CODEBASE_FILE, 'r', encoding='utf-8') as f: | |
pyperclip.copy(f.read()) | |
console.print(Panel("[bold green]Codebase content copied to clipboard![/bold green]")) | |
except Exception as e: | |
console.print(f"[yellow]Warning: Could not copy to clipboard: {e}[/yellow]") | |
console.print(Panel("[bold cyan]Next Step: Copy the codebase to your reasoning model and get a plan[/bold cyan]")) | |
Prompt.ask("[bold]Press Enter when ready to proceed[/bold]", default="") | |
# Step 2: Create Implementation and Open Files | |
console.print(Panel("[bold cyan]Next Step: Paste the implementation plan from your reasoning model.[/bold cyan]")) | |
implementation_content = pyperclip.paste() | |
if not implementation_content: | |
console.print(Panel("[bold red]No implementation plan found in clipboard. Exiting.[/bold red]")) | |
return | |
if not create_and_open_files(implementation_content): | |
console.print(Panel("[bold red]Failed to create and open files. Exiting.[/bold red]")) | |
return | |
console.print(Panel("[bold cyan]Next Step: Implement the first phase, get a progress report[/bold cyan]")) | |
Prompt.ask("[bold]Press Enter when ready to proceed[/bold]", default="") | |
# Step 3: Update Progress File | |
console.print(Panel("[bold cyan]Next Step: Paste the progress report from your code generation model.[/bold cyan]")) | |
progress_content = pyperclip.paste() | |
if not progress_content: | |
console.print(Panel("[bold red]No progress report found in clipboard. Exiting.[/bold red]")) | |
return | |
if not update_file(progress_content, PROGRESS_FILE): | |
console.print(Panel("[bold red]Failed to update progress file. Exiting.[/bold red]")) | |
return | |
console.print(Panel("[bold green]Workflow completed.[/bold green]")) | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment