#!/bin/bash # ------------------------------------------------------------------ # Author: ChatGPT # Generated on: $(date '+%Y-%m-%d') # # This script recursively creates or updates a table-of-contents README # file in each non-hidden directory. The file is named "Folder Name - README.md". # # Each README includes: # - An author/date header. # - A header with the folder's name. # - An alphabetically sorted list of immediate subdirectories, with links # to that subdirectory’s own README. # - An alphabetically sorted list of immediate files (excluding the generated README). # - A "Summary" section with a short description generated by an LLM (using llama3.2:latest). # # Hidden directories (or any directory under a hidden parent such as .git) are skipped. # # The script only updates a README if the static content (header, subdirectories and files) # changes. The LLM summary output is excluded from the diff check. # # Progress is printed as "[x/y] Updated: {dir}" or "[x/y] No change: {dir}". # ------------------------------------------------------------------ # Set the base directory (change "." if necessary) base_dir="." # Build an array of directories to process. dirs=() while IFS= read -r -d '' dir; do # Skip directories that are hidden or inside a hidden parent (like .git) if [[ "$(basename "$dir")" == .* ]] || [[ "$dir" == *"/.git"* ]]; then continue fi dirs+=( "$dir" ) done < <(find "$base_dir" -type d -print0) total=${#dirs[@]} count=0 for dir in "${dirs[@]}"; do count=$((count+1)) # For the top-level directory, use the actual name from $PWD; otherwise, use the directory's basename. if [ "$dir" = "$base_dir" ]; then base=$(basename "$PWD") else base=$(basename "$dir") fi # Define the path for the README file: "Folder Name - README.md" readme="$dir/${base} - README.md" # Create a temporary file to hold the new static content. tmp_static=$(mktemp) { echo "Generated by ChatGPT on $(date '+%Y-%m-%d')" echo "" echo "# Table of Contents for ${base}" echo "" } > "$tmp_static" ######################### # Process Subdirectories ######################### subdirs=() while IFS= read -r -d '' subdir; do sub_basename=$(basename "$subdir") if [ -n "$sub_basename" ]; then subdirs+=( "$sub_basename" ) fi done < <(find "$dir" -mindepth 1 -maxdepth 1 -type d ! -name '.*' -print0) if [ ${#subdirs[@]} -gt 0 ]; then mapfile -t sorted_subdirs < <(printf "%s\n" "${subdirs[@]}" | sort) echo "## Subdirectories" >> "$tmp_static" for sub in "${sorted_subdirs[@]}"; do # Link format: [[Subfolder/Subfolder - README]] line="- [[${sub}/${sub} - README]]" printf "%s\n" "$line" >> "$tmp_static" done echo "" >> "$tmp_static" fi ################# # Process Files ################# files=() while IFS= read -r -d '' file; do fbase=$(basename "$file") if [ -n "$fbase" ]; then files+=( "$fbase" ) fi done < <(find "$dir" -mindepth 1 -maxdepth 1 -type f ! -path "$readme" -print0) if [ ${#files[@]} -gt 0 ]; then mapfile -t sorted_files < <(printf "%s\n" "${files[@]}" | sort) echo "## Files" >> "$tmp_static" for f in "${sorted_files[@]}"; do line="- [[${f}]]" printf "%s\n" "$line" >> "$tmp_static" done echo "" >> "$tmp_static" fi # Determine if the static content has changed. static_changed=1 if [ -f "$readme" ]; then # Extract the static portion from the existing README (everything before "## Summary") existing_static=$(sed '/^## Summary/ q' "$readme") new_static=$(cat "$tmp_static") if [ "$existing_static" = "$new_static" ]; then static_changed=0 fi fi if [ $static_changed -eq 0 ]; then echo "[$count/$total] No change: $dir" rm "$tmp_static" continue fi ################# # Query LLM for Summary ################# prompt="Based on the following table of contents, provide a short summary description of what this directory is about: $(cat "$tmp_static")" # Query the model using the Ollama CLI with the llama3.2:latest model. summary=$(ollama run llama3.2 "$prompt") # Build the full new content: static portion + summary section. { cat "$tmp_static" echo "## Summary" echo "$summary" echo "" } > "$readme" rm "$tmp_static" echo "[$count/$total] Updated: $dir" done