Files
boshu2__agentops/scripts/install.sh
T
Bo b9d64d1719 feat(install): install.sh per-runtime detection + informative degrade (soc-vuu6.31 #install-single-runtime) (#380)
## Why

`install.sh` line 100 used `command -v claude || command -v codex` —
failing only when ZERO runtimes are present. Single-runtime users got
the warning skipped, then ran straight at the README mixed-model example
and hit failures. Council non-negotiable #3 + GOALS.md North Star line
13 ("install to first validated flow in under 5 minutes") both name
this. Codex auth model-mismatch (gpt-5.2-codex unsupported by ChatGPT
account) hit it for real earlier this session.

## What

Replace the single-line OR-detect with per-runtime detection:

```text
Detected Claude Code: yes/no. Detected Codex CLI: yes/no.
AgentOps will use [mixed-model | single-runtime] mode.
To unlock mixed-model judging, install [other]: [link]
```

Four cases handled:
- both present → mixed-model mode
- Claude only → single-runtime mode + Codex install link
- Codex only → single-runtime mode + Claude install link
- neither → existing warning preserved + both links

Total diff: 20 lines added, 5 changed in `scripts/install.sh`.

## Test

5 bats tests, all passing. Cover each runtime combination by stubbing
`claude` / `codex` / `curl` on PATH; assert detection lines + mode line
+ correct install link. Stub `curl` exits 1 so script bails at the
network step after the detection block runs, capturing the output we
want without touching the network.

Self-dogfood: re-run install.sh from this worktree → "Detected Claude
Code: yes. Detected Codex CLI: yes. AgentOps will use mixed-model mode."

## Acceptance

Per bead BDD: "Given a user with Claude Code installed but not Codex
CLI, When install.sh runs, Then output reads runtime-by-runtime
detection + mode + install-the-other one-liner. Install completes
without bouncing." ✓ (covered by test 2).

Closes-scenario: soc-vuu6.31#install-single-runtime
Bounded-context: BC5-Runtime
Evidence: scripts/install.sh
Evidence: tests/scripts/install-sh-runtime-detection.bats

Co-authored-by: Codex <codex@example.invalid>
2026-05-20 22:55:21 +00:00

188 lines
6.3 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
# AgentOps Installer
# Usage: bash <(curl -fsSL https://raw.githubusercontent.com/boshu2/agentops/main/scripts/install.sh)
# bash scripts/install.sh --dev
usage() {
cat <<'EOF'
Usage:
bash scripts/install.sh
bash scripts/install.sh --dev
bash scripts/install.sh --with-hooks
Options:
--dev Configure this checkout for AgentOps development: install repo
hooks, build cli/bin/ao, and smoke-test pre-push wiring.
--with-hooks
Also install runtime hooks. Default install is hookless.
-h, --help Show this help.
EOF
}
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
WITH_HOOKS="${AGENTOPS_INSTALL_HOOKS:-0}"
install_dev() {
local repo_root
repo_root="$(cd "$SCRIPT_DIR/.." && pwd)"
if [[ ! -f "$repo_root/scripts/install-dev-hooks.sh" || ! -d "$repo_root/cli" ]]; then
echo "Error: --dev must be run from an AgentOps source checkout." >&2
exit 1
fi
echo "Installing AgentOps development wiring..."
echo "Step 1/2: Configuring repo-managed git hooks..."
bash "$repo_root/scripts/install-dev-hooks.sh"
echo "Step 2/2: Building cli/bin/ao..."
make -C "$repo_root/cli" build
# Pre-push gate-wiring verification retired (soc-bbvw / soc-g2r9):
# local pre-push gate retired; CI is sole authoritative push gate.
# See docs/contracts/local-pre-push-gate-retirement.md.
echo ""
echo "Done! Development checkout ready."
}
while [[ $# -gt 0 ]]; do
case "$1" in
--dev)
shift
if [[ $# -gt 0 ]]; then
echo "Unknown option for --dev: $1" >&2
usage >&2
exit 2
fi
install_dev
exit 0
;;
--with-hooks)
WITH_HOOKS=1
shift
;;
--no-hooks)
WITH_HOOKS=0
shift
;;
-h|--help)
usage
exit 0
;;
*)
echo "Unknown option: $1" >&2
usage >&2
exit 2
;;
esac
done
WITH_HOOKS_NORMALIZED="$(printf '%s' "$WITH_HOOKS" | tr '[:upper:]' '[:lower:]')"
case "$WITH_HOOKS_NORMALIZED" in
1|true|yes|on)
WITH_HOOKS=1
;;
0|false|no|off|"")
WITH_HOOKS=0
;;
*)
echo "Invalid AGENTOPS_INSTALL_HOOKS/--with-hooks value: $WITH_HOOKS" >&2
exit 2
;;
esac
echo "Installing AgentOps..."
# Check prerequisites
command -v curl >/dev/null 2>&1 || { echo "Error: curl required."; exit 1; }
# Per-runtime detection (soc-vuu6.31). The old `claude || codex` test bounced
# only on zero runtimes — single-runtime users got the README mixed-model
# example silently. Detect each runtime explicitly so we can: (a) report
# yes/no per runtime, (b) name the mode AgentOps will operate in, and
# (c) point single-runtime users at the install link for the other.
HAS_CLAUDE=no
HAS_CODEX=no
command -v claude >/dev/null 2>&1 && HAS_CLAUDE=yes
command -v codex >/dev/null 2>&1 && HAS_CODEX=yes
echo "Detected Claude Code: $HAS_CLAUDE. Detected Codex CLI: $HAS_CODEX."
if [ "$HAS_CLAUDE" = "yes" ] && [ "$HAS_CODEX" = "yes" ]; then
echo "AgentOps will use mixed-model mode (cross-vendor council, parallel /rpi)."
elif [ "$HAS_CLAUDE" = "yes" ]; then
echo "AgentOps will use single-runtime mode (Claude Code only)."
echo "To unlock mixed-model judging, install Codex CLI: https://github.com/openai/codex"
elif [ "$HAS_CODEX" = "yes" ]; then
echo "AgentOps will use single-runtime mode (Codex CLI only)."
echo "To unlock mixed-model judging, install Claude Code: https://docs.anthropic.com/en/docs/claude-code"
else
echo "Warning: No supported coding agent found (claude, codex)."
echo "AgentOps requires Claude Code or Codex CLI. Install one first:"
echo " Claude Code: https://docs.anthropic.com/en/docs/claude-code"
echo " Codex CLI: https://github.com/openai/codex"
echo "Continuing anyway — you can install an agent later."
fi
# Step 1: Install Codex plugin
echo "Step 1/3: Installing Codex plugin..."
TMP=$(mktemp -d)
trap 'rm -rf "$TMP"' EXIT
curl -fsSL https://codeload.github.com/boshu2/agentops/tar.gz/refs/heads/main \
| tar xz -C "$TMP" --strip-components=1
if command -v codex >/dev/null 2>&1; then
codex_args=()
if [[ "$WITH_HOOKS" == "1" ]]; then
codex_args+=(--with-hooks)
fi
AGENTOPS_BUNDLE_ROOT="$TMP" bash "$TMP/scripts/install-codex.sh" "${codex_args[@]}"
else
echo "Codex CLI not found. Skipping Codex plugin install."
echo "For Claude Code, install skills via the plugin system:"
echo " npx skills@latest add boshu2/agentops --all -g"
fi
# Step 2: Install CLI (optional — enhances with knowledge flywheel)
if command -v brew >/dev/null 2>&1; then
echo "Step 2/3: Installing CLI via Homebrew..."
if ! brew tap boshu2/agentops https://github.com/boshu2/homebrew-agentops; then
echo "Error: failed to add Homebrew tap boshu2/agentops." >&2
exit 1
fi
if ! brew install agentops; then
echo "brew install agentops failed; trying brew upgrade agentops..."
if ! brew upgrade agentops; then
echo "Error: Homebrew could not install or upgrade agentops." >&2
echo "Try manually:" >&2
echo " brew update && brew upgrade agentops" >&2
exit 1
fi
fi
# Step 3: Optional hooks
if command -v ao >/dev/null 2>&1; then
echo "Note: To create repo-local .agents/ scaffolding, run 'ao init' from your repo root."
if [[ "$WITH_HOOKS" == "1" ]]; then
echo "Step 3/3: Registering hooks..."
ao hooks install --force
else
echo "Step 3/3: Hooks skipped (hookless default)."
echo "Optional: rerun with --with-hooks, or run 'ao hooks install --force' later."
fi
# Optional health check
ao doctor 2>/dev/null && echo "Health check: PASS" || echo "Health check: run 'ao doctor' after setup"
fi
else
echo "Step 2/3: Skipping CLI (Homebrew not found). Install manually:"
echo " brew tap boshu2/agentops https://github.com/boshu2/homebrew-agentops"
echo " brew install agentops"
echo "Step 3/3: Skipped (CLI needed for optional hooks)"
fi
echo ""
echo "Done! Start with: /quickstart"