obm/LLMs.md
Jezza Hehn 79d08fb63c
Some checks failed
CI / Test (push) Failing after 45s
CI / Build-3 (push) Has been skipped
CI / Build (push) Has been skipped
CI / Build-1 (push) Has been skipped
CI / Build-2 (push) Has been skipped
CI / Build-4 (push) Has been skipped
whitespace adjustment
2026-05-22 19:32:06 -04:00

9.6 KiB

LLMs.md — Agent Reference for obm

This file is written for AI agents (LLMs, coding assistants, autonomous agents) who need to understand the obm project and work with their human to deploy, configure, or develop it. If you're reading this, you're probably an agent trying to help someone. Here's what you need to know.


What obm Is

obm (OpenBoatMobile) is a Go CLI tool that deploys AI agents to cloud infrastructure. It generates Terraform-compatible .env files through an interactive walkthrough or a YAML config, validates API credentials against live endpoints, and wraps Terraform lifecycle commands.

Think of it as: "Terraform for AI agents, with a friendly wizard instead of a 94-line .env template."


Quick Orientation

Fact Value
Language Go 1.22
Module path github.com/openboatmobile/obm
External deps gopkg.in/yaml.v3 only
Binary type Static, zero runtime deps
Version file VERSION (single line, e.g. 0.1.0)
Current version 0.1.0
License MIT

Repos:

  • obm (this repo) — the Go CLI
  • openboatmobile-ai — the Terraform configs that obm generates .env files for
  • openboatmobile (private) — live deployment with keys, do NOT touch

Package Map

Use this to find what you need:

cmd/obm/main.go             → Entry point, subcommand routing, build-time version vars
internal/config/            → All configuration types and I/O:
  config.go                 → Config struct, GetValue/SetValue
  deployment.go             → DeploymentConfig (30+ fields), cost estimation
  schema.go                 → VarDef schema (all Terraform variables), VarGroup enum
  dotenv.go                 → DotEnvFile round-trip parser
  dotenv_writer.go          → WriteDotEnv — grouped .env output
  tfvars.go                 → WriteTfVars — HCL-format output
  yaml.go                   → YAMLConfig, LoadYAMLConfig, ToDeploymentConfig
internal/deploy/deploy.go   → Walkthrough orchestrator (Run, RunFromFile, RunWithConfig)
internal/destroy/destroy.go → Terraform destroy with state parsing
internal/inference/         → Inference provider validation:
  client.go                 → HTTP client, ValidateAPIKey, ValidationResult
  inference.go              → Provider enum, ProviderConfig, FallbackChain
internal/prompt/prompt.go   → Terminal I/O: Select, Confirm, Input, Password, colors
internal/provider/          → Cloud provider abstraction:
  provider.go               → Provider interface, BaseProvider, Registry
  hetzner/hetzner.go        → Hetzner Cloud API: token validation, SSH key listing
internal/terraform/terraform.go    → Runner: Init, Plan, Apply, Destroy
internal/validation/validation.go  → Check interface, Runner, CheckResult, Status enum

CLI Commands Your Human Might Ask About

Command What it does When they'd use it
obm deploy Interactive 8-step walkthrough First-time setup or redeploy
obm deploy --config deploy.yaml Non-interactive from YAML CI/CD, automation, repeat deploys
obm validate Check .env + validate API keys "Did I configure this right?"
obm destroy Tear down infrastructure "I'm done with this server"
obm version Print version with commit/build info Debugging

Deploy Walkthrough Steps

When your human runs obm deploy, they'll go through these in order:

  1. Framework — Hermes or OpenClaw
  2. Cloud Provider — Hetzner or DigitalOcean
  3. Provider Token — API key for their cloud provider (validated live)
  4. SSH Key — Select from provider or enter manually
  5. Server Config — Name, location/region, size
  6. Inference Provider — ZAI, Venice, or OpenRouter (API key validated live)
  7. Tailscale — Optional VPN (auth key + tailnet)
  8. Discord — Optional bot integration (token, server ID, user IDs)

After all 8 steps: summary + cost estimate → confirm → .env written → optional terraform init && apply.


What Your Human Needs Before Deploying

Tell them to have these ready:

  1. Cloud provider account with API token (Hetzner: console.hetzner.cloud → Security → API Tokens; DO: cloud.digitalocean.com → API)
  2. SSH public key uploaded to their cloud provider
  3. Inference provider API key (Venice, OpenRouter, or ZAI)
  4. (Optional) Tailscale auth key
  5. (Optional) Discord bot token + server ID

Framework Differences

When your human asks "Hermes or OpenClaw?":

Hermes Agent — if they want:

  • Discord chat, voice, web search, many integrations
  • Python-based, Docker or direct install
  • More configurable (gateway, allowed users, auto-threading)

OpenClaw — if they want:

  • Simpler setup, fewer moving parts
  • Node.js-based
  • Built-in security (fail2ban, unattended upgrades, swap)

Configuration Files

.env (Terraform input)

All variables prefixed with TF_VAR_. Generated by obm deploy or WriteDotEnv(). This is the primary output of the tool. Groups: PROVIDER, SERVER, SSH, API KEYS, MODEL, DISCORD, TAILSCALE, HERMES-SPECIFIC, OPENCLAW-SPECIFIC, SECURITY, PROJECT.

Special format for SSH keys: TF_VAR_ssh_key_names='["key-name"]' — single-quoted shell string containing JSON array.

deploy.yaml (Non-interactive input)

Full schema in deploy.yaml.example. Key sections:

framework: hermes
provider:
  name: hetzner
  token: "..."
  ssh:
    names: ["my-key"]
server:
  name: "agent"
  location: "ash"
  type: "cpx21"
inference:
  provider: venice
  api_key: "..."
  primary_model: "zai-org-glm-5"
tailscale:
  enabled: true
  auth_key: "..."
discord:
  enabled: false

Build Commands

make build           # Build for current platform
make test            # Test with race detection + coverage
make lint            # go vet + gofmt
make cross-compile   # All platforms: linux-{amd64,arm64}, darwin-arm64, windows-{amd64,arm64}
make clean           # Remove binary + coverage

From source without make:

go build -o obm ./cmd/obm
go test ./...
go vet ./...

Version injection at build time:

go build -ldflags "-s -w -X main.version=$(cat VERSION) -X main.gitCommit=$(git rev-parse --short HEAD) -X main.buildTime=$(date -u +%Y-%m-%dT%H:%M:%SZ)" -o obm ./cmd/obm

Common Tasks Your Human Might Ask For

"Help me deploy an agent"

  1. Make sure they have API keys ready (see "What Your Human Needs" above)
  2. Run obm deploy
  3. Walk them through the 8 steps if they have questions
  4. The cost estimate at the end is approximate — cloud providers may vary

"Check if my config is valid"

obm validate

This loads .env, checks required variables, and validates inference API keys against live endpoints.

"I want to tear down my server"

obm destroy

It asks for confirmation. It reads terraform.tfstate to show what will be destroyed.

"Set up CI/CD deployment"

  1. Create a deploy.yaml from deploy.yaml.example
  2. Store secrets in your CI secrets manager
  3. In pipeline: obm deploy --config deploy.yaml

"Add a new cloud provider"

  1. Create internal/provider/<name>/<name>.go implementing the Provider interface
  2. Register via init(): provider.Register("<name>", func() provider.Provider { return New() })
  3. Add provider-specific fields to DeploymentConfig
  4. Update schema.go with new VarGroup and VarDef entries
  5. Add step function in deploy.go

"Add a new inference provider"

  1. Add Provider<Name> constant to internal/inference/inference.go
  2. Add case to Info() method (name, env var, base URL)
  3. Add case to UnmarshalText() for YAML parsing
  4. Add case to setAuthHeaders() in client.go if auth differs from Bearer token
  5. Update AllProviders() return slice

Known Limitations

  • obm status is stubbed — not yet functional
  • DigitalOcean provider validation not yet implemented (only Hetzner)
  • No resumable deploy — interrupted walkthrough = start over
  • No cost preview before the summary step
  • openai and anthropic inference providers listed in schema but not fully implemented in the inference client (only ZAI, Venice, OpenRouter have live validation)

Relationship to Terraform Configs

obm generates the .env file. The Terraform configs that consume it live in the openboatmobile-ai repo. The variable schema in internal/config/schema.go must stay in sync with the Terraform variable definitions in openboatmobile-ai/variables-*.tf.

If you add a variable to the Terraform configs, you must also add a corresponding VarDef to schema.go.


Testing Strategy

  • Unit tests in each package (*_test.go)
  • Hetzner provider tested with mock HTTP servers (WithHTTPClient + WithBaseURL options)
  • Inference client tested with mock /models endpoints
  • Run with: make test or go test -v -race -coverprofile=coverage.out ./...

File Locations Summary

File Purpose
VERSION Single-line semver string
Makefile Build, test, lint, cross-compile targets
Dockerfile Multi-stage build for containerized obm
deploy.yaml.example Full YAML config reference
scripts/install.sh curl | sh installer
scripts/release.sh Tag + push release automation
.github/workflows/ci.yml Test + build on push/PR
.github/workflows/release.yml Cross-compile + GitHub Release on tag
CHANGELOG.md Version history
CONTRIBUTING.md Dev setup, PR checklist, release process
README.md User-facing overview (casual tone)
DETAILS.md Full technical reference
LLMs.md This file — agent-oriented reference