#!/usr/bin/env bash # plan-status — Scan projects for plan files and show pipeline status # Usage: plan-status [search-root] [options] set -euo pipefail # Resolve symlinks to find real script location SOURCE="${BASH_SOURCE[0]}" while [[ -L "$SOURCE" ]]; do DIR="$(cd -P "$(dirname "$SOURCE")" && pwd)" SOURCE="$(readlink "$SOURCE")" [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" done SCRIPT_DIR="$(cd -P "$(dirname "$SOURCE")/.." && pwd)" source "$SCRIPT_DIR/lib/frontmatter.sh" SEARCH_ROOT="${HOME}/projects" JSON_OUTPUT=false FILTER_STATUS="" usage() { cat <<'EOF' plan-status — Dashboard for plan files across projects Usage: plan-status [search-root] [options] Scans for markdown files with plan: true frontmatter and shows their position in the refinement pipeline. Pipeline: drafting -> iterating -> splitting -> refining -> ready -> implementing -> completed Options: --json Machine-readable JSON output --status Filter to plans with this status --root Search root (default: ~/projects) -h, --help Show this help EOF exit 0 } while [[ $# -gt 0 ]]; do case "$1" in --json) JSON_OUTPUT=true; shift ;; --status) FILTER_STATUS="$2"; shift 2 ;; --root) SEARCH_ROOT="$2"; shift 2 ;; -h|--help) usage ;; -*) echo "Unknown option: $1" >&2; exit 2 ;; *) SEARCH_ROOT="$1"; shift ;; esac done if [[ ! -d "$SEARCH_ROOT" ]]; then echo "Error: Search root not found: $SEARCH_ROOT" >&2 exit 1 fi # Collect plan files declare -a PLAN_FILES=() while IFS= read -r -d '' file; do if is_plan_file "$file"; then PLAN_FILES+=("$file") fi done < <(find "$SEARCH_ROOT" \ -name "*.md" \ -not -path "*/node_modules/*" \ -not -path "*/.git/*" \ -not -path "*/.jj/*" \ -not -path "*/target/*" \ -not -name "*.feedback-*" \ -print0 2>/dev/null) if [[ ${#PLAN_FILES[@]} -eq 0 ]]; then if [[ "$JSON_OUTPUT" == "true" ]]; then echo '{"plans":[],"summary":{"total":0}}' else echo "No plan files found under $SEARCH_ROOT" echo "Initialize a plan: plan-refine --init" fi exit 0 fi if [[ "$JSON_OUTPUT" == "true" ]]; then # JSON output echo '{"plans":[' first=true for file in "${PLAN_FILES[@]}"; do status=$(get_frontmatter "$file" "status" "unknown") [[ -n "$FILTER_STATUS" && "$status" != "$FILTER_STATUS" ]] && continue title=$(get_frontmatter "$file" "title" "$(basename "$file" .md)") iteration=$(get_frontmatter "$file" "iteration" "0") target=$(get_frontmatter "$file" "target_iterations" "") beads_rev=$(get_frontmatter "$file" "beads_revision" "0") updated=$(get_frontmatter "$file" "updated" "") project=$(echo "$file" | sed "s|${SEARCH_ROOT}/||" | cut -d/ -f1) # Count feedback files feedback_count=$(ls "${file%.md}".feedback-*.md 2>/dev/null | wc -l | tr -d ' ') [[ "$first" != "true" ]] && echo "," first=false cat < iterating -> splitting -> refining -> ready -> implementing -> completed" echo "" fi