diff --git a/README.md b/README.md index e64b0c11..1b0fe477 100644 --- a/README.md +++ b/README.md @@ -235,11 +235,11 @@ PyAutoMind/ `OWNERSHIP.md`). The development-workflow skills were re-homed to the organs that own them — **PyAutoBrain** (`start_dev`, `start_dev_for_user`, `plan_branches`, `start_library`, `start_workspace`, `ship_library`, `ship_workspace`, -`register_and_iterate`, `health` [the single health door, with `check` sweep + -`status` dashboard legs]), **PyAutoHeart** (`pyauto-status-full`, -`worktree_status`, and the health-leg procedures `health_sweep/` + -`pyauto-status/` that `/health` drives), and **autolens_profiling** -(`profile_likelihood`). The +`register_and_iterate`, `health` [the single health door, with `check` sweep, +`status` dashboard, and `full` release-run legs]), **PyAutoHeart** +(`worktree_status`, and the health-leg procedures `health_sweep/`, +`pyauto-status/`, and `pyauto-status-full/` that `/health` drives), and +**autolens_profiling** (`profile_likelihood`). The `handoff` skill was retired (PyAutoBrain runs uniformly across execution environments — see `OWNERSHIP.md`). General PyAuto tooling (release prep, dependency audits, smoke tests, lint sweeps) lives in `admin_jammy/skills/`. diff --git a/scripts/health.sh b/scripts/health.sh new file mode 100644 index 00000000..d25fbed3 --- /dev/null +++ b/scripts/health.sh @@ -0,0 +1,47 @@ +#!/usr/bin/env bash +# health.sh — the `health` shell dispatcher. +# +# Front door for the local health/dev shell tools, mirroring the Claude `/health` +# command door. Routes to the implementations defined in the sibling scripts +# (source all four via ~/.bashrc): +# +# health cross-repo git-sync dashboard (health_sync.sh -> _health_sync) +# health sync explicit alias of the above +# health release last release-prep run dashboard (health_release.sh -> _health_release) +# health audit structural repo-health audit (health_audit.sh -> _health_audit) +# health help this usage +# +# Distinct from the `pyauto-heart` binary (the Heart organ CLI) — this is the +# local shell convenience layer. Any argument after the subcommand is passed +# through (e.g. `health release `). + +health() { + local sub="${1:-sync}" + # Consume the subcommand token only if one was actually given, so bare + # `health` (defaults to sync) and `health ` both pass the + # remaining "$@" straight through to the implementation. + [ "$#" -gt 0 ] && shift + case "$sub" in + sync) _health_sync "$@" ;; + release) _health_release "$@" ;; + audit) _health_audit "$@" ;; + -h|--help|help) + cat <<'EOF' +health — local health/dev shell dispatcher (mirrors the Claude /health door). + +Usage: health [sync|release|audit] + + health cross-repo git-sync dashboard (branch, behind/ahead, dirty) + health sync same as bare `health` + health release last PyAutoBuild release-prep run dashboard + health audit structural repo-health audit (non-repo dirs, stashes, dead branches) + +Release-run helpers: health-report / health-json / health-triage. +EOF + ;; + *) + echo "health: unknown subcommand '$sub' (try: health help)" >&2 + return 2 + ;; + esac +} diff --git a/scripts/pyauto_audit.sh b/scripts/health_audit.sh similarity index 88% rename from scripts/pyauto_audit.sh rename to scripts/health_audit.sh index 08e5551b..4215f83d 100644 --- a/scripts/pyauto_audit.sh +++ b/scripts/health_audit.sh @@ -1,8 +1,8 @@ #!/usr/bin/env bash -# pyauto_audit.sh — on-demand structural repo-health audit. +# health_audit.sh — on-demand structural repo-health audit. # -# Defines a shell function `pyauto-audit` that scans ~/Code/PyAutoLabs/ for -# state the dashboard (`pyauto-status`) doesn't surface: +# Defines `_health_audit` (run via `health audit`) that scans ~/Code/PyAutoLabs/ +# for state the git-sync dashboard (`health` / `health sync`) doesn't surface: # # 1. Top-level directories with no .git (intentionally-not-a-repo or bug). # Skip prefixes "." (hidden) and "z_" (user's personal/staging convention). @@ -13,9 +13,9 @@ # # Run on demand. Always exits 0 — informational, the user reads + decides. # -# Usage: -# source ~/Code/PyAutoLabs/PyAutoMind/scripts/pyauto_audit.sh -# pyauto-audit +# Usage (normally sourced via ~/.bashrc, run through the `health` dispatcher): +# source ~/Code/PyAutoLabs/PyAutoMind/scripts/health_audit.sh +# health audit # # Override via env vars: # PYAUTO_AUDIT_ROOT scan root (default $HOME/Code/PyAutoLabs) @@ -26,10 +26,10 @@ PYAUTO_AUDIT_ROOT="${PYAUTO_AUDIT_ROOT:-$HOME/Code/PyAutoLabs}" PYAUTO_AUDIT_STASH_DAYS="${PYAUTO_AUDIT_STASH_DAYS:-14}" PYAUTO_AUDIT_BRANCH_DAYS="${PYAUTO_AUDIT_BRANCH_DAYS:-30}" -pyauto-audit() { +_health_audit() { local root="$PYAUTO_AUDIT_ROOT" if [[ ! -d "$root" ]]; then - echo "pyauto-audit: $root does not exist" >&2 + echo "health audit: $root does not exist" >&2 return 1 fi @@ -108,6 +108,6 @@ pyauto-audit() { for line in "${branch_lines[@]}"; do echo " $line"; done printed=true fi - [[ "$printed" == "false" ]] && echo "pyauto-audit: clean (no findings under $root)" + [[ "$printed" == "false" ]] && echo "health audit: clean (no findings under $root)" return 0 } diff --git a/scripts/pyauto_status_full.sh b/scripts/health_release.sh similarity index 80% rename from scripts/pyauto_status_full.sh rename to scripts/health_release.sh index f919f3c2..34dc804a 100755 --- a/scripts/pyauto_status_full.sh +++ b/scripts/health_release.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash -# pyauto_status_full.sh — release-prep run dashboard. +# health_release.sh — release-prep run dashboard. # -# Defines a shell function `pyauto-status-full` that reads the latest +# Defines `_health_release` (run via `health release`) that reads the latest # PyAutoBuild full release-prep run (the one symlinked from # PyAutoBuild/test_results/latest/) and prints a dashboard: # @@ -13,27 +13,29 @@ # - Slow-skip / needs-fix banner counts # - Pointer to triage.md if present (free-form analytical clustering) # -# Usage: -# source ~/Code/PyAutoLabs/PyAutoMind/scripts/pyauto_status_full.sh -# pyauto-status-full +# Usage (normally sourced via ~/.bashrc, run through the `health` dispatcher): +# source ~/Code/PyAutoLabs/PyAutoMind/scripts/health_release.sh +# health release # -# Override the run path (e.g. to inspect a specific historical run) -# by passing it as the first argument: -# pyauto-status-full ~/Code/PyAutoLabs/PyAutoBuild/test_results/runs/2026-04-29T14-48-47Z +# Override the run path (e.g. to inspect a specific historical run) by passing +# it as the first argument: +# health release ~/Code/PyAutoLabs/PyAutoBuild/test_results/runs/2026-04-29T14-48-47Z # -# Note: this shell function shares its name with the /pyauto-status-full -# slash command (PyAutoHeart/skills/pyauto-status-full/) but lives in a -# different namespace. The slash command is the conversational layer; this -# function is the same data, printed straight to stdout, no Claude needed. +# Sibling helpers: health-report / health-json / health-triage open the last +# run's report.md / report.json / triage.md. +# +# Note: distinct from the Claude `/health full` command (the conversational +# layer over the same run artefacts). This function prints straight to stdout, +# no Claude needed. PYAUTO_STATUS_FULL_DEFAULT="${PYAUTO_STATUS_FULL_DEFAULT:-$HOME/Code/PyAutoLabs/PyAutoBuild/test_results/latest}" -pyauto-status-full() { +_health_release() { local run_dir="${1:-$PYAUTO_STATUS_FULL_DEFAULT}" if [[ ! -e "$run_dir" ]]; then cat >&2 <&2 + echo "health release: $report_json missing — run incomplete?" >&2 return 1 fi @@ -158,11 +160,11 @@ if slow_skips or nf_skips: # Pointers print("Pointers") print("-" * 76) -print(f" Markdown report: {run_dir}/report.md {DIM}(pyauto-report){RST}") -print(f" Run JSON: {run_dir}/report.json {DIM}(pyauto-json){RST}") +print(f" Markdown report: {run_dir}/report.md {DIM}(health-report){RST}") +print(f" Run JSON: {run_dir}/report.json {DIM}(health-json){RST}") triage = run_dir / "triage.md" if triage.exists(): - print(f" {GREEN}Triage notes: {triage}{RST} {DIM}(pyauto-triage){RST}") + print(f" {GREEN}Triage notes: {triage}{RST} {DIM}(health-triage){RST}") PY } @@ -186,16 +188,16 @@ _pyauto_run_file() { printf '%s' "$target" } -# pyauto-report [run-dir] — view report.md in the pager. -pyauto-report() { +# health-report [run-dir] — view report.md in the pager. +health-report() { local f f="$(_pyauto_run_file report.md "$1")" || return 1 "${PAGER:-less}" "$f" } -# pyauto-json [run-dir] — view report.json. Uses jq for color + paging when +# health-json [run-dir] — view report.json. Uses jq for color + paging when # available, falls back to plain cat otherwise. -pyauto-json() { +health-json() { local f f="$(_pyauto_run_file report.json "$1")" || return 1 if command -v jq >/dev/null 2>&1; then @@ -205,8 +207,8 @@ pyauto-json() { fi } -# pyauto-triage [run-dir] — view triage.md in the pager. -pyauto-triage() { +# health-triage [run-dir] — view triage.md in the pager. +health-triage() { local f f="$(_pyauto_run_file triage.md "$1")" || return 1 "${PAGER:-less}" "$f" diff --git a/scripts/pyauto_status.sh b/scripts/health_sync.sh similarity index 92% rename from scripts/pyauto_status.sh rename to scripts/health_sync.sh index cd371976..51a5cfd1 100644 --- a/scripts/pyauto_status.sh +++ b/scripts/health_sync.sh @@ -1,14 +1,15 @@ #!/usr/bin/env bash -# pyauto_status.sh — cross-repo sync status dashboard. +# health_sync.sh — cross-repo git-sync dashboard. # -# Defines a shell function `pyauto-status` that prints, for every git repo -# under ~/Code/PyAutoLabs/, the branch, upstream tracking ref, behind/ahead -# counts vs @{u}, dirty file count, and a flag column. Designed to run in -# under 10 seconds — fetches are parallelised one background job per repo. +# Defines `_health_sync` (run via the `health` dispatcher: bare `health` or +# `health sync`) that prints, for every git repo under ~/Code/PyAutoLabs/, the +# branch, upstream tracking ref, behind/ahead counts vs @{u}, dirty file count, +# and a flag column. Designed to run in under 10 seconds — fetches are +# parallelised one background job per repo. # -# Usage: -# source ~/Code/PyAutoLabs/PyAutoMind/scripts/pyauto_status.sh -# pyauto-status +# Usage (normally sourced via ~/.bashrc, run through the `health` dispatcher): +# source ~/Code/PyAutoLabs/PyAutoMind/scripts/health_sync.sh +# health # (or: health sync) # # Override the repo root (e.g. for testing) via PYAUTO_STATUS_ROOT. # @@ -34,17 +35,17 @@ # (committed by the autobuild release pipeline). # Suppressed when no JSONs exist. # -# Note: this shell function shares its name with the /pyauto-status slash -# command (PyAutoHeart/skills/pyauto-status/) but lives in a different -# namespace. The slash command shows workflow registry status (planned / -# active / complete tasks); this function shows git sync state. +# Note: distinct from the Claude `/health status` command (the active-work +# registry dashboard). This shell command shows git *sync* state across repos; +# `/health status` shows planned / active / complete tasks. Different views, +# both under the "health" vocabulary. PYAUTO_STATUS_ROOT="${PYAUTO_STATUS_ROOT:-$HOME/Code/PyAutoLabs}" -pyauto-status() { +_health_sync() { local root="$PYAUTO_STATUS_ROOT" if [[ ! -d "$root" ]]; then - echo "pyauto-status: $root does not exist" >&2 + echo "health sync: $root does not exist" >&2 return 1 fi @@ -61,7 +62,7 @@ pyauto-status() { ) if [[ ${#repos[@]} -eq 0 ]]; then - echo "pyauto-status: no git repos found under $root" + echo "health sync: no git repos found under $root" return 0 fi diff --git a/skills/OWNERSHIP.md b/skills/OWNERSHIP.md index 687a618a..4dd5b1e5 100644 --- a/skills/OWNERSHIP.md +++ b/skills/OWNERSHIP.md @@ -31,8 +31,8 @@ in `skill_redesign.md`: | `ship_workspace` | `PyAutoBrain/skills/` | **PyAutoBrain** dev-workflow → Heart gate (Build only at release) | **moved → Brain** | | `register_and_iterate` | `PyAutoBrain/skills/` | **PyAutoBrain** (dev-workflow orchestration loop) | **moved → Brain** | | `repo_cleanup` | `PyAutoBrain/skills/` | **PyAutoBrain** (between-tasks git hygiene; Heart observes, Brain decides + executes — natural home is a future Cleanup Agent) | **moved → Brain** (from admin_jammy) | -| `pyauto-status` | `PyAutoHeart/skills/` | **PyAutoHeart** (status/readiness view) | **moved → Heart** | -| `pyauto-status-full` | `PyAutoHeart/skills/` | **PyAutoHeart** (release-readiness dashboard) | **moved → Heart** | +| `pyauto-status` | `PyAutoHeart/skills/` | **PyAutoHeart** (active-work dashboard) | **retired as command → `/health status` leg (`pyauto-status/reference.md`)** | +| `pyauto-status-full` | `PyAutoHeart/skills/` | **PyAutoHeart** (release-run dashboard) | **retired as command → `/health full` leg (`pyauto-status-full/reference.md`)** | | `worktree_status` | `PyAutoHeart/skills/` | **PyAutoHeart** (diagnostic) | **moved → Heart** | | `profile_likelihood` | `autolens_profiling/skills/` | **`autolens_profiling`** (science profiling) | **moved → autolens_profiling** | | `handoff` | — (removed) | — | **deleted** — the phone↔laptop park/resume dance is obsolete now PyAutoBrain runs uniformly across execution environments; `active.md` is the shared task state, so any environment resumes a task directly |