import streamlit as st import tempfile import git import os from pathlib import Path from datetime import datetime from typing import List, Set, Optional from config.settings import Settings from core.file_scanner import FileScanner, FileInfo from services.llm_service import LLMService from main import DirectoryStructureScanner, MarkdownGenerator class StreamlitFileWriter: def __init__(self, output_file: Path): self.output_file = output_file def create_markdown(self, files: List[FileInfo]) -> str: content = [] for file_info in files: content.append(f"## {file_info.path}") content.append("------------") if file_info.content is not None: content.append(file_info.content) else: content.append("# Failed to read content") content.append("\n") return "\n".join(content) # ページ設定 st.set_page_config( page_title="Repository Code Analysis", page_icon="🔍", layout="wide" ) # スタイル設定 st.markdown(""" """, unsafe_allow_html=True) # セッション状態の初期化 if 'repo_content' not in st.session_state: st.session_state.repo_content = None if 'directory_structure' not in st.session_state: st.session_state.directory_structure = None if 'content_md' not in st.session_state: st.session_state.content_md = None if 'structure_md' not in st.session_state: st.session_state.structure_md = None if 'temp_dir' not in st.session_state: st.session_state.temp_dir = None if 'llm_service' not in st.session_state: try: api_key = os.getenv("ANTHROPIC_API_KEY") if not api_key: st.error("ANTHROPIC_API_KEY環境変数が設定されていません") st.stop() st.session_state.llm_service = LLMService(api_key) except Exception as e: st.error(str(e)) st.stop() # メインのUIレイアウト st.title("🔍 リポジトリ解析・質問システム") # サイドバーの設定 with st.sidebar: st.subheader("📌 使い方") st.markdown(""" 1. GitHubリポジトリのURLを入力 2. スキャン対象の拡張子を選択 3. スキャンを実行 4. ディレクトリ構造と内容を確認 5. Markdownファイルをダウンロード 6. コードについて質問 """) # スキャン対象の拡張子選択 st.subheader("🔍 スキャン対象の選択") # プログラミング言語 st.write("プログラミング言語:") prog_exts = {'.py', '.js', '.ts', '.java', '.cpp', '.hpp', '.c', '.h', '.go', '.rs'} selected_prog = {ext: st.checkbox(ext, value=True, key=f"prog_{ext}") for ext in prog_exts} # 設定ファイル st.write("設定ファイル:") config_exts = {'.json', '.yml', '.yaml', '.toml'} selected_config = {ext: st.checkbox(ext, value=True, key=f"config_{ext}") for ext in config_exts} # ドキュメント st.write("ドキュメント:") doc_exts = {'.md', '.txt'} selected_doc = {ext: st.checkbox(ext, value=True, key=f"doc_{ext}") for ext in doc_exts} # 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('リポジトリを解析中...'): # 選択された拡張子を集約 selected_extensions = {ext for exts in [selected_prog, selected_config, selected_doc] for ext, selected in exts.items() if selected} # 選択がない場合はデフォルトを使用 if not selected_extensions: selected_extensions = Settings.DEFAULT_EXTENSIONS # MarkdownGeneratorを初期化 generator = MarkdownGenerator(repo_url, selected_extensions) content_md, structure_md, files = generator.generate_markdowns() writer = StreamlitFileWriter(Path("dummy")) formatted_content = writer.create_markdown(files) st.session_state.content_md = formatted_content st.session_state.structure_md = structure_md st.session_state.repo_content = LLMService.format_code_content(files) st.success(f"スキャン完了: {len(files)}個のファイルを検出") st.session_state.llm_service.clear_history() except Exception as e: st.error(f"エラーが発生しました: {str(e)}") # スキャン結果の表示 if st.session_state.structure_md and st.session_state.content_md: tab1, tab2 = st.tabs(["📁 ディレクトリ構造", "📄 ファイル内容"]) with tab1: st.markdown(f'