2929
3030
3131def convert_notebooks_to_md (src_dir : Path , dst_dir : Path ) -> List [Path ]:
32- """Convert Jupyter notebooks (*.ipynb) to Markdown."""
32+ """
33+ Convert Jupyter notebooks (*.ipynb) to Markdown files.
34+
35+ Parameters
36+ ----------
37+ src_dir : Path
38+ Source directory containing Jupyter notebooks.
39+ dst_dir : Path
40+ Destination directory where converted Markdown files will be written.
41+
42+ Returns
43+ -------
44+ List[Path]
45+ List of paths to the generated Markdown files.
46+
47+ Raises
48+ ------
49+ FileNotFoundError
50+ If no notebooks are found in `src_dir`.
51+ """
3352 created : List [Path ] = []
53+
3454 for ipynb_file in sorted (src_dir .glob ("*.ipynb" )):
3555 notebook = json .loads (ipynb_file .read_text (encoding = "utf-8" ))
3656 parts : List [str ] = []
57+
3758 for cell in notebook .get ("cells" , []):
3859 src = "" .join (cell .get ("source" , []))
3960 if cell .get ("cell_type" ) == "markdown" :
4061 parts .append (src )
4162 elif cell .get ("cell_type" ) == "code" :
4263 parts .append (f"```python\n { src } \n ```" )
64+
4365 if parts :
4466 md_file = dst_dir / f"{ ipynb_file .stem } .md"
4567 md_file .write_text ("\n \n " .join (parts ), encoding = "utf-8" )
4668 created .append (md_file .resolve ())
69+
4770 if not created :
4871 raise FileNotFoundError ("No example notebooks (*.ipynb) found." )
72+
4973 return created
5074
5175
5276def collect_py_files (root : Path , exclude : Sequence [str ] = ()) -> List [Path ]:
53- """Collect Python source files from a directory."""
77+ """
78+ Collect Python source files from a directory, excluding specified folders.
79+
80+ Parameters
81+ ----------
82+ root : Path
83+ Root directory to search for Python files.
84+ exclude : Sequence[str], optional
85+ Names of directories to exclude from the search (default is empty).
86+
87+ Returns
88+ -------
89+ List[Path]
90+ Sorted list of resolved paths to Python files.
91+ """
5492 excluded = set (exclude )
5593 return sorted (
5694 f .resolve ()
@@ -60,11 +98,30 @@ def collect_py_files(root: Path, exclude: Sequence[str] = ()) -> List[Path]:
6098
6199
62100def run_gitingest (work_dir : Path , output : Path , exclude : Sequence [str ] | None = None ) -> None :
63- """Run gitingest on a directory."""
101+ """
102+ Run `gitingest` on a directory to generate an LLM context bundle.
103+
104+ Parameters
105+ ----------
106+ work_dir : Path
107+ Directory to run gitingest on.
108+ output : Path
109+ Output Markdown file path where results will be saved.
110+ exclude : Sequence[str] or None, optional
111+ List of exclusion patterns for gitingest (default is None).
112+
113+ Raises
114+ ------
115+ FileNotFoundError
116+ If `gitingest` is not installed or not found in PATH.
117+ subprocess.CalledProcessError
118+ If `gitingest` execution fails.
119+ """
64120 cmd = ["gitingest" , str (work_dir ), "--output" , str (output )]
65121 if exclude :
66122 for pat in exclude :
67123 cmd .extend (["--exclude-pattern" , pat ])
124+
68125 try :
69126 subprocess .run (cmd , check = True )
70127 except FileNotFoundError :
@@ -73,11 +130,29 @@ def run_gitingest(work_dir: Path, output: Path, exclude: Sequence[str] | None =
73130 except subprocess .CalledProcessError as e :
74131 sys .stderr .write (f"ERROR: gitingest failed (exit code { e .returncode } ).\n " )
75132 raise
133+
76134 print (f"Gitingest executed; output saved to { output } " )
77135
78136
79137def main () -> None :
80- """Build compact and full LLM context bundles with versioned filenames."""
138+ """
139+ Build compact and full LLM context bundles with versioned filenames.
140+
141+ Workflow
142+ --------
143+ 1. Validate presence of README and examples directory.
144+ 2. Remove old context files from the output directory.
145+ 3. Convert Jupyter notebooks in `examples/` to Markdown.
146+ 4. Build two bundles:
147+ - Compact: README + examples
148+ - Full: README + examples + source files (excluding certain directories)
149+ 5. Run `gitingest` to generate Markdown bundles.
150+
151+ Raises
152+ ------
153+ FileNotFoundError
154+ If required files or directories are missing.
155+ """
81156 tag = (sys .argv [1 ] if len (sys .argv ) > 1 else None ) or "dev"
82157
83158 if not README_FILE .exists ():
0 commit comments