From f00803300175d6a56caf259318d95186a1d3a9b3 Mon Sep 17 00:00:00 2001 From: Snider Date: Mon, 2 Feb 2026 07:26:48 +0000 Subject: [PATCH] feat(code): add /core:status multi-repo status command (#78) Migrated from host-uk/core-claude#37 Co-authored-by: Claude Opus 4.5 --- claude/code/commands/status.md | 16 ++++++ claude/code/scripts/core-status.sh | 79 ++++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+) create mode 100755 claude/code/scripts/core-status.sh diff --git a/claude/code/commands/status.md b/claude/code/commands/status.md index c3333e2..7b53d78 100644 --- a/claude/code/commands/status.md +++ b/claude/code/commands/status.md @@ -1,4 +1,12 @@ --- +name: status +description: Show status across all Host UK repos +args: [--dirty|--behind] +--- + +# Multi-Repo Status + +Wraps `core dev health` with better formatting. name: /core:status description: Show status across all Host UK repos hooks: @@ -17,3 +25,11 @@ A quick command to show the status across all Host UK repos. `/core:status` - Show all repo statuses `/core:status --dirty` - Only show repos with changes `/core:status --behind` - Only show repos behind remote + +## Action + +Run this command to get the status: + +```bash +"${CLAUDE_PLUGIN_ROOT}/scripts/core-status.sh" "$@" +``` diff --git a/claude/code/scripts/core-status.sh b/claude/code/scripts/core-status.sh new file mode 100755 index 0000000..95a4043 --- /dev/null +++ b/claude/code/scripts/core-status.sh @@ -0,0 +1,79 @@ +#!/bin/bash + +# Fetch the raw status from the core dev health command. +# The output format is assumed to be: +# module branch status ahead behind insertions deletions +RAW_STATUS=$(core dev health 2>/dev/null) + +# Exit if the command fails or produces no output +if [ -z "$RAW_STATUS" ]; then + echo "Failed to get repo status from 'core dev health'." + echo "Make sure the 'core' command is available and repositories are correctly configured." + exit 1 +fi + +FILTER="$1" + +# --- Header --- +echo "Host UK Monorepo Status" +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +printf "%-15s %-15s %-10s %s\n" "Module" "Branch" "Status" "Behind/Ahead" +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + +# --- Data Processing and Printing --- +while read -r module branch status ahead behind insertions deletions; do + is_dirty=false + is_behind=false + + if [[ "$status" == "dirty" ]]; then + is_dirty=true + fi + + if (( behind > 0 )); then + is_behind=true + fi + + # Apply filters + if [[ "$FILTER" == "--dirty" && "$is_dirty" == "false" ]]; then + continue + fi + if [[ "$FILTER" == "--behind" && "$is_behind" == "false" ]]; then + continue + fi + + # Format the "Behind/Ahead" column based on status + if [[ "$status" == "dirty" ]]; then + behind_ahead_text="+${insertions} -${deletions}" + else # status is 'clean' + if (( behind > 0 )); then + behind_ahead_text="-${behind} (behind)" + elif (( ahead > 0 )); then + behind_ahead_text="+${ahead}" + else + behind_ahead_text="✓" + fi + fi + + printf "%-15s %-15s %-10s %s\n" "$module" "$branch" "$status" "$behind_ahead_text" + +done <<< "$RAW_STATUS" + +# --- Summary --- +# The summary is always based on the full, unfiltered data. +dirty_count=$(echo "$RAW_STATUS" | grep -cw "dirty") +behind_count=$(echo "$RAW_STATUS" | awk '($5+0) > 0' | wc -l) +clean_count=$(echo "$RAW_STATUS" | grep -cw "clean") + +summary_parts=() +if (( dirty_count > 0 )); then + summary_parts+=("$dirty_count dirty") +fi +if (( behind_count > 0 )); then + summary_parts+=("$behind_count behind") +fi +summary_parts+=("$clean_count clean") + +summary="Summary: $(IFS=, ; echo "${summary_parts[*]}")" + +echo +echo "$summary"