| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277 |
- #!/usr/bin/env bash
- #############################################################################
- # Documentation Sync Validator
- # Validates that component counts in README.md match registry.json
- # Used in CI to detect when docs are out of sync
- #
- # For actual syncing, use the sync-docs.yml GitHub workflow which
- # leverages OpenCode to intelligently update documentation
- #############################################################################
- set -e
- # Colors
- RED='\033[0;31m'
- GREEN='\033[0;32m'
- YELLOW='\033[1;33m'
- BLUE='\033[0;34m'
- CYAN='\033[0;36m'
- BOLD='\033[1m'
- NC='\033[0m'
- # Configuration
- REGISTRY_FILE="registry.json"
- README_FILE="README.md"
- REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
- DRY_RUN=false
- VERBOSE=false
- #############################################################################
- # Utility Functions
- #############################################################################
- print_header() {
- echo -e "${CYAN}${BOLD}"
- echo "╔════════════════════════════════════════════════════════════════╗"
- echo "║ ║"
- echo "║ Documentation Sync v1.0.0 ║"
- echo "║ Keep README in sync with registry ║"
- echo "║ ║"
- echo "╚════════════════════════════════════════════════════════════════╝"
- echo -e "${NC}"
- }
- print_success() {
- echo -e "${GREEN}✓${NC} $1"
- }
- print_error() {
- echo -e "${RED}✗${NC} $1"
- }
- print_warning() {
- echo -e "${YELLOW}⚠${NC} $1"
- }
- print_info() {
- echo -e "${BLUE}ℹ${NC} $1"
- }
- usage() {
- echo "Usage: $0 [OPTIONS]"
- echo ""
- echo "Options:"
- echo " -d, --dry-run Show what would be changed without modifying files"
- echo " -v, --verbose Show detailed output"
- echo " -h, --help Show this help message"
- echo ""
- echo "Description:"
- echo " Syncs component counts and lists from registry.json to README.md"
- echo " Ensures documentation stays accurate with the component registry"
- echo ""
- exit 0
- }
- #############################################################################
- # Dependency Checks
- #############################################################################
- check_dependencies() {
- local missing_deps=()
-
- if ! command -v jq &> /dev/null; then
- missing_deps+=("jq")
- fi
-
- if [ ${#missing_deps[@]} -ne 0 ]; then
- print_error "Missing required dependencies: ${missing_deps[*]}"
- echo ""
- echo "Please install them:"
- echo " macOS: brew install ${missing_deps[*]}"
- echo " Ubuntu: sudo apt-get install ${missing_deps[*]}"
- exit 2
- fi
- }
- #############################################################################
- # Registry Parsing
- #############################################################################
- get_component_count() {
- local component_type="$1"
- jq -r ".components.${component_type} | length" "$REGISTRY_FILE"
- }
- get_profile_component_count() {
- local profile="$1"
- jq -r ".profiles.${profile}.components | length" "$REGISTRY_FILE"
- }
- get_total_components() {
- jq -r '
- .components.agents +
- .components.subagents +
- .components.commands +
- .components.tools +
- .components.plugins +
- .components.contexts +
- .components.config | length
- ' "$REGISTRY_FILE"
- }
- #############################################################################
- # README Update Functions
- #############################################################################
- update_profile_counts() {
- local readme_content
- readme_content=$(cat "$README_FILE")
-
- # Update Essential profile count
- local essential_count
- essential_count=$(get_profile_component_count "essential")
- readme_content=$(echo "$readme_content" | sed -E "s/(Essential.*\()([0-9]+)( components\))/\1${essential_count}\3/g")
-
- # Update Developer profile count
- local developer_count
- developer_count=$(get_profile_component_count "developer")
- readme_content=$(echo "$readme_content" | sed -E "s/(Developer.*\()([0-9]+)( components\))/\1${developer_count}\3/g")
-
- # Update Business profile count
- local business_count
- business_count=$(get_profile_component_count "business")
- readme_content=$(echo "$readme_content" | sed -E "s/(Business.*\()([0-9]+)( components\))/\1${business_count}\3/g")
-
- # Update Full profile count
- local full_count
- full_count=$(get_profile_component_count "full")
- readme_content=$(echo "$readme_content" | sed -E "s/(Full.*\()([0-9]+)( components\))/\1${full_count}\3/g")
-
- # Update Advanced profile count
- local advanced_count
- advanced_count=$(get_profile_component_count "advanced")
- readme_content=$(echo "$readme_content" | sed -E "s/(Advanced.*\()([0-9]+)( components\))/\1${advanced_count}\3/g")
-
- echo "$readme_content"
- }
- update_component_counts() {
- local readme_content="$1"
-
- # Get counts from registry
- local agents_count subagents_count commands_count tools_count plugins_count contexts_count
- agents_count=$(get_component_count "agents")
- subagents_count=$(get_component_count "subagents")
- commands_count=$(get_component_count "commands")
- tools_count=$(get_component_count "tools")
- plugins_count=$(get_component_count "plugins")
- contexts_count=$(get_component_count "contexts")
-
- if [ "$VERBOSE" = true ]; then
- print_info "Component counts from registry:"
- echo " Agents: $agents_count"
- echo " Subagents: $subagents_count"
- echo " Commands: $commands_count"
- echo " Tools: $tools_count"
- echo " Plugins: $plugins_count"
- echo " Contexts: $contexts_count"
- fi
-
- echo "$readme_content"
- }
- #############################################################################
- # Main Logic
- #############################################################################
- main() {
- # Parse arguments
- while [[ $# -gt 0 ]]; do
- case $1 in
- -d|--dry-run)
- DRY_RUN=true
- shift
- ;;
- -v|--verbose)
- VERBOSE=true
- shift
- ;;
- -h|--help)
- usage
- ;;
- *)
- print_error "Unknown option: $1"
- usage
- ;;
- esac
- done
-
- print_header
-
- # Check dependencies
- check_dependencies
-
- # Change to repo root
- cd "$REPO_ROOT"
-
- # Verify files exist
- if [ ! -f "$REGISTRY_FILE" ]; then
- print_error "Registry file not found: $REGISTRY_FILE"
- exit 1
- fi
-
- if [ ! -f "$README_FILE" ]; then
- print_error "README file not found: $README_FILE"
- exit 1
- fi
-
- print_info "Reading registry: $REGISTRY_FILE"
- print_info "Updating README: $README_FILE"
- echo ""
-
- # Update profile counts
- print_info "Updating installation profile counts..."
- local updated_content
- updated_content=$(update_profile_counts)
-
- # Update component counts
- print_info "Updating component counts..."
- updated_content=$(update_component_counts "$updated_content")
-
- # Check if anything changed
- if [ "$updated_content" = "$(cat "$README_FILE")" ]; then
- print_success "README is already up to date!"
- exit 0
- fi
-
- # Show diff if verbose
- if [ "$VERBOSE" = true ]; then
- echo ""
- print_info "Changes to be made:"
- diff -u "$README_FILE" <(echo "$updated_content") || true
- echo ""
- fi
-
- # Apply changes or show dry-run
- if [ "$DRY_RUN" = true ]; then
- print_warning "DRY RUN - No changes made"
- print_info "Run without --dry-run to apply changes"
- else
- echo "$updated_content" > "$README_FILE"
- print_success "README updated successfully!"
- fi
-
- echo ""
- print_info "Summary:"
- echo " Essential: $(get_profile_component_count "essential") components"
- echo " Developer: $(get_profile_component_count "developer") components"
- echo " Business: $(get_profile_component_count "business") components"
- echo " Full: $(get_profile_component_count "full") components"
- echo " Advanced: $(get_profile_component_count "advanced") components"
- echo ""
- echo " Total: $(get_total_components) components"
- }
- # Run main function
- main "$@"
|