From 2dea56ea3945fb37445a1ac863ce6007c2139a3f Mon Sep 17 00:00:00 2001 From: Max Date: Sat, 21 Feb 2026 17:32:03 -0600 Subject: [PATCH] Add CLI coverage audit script - New audit-cli-coverage.sh to verify CLI matches API surface area - Updated README with audit instructions - Helps ensure Rule 2.5 compliance (CLI sync with web UI) --- scripts/README.md | 10 +++ scripts/audit-cli-coverage.sh | 150 ++++++++++++++++++++++++++++++++++ 2 files changed, 160 insertions(+) create mode 100755 scripts/audit-cli-coverage.sh diff --git a/scripts/README.md b/scripts/README.md index 2c9c328..eddacd4 100644 --- a/scripts/README.md +++ b/scripts/README.md @@ -148,6 +148,16 @@ Displays text files in terminal, saves binary files to `/tmp/`. | Auth login/logout | ✅ | ✅ | ❌ | | View attachments | ✅ | ❌ | ✅ | +### Auditing Coverage + +Use the audit script to verify CLI stays in sync with API: + +```bash +./scripts/audit-cli-coverage.sh +``` + +This scans all API routes and checks that each has a matching CLI command. Run this before committing any API changes to ensure Rule 2.5 compliance. + ## Requirements - `curl` - HTTP requests (built into macOS) diff --git a/scripts/audit-cli-coverage.sh b/scripts/audit-cli-coverage.sh new file mode 100755 index 0000000..908e1ed --- /dev/null +++ b/scripts/audit-cli-coverage.sh @@ -0,0 +1,150 @@ +#!/bin/bash +# CLI Coverage Audit Script +# Compares API endpoints to CLI commands to ensure sync +# Usage: ./scripts/audit-cli-coverage.sh + +set -e + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_ROOT="$(dirname "$SCRIPT_DIR")" +API_DIR="${PROJECT_ROOT}/src/app/api" + +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' + +log_info() { echo -e "${GREEN}✓${NC} $1"; } +log_warn() { echo -e "${YELLOW}⚠${NC} $1"; } +log_error() { echo -e "${RED}✗${NC} $1"; } + +echo "═══════════════════════════════════════════════════════════" +echo " CLI Coverage Audit" +echo "═══════════════════════════════════════════════════════════" +echo "" + +# Check if API directory exists +if [ ! -d "$API_DIR" ]; then + log_error "API directory not found: $API_DIR" + exit 1 +fi + +# Find all API route files +echo "📁 Scanning API routes in $API_DIR..." +echo "" + +# Extract API endpoints from route.ts files +declare -a API_ENDPOINTS=() + +while IFS= read -r -d '' route_file; do + # Get the directory path relative to api/ + rel_path=$(dirname "$route_file" | sed "s|$API_DIR/||") + + # Check for HTTP methods in the file + if grep -q "export async function GET" "$route_file"; then + API_ENDPOINTS+=("GET /api/$rel_path") + fi + if grep -q "export async function POST" "$route_file"; then + API_ENDPOINTS+=("POST /api/$rel_path") + fi + if grep -q "export async function PATCH" "$route_file"; then + API_ENDPOINTS+=("PATCH /api/$rel_path") + fi + if grep -q "export async function DELETE" "$route_file"; then + API_ENDPOINTS+=("DELETE /api/$rel_path") + fi + if grep -q "export async function PUT" "$route_file"; then + API_ENDPOINTS+=("PUT /api/$rel_path") + fi +done < <(find "$API_DIR" -name "route.ts" -print0) + +# Sort and dedupe API endpoints +IFS=$'\n' API_ENDPOINTS=($(sort <<< "${API_ENDPOINTS[*]}")) +unset IFS + +echo "Found ${#API_ENDPOINTS[@]} API endpoint(s):" +for endpoint in "${API_ENDPOINTS[@]}"; do + echo " • $endpoint" +done +echo "" + +# Check CLI coverage +echo "🔍 Checking CLI coverage..." +echo "" + +# Extract CLI commands from gantt.sh (or similar unified CLI) +CLI_FILE="${SCRIPT_DIR}/gantt.sh" +if [ ! -f "$CLI_FILE" ]; then + log_warn "Unified CLI not found at $CLI_FILE" + log_info "Checking for individual scripts..." + + # Look for any shell scripts + CLI_SCRIPTS=($(find "$SCRIPT_DIR" -name "*.sh" -type f ! -name "audit-cli-coverage.sh" | sort)) + + if [ ${#CLI_SCRIPTS[@]} -eq 0 ]; then + log_error "No CLI scripts found!" + exit 1 + fi + + echo "Found CLI scripts:" + for script in "${CLI_SCRIPTS[@]}"; do + echo " • $(basename "$script")" + done +fi + +# Compare API to CLI coverage +echo "" +echo "═══════════════════════════════════════════════════════════" +echo " Coverage Report" +echo "═══════════════════════════════════════════════════════════" +echo "" + +# This is project-specific - customize based on your CLI structure +# For gantt-board, we check against known CLI commands + +declare -A CLI_MAP=( + ["GET /api/tasks"]='task list' + ["POST /api/tasks"]='task create' + ["DELETE /api/tasks"]='task delete' + ["POST /api/tasks/natural"]='task natural' +) + +MISSING=0 +COVERED=0 + +for endpoint in "${API_ENDPOINTS[@]}"; do + if [ -n "${CLI_MAP[$endpoint]}" ]; then + log_info "$endpoint → ${CLI_MAP[$endpoint]}" + ((COVERED++)) + else + log_error "$endpoint → NO CLI COMMAND" + ((MISSING++)) + fi +done + +echo "" +echo "═══════════════════════════════════════════════════════════" +echo " Summary" +echo "═══════════════════════════════════════════════════════════" +echo "" + +if [ $MISSING -eq 0 ]; then + log_info "All API endpoints have CLI coverage!" + echo "" + echo " Total endpoints: ${#API_ENDPOINTS[@]}" + echo " Covered: $COVERED" + echo " Missing: $MISSING" + echo "" + exit 0 +else + log_error "CLI coverage incomplete!" + echo "" + echo " Total endpoints: ${#API_ENDPOINTS[@]}" + echo " Covered: $COVERED" + echo " Missing: $MISSING" + echo "" + echo "Add CLI commands for missing endpoints before committing." + echo "See Rule 2.5 in MEMORY.md for details." + echo "" + exit 1 +fi