import streamlit as st import tempfile import git from pathlib import Path from datetime import datetime import time from dotenv import load_dotenv from core.file_scanner import FileScanner from services.llm_service import LLMService # 環境変数の読み込み load_dotenv() # ページ設定 st.set_page_config( page_title="Repository Code Analysis", page_icon="🔍", layout="wide" ) # カスタムCSS st.markdown(""" """, unsafe_allow_html=True) def clone_repository(repo_url: str) -> Path: """リポジトリをクローンして一時ディレクトリに保存""" temp_dir = Path(tempfile.mkdtemp()) git.Repo.clone_from(repo_url, temp_dir) return temp_dir # セッション状態の初期化 if 'repo_content' not in st.session_state: st.session_state.repo_content = None if 'temp_dir' not in st.session_state: st.session_state.temp_dir = None if 'llm_service' not in st.session_state: st.session_state.llm_service = None # メインのUIレイアウト st.title("🔍 リポジトリ解析・質問システム") # OpenAI APIキーの設定 api_key = st.sidebar.text_input("OpenAI APIキー", type="password", key="api_key") if api_key: st.session_state.llm_service = LLMService(api_key) # URLの入力 repo_url = st.text_input( "GitHubリポジトリのURLを入力", placeholder="https://github.com/username/repository.git" ) # スキャン実行ボタン if st.button("スキャン開始", disabled=not repo_url): try: with st.spinner('リポジトリをクローン中...'): temp_dir = clone_repository(repo_url) st.session_state.temp_dir = temp_dir with st.spinner('ファイルをスキャン中...'): scanner = FileScanner(temp_dir) files_content = scanner.scan_files() if st.session_state.llm_service: st.session_state.repo_content = LLMService.format_code_content(files_content) st.success(f"スキャン完了: {len(files_content)}個のファイルを検出") except Exception as e: st.error(f"エラーが発生しました: {str(e)}") # スキャン完了後の質問セクション if st.session_state.repo_content and st.session_state.llm_service: st.divider() st.subheader("💭 コードについて質問する") query = st.text_area( "質問を入力してください", placeholder="例: このコードの主な機能は何ですか?" ) if st.button("質問する", disabled=not query): with st.spinner('回答を生成中...'): response, error = st.session_state.llm_service.get_response( st.session_state.repo_content, query ) if error: st.error(error) else: st.markdown("### 回答:") st.markdown(response) # セッション終了時のクリーンアップ if st.session_state.temp_dir and Path(st.session_state.temp_dir).exists(): try: import shutil shutil.rmtree(st.session_state.temp_dir) except: pass # サイドバー情報 with st.sidebar: st.subheader("📌 使い方") st.markdown(""" 1. OpenAI APIキーを入力 2. GitHubリポジトリのURLを入力 3. スキャンを実行 4. コードについて質問 """) st.subheader("🔍 スキャン対象") st.markdown(""" - Python (.py) - JavaScript (.js) - Java (.java) - C/C++ (.c, .h, .cpp, .hpp) - その他の主要なプログラミング言語 """)