2025-04-06 17:07:47 -04:00
import dotenv
2025-04-04 15:06:41 -04:00
import os
import argparse
# Import the function that creates the flow
from flow import create_tutorial_flow
2025-04-02 16:56:35 -04:00
2025-04-06 17:07:47 -04:00
dotenv . load_dotenv ( )
2025-04-04 15:06:41 -04:00
# Default file patterns
DEFAULT_INCLUDE_PATTERNS = {
2025-04-16 15:36:28 +07:00
" *.py " , " *.js " , " *.jsx " , " *.ts " , " *.tsx " , " *.go " , " *.java " , " *.pyi " , " *.pyx " ,
" *.c " , " *.cc " , " *.cpp " , " *.h " , " *.md " , " *.rst " , " Dockerfile " ,
2025-04-08 18:27:32 +00:00
" Makefile " , " *.yaml " , " *.yml " ,
2025-04-04 15:06:41 -04:00
}
DEFAULT_EXCLUDE_PATTERNS = {
2025-04-30 19:00:50 +10:00
" assets/* " , " data/* " , " examples/* " , " images/* " , " public/* " , " static/* " , " temp/* " ,
" docs/* " ,
2025-04-21 11:22:52 +01:00
" venv/* " , " .venv/* " , " *test* " , " tests/* " , " docs/* " , " examples/* " , " v1/* " ,
2025-04-30 19:00:50 +10:00
" dist/* " , " build/* " , " experimental/* " , " deprecated/* " , " misc/* " ,
2025-04-08 18:27:32 +00:00
" legacy/* " , " .git/* " , " .github/* " , " .next/* " , " .vscode/* " , " obj/* " , " bin/* " , " node_modules/* " , " *.log "
2025-04-04 15:06:41 -04:00
}
# --- Main Function ---
2025-04-02 16:56:35 -04:00
def main ( ) :
2025-04-08 18:27:32 +00:00
parser = argparse . ArgumentParser ( description = " Generate a tutorial for a GitHub codebase or local directory. " )
2025-04-16 15:36:28 +07:00
2025-04-08 18:27:32 +00:00
# Create mutually exclusive group for source
source_group = parser . add_mutually_exclusive_group ( required = True )
source_group . add_argument ( " --repo " , help = " URL of the public GitHub repository. " )
source_group . add_argument ( " --dir " , help = " Path to local directory. " )
2025-04-16 15:36:28 +07:00
2025-04-08 18:27:32 +00:00
parser . add_argument ( " -n " , " --name " , help = " Project name (optional, derived from repo/directory if omitted). " )
2025-04-04 15:06:41 -04:00
parser . add_argument ( " -t " , " --token " , help = " GitHub personal access token (optional, reads from GITHUB_TOKEN env var if not provided). " )
parser . add_argument ( " -o " , " --output " , default = " output " , help = " Base directory for output (default: ./output). " )
parser . add_argument ( " -i " , " --include " , nargs = " + " , help = " Include file patterns (e.g. ' *.py ' ' *.js ' ). Defaults to common code files if not specified. " )
parser . add_argument ( " -e " , " --exclude " , nargs = " + " , help = " Exclude file patterns (e.g. ' tests/* ' ' docs/* ' ). Defaults to test/build directories if not specified. " )
parser . add_argument ( " -s " , " --max-size " , type = int , default = 100000 , help = " Maximum file size in bytes (default: 100000, about 100KB). " )
2025-04-16 15:36:28 +07:00
# Add language parameter for multi-language support
parser . add_argument ( " --language " , default = " english " , help = " Language for the generated tutorial (default: english) " )
2025-04-30 19:00:50 +10:00
# Add use_cache parameter to control LLM caching
parser . add_argument ( " --no-cache " , action = " store_true " , help = " Disable LLM response caching (default: caching enabled) " )
2025-05-01 15:43:26 +10:00
# Add max_abstraction_num parameter to control the number of abstractions
parser . add_argument ( " --max-abstractions " , type = int , default = 10 , help = " Maximum number of abstractions to identify (default: 20) " )
2025-04-04 15:06:41 -04:00
args = parser . parse_args ( )
2025-04-08 18:27:32 +00:00
# Get GitHub token from argument or environment variable if using repo
github_token = None
if args . repo :
github_token = args . token or os . environ . get ( ' GITHUB_TOKEN ' )
if not github_token :
print ( " Warning: No GitHub token provided. You might hit rate limits for public repositories. " )
2025-04-04 15:06:41 -04:00
# Initialize the shared dictionary with inputs
2025-04-02 16:56:35 -04:00
shared = {
2025-04-08 18:27:32 +00:00
" repo_url " : args . repo ,
" local_dir " : args . dir ,
2025-04-04 15:06:41 -04:00
" project_name " : args . name , # Can be None, FetchRepo will derive it
" github_token " : github_token ,
" output_dir " : args . output , # Base directory for CombineTutorial output
# Add include/exclude patterns and max file size
" include_patterns " : set ( args . include ) if args . include else DEFAULT_INCLUDE_PATTERNS ,
" exclude_patterns " : set ( args . exclude ) if args . exclude else DEFAULT_EXCLUDE_PATTERNS ,
" max_file_size " : args . max_size ,
2025-04-16 15:36:28 +07:00
# Add language for multi-language support
" language " : args . language ,
2025-04-30 19:00:50 +10:00
# Add use_cache flag (inverse of no-cache flag)
" use_cache " : not args . no_cache ,
2025-05-01 15:43:26 +10:00
# Add max_abstraction_num parameter
" max_abstraction_num " : args . max_abstractions ,
2025-04-16 15:36:28 +07:00
2025-04-04 15:06:41 -04:00
# Outputs will be populated by the nodes
" files " : [ ] ,
" abstractions " : [ ] ,
" relationships " : { } ,
" chapter_order " : [ ] ,
" chapters " : [ ] ,
" final_output_dir " : None
2025-04-02 16:56:35 -04:00
}
2025-04-16 15:36:28 +07:00
# Display starting message with repository/directory and language
print ( f " Starting tutorial generation for: { args . repo or args . dir } in { args . language . capitalize ( ) } language " )
2025-04-30 19:00:50 +10:00
print ( f " LLM caching: { ' Disabled ' if args . no_cache else ' Enabled ' } " )
2025-04-04 15:06:41 -04:00
# Create the flow instance
tutorial_flow = create_tutorial_flow ( )
2025-04-02 16:56:35 -04:00
2025-04-04 15:06:41 -04:00
# Run the flow
tutorial_flow . run ( shared )
2025-04-16 15:36:28 +07:00
2025-04-02 16:56:35 -04:00
if __name__ == " __main__ " :
2025-04-16 15:36:28 +07:00
main ( )