Repository Lifecycle Scripts in Background Agents: Understanding setup.sh and start.sh

Background Agents utilizes a two-step boot process where .openinspect/setup.sh handles one-time provisioning during image builds while .openinspect/start.sh manages per-session runtime initialization in sandboxed Modal environments.

The ColeMurray/background-agents repository orchestrates autonomous coding agents inside isolated Modal sandboxes. Understanding the repository lifecycle scripts is essential for customizing your agent's environment, as these Bash scripts control exactly how dependencies are installed, shared packages are built, and long-running services are started before any agent code executes.

The Setup Phase: Provisioning with setup.sh

The .openinspect/setup.sh script runs once during repository image builds or the first time a fresh session initializes. Located at /.openinspect/setup.sh, this script prepares the entire repository for execution by installing tooling, building dependencies, and validating the environment.

Prerequisite Validation and Node.js Requirements

The script begins with strict prerequisite checks to ensure the environment meets baseline requirements. It verifies that node and npm are available and enforces Node.js ≥ 20 for compatibility with the modern TypeScript toolchain. These checks ensure that subsequent build steps fail fast with clear error messages rather than obscure dependency failures.

Dependency Installation and Shared Package Builds

After validation, the script executes npm install, which simultaneously triggers Husky’s prepare hook to install Git hooks. The provisioning process prioritizes building @open-inspect/shared first, as every other package in the monorepo depends on this shared library. The script explicitly verifies that the pre-commit hook is installed, running npx husky if missing.

Optional Python Environment Configuration

When the packages/modal-infra directory exists and Python ≥ 3.12 is detected on the host, the script automatically configures a Python environment. It prefers uv for lockfile synchronization if available, falling back to a traditional venv combined with pip install -e workflow. This ensures the Modal infrastructure package is ready for agents requiring Python tooling.

Type Checking and Idempotency

The script concludes by running npm run typecheck across all packages and warning if any package still requires building. Designed to be idempotent, setup.sh can be re-run safely without side effects. Failures during image-build mode are treated as fatal errors, while failures during fresh sessions are logged but allow the session to continue starting.

The Runtime Phase: Initialization with start.sh

After provisioning completes, the boot sequence proceeds to the optional start phase. According to the source code in packages/control-plane/src/sandbox/lifecycle/decisions.ts (line 491), the script at /.openinspect/start.sh executes once per session after the repository image has been restored.

Long-Running Processes and Development Servers

When present, start.sh is responsible for launching any long-running processes the agent requires. Common use cases include starting local development servers with commands like npm run dev -w @open-inspect/web, initializing background workers, running database migrations, or spawning custom service daemons. The platform skips this step entirely if the file is missing.

Environment Variable Export

The script typically exports critical environment variables that subsequent components rely on. Variables defined here become available to the opencode bridge and the Modal sandbox connection, ensuring proper communication between the agent and its host environment.

Implementation Examples

Both scripts follow defensive Bash conventions using set -euo pipefail to ensure strict error handling.

Customizing setup.sh for Additional Tooling

The following snippet demonstrates installing a global CLI tool and building a new package:

#!/usr/bin/env bash
set -euo pipefail

# Helpers

info() { printf '\033[1;34m==>\033[0m %s\n' "$*"; }

info "Installing additional CLI"
npm install -g my-cli-tool

info "Building new package @open-inspect/my-package"
npm run build -w @open-inspect/my-package

Configuring start.sh for Development Servers

This example launches a web server and exposes its port to the sandbox:

#!/usr/bin/env bash
set -euo pipefail

info() { printf '\033[1;34m==>\033[0m %s\n' "$*"; }

info "Starting local web server"
npm run dev -w @open-inspect/web &
SERVER_PID=$!

# Export the port so the sandbox bridge can connect

export WEB_PORT=3000

# Wait for the server to exit (or trap signals for graceful shutdown)

wait $SERVER_PID

Boot Sequence Integration

These scripts fit into a specific execution order defined in the Background Agents platform. The complete boot sequence flows as:

  1. .openinspect/setup.sh – Provisioning and dependency installation
  2. .openinspect/start.sh – Runtime initialization (if present)
  3. opencode – Agent code execution
  4. Bridge connection – Modal sandbox communication established

This architecture ensures that every sandboxed session starts from a reproducible, fully-provisioned state before the actual agent logic begins execution.

Summary

  • .openinspect/setup.sh runs once during image builds to install Node.js dependencies, build the @open-inspect/shared package, configure Python ≥ 3.12 environments using uv or venv, and verify Git hooks.
  • .openinspect/start.sh runs once per session to launch long-running processes like development servers and export environment variables required by the Modal sandbox.
  • Both scripts use set -euo pipefail for fail-safe execution and are referenced in packages/control-plane/src/sandbox/lifecycle/decisions.ts at line 491.
  • The setup script is idempotent and safe to re-run, while the start script is optional and skipped if missing.

Frequently Asked Questions

What is the difference between setup.sh and start.sh in Background Agents?

setup.sh executes during image builds and first-run sessions to install dependencies and build shared packages, while start.sh runs after provisioning to initialize long-running services for that specific session. The setup script prepares the environment once; the start script configures the runtime for each individual agent execution.

How do I add Python dependencies to my Background Agents repository?

Place your Python code in packages/modal-infra and ensure Python ≥ 3.12 is available. The setup.sh script automatically detects this directory and installs dependencies using uv (preferred) or falls back to venv plus pip install -e. You can also manually activate the environment in start.sh if you need Python services running during the session.

What happens if start.sh is missing from my repository?

The platform treats start.sh as optional. If the file does not exist at /.openinspect/start.sh, the boot sequence skips the runtime initialization phase and proceeds directly to executing the agent code. This is the default behavior for repositories that do not require custom background processes.

Is setup.sh idempotent and safe to run multiple times?

Yes, the setup.sh script is designed to be idempotent. You can safely re-run it without causing duplicate installations or build errors. The script validates existing installations and only performs destructive operations when necessary, making it safe for both local development and CI/CD pipelines.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →