diff --git a/scripts/codex-fleet/cap-probe.sh b/scripts/codex-fleet/cap-probe.sh index 0e0b5e3..dd1e9f8 100755 --- a/scripts/codex-fleet/cap-probe.sh +++ b/scripts/codex-fleet/cap-probe.sh @@ -17,6 +17,32 @@ # Usage: bash cap-probe.sh email1 email2 ... set -eo pipefail +# --help / --version plumbing (see lib/version.sh). +FLEET_USAGE="cap-probe.sh — verify candidate codex accounts are usable. + +Usage: + bash cap-probe.sh email1 email2 ... + bash cap-probe.sh --help | --version + +Args: + need_n minimum number of healthy accounts required (exit 3 otherwise) + email1 email2 ... candidate accounts to probe (cached per email) + +Env: + CACHE_DIR cache root (default /tmp/claude-viz/cap-probe-cache) + CACHE_TTL_HEALTHY healthy verdict TTL seconds (default 60) + CODEX_FLEET_CAP_CACHE_TTL alias for healthy TTL (operator pin) + CACHE_TTL_UNKNOWN unknown verdict TTL seconds (default 60) + BRINGUP_FAILURE_MARKER presence forces cold re-probe + PROBE_TIMEOUT per-account codex exec timeout (default 60s) + LOG log path (default /tmp/claude-viz/cap-probe.log) + +Flags: + -h, --help print this help and exit 0 + --version print ' ' and exit 0" +source "$(dirname "${BASH_SOURCE[0]}")/lib/version.sh" +handle_help_version_flags "$@" + NEED="${1:-1}"; shift CACHE_DIR="${CACHE_DIR:-/tmp/claude-viz/cap-probe-cache}" diff --git a/scripts/codex-fleet/force-claim.sh b/scripts/codex-fleet/force-claim.sh index 37ea2c4..9cab65b 100755 --- a/scripts/codex-fleet/force-claim.sh +++ b/scripts/codex-fleet/force-claim.sh @@ -52,6 +52,44 @@ # CODEX_FLEET_CLAIM_MODE=both|event|poll # default: both set -eo pipefail +# --help / --version plumbing (see lib/version.sh). Handled before sourcing +# _tmux.sh / claim-fence.sh so docs work even when those libs misbehave. +FLEET_USAGE="force-claim.sh — dispatch ready plan sub-tasks across all +non-empty openspec plans onto idle codex panes. + +Usage: + bash scripts/codex-fleet/force-claim.sh # one-shot + bash scripts/codex-fleet/force-claim.sh --dry-run # show plan, no dispatch + bash scripts/codex-fleet/force-claim.sh --loop # event + poll every 15s + bash scripts/codex-fleet/force-claim.sh --loop --quit-when-empty + bash scripts/codex-fleet/force-claim.sh --loop --empty-threshold=5 + bash scripts/codex-fleet/force-claim.sh --no-token-check + bash scripts/codex-fleet/force-claim.sh --help | --version + +Env: + FORCE_CLAIM_REPO / CODEX_FLEET_REPO_ROOT repo root (default: derived) + FORCE_CLAIM_SESSION tmux session (default: codex-fleet) + FORCE_CLAIM_WINDOW tmux window (default: overview) + FORCE_CLAIM_PLAN_JSON pin to a single plan + FORCE_CLAIM_INTERVAL loop poll seconds (default: 15) + FORCE_CLAIM_EMPTY_THRESHOLD consecutive empties to quit (default: 3) + CODEX_FLEET_CLAIM_MODE both | event | poll (default: both) + FORCE_CLAIM_TOKEN_METER path to token-meter.sh + FORCE_CLAIM_TOKEN_MIN_5H / _MIN_WK cap thresholds for skipping panes + FORCE_CLAIM_SKIP_READY_CHECK=1 bypass worker-ready gate + +Flags: + --dry-run show plan; do not dispatch + --loop event + poll backstop + --interval=N poll interval (seconds) + --quit-when-empty exit 0 after empty-streak + --empty-threshold=N consecutive empty passes required + --no-token-check bypass token-meter cap filter + -h, --help print this help and exit 0 + --version print ' ' and exit 0" +source "$(dirname "${BASH_SOURCE[0]}")/lib/version.sh" +handle_help_version_flags "$@" + # Route every `tmux ...` call through scripts/codex-fleet/lib/_tmux.sh — when # CODEX_FLEET_TMUX_SOCKET is set in the env (e.g. by full-bringup.sh), this # transparently rewrites the call to `tmux -L $SOCKET ...`. Default behavior diff --git a/scripts/codex-fleet/lib/version.sh b/scripts/codex-fleet/lib/version.sh new file mode 100755 index 0000000..51e87d1 --- /dev/null +++ b/scripts/codex-fleet/lib/version.sh @@ -0,0 +1,54 @@ +#!/usr/bin/env bash +# version.sh — shared --help / --version plumbing for codex-fleet scripts. +# +# Source via: +# source "$(dirname "${BASH_SOURCE[0]}")/lib/version.sh" +# +# Exports: +# FLEET_VERSION version string (env override > nearest git tag > "0.0.0-dev") +# print_usage_and_exit USAGE print USAGE to stdout and exit 0 +# handle_help_version_flags scan "$@" for --help/-h/--version; if found, +# print the appropriate banner and exit 0 +# +# Conventions: +# - Scripts pre-set FLEET_USAGE (a heredoc string) before sourcing or before +# calling handle_help_version_flags. +# - $0's basename is used in the --version banner. + +# Resolve FLEET_VERSION once per process. Env wins so CI can pin without git. +if [ -z "${FLEET_VERSION:-}" ]; then + _fleet_version_git="" + if command -v git >/dev/null 2>&1; then + _fleet_version_git=$(git -C "$(dirname "${BASH_SOURCE[0]}")" describe --tags --abbrev=0 2>/dev/null || true) + fi + if [ -n "$_fleet_version_git" ]; then + FLEET_VERSION="$_fleet_version_git" + else + FLEET_VERSION="0.0.0-dev" + fi + unset _fleet_version_git +fi +export FLEET_VERSION + +print_usage_and_exit() { + printf '%s\n' "$1" + exit 0 +} + +# Scan args for --help/-h or --version and act on the first match. +# Callers MUST set FLEET_USAGE before invoking. Returns silently if no match +# so the host script keeps processing its real flags. +handle_help_version_flags() { + local arg + for arg in "$@"; do + case "$arg" in + -h|--help) + print_usage_and_exit "${FLEET_USAGE:-no usage text provided}" + ;; + --version) + printf '%s %s\n' "$(basename "$0")" "$FLEET_VERSION" + exit 0 + ;; + esac + done +} diff --git a/scripts/codex-fleet/score-checkpoint.sh b/scripts/codex-fleet/score-checkpoint.sh index 45b9d92..be30277 100755 --- a/scripts/codex-fleet/score-checkpoint.sh +++ b/scripts/codex-fleet/score-checkpoint.sh @@ -27,6 +27,26 @@ set -euo pipefail +# --help / --version plumbing (see lib/version.sh). +FLEET_USAGE="score-checkpoint.sh — score uncommitted diffs in active Guardex +agent worktrees against their plan's acceptance criteria. + +Usage: + ./scripts/codex-fleet/score-checkpoint.sh # scan all active worktrees + ./scripts/codex-fleet/score-checkpoint.sh # score a single worktree + ./scripts/codex-fleet/score-checkpoint.sh --help | --version + +Env: + ANTHROPIC_API_KEY required (consumed by lib/score-diff.py) + CODEX_FLEET_CHECKPOINT_PATH sink path (default /tmp/claude-viz/fleet-checkpoint-warnings.json) + CODEX_FLEET_REPO_ROOT repo root (default: git toplevel) + +Flags: + -h, --help print this help and exit 0 + --version print ' ' and exit 0" +source "$(dirname "${BASH_SOURCE[0]}")/lib/version.sh" +handle_help_version_flags "$@" + SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" SCORER="$SCRIPT_DIR/lib/score-diff.py" REPO_ROOT="${CODEX_FLEET_REPO_ROOT:-$(git rev-parse --show-toplevel)}" diff --git a/tests/scripts/test-script-help.sh b/tests/scripts/test-script-help.sh new file mode 100755 index 0000000..089ae95 --- /dev/null +++ b/tests/scripts/test-script-help.sh @@ -0,0 +1,83 @@ +#!/usr/bin/env bash +# test-script-help.sh — smoke test for the --help / --version flags added to +# cap-probe.sh, score-checkpoint.sh, and force-claim.sh. +# +# Asserts, for each script: +# * --help exits 0 with non-empty stdout that mentions the script name +# * --version exits 0, mentions the script name, and emits something that +# looks like a version token +# +# Run from the repo root: `bash tests/scripts/test-script-help.sh` +# Exits 0 on success, non-zero on the first failure. + +set -uo pipefail + +REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" +SCRIPTS_DIR="$REPO_ROOT/scripts/codex-fleet" + +SCRIPTS=( + cap-probe.sh + score-checkpoint.sh + force-claim.sh +) + +fail=0 +pass=0 + +check() { + local script="$1" flag="$2" want_token="$3" + local out rc + out=$(bash "$SCRIPTS_DIR/$script" "$flag" 2>&1) + rc=$? + if [ "$rc" -ne 0 ]; then + printf 'FAIL: %s %s exited %d\n' "$script" "$flag" "$rc" >&2 + printf ' stdout/stderr:\n%s\n' "$out" >&2 + fail=$((fail + 1)) + return 1 + fi + if [ -z "$out" ]; then + printf 'FAIL: %s %s produced empty stdout\n' "$script" "$flag" >&2 + fail=$((fail + 1)) + return 1 + fi + if ! printf '%s' "$out" | grep -qF "$want_token"; then + printf 'FAIL: %s %s output missing token %q\n' "$script" "$flag" "$want_token" >&2 + printf ' output:\n%s\n' "$out" >&2 + fail=$((fail + 1)) + return 1 + fi + pass=$((pass + 1)) + return 0 +} + +for s in "${SCRIPTS[@]}"; do + # --help: must mention the script name somewhere in usage. + check "$s" "--help" "$s" + # --version: must mention the script name. Additionally assert a digit + # appears (covers both "0.0.0-dev" and any future "vX.Y.Z" tag). + out=$(bash "$SCRIPTS_DIR/$s" --version 2>&1) + rc=$? + if [ "$rc" -ne 0 ]; then + printf 'FAIL: %s --version exited %d\n' "$s" "$rc" >&2 + printf ' output:\n%s\n' "$out" >&2 + fail=$((fail + 1)) + continue + fi + if ! printf '%s' "$out" | grep -qF "$s"; then + printf 'FAIL: %s --version missing script name; got: %s\n' "$s" "$out" >&2 + fail=$((fail + 1)) + continue + fi + if ! printf '%s' "$out" | grep -qE '[0-9]'; then + printf 'FAIL: %s --version missing version token; got: %s\n' "$s" "$out" >&2 + fail=$((fail + 1)) + continue + fi + pass=$((pass + 1)) +done + +printf 'test-script-help: %d passed, %d failed\n' "$pass" "$fail" +if [ "$fail" -ne 0 ]; then + exit 1 +fi +exit 0