#!/usr/bin/env bash set -euo pipefail ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" OUT_DIR="$ROOT_DIR/docs/consolidation/pieces" DRY_RUN=1 APPLY=0 PROBE_PORTS="" usage() { cat <<'USAGE' Usage: bash scripts/docs/pieces_sync.sh [--dry-run] [--apply] [--probe-ports 39300,39301] Behavior: - default mode is --dry-run - --apply writes markdown/csv outputs under docs/consolidation/pieces - optional --probe-ports performs local API probe on localhost for /health and /status USAGE } while [[ $# -gt 0 ]]; do case "$1" in --dry-run) DRY_RUN=1 APPLY=0 shift ;; --apply) APPLY=1 DRY_RUN=0 shift ;; --probe-ports) PROBE_PORTS="$2" shift 2 ;; -h|--help) usage exit 0 ;; *) echo "Unknown arg: $1" >&2 usage exit 2 ;; esac done EXT_DIR="$HOME/.cursor/extensions" APP_SUPPORT="$HOME/Library/Application Support" ext_hits="" if [[ -d "$EXT_DIR" ]]; then ext_hits="$(find "$EXT_DIR" -maxdepth 1 -type d -iname '*pieces*' | sort || true)" fi ext_count="$(echo "$ext_hits" | sed '/^\s*$/d' | wc -l | tr -d ' ')" support_hits="" if [[ -d "$APP_SUPPORT" ]]; then support_hits="$(find "$APP_SUPPORT" -maxdepth 1 -type d -iname '*pieces*' | sort || true)" fi support_count="$(echo "$support_hits" | sed '/^\s*$/d' | wc -l | tr -d ' ')" proc_hits="$(pgrep -fal -i 'pieces|copilot' | rg -v 'scripts/docs/pieces_sync.sh' || true)" proc_count="$(echo "$proc_hits" | sed '/^\s*$/d' | wc -l | tr -d ' ')" probe_lines="" probe_ok=0 probe_total=0 if [[ -n "$PROBE_PORTS" ]]; then IFS=',' read -r -a ports <<< "$PROBE_PORTS" for port in "${ports[@]}"; do port_trimmed="$(echo "$port" | xargs)" [[ -z "$port_trimmed" ]] && continue for endpoint in health status; do url="http://127.0.0.1:${port_trimmed}/${endpoint}" code="$(curl -sS -o /dev/null -w '%{http_code}' "$url" || true)" probe_total=$((probe_total + 1)) if [[ "$code" == "200" ]]; then probe_ok=$((probe_ok + 1)) fi probe_lines+="- ${url} -> HTTP ${code}"$'\n' done done fi if [[ "$DRY_RUN" -eq 1 ]]; then echo "[dry-run] pieces_extensions_count: $ext_count" echo "[dry-run] pieces_data_dirs_count: $support_count" echo "[dry-run] pieces_process_count: $proc_count" echo "[dry-run] api_probe_ok: $probe_ok/$probe_total" if [[ -n "$probe_lines" ]]; then echo "[dry-run] api_probes:" printf "%s" "$probe_lines" fi exit 0 fi mkdir -p "$OUT_DIR" STAMP="$(date +%Y%m%d-%H%M%S)" REPORT="$OUT_DIR/PIECES_SYNC_${STAMP}.md" LATEST="$OUT_DIR/PIECES_SYNC_LATEST.md" INDEX="$OUT_DIR/pieces_index_${STAMP}.csv" INDEX_LATEST="$OUT_DIR/pieces_index_latest.csv" { echo "# Pieces Sync Report" echo echo "Generated: $(date -u '+%Y-%m-%d %H:%M:%S UTC')" echo echo "- pieces_extensions_count: $ext_count" echo "- pieces_data_dirs_count: $support_count" echo "- pieces_process_count: $proc_count" echo "- api_probe_ok: $probe_ok/$probe_total" echo echo "## Extensions" echo if [[ -n "$ext_hits" ]]; then echo "$ext_hits" | sed 's/^/- /' else echo "- no pieces extensions found" fi echo echo "## Data Dirs" echo if [[ -n "$support_hits" ]]; then echo "$support_hits" | sed 's/^/- /' else echo "- no pieces data directories found" fi echo echo "## Processes" echo if [[ -n "$proc_hits" ]]; then echo "$proc_hits" | sed 's/^/- /' else echo "- no pieces related processes found" fi echo echo "## API Probes" echo if [[ -n "$probe_lines" ]]; then printf "%s" "$probe_lines" else echo "- no api probe ports supplied" fi } > "$REPORT" { echo "kind,path_or_process" if [[ -n "$ext_hits" ]]; then while IFS= read -r row; do [[ -z "$row" ]] && continue echo "extension,\"$row\"" done <<< "$ext_hits" fi if [[ -n "$support_hits" ]]; then while IFS= read -r row; do [[ -z "$row" ]] && continue echo "data_dir,\"$row\"" done <<< "$support_hits" fi if [[ -n "$proc_hits" ]]; then while IFS= read -r row; do [[ -z "$row" ]] && continue echo "process,\"$row\"" done <<< "$proc_hits" fi } > "$INDEX" cp "$REPORT" "$LATEST" cp "$INDEX" "$INDEX_LATEST" echo "Wrote: $REPORT" echo "Updated: $LATEST" echo "Wrote: $INDEX" echo "Updated: $INDEX_LATEST"