Skip to main content

Developer Setup

Local development environment setup for OpenClaw.

Quick Start (Scripts)

Run both setup scripts to get going fast:

# 1. Install all macOS tools (Homebrew, 1Password CLI, git, gh, linters)
./scripts/setup-mac.sh

# 2. Configure the repo (remote, Dropbox ignore, hooks, branch tracking)
./scripts/setup-repo.sh

Both scripts are idempotent — safe to re-run anytime to verify or repair your setup.

Manual Steps (Reference)

The sections below explain what the scripts do, step by step.

1. Install Homebrew (if needed)

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

2. Install 1Password and CLI

Install the 1Password desktop app, then install the CLI:

brew install --cask 1password-cli

Verify:

op --version
op account list # should show your account

3. Set Up SSH Authentication with GitHub

Follow the full guide in ssh-github-setup.md. The short version:

  1. Enable the SSH agent in 1Password (Settings → Developer → SSH Agent)

  2. Create or confirm an SSH key exists in 1Password (ed25519, Shared-Infrastructure vault)

  3. Register the key in ~/.config/1Password/ssh/agent.toml

  4. Configure ~/.ssh/config to use the 1Password agent:

    Host *
    IdentityAgent "~/Library/Group Containers/2BUA8C4S2C.com.1password/t/agent.sock"
  5. Add GitHub's host key:

    ssh-keyscan github.com >> ~/.ssh/known_hosts
  6. Test:

    ssh -T git@github.com
    # Expected: Hi langhalsb! You've successfully authenticated...

4. Install Git and GitHub CLI

brew install git gh

Configure git identity, authenticate gh via browser OAuth, and set SSH protocol:

git config --global user.name "Ben Langhals"
git config --global user.email "ben.langhals@iamconsult.net"
gh auth login --hostname github.com --git-protocol ssh --web

5. Clone the Repo into Dropbox

cd ~/Library/CloudStorage/Dropbox
git init openclaw
cd openclaw
git remote add origin git@github.com:langhalsb/openclaw.git
git fetch origin
git branch -M main
git reset --mixed origin/main
git checkout -- .
git branch --set-upstream-to=origin/main main

6. Tell Dropbox to Ignore .git

Dropbox syncing .git internals causes corruption and conflicts. Mark the folder ignored:

xattr -w com.dropbox.ignored 1 .git

Verify:

xattr -p com.dropbox.ignored .git
# Expected: 1

The .git folder will show a grey minus icon in Finder, confirming Dropbox is skipping it.

7. Install Node.js and Cloudflare Wrangler

Node.js is required for Docusaurus and Wrangler. Wrangler is the Cloudflare CLI for managing Pages deployments.

brew install node
npm install -g wrangler

Authenticate Wrangler with your Cloudflare account:

wrangler login

This opens a browser window for OAuth. After authorizing, verify:

wrangler whoami

8. Install Linters and Task Runner

brew install jq shellcheck markdownlint-cli2 just

9. Install Docusaurus (Documentation Site)

The docs site lives in docs-openclaw/ and deploys to Cloudflare Pages automatically on push to main.

cd docs-openclaw && npm install

Local development:

just docs-build    # Build + preview at http://localhost:3001
just docs-preview # Preview existing build at http://localhost:3001

The site generates llms.txt and llms-full.txt at build time for LLM consumption.

10. Task Runner (just)

The project uses just as a task runner. Run just to see all available commands:

just            # List all commands
just setup # Full setup (mac + repo + docs)
just docs-build # Build + preview at http://localhost:3001
just docs-preview # Preview existing build
just docs-deploy # Build + deploy to Cloudflare Pages
just lint # Run all linters (shell + markdown)
just lint-sh # Lint shell scripts only
just lint-md # Lint markdown only
just verify # Lint + build docs
just pr NAME # Create branch, push, open PR, wait for CodeRabbit
just pr-merge # Merge current PR after checks pass

Git Hooks

The repo includes pre-commit hooks that lint staged .sh and .md files before each commit. To enable them:

git config core.hooksPath .githooks

This tells git to use the .githooks/ directory (committed to the repo) instead of .git/hooks/ (local only).

What the pre-commit hook checks

  • Shell scripts (.sh): Runs shellcheck for common bugs, quoting issues, and portability problems
  • Markdown files (.md): Runs markdownlint-cli2 using .markdownlint.jsonc config

Skipping hooks

If you need to bypass the hook for a specific commit:

git commit --no-verify -m "message"

Linter Configuration

Markdown lint rules are configured in .markdownlint.jsonc:

  • MD013 (line length) — disabled, tables and URLs make strict line limits impractical
  • MD025 (single top-level heading) — disabled
  • MD040 (fenced code block language) — enabled, all code fences must specify a language
  • MD060 (table column style) — disabled, too noisy for compact tables
  • MD032 (blanks around lists) — disabled

Claude Code Web Environment

If you're working in a Claude Code web session (claude.ai/code) instead of a local Mac, the setup is different. There's no 1Password desktop app, no Homebrew, and the sandbox has an egress proxy that blocks outbound connections to hosts not on its allowlist.

1. Configure Network Access

In your Claude Code environment settings (claude.ai/code):

  1. Set Network access to Custom (or Full if your security policy allows)
  2. Add these domains to the allowlist:
    • developers.hostinger.com (Hostinger API)
    • srv1296613.hstgr.cloud (VPS hostname)
    • 76.13.100.227 (VPS IP)

Known issue: Custom domain allowlists may not take effect due to open bugs (anthropics/claude-code#30112, anthropics/claude-code#34690). If Custom doesn't work, try Full network access.

2. Set Environment Variables

In your Claude Code project settings, add these environment variables:

VariableRequiredPurpose
HOSTINGER_API_TOKENFor API accessHostinger API token from 1Password (Shared-Infrastructure vault)
VPS_SSH_PRIVATE_KEYFor SSH accessEd25519 private key content (base64-encoded)

Getting the values from 1Password (on your Mac):

# Hostinger API token
op item get "Hostinger API Token" --vault="Shared-Infrastructure" --fields credential --reveal

# SSH private key (base64-encode it for safe transport)
op item get "openclaw-vps-1" --vault="Shared-Infrastructure" --fields "private key" --reveal | base64

Alternatively, set OP_SERVICE_ACCOUNT_TOKEN if you have a service account with Shared-Infrastructure vault access — the op CLI can then fetch everything at runtime.

3. Install Tools and Set Up SSH

Once the environment is configured, install prerequisites and set up SSH:

just setup-web        # Install openssh-client + just, set up SSH access
just vps-test # Verify SSH connectivity
just vps-status # Check VPS status via Hostinger API

4. Available Web Recipes

CommandWhat It Does
just setup-webInstall tools + generate SSH key + configure SSH
just vps-setup-webGenerate SSH key + configure SSH access only
just vps-statusVPS status via Hostinger API
just vps-testTest SSH connectivity
just vps-exec CMDRun command on VPS via SSH
just vps-logsView bot container logs
just vps-deployDeploy latest code to VPS
just vps-pubkeyPrint SSH public key
just agent-testRun all tests
just agent-typecheckTypeScript type check