{"id":45421683,"url":"https://github.com/stepandel/clawup","last_synced_at":"2026-03-03T21:04:58.212Z","repository":{"id":337708771,"uuid":"1152363985","full_name":"stepandel/clawup","owner":"stepandel","description":"Deploy fleets of specialized OpenClaw agents to your cloud. Define identities in YAML, provision with one command, track changes in git.","archived":false,"fork":false,"pushed_at":"2026-03-01T03:14:56.000Z","size":132167,"stargazers_count":2,"open_issues_count":2,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-01T06:06:31.427Z","etag":null,"topics":["aws","clawup","cli","hetzner","infrastructure","npm","openclaw","pulumi","tailscale","typescript","yaml"],"latest_commit_sha":null,"homepage":"https://clawup.sh","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/stepandel.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"docs/contributing.mdx","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-02-07T19:06:57.000Z","updated_at":"2026-03-01T03:14:59.000Z","dependencies_parsed_at":"2026-02-14T04:01:50.472Z","dependency_job_id":"1cb8d89d-5674-46f7-81f1-40f03d6e7a04","html_url":"https://github.com/stepandel/clawup","commit_stats":null,"previous_names":["stepandel/agent-army"],"tags_count":98,"template":false,"template_full_name":null,"purl":"pkg:github/stepandel/clawup","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stepandel%2Fclawup","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stepandel%2Fclawup/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stepandel%2Fclawup/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stepandel%2Fclawup/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/stepandel","download_url":"https://codeload.github.com/stepandel/clawup/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stepandel%2Fclawup/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30060778,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-03T18:21:05.932Z","status":"ssl_error","status_checked_at":"2026-03-03T18:20:59.341Z","response_time":61,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aws","clawup","cli","hetzner","infrastructure","npm","openclaw","pulumi","tailscale","typescript","yaml"],"created_at":"2026-02-22T01:36:01.576Z","updated_at":"2026-03-03T21:04:58.195Z","avatar_url":"https://github.com/stepandel.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Clawup\n\n[![npm](https://img.shields.io/npm/v/clawup)](https://www.npmjs.com/package/clawup)\n[![license](https://img.shields.io/npm/l/clawup)](./LICENSE)\n\nDeploy a fleet of specialized [OpenClaw](https://openclaw.bot/) AI agents on **AWS** or **Hetzner Cloud** — managed entirely from your terminal.\n\n## What Is This?\n\nClawup provisions autonomous AI agents with persistent memory, role-specific behavior, and secure networking. Each agent runs in a Docker sandbox with its own identity — personality, skills, tools, and model preferences — connected over a Tailscale mesh VPN with no public port exposure.\n\nYou define _what_ your agents do. Clawup handles _where_ and _how_ they run.\n\n```\n┌─────────────────────────────────────────────────────────────────────┐\n│                      AWS VPC / Hetzner Cloud                        │\n│                                                                     │\n│  ┌──────────────┐   ┌──────────────┐   ┌──────────────┐             │\n│  │  Agent A      │   │  Agent B     │   │  Agent C     │             │\n│  │              │   │              │   │              │             │\n│  │  • OpenClaw  │   │  • OpenClaw  │   │  • OpenClaw  │             │\n│  │  • Docker    │   │  • Docker    │   │  • Docker    │             │\n│  │  • Tailscale │   │  • Tailscale │   │  • Tailscale │             │\n│  └──────┬───────┘   └──────┬───────┘   └──────┬───────┘             │\n│         └──────────────────┼──────────────────┘                     │\n└────────────────────────────┼────────────────────────────────────────┘\n                             │\n                ┌────────────▼────────────┐\n                │   Tailscale Mesh VPN    │\n                │   (Encrypted P2P)       │\n                └────────────┬────────────┘\n                             │\n                ┌────────────▼────────────┐\n                │     Your Machine        │\n                └─────────────────────────┘\n```\n\n## Identity System\n\nAgents are defined by **identities** — composable, self-contained packages that include everything an agent needs to operate: personality, skills, model preferences, plugin configuration, and dependencies.\n\n### How Identities Work\n\nAn identity is a directory with an `identity.yaml` manifest and workspace files:\n\n```\nmy-identity/\n├── identity.yaml       # Manifest: model, plugins, deps, skills, template vars\n├── SOUL.md             # Personality, role, approach, communication style\n├── IDENTITY.md         # Name, role, emoji\n├── HEARTBEAT.md        # Periodic tasks and state machine logic\n├── TOOLS.md            # Tool reference (integrations, local env)\n├── AGENTS.md           # Multi-agent coordination instructions\n├── BOOTSTRAP.md        # First-run setup instructions\n├── USER.md             # Owner-specific info (templated)\n└── skills/             # Bundled skills\n    └── my-skill/\n        └── SKILL.md\n```\n\nIdentities can live in a **Git repo**, a **monorepo subdirectory**, or a **local path**. Point any agent at any identity:\n\n```yaml\n# clawup.yaml\nagents:\n  - name: agent-researcher\n    displayName: Atlas\n    role: researcher\n    identity: \"https://github.com/your-org/your-identities#researcher\"\n    identityVersion: \"v1.0.0\"   # optional: pin to a tag or commit\n    volumeSize: 20\n```\n\n### `identity.yaml`\n\nThe identity manifest declares the agent's defaults:\n\n```yaml\nname: researcher\ndisplayName: Atlas\nrole: researcher\nemoji: telescope\ndescription: Deep research, source analysis, report generation\nvolumeSize: 20\n\nmodel: anthropic/claude-sonnet-4-5\ncodingAgent: claude-code\n\ndeps:\n  - brave-search\n\nplugins:\n  - slack\n\npluginDefaults:\n  slack:\n    mode: socket\n    dm:\n      enabled: true\n      policy: open\n\nskills:\n  - research-report\n\ntemplateVars:\n  - OWNER_NAME\n  - TIMEZONE\n  - WORKING_HOURS\n  - USER_NOTES\n\n# Additional secrets not covered by plugins/deps\nrequiredSecrets:\n  - notionApiKey       # → \u003cROLE\u003e_NOTION_API_KEY in .env\n```\n\n### Built-in Identities\n\nClawup ships with three built-in identities to get you started:\n\n| Alias | Role | What It Does |\n|-------|------|-------------|\n| **Juno** | PM | Breaks down tickets, researches requirements, plans \u0026 sequences work, tracks progress |\n| **Titus** | Engineer | Picks up tickets, writes code via Claude Code, builds/tests, creates PRs |\n| **Scout** | Tester | Reviews PRs, tests happy/sad/edge cases, files bugs, verifies fixes |\n\nThese are standard identities hosted in a Git repo — the same format as any custom identity you'd create.\n\n### Creating Your Own Identity\n\nSee the [`examples/identity/`](./examples/identity/) directory for a complete, minimal example (a \"researcher\" agent), and the [Creating Identities](./docs/guides/creating-identities.mdx) guide for the full authoring reference covering:\n\n- Identity structure and required files\n- `identity.yaml` field reference\n- Workspace file conventions\n- Skill authoring (private and public)\n- Template variable substitution\n- Available registries (deps, plugins, coding agents)\n\n## Quick Start\n\n### 1. Install\n\n```bash\nnpm install -g clawup\n```\n\n### 2. Generate Config\n\n```bash\nclawup init\n```\n\nScaffolds a `clawup.yaml` manifest and `.env.example` with sensible defaults (AWS, us-east-1, all built-in agents). Edit `clawup.yaml` by hand to customize your provider, region, instance type, owner info, and agents.\n\n### 3. Fill in Secrets\n\n```bash\ncp .env.example .env\n# Edit .env and fill in your API keys\n```\n\n### 4. Validate \u0026 Configure\n\n```bash\nclawup setup\n```\n\nValidates all secrets from `.env`, fetches Linear user UUIDs, and configures Pulumi. If any secrets are missing, it prints exactly what's needed.\n\n### 5. Deploy\n\n```bash\nclawup deploy\n```\n\n### 6. Validate\n\nWait 3-5 minutes for cloud-init to complete, then:\n\n```bash\nclawup validate\n```\n\n### 7. Access Your Agents\n\n```bash\nclawup ssh \u003cagent-name\u003e    # SSH by name, role, or alias\n```\n\n## CLI Reference\n\nRun `clawup --help` for the full list.\n\n| Command | Description |\n|---------|-------------|\n| `clawup init` | Generate clawup.yaml scaffold (or refresh from identity changes) |\n| `clawup setup` | Validate secrets from `.env` and configure Pulumi |\n| `clawup deploy` | Deploy agents (`pulumi up` under the hood) |\n| `clawup deploy --local` | Deploy to local Docker containers |\n| `clawup status` | Show agent statuses and outputs |\n| `clawup status --local` | Show local Docker container status |\n| `clawup ssh \u003cagent\u003e` | SSH to an agent by name, role, or alias |\n| `clawup ssh \u003cagent\u003e --local` | Shell into a local Docker container |\n| `clawup validate` | Health check all agents via Tailscale |\n| `clawup validate --local` | Health check local Docker containers |\n| `clawup redeploy` | Update agents in-place (`pulumi up --refresh`) |\n| `clawup redeploy --local` | Redeploy local Docker containers |\n| `clawup destroy` | Tear down all resources (with confirmation) |\n| `clawup destroy --local` | Destroy local Docker containers only |\n| `clawup list` | Show project config |\n| `clawup config show` | Display current config |\n| `clawup config show --json` | Config in JSON format |\n| `clawup config set \u003ckey\u003e \u003cvalue\u003e` | Update a config value |\n| `clawup config set \u003ckey\u003e \u003cvalue\u003e -a \u003cagent\u003e` | Update a per-agent config value |\n| `clawup secrets set \u003ckey\u003e \u003cvalue\u003e` | Set a Pulumi secret (e.g. API keys) |\n| `clawup secrets list` | Show which secrets are configured (redacted) |\n| `clawup push` | Push workspace files, skills, and config to running agents |\n| `clawup webhooks setup` | Configure Linear webhooks for deployed agents |\n| `clawup update` | Update clawup CLI to the latest version |\n\nAgent resolution is flexible — all of these target the same agent:\n\n```bash\nclawup ssh juno        # by alias\nclawup ssh pm          # by role\nclawup ssh agent-pm    # by resource name\n```\n\n## Cloud Providers\n\n### Provider Comparison\n\n| Feature | AWS | Hetzner Cloud |\n|---------|-----|---------------|\n| **3x Agents (monthly)** | ~$110-120 | ~$18-22 |\n| **Instance Type** | t3.medium (2 vCPU, 4GB) | CX22 (2 vCPU, 4GB) |\n| **Storage** | ~$2.40/month per 30GB | Included |\n| **Data Transfer** | ~$5-10/month | 20TB included |\n| **Regions** | Global (25+) | EU \u0026 US (5 locations) |\n| **Setup Complexity** | Moderate (VPC, IAM) | Simple (API token) |\n\nUse Hetzner for development and cost savings (~80% cheaper). Use AWS for production or global reach.\n\n### What Gets Provisioned\n\nEach agent gets:\n- Cloud instance (EC2 or Hetzner server) with Ubuntu 24.04 LTS\n- Docker (for OpenClaw sandbox)\n- Node.js v22, OpenClaw CLI, coding agent CLI (from registry), GitHub CLI\n- Tailscale VPN (encrypted mesh, no public ports)\n- Workspace files and skills injected from its identity\n- AI model configured per-identity (with fallback support)\n- Plugins and deps installed per-identity\n\nAll agents share a single VPC/network for cost optimization.\n\n## Dependencies\n\nYou need the following installed on your **local machine** before running `clawup init`.\n\n### Required (all providers)\n\n| Dependency | Why | Install |\n|------------|-----|---------|\n| **Node.js 18+** | Runtime for CLI and Pulumi program | [nodejs.org](https://nodejs.org/) |\n| **Pulumi CLI** | Infrastructure provisioning | [pulumi.com/docs/iac/download-install](https://www.pulumi.com/docs/iac/download-install/) |\n| **Pulumi Account** | State management and encrypted secrets | [app.pulumi.com/signup](https://app.pulumi.com/signup) |\n| **Tailscale** | Secure mesh VPN to reach your agents | [tailscale.com/download](https://tailscale.com/download) |\n\n### Required (provider-specific)\n\nPick one depending on where you want to deploy:\n\n| Provider | Dependency | Install |\n|----------|-----------|---------|\n| **AWS** | AWS CLI (configured with credentials) | [aws.amazon.com/cli](https://aws.amazon.com/cli/) — then run `aws configure` |\n| **Hetzner** | API token with Read \u0026 Write permissions | [console.hetzner.cloud](https://console.hetzner.cloud/) → Project → Security → API Tokens |\n\n### Tailscale Setup\n\nTailscale requires a few one-time setup steps:\n\n1. [Create an account](https://login.tailscale.com/start)\n2. [Enable HTTPS certificates](https://tailscale.com/kb/1153/enabling-https) (required for OpenClaw web UI)\n3. [Generate a reusable auth key](https://login.tailscale.com/admin/settings/keys) with tags\n4. Note your tailnet DNS name (e.g., `tail12345.ts.net`)\n\n### Installed on agents automatically\n\nThese are provisioned on the cloud instances via cloud-init — you do **not** need them locally:\n\n- Docker, Node.js v22, OpenClaw CLI, coding agent CLI (e.g., Claude Code)\n- Tailscale (agent-side)\n- GitHub CLI, Brave Search, and other deps (per-identity)\n- OpenClaw plugins: Linear, Slack (per-identity)\n\n## Required API Keys\n\n| Key | Required | Where to Get |\n|-----|----------|--------------|\n| **Anthropic Credentials** | Yes | [API Key](https://console.anthropic.com/) or OAuth token (`claude setup-token`) |\n| **Tailscale Auth Key** | Yes | [Tailscale Admin](https://login.tailscale.com/admin/settings/keys) (reusable, with tags) |\n| **Slack Bot Token** | No | [Slack API](https://api.slack.com/apps) — per agent |\n| **Linear API Token** | No | [Linear Settings](https://linear.app/settings/api) — per agent |\n| **GitHub Token** | No | [GitHub Settings](https://github.com/settings/tokens) — per agent |\n\n### Claude Code Authentication\n\nTwo authentication methods are supported:\n\n| Method | Token Format | Best For |\n|--------|-------------|----------|\n| **API Key** | `sk-ant-api03-...` | Pay-as-you-go API usage |\n| **OAuth Token** | `sk-ant-oat01-...` | Pro/Max subscription (flat rate) |\n\nThe system auto-detects which type you provide and sets the correct environment variable.\n\n## Updating \u0026 Redeploying\n\nFor in-place updates that preserve Tailscale devices and existing infrastructure:\n\n```bash\nclawup redeploy\n```\n\nThis runs `pulumi up --refresh` to sync cloud state and apply changes. If the stack doesn't exist yet, it falls back to a fresh deploy automatically.\n\nFor local Docker containers:\n\n```bash\nclawup redeploy --local\n```\n\nFor a clean rebuild (when in-place update can't recover):\n\n```bash\nclawup destroy -y \u0026\u0026 clawup deploy -y\n```\n\n## Configuration\n\n### Viewing \u0026 Modifying Config\n\nView your current configuration without opening the manifest file:\n\n```bash\nclawup config show              # Human-readable summary\nclawup config show --json       # Full JSON output\n```\n\nModify config values with validation (no need to re-run `init`):\n\n```bash\nclawup config set region us-west-2\nclawup config set instanceType t3.large\nclawup config set instanceType cx32 -a atlas     # Per-agent override\nclawup config set volumeSize 50 -a atlas         # Per-agent volume\n```\n\nRun `clawup redeploy` after changing config to apply.\n\n### `clawup.yaml`\n\nGenerated by `clawup init`. This manifest drives the entire deployment:\n\n```yaml\nstackName: dev\nprovider: aws\nregion: us-east-1\ninstanceType: t3.medium\nownerName: Your Name\ntimezone: America/New_York\nworkingHours: 9am-6pm\nsecrets:\n  anthropicApiKey: \"${env:ANTHROPIC_API_KEY}\"\n  tailscaleAuthKey: \"${env:TAILSCALE_AUTH_KEY}\"\n  tailnetDnsName: \"${env:TAILNET_DNS_NAME}\"\n  tailscaleApiKey: \"${env:TAILSCALE_API_KEY}\"\nagents:\n  - name: agent-pm\n    displayName: Juno\n    role: pm\n    identity: \"https://github.com/your-org/army-identities#pm\"\n    volumeSize: 30\n    secrets:\n      slackBotToken: \"${env:PM_SLACK_BOT_TOKEN}\"\n      slackAppToken: \"${env:PM_SLACK_APP_TOKEN}\"\n    plugins:\n      - openclaw-linear\n      - slack\n    deps:\n      - gh\n      - brave-search\n  - name: agent-researcher\n    displayName: Atlas\n    role: researcher\n    identity: \"./my-identities/researcher\"\n    volumeSize: 20\n```\n\nThe `secrets` section uses `${env:VAR}` references — actual values are loaded from a `.env` file at init time. A `.env.example` is generated alongside the manifest. Model, backup model, and coding agent are configured in the identity (not the manifest). The manifest defines _which_ agents to deploy and _where_.\n\n### Pulumi Config\n\nSecrets are stored encrypted in Pulumi config, set automatically by `clawup setup`. You can also manage them directly:\n\n```bash\npulumi config set --secret anthropicApiKey sk-ant-xxxxx\npulumi config set --secret tailscaleAuthKey tskey-auth-xxxxx\npulumi config set tailnetDnsName tail12345.ts.net\n```\n\n### Pulumi ESC\n\nFor more advanced secret management, use [Pulumi ESC](https://www.pulumi.com/docs/esc/). See `esc/clawup-secrets.yaml.example` for the full template.\n\n## Project Structure\n\n```\nclawup/\n├── packages/\n│   ├── core/               # @clawup/core — shared types, constants, registries\n│   │   └── src/\n│   │       ├── schemas/    # Zod schemas (source of truth for types)\n│   │       ├── constants.ts\n│   │       ├── identity.ts # Identity loader (Git repos, local paths)\n│   │       ├── plugin-registry.ts\n│   │       ├── coding-agent-registry.ts\n│   │       ├── dep-registry.ts\n│   │       └── skills.ts\n│   ├── cli/                # clawup CLI (published npm package)\n│   │   ├── bin.ts          # Entry point (Commander.js)\n│   │   ├── commands/       # init, deploy, redeploy, status, ssh, validate, destroy, config, list, push, secrets, webhooks, update\n│   │   ├── tools/          # Tool implementations (adapter-based)\n│   │   ├── lib/            # CLI-only: config, pulumi, ui, tailscale, exec\n│   │   └── adapters/       # Runtime adapters (CLI vs API)\n│   ├── pulumi/             # @clawup/pulumi — infrastructure as code\n│   │   └── src/\n│   │       ├── components/\n│   │       │   ├── openclaw-agent.ts    # AWS EC2 agent component\n│   │       │   ├── hetzner-agent.ts     # Hetzner Cloud agent component\n│   │       │   ├── cloud-init.ts        # Cloud-init script generation\n│   │       │   └── config-generator.ts  # OpenClaw config builder\n│   │       ├── shared-vpc.ts\n│   │       └── index.ts    # Main Pulumi stack program\n│   └── web/                # Next.js dashboard (clawup-web)\n├── identities/             # Built-in identity stubs (point to external repos)\n├── examples/               # Example identities for reference\n│   └── identity/           # Complete \"researcher\" identity example\n├── docs/                   # Documentation (Mintlify site + guides)\n├── esc/                    # Pulumi ESC secret templates\n├── scripts/                # Shell script helpers\n├── Pulumi.yaml             # Pulumi project config (points to packages/pulumi/)\n└── pnpm-workspace.yaml     # Monorepo workspace config\n```\n\n## Security\n\n- All agent ports bind to `127.0.0.1` — access is via **Tailscale only**\n- No public port exposure; Tailscale Serve proxies traffic\n- Token-based gateway authentication\n- Secrets encrypted via Pulumi config\n- Cloud-init scripts use environment variable interpolation\n- SSH available as fallback for debugging\n\n## Troubleshooting\n\n### Agents not appearing in Tailscale\n\n1. Wait 3-5 minutes for cloud-init to complete\n2. Check logs: `clawup ssh \u003cagent\u003e 'sudo cat /var/log/cloud-init-output.log | tail -100'`\n3. Verify your Tailscale auth key is valid and reusable\n\n### OpenClaw gateway not running\n\n```bash\nclawup ssh \u003cagent\u003e 'openclaw gateway status'\nclawup ssh \u003cagent\u003e 'journalctl -u openclaw -n 50'\nclawup ssh \u003cagent\u003e 'openclaw gateway restart'\n```\n\n### SSH connection refused\n\n1. Check Tailscale is running locally: `tailscale status`\n2. Verify the agent appears in your tailnet\n3. Ensure you're using the correct tailnet DNS name\n\n### Pulumi state issues\n\n```bash\npulumi refresh    # Refresh state from actual infrastructure\npulumi cancel     # Force unlock if locked\n```\n\n## Development\n\nFor contributing to Clawup itself:\n\n```bash\ngit clone https://github.com/stepandel/clawup.git\ncd clawup\npnpm install\npnpm build                                # Build all packages\npnpm test                                 # Run all tests\n\n# Individual packages\npnpm --filter @clawup/core build      # Build core\npnpm --filter clawup build            # Build CLI\npnpm --filter @clawup/pulumi build    # Build Pulumi\npnpm --filter clawup-web dev          # Web dev server\n```\n\n## License\n\nMIT\n\n## Related\n\n- [OpenClaw Documentation](https://docs.openclaw.ai/)\n- [Pulumi AWS Provider](https://www.pulumi.com/registry/packages/aws/)\n- [Pulumi Hetzner Provider](https://www.pulumi.com/registry/packages/hcloud/)\n- [Pulumi ESC](https://www.pulumi.com/docs/esc/)\n- [Tailscale Documentation](https://tailscale.com/kb/)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstepandel%2Fclawup","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstepandel%2Fclawup","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstepandel%2Fclawup/lists"}