BraiinsRatchet/scripts/ratchet

230 lines
6.3 KiB
Bash
Executable file

#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
PYTHON_BIN="$ROOT_DIR/.venv/bin/python"
usage() {
cat <<'USAGE'
Braiins Ratchet
Commands:
next Show exactly what to do next. Default command.
setup Create the local .venv and initialize the local database.
once Fetch one fresh sample, then print the cockpit.
watch [hours] Run repeated monitor cycles for N hours. Default: 6.
supervise Run the durable forever lifecycle supervisor.
engine Start/stop/status for the background monitor engine.
app Build and open the native macOS app.
mirror Print the app's latest self-written visual-state snapshot.
position Record/list/close manually executed Braiins exposure.
report Print the latest stored report without fetching new data.
app-state Print structured JSON for the native macOS app.
experiments Print the Karpathy-style experiment ledger.
retro SINCE [UNTIL] Write a retroactive report from stored snapshots.
raw-cycle Run one full monitor cycle and print raw JSON.
test Run the network-free test suite.
guide Print the noob-friendly user guide.
operator-guide Print the installation, migration, and recovery guide.
explain Alias for guide.
Examples:
./scripts/ratchet
./scripts/ratchet next
./scripts/ratchet setup
./scripts/ratchet once
./scripts/ratchet watch 6
./scripts/ratchet supervise
./scripts/ratchet engine status
./scripts/ratchet app
./scripts/ratchet mirror
./scripts/ratchet position list
./scripts/ratchet report
./scripts/ratchet experiments
./scripts/ratchet guide
./scripts/ratchet operator-guide
./scripts/ratchet retro 2026-04-25T19:08:00+00:00 2026-04-25T21:05:00+00:00
USAGE
}
ensure_venv() {
if [[ ! -x "$PYTHON_BIN" ]]; then
echo "Creating local virtual environment at .venv ..." >&2
python3 -m venv "$ROOT_DIR/.venv"
fi
}
run_python() {
ensure_venv
PYTHONPATH="$ROOT_DIR/src" "$PYTHON_BIN" "$@"
}
cmd_setup() {
ensure_venv
run_python -m braiins_ratchet.cli init-db
echo
echo "Setup complete. Next: ./scripts/ratchet next"
}
cmd_next() {
run_python -m braiins_ratchet.cli next
}
cmd_once() {
run_python -m braiins_ratchet.cli cycle >/dev/null
echo
echo "Fresh sample collected. Reading the cockpit now."
echo "Technical report is available with: ./scripts/ratchet report"
echo
run_python -m braiins_ratchet.cli next
}
cmd_raw_cycle() {
run_python -m braiins_ratchet.cli cycle
}
cmd_watch() {
local hours="${1:-6}"
local interval_seconds=300
local cycles
if ! [[ "$hours" =~ ^[0-9]+$ ]] || [[ "$hours" -lt 1 ]]; then
echo "watch expects whole hours, e.g. ./scripts/ratchet watch 6" >&2
exit 2
fi
cycles=$((hours * 3600 / interval_seconds))
echo "Watch started. This terminal is now controlled by Braiins Ratchet for about $hours hour(s)."
echo "You do not need to babysit it. Leave this terminal open and come back later."
echo "It will run $cycles cycles, one cycle every $interval_seconds seconds."
echo "It only reads public/OCEAN data and writes local snapshots inside this repo."
echo "At the end it writes reports/EXPERIMENT_LOG.md plus a run report, then prints DO THIS NOW."
echo "Stop early only if you intentionally want a partial run: Ctrl-C."
echo
set +e
run_python -m braiins_ratchet.cli watch --cycles "$cycles" --interval-seconds "$interval_seconds"
local status=$?
set -e
if [[ "$status" -ne 0 && "$status" -ne 130 ]]; then
exit "$status"
fi
echo
echo "Watch finished. Reading the cockpit now."
echo
BRAIINS_RATCHET_IGNORE_PROCESS_WATCH=1 run_python -m braiins_ratchet.cli next
return "$status"
}
cmd_report() {
run_python -m braiins_ratchet.cli report
}
cmd_app_state() {
run_python -m braiins_ratchet.cli app-state
}
cmd_pipeline() {
run_python -m braiins_ratchet.cli pipeline "$@"
}
cmd_supervise() {
run_python -m braiins_ratchet.cli supervise "$@"
}
cmd_engine() {
run_python -m braiins_ratchet.cli engine "$@"
}
cmd_app() {
local app_path
app_path="$("$ROOT_DIR/scripts/build_mac_app" | tail -n 1)"
echo "Opening $app_path"
pkill -x BraiinsRatchetMac 2>/dev/null || true
open "$app_path"
}
cmd_mirror() {
local path="$ROOT_DIR/data/app_visual_state.md"
if [[ ! -f "$path" ]]; then
echo "No app visual-state snapshot exists yet."
echo "Open the native app with: ./scripts/ratchet app"
echo "Then refresh or open the Reality Mirror tab."
return 0
fi
cat "$path"
}
cmd_position() {
run_python -m braiins_ratchet.cli position "$@"
}
cmd_experiments() {
run_python -m braiins_ratchet.cli experiments
}
cmd_retro() {
local since="${1:-}"
local until="${2:-}"
local run_id
if [[ -z "$since" ]]; then
echo "retro expects an ISO timestamp, e.g. ./scripts/ratchet retro 2026-04-25T19:08:00+00:00" >&2
exit 2
fi
run_id="retro-${since//[:+]/-}"
if [[ -n "$until" ]]; then
run_python -m braiins_ratchet.cli retro-report --since "$since" --until "$until" --run-id "$run_id" --write
else
run_python -m braiins_ratchet.cli retro-report --since "$since" --run-id "$run_id" --write
fi
}
cmd_test() {
run_python -m unittest discover -s "$ROOT_DIR/tests"
}
cmd_explain() {
cat "$ROOT_DIR/docs/USER_GUIDE.md"
}
cmd_operator_guide() {
cat "$ROOT_DIR/docs/OPERATOR_GUIDE.md"
}
main() {
cd "$ROOT_DIR"
local command="${1:-next}"
shift || true
case "$command" in
next) cmd_next "$@" ;;
setup) cmd_setup "$@" ;;
once) cmd_once "$@" ;;
watch) cmd_watch "$@" ;;
pipeline|auto) cmd_pipeline "$@" ;;
supervise|daemon) cmd_supervise "$@" ;;
engine) cmd_engine "$@" ;;
app|mac-app) cmd_app "$@" ;;
mirror|reality) cmd_mirror "$@" ;;
position|positions) cmd_position "$@" ;;
report) cmd_report "$@" ;;
app-state) cmd_app_state "$@" ;;
experiments) cmd_experiments "$@" ;;
retro) cmd_retro "$@" ;;
raw-cycle) cmd_raw_cycle "$@" ;;
test) cmd_test "$@" ;;
guide|user-guide|explain) cmd_explain "$@" ;;
operator-guide|operator) cmd_operator_guide "$@" ;;
help|-h|--help) usage ;;
*)
echo "Unknown command: $command" >&2
echo >&2
usage >&2
exit 2
;;
esac
}
main "$@"