#!/usr/bin/env bash # # Orb setup for idx-cli. # # A fresh orb has no Rust toolchain and no Nix, while the repository builds and # verifies through its flake dev shell (`nix develop`). This script installs Nix # (single-user), realizes the dev shell, makes that environment available to the # login shells Amp and orb services start, and warms the Cargo build so the # first agent command is incremental. # # Idempotent by design: an orb restored from a stale snapshot re-runs this and # keeps /nix, ~/.cargo, and target/ instead of rebuilding them. set -euo pipefail repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" nix_profile="$HOME/.nix-profile" nix_bin="$nix_profile/bin/nix" nix_conf="$HOME/.config/nix/nix.conf" bash_profile="$HOME/.bash_profile" agent_guidance="$HOME/.config/amp/AGENTS.md" profile_marker="# idx-cli orb dev shell (managed by .agents/setup)" guidance_marker="" step() { printf '\n==> %s\n' "$*"; } # Runs "$@" with timing so setup.log shows which step is slow or failing. run() { local label="$1" shift local start=$SECONDS if "$@"; then printf ' ok: %s (%ss)\n' "$label" "$((SECONDS - start))" return 0 fi local status=$? printf ' FAILED: %s (%ss, exit %s)\n' "$label" "$((SECONDS - start))" "$status" >&2 return "$status" } # Warm-up work whose failure should not stop snapshot publication. run_warn() { if ! run "$@"; then printf 'warning: %s failed; rerun .agents/setup once the cause is fixed\n' "$1" >&2 fi } step "Nix package manager" if [ -x "$nix_bin" ]; then printf ' ok: already installed (%s)\n' "$("$nix_bin" --version)" else installer="$(mktemp)" curl -fsSL https://nixos.org/nix/install -o "$installer" run "install nix (single-user)" sh "$installer" --no-daemon --no-modify-profile --yes rm -f "$installer" fi # The installer cannot update the environment of this already-running script. # shellcheck source=/dev/null if [ -f "$nix_profile/etc/profile.d/nix.sh" ]; then . "$nix_profile/etc/profile.d/nix.sh" fi step "Nix flake support" mkdir -p "$(dirname "$nix_conf")" touch "$nix_conf" if ! grep -qE '^[[:space:]]*experimental-features[[:space:]]*=.*nix-command' "$nix_conf"; then printf 'experimental-features = nix-command flakes\n' >>"$nix_conf" fi if ! grep -qE '^[[:space:]]*warn-dirty[[:space:]]*=' "$nix_conf"; then printf 'warn-dirty = false\n' >>"$nix_conf" fi printf ' ok: %s\n' "$nix_conf" step "Flake dev shell" run "realize dev shell" "$nix_bin" develop --command true step "Warm Cargo build (kept in the snapshot for the first agent command)" run_warn "cargo build --locked" "$nix_bin" develop --command bash -c 'cargo build --locked' run_warn "cargo test --no-run --locked" "$nix_bin" develop --command bash -c 'cargo test --no-run --locked' run_warn "cargo clippy --locked -- -D warnings" "$nix_bin" develop --command bash -c 'cargo clippy --locked -- -D warnings' step "Login shell environment" # Amp starts its login shells (the headless executor and orb services) from /, # so activate the dev shell by repository path instead of by $PWD. The # IN_NIX_SHELL guard keeps nested shells and `nix develop` itself cheap. profile_hook() { cat </dev/null; then printf ' ok: dev shell hook already present in %s\n' "$bash_profile" else printf '\n' >>"$bash_profile" profile_hook >>"$bash_profile" printf ' ok: added dev shell hook to %s\n' "$bash_profile" fi step "Orb guidance for agents" mkdir -p "$(dirname "$agent_guidance")" if grep -Fq "$guidance_marker" "$agent_guidance" 2>/dev/null; then printf ' ok: guidance already present in %s\n' "$agent_guidance" else cat >>"$agent_guidance" <&2 exit 1 fi