Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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/`.
Expand Down
47 changes: 47 additions & 0 deletions scripts/health.sh
Original file line number Diff line number Diff line change
@@ -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 <run-dir>`).

health() {
local sub="${1:-sync}"
# Consume the subcommand token only if one was actually given, so bare
# `health` (defaults to sync) and `health <sub> <args…>` 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
}
18 changes: 9 additions & 9 deletions scripts/pyauto_audit.sh → scripts/health_audit.sh
Original file line number Diff line number Diff line change
@@ -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).
Expand All @@ -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)
Expand All @@ -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

Expand Down Expand Up @@ -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
}
50 changes: 26 additions & 24 deletions scripts/pyauto_status_full.sh → scripts/health_release.sh
Original file line number Diff line number Diff line change
@@ -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:
#
Expand All @@ -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 <<EOF
pyauto-status-full: no run found at $run_dir
health release: no run found at $run_dir

To produce one, from PyAutoBuild root:
source ../activate.sh
Expand All @@ -47,7 +49,7 @@ EOF

local report_json="$run_dir/report.json"
if [[ ! -f "$report_json" ]]; then
echo "pyauto-status-full: $report_json missing — run incomplete?" >&2
echo "health release: $report_json missing — run incomplete?" >&2
return 1
fi

Expand Down Expand Up @@ -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
}

Expand All @@ -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
Expand All @@ -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"
Expand Down
31 changes: 16 additions & 15 deletions scripts/pyauto_status.sh → scripts/health_sync.sh
Original file line number Diff line number Diff line change
@@ -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.
#
Expand All @@ -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

Expand All @@ -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

Expand Down
4 changes: 2 additions & 2 deletions skills/OWNERSHIP.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 |
Expand Down