{"_id":"@aehrt55/create-moltbot-env","_rev":"3-d1abbc27e2bf46e472250b68e6354905","name":"@aehrt55/create-moltbot-env","dist-tags":{"latest":"0.2.0"},"versions":{"0.1.0":{"name":"@aehrt55/create-moltbot-env","version":"0.1.0","keywords":["moltbot","openclaw","cloudflare-workers","scaffold","cli"],"author":{"name":"aehrt55"},"license":"MIT","_id":"@aehrt55/create-moltbot-env@0.1.0","maintainers":[{"name":"aehrt55","email":"aehrt55@aehrt55.net"}],"bin":{"create-moltbot-env":"dist/index.js"},"dist":{"shasum":"3fb7dc3f0995f141f57cf4f85a55f9673e29cece","tarball":"https://registry.npmjs.org/@aehrt55/create-moltbot-env/-/create-moltbot-env-0.1.0.tgz","fileCount":21,"integrity":"sha512-PBL8CXnbdSRFVf2evsI3sZppUatlv6lGTkVxEYECiVxBXi/FBSZI6N5RYj/XzxrpB6b0gNRd8v7NFMUXNA7sMQ==","signatures":[{"sig":"MEUCIQDcQSw2i7zl9YZMWjFNbi2OcU8rRzZ4EUnVq6N6O5q4rwIgfoKyrfasrh6zjTJhIseBGUtPXitSqpJ8in/eSEOj78U=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":56086},"type":"module","gitHead":"9aabf5c01750f5ea9ae7b875b97bead3651b426d","scripts":{"build":"tsup src/index.ts src/diff.ts --format esm","prepublishOnly":"npm run build"},"_npmUser":{"name":"aehrt55","email":"aehrt55@aehrt55.net"},"_npmVersion":"11.6.2","description":"Scaffold a moltbot-env GitOps repository for deploying OpenClaw on Cloudflare Workers","directories":{},"_nodeVersion":"24.13.0","dependencies":{"ejs":"^3.1.10","chalk":"^5.4.1","prompts":"^2.4.2"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.4.0","@types/ejs":"^3.1.5","typescript":"^5.7.3","@types/node":"^22.13.4","@types/prompts":"^2.4.9"},"_npmOperationalInternal":{"tmp":"tmp/create-moltbot-env_0.1.0_1771850484466_0.7121678654432664","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@aehrt55/create-moltbot-env","version":"0.1.1","keywords":["moltbot","openclaw","cloudflare-workers","scaffold","cli"],"author":{"name":"aehrt55"},"license":"MIT","_id":"@aehrt55/create-moltbot-env@0.1.1","maintainers":[{"name":"aehrt55","email":"aehrt55@aehrt55.net"}],"bin":{"create-moltbot-env":"dist/index.js"},"dist":{"shasum":"9f65b3ee2d19e0bc149a3f9cd77843aca9141f28","tarball":"https://registry.npmjs.org/@aehrt55/create-moltbot-env/-/create-moltbot-env-0.1.1.tgz","fileCount":22,"integrity":"sha512-j4P2i45Gb84sDjsut2y2S+mPgKhcYBeC3rsmcO/VbrB7REbfsAmXn+7SaHvC+c36D0ksjlO84QKDPmYbHWB/7Q==","signatures":[{"sig":"MEUCIAi5Yz5TP3eKPoNJIf4oaFtQzrzDbTeSp5wkKFNL29qEAiEA9ywrJFjcqntLa5otR6WYSDf3ZmFZSqj3y/AMFRj4LK4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":63372},"type":"module","gitHead":"7769e7aa481904af568ef01b81dcf954ba6ae873","scripts":{"build":"tsup src/index.ts src/diff.ts --format esm","prepublishOnly":"npm run build"},"_npmUser":{"name":"aehrt55","email":"aehrt55@aehrt55.net"},"_npmVersion":"11.6.2","description":"Scaffold a moltbot-env GitOps repository for deploying OpenClaw on Cloudflare Workers","directories":{},"_nodeVersion":"24.13.0","dependencies":{"ejs":"^3.1.10","chalk":"^5.4.1","prompts":"^2.4.2"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.4.0","@types/ejs":"^3.1.5","typescript":"^5.7.3","@types/node":"^22.13.4","@types/prompts":"^2.4.9"},"_npmOperationalInternal":{"tmp":"tmp/create-moltbot-env_0.1.1_1771850718437_0.6049004635015627","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@aehrt55/create-moltbot-env","version":"0.2.0","description":"Scaffold a moltbot-env GitOps repository for deploying OpenClaw on Cloudflare Workers","type":"module","bin":{"create-moltbot-env":"dist/index.js"},"scripts":{"build":"tsup src/index.ts src/diff.ts --format esm","prepublishOnly":"npm run build"},"keywords":["moltbot","openclaw","cloudflare-workers","scaffold","cli"],"author":{"name":"aehrt55"},"license":"MIT","dependencies":{"chalk":"^5.4.1","ejs":"^3.1.10","prompts":"^2.4.2"},"devDependencies":{"@types/ejs":"^3.1.5","@types/node":"^22.13.4","@types/prompts":"^2.4.9","tsup":"^8.4.0","typescript":"^5.7.3"},"gitHead":"d29cdf4abc190232ca5d417ad760b7106d3c6fad","_id":"@aehrt55/create-moltbot-env@0.2.0","_nodeVersion":"24.13.0","_npmVersion":"11.6.2","dist":{"integrity":"sha512-WERt0L0nDwEE5XYpkOQOXumrrcs7UwCJRdxgStsDXwWqg/6PYZ/Qt7PASVvK43fOvjP6TKHqT2L1kPP5NPRzsg==","shasum":"8e9c5d1dd98fd3e73b3a502308f06cfe622134fd","tarball":"https://registry.npmjs.org/@aehrt55/create-moltbot-env/-/create-moltbot-env-0.2.0.tgz","fileCount":28,"unpackedSize":104854,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCVX1Qp/uOf8A/12yy59Eg0XFP37Mv046B6h08/tMQDXwIhAJHc3x0NeBncUrviOx3Yim1DLuEhjH1ksvJinqzBxTBF"}]},"_npmUser":{"name":"aehrt55","email":"aehrt55@aehrt55.net"},"directories":{},"maintainers":[{"name":"aehrt55","email":"aehrt55@aehrt55.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/create-moltbot-env_0.2.0_1772002284324_0.76427705737267"},"_hasShrinkwrap":false}},"time":{"created":"2026-02-23T12:41:24.362Z","modified":"2026-02-25T06:51:24.603Z","0.1.0":"2026-02-23T12:41:24.613Z","0.1.1":"2026-02-23T12:45:18.570Z","0.2.0":"2026-02-25T06:51:24.496Z"},"author":{"name":"aehrt55"},"license":"MIT","keywords":["moltbot","openclaw","cloudflare-workers","scaffold","cli"],"description":"Scaffold a moltbot-env GitOps repository for deploying OpenClaw on Cloudflare Workers","maintainers":[{"name":"aehrt55","email":"aehrt55@aehrt55.net"}],"readme":"# create-moltbot-env\n\nScaffold a GitOps environment repository for deploying [moltbot-app](https://github.com/aehrt55/moltbot-app) on Cloudflare Workers.\n\n```bash\nnpx @aehrt55/create-moltbot-env\n```\n\n## What It Does\n\nGenerates a complete `moltbot-env` repository with:\n\n- **Overlay pattern** — per-environment config directories (`overlays/<env>/`) with Wrangler config, pinned app version, and SOPS-encrypted secrets\n- **Make targets** — deploy, secret management, wrangler commands, CF Access sync\n- **Shell scripts** — create/delete environments, deploy pipeline, Access app reconciliation\n- **Claude Code commands** — `/create-env`, `/delete-env`, `/upgrade` for agent-assisted operations\n- **Secret management** — SOPS + AGE encryption with multi-recipient support\n\n## Prerequisites\n\nInstall these before running:\n\n```bash\nbrew install sops age node jq\nnpm install -g wrangler\n```\n\n## Usage\n\n```bash\nnpx @aehrt55/create-moltbot-env\n```\n\nThe CLI walks you through these prompts:\n\n| Prompt | Example | Notes |\n|--------|---------|-------|\n| Project directory name | `moltbot-env` | Must not already exist |\n| Cloudflare Account ID | `cc38da97...` | 32-character hex, from [CF dashboard](https://dash.cloudflare.com/) |\n| Workers subdomain | `myteam` | Your `*.myteam.workers.dev` subdomain |\n| CF Access team domain | `myteam.cloudflareaccess.com` | Auto-derived from subdomain |\n| Access policy email | `you@example.com` | Email for initial Access allow-list |\n| App repo git URL | `git@github.com:aehrt55/moltbot-app.git` | Default provided |\n| Generate AGE key pair? | `Y` | Creates manager key for secret encryption |\n\nOn completion, the CLI:\n1. Renders all templates with your values\n2. Optionally generates an AGE key pair and saves to macOS Keychain\n3. Initializes a git repo with an initial commit\n\n## Generated Repository\n\n```\nmoltbot-env/\n├── Makefile                         # Shared make targets\n├── .sops.yaml                       # SOPS encryption rules (empty initially)\n├── .moltbot-env-meta.json           # Version tracking for upgrades\n├── overlays/                        # Per-environment directories (created via create-env.sh)\n├── scripts/\n│   ├── create-env.sh                # Create: R2 bucket + CF Access + overlay\n│   ├── delete-env.sh                # Delete: reverse of create-env\n│   ├── deploy.sh                    # Clone app → merge config → wrangler deploy\n│   ├── sync-access.sh               # Reconcile CF Access webhook bypass apps\n│   └── jsonc-strip.js               # JSONC → JSON converter\n├── docs/\n│   ├── cf-api-token.md              # How to create CF Access API token\n│   └── sops-age.md                  # SOPS + AGE guide\n└── .claude/commands/\n    ├── create-env.md                # Claude Code: guided environment creation\n    ├── delete-env.md                # Claude Code: guided environment deletion\n    └── upgrade.md                   # Claude Code: agent-native upgrade\n```\n\n## Quick Start\n\nAfter scaffolding:\n\n```bash\ncd moltbot-env\nnpx wrangler login\n```\n\n### Create your first environment\n\nThe `create-env.sh` script requires a `CF_ACCESS_API_TOKEN` for Cloudflare Access API calls. Create one at [CF API Tokens](https://dash.cloudflare.com/profile/api-tokens) with **Account > Access: Apps and Policies > Edit** permission. See `docs/cf-api-token.md` for details.\n\n```bash\nCF_ACCESS_API_TOKEN=\"<token>\" bash scripts/create-env.sh my-env\n```\n\nThis creates:\n- R2 bucket (`moltbot-my-env-data`)\n- Cloudflare Access app with email policy\n- Overlay directory with `wrangler.jsonc`, `version.txt`, Makefile symlink\n- `.sops.yaml` rule for the new environment\n\n### Create and encrypt secrets\n\n```bash\ncd overlays/my-env\nmake edit-secrets    # Opens $EDITOR with decrypted JSON; re-encrypts on save\n```\n\n### Deploy\n\n```bash\ncd overlays/my-env\nmake deploy          # Clone app → npm ci → merge config → wrangler deploy → push secrets\n```\n\n### Using with Claude Code\n\nIf you use [Claude Code](https://claude.ai/code), the generated repo includes slash commands:\n\n- `/create-env` — guided environment creation (collects info, runs script, creates secrets)\n- `/delete-env` — guided environment deletion with confirmation\n- `/upgrade` — apply migrations from newer CLI versions\n\n## Secret Management with SOPS + AGE\n\nSecrets are stored as SOPS-encrypted JSON files (`overlays/<env>/secrets.json`) using [AGE](https://github.com/FiloSottile/age) encryption, committed directly to git.\n\n### How it works\n\nEach environment's `secrets.json` is encrypted to multiple AGE recipients:\n\n- **Manager key** — your personal key, decrypts all environments\n- **Env key** — per-environment key for CI/CD, decrypts only that environment\n\n```yaml\n# .sops.yaml\ncreation_rules:\n  - path_regex: overlays/my-env/secrets\\.json$\n    age: >-\n      age1abc...env_key,\n      age1xyz...manager_key\n```\n\n### Initial setup (one-time)\n\nThe scaffold CLI can generate the manager key pair automatically. If you chose to generate one, it's already saved to macOS Keychain. Add this to `~/.zshrc`:\n\n```bash\nexport SOPS_AGE_KEY=$(security find-generic-password -a \"sops-age\" -s \"sops-age-key\" -w 2>/dev/null)\n```\n\nIf you skipped key generation during scaffold, create one manually:\n\n```bash\nage-keygen\n# Save private key (AGE-SECRET-KEY-1...) to Keychain:\nsecurity add-generic-password -a \"sops-age\" -s \"sops-age-key\" -w \"AGE-SECRET-KEY-1...\"\n```\n\n### Daily operations\n\nAll commands run from an overlay directory (`cd overlays/<env>`):\n\n```bash\nmake edit-secrets                # Edit secrets (opens $EDITOR, re-encrypts on save)\nmake push-secrets                # Push decrypted secrets to Cloudflare Workers\nmake deploy                      # Full deploy (code + secrets)\nsops decrypt secrets.json | jq . # View secrets (read-only)\n```\n\n### Adding a new manager\n\n1. New manager runs `age-keygen` and shares their public key\n2. Add the public key to every rule in `.sops.yaml`\n3. Re-encrypt all environments:\n   ```bash\n   sops updatekeys overlays/<env>/secrets.json\n   ```\n\n### CI/CD keys\n\nEach environment can have a dedicated AGE key for CI/CD:\n\n1. `age-keygen` — save private key as CI/CD secret (`SOPS_AGE_KEY`)\n2. Add public key to the environment's `.sops.yaml` rule\n3. `sops updatekeys overlays/<env>/secrets.json`\n\n### Troubleshooting\n\n| Error | Cause | Fix |\n|-------|-------|-----|\n| `no matching creation rules found` | SOPS can't find a rule for the file | Run from repo root; check `.sops.yaml` has the env's `path_regex` |\n| `could not decrypt data key` | Your private key can't decrypt this file | Verify `SOPS_AGE_KEY` is set; ensure your public key is in `.sops.yaml`; run `sops updatekeys` if newly added |\n\n## Upgrading\n\nWhen a new version of this CLI is released with template changes, upgrade your existing repo:\n\n```bash\n# Check for available migrations\nnpx @aehrt55/create-moltbot-env diff\n\n# Or use Claude Code\n/upgrade\n```\n\nThe `diff` subcommand reads `.moltbot-env-meta.json` in your repo, compares against the latest CLI version, and outputs migration instructions as markdown. Claude Code's `/upgrade` command runs this automatically and applies changes semantically.\n\n## License\n\nMIT\n","readmeFilename":"README.md"}