diff --git a/exact_dot_claude/CLAUDE.md b/exact_dot_claude/CLAUDE.md index 5d45486f..49187629 100644 --- a/exact_dot_claude/CLAUDE.md +++ b/exact_dot_claude/CLAUDE.md @@ -47,3 +47,4 @@ When installing new tools, prefer earlier options: ## Development Notes - If a justfile exists, prefer its recipes (check `just --help`) over calling tools directly (e.g. use `just test` instead of `bun run test`); run `just --list` to discover recipes +- Global recipes also exist at `~/.config/just/justfile`, invokable from **any** directory via `just -g ` (source: `private_dot_config/just/*.just` in the dotfiles repo). Run `just -g --list` to discover them before re-deriving mechanical work — they cover branch cleanup (`branch-audit`), blocked-PR triage (`pr-todo`), Claude plugin management (`plugins-*`), MCP/Claude setup (`claude-setup`, `mcp-*`), and settings hygiene (`settings-audit`). Prefer an existing recipe over hand-rolling the equivalent (per the `offload-to-deterministic-substrate` rule). diff --git a/private_dot_config/just/git.just b/private_dot_config/just/git.just index 7cfde71a..c229a2fb 100644 --- a/private_dot_config/just/git.just +++ b/private_dot_config/just/git.just @@ -53,3 +53,40 @@ branch-audit: echo "# ${#merged[@]} branch(es) safe to delete:" echo "git branch -D ${merged[*]}" fi + +# List your own open PRs blocked on YOU — changes requested or CI failing. Read-only. +# +# Two independent GitHub searches, unioned by URL: +# 1. --review=changes_requested — a reviewer asked for changes. +# 2. --checks=failure — the PR's checks are failing. +# A PR matching both shows both reasons. Empty result prints a clean line +# and still exits 0 (safe in pipelines / autonomous sweeps). +[group: "git"] +pr-todo: + #!/usr/bin/env bash + set -euo pipefail + + changes=$(gh search prs --author=@me --state=open --review=changes_requested \ + --json repository,number,title,url \ + --jq '.[] | [.url, .repository.nameWithOwner, "#"+(.number|tostring), "changes-requested", .title] | @tsv' 2>/dev/null || true) + failing=$(gh search prs --author=@me --state=open --checks=failure \ + --json repository,number,title,url \ + --jq '.[] | [.url, .repository.nameWithOwner, "#"+(.number|tostring), "ci-failing", .title] | @tsv' 2>/dev/null || true) + + # Union by URL; a PR in both searches gets both reasons joined with "+". + rows=$(printf '%s\n%s\n' "$changes" "$failing" | grep -v '^$' | awk -F'\t' ' + { url=$1; repo[$1]=$2; num[$1]=$3; title[$1]=$5; + reason[$1] = ($1 in reason) ? reason[$1]"+"$4 : $4 } + END { for (u in repo) printf "%s\t%s\t%s\t%s\t%s\n", repo[u], num[u], reason[u], title[u], u } + ' | sort) + + if [ -z "$rows" ]; then + echo "Nothing blocked on you — no open PRs with changes requested or failing CI." + exit 0 + fi + + printf '%-40s %-7s %-24s %s\n' REPO PR REASON TITLE + printf '%.0s-' {1..100}; echo + printf '%s\n' "$rows" | while IFS=$'\t' read -r repo num reason title url; do + printf '%-40s %-7s %-24s %s\n' "$repo" "$num" "$reason" "$title" + done