conduit-ui / cloudflare
Cloudflare management CLI for the Conduit agent ecosystem
Requires
- php: ^8.3
- laravel-zero/framework: ^13.0
- saloonphp/laravel-plugin: ^4.0
- saloonphp/saloon: ^4.0
Requires (Dev)
- laravel/pint: ^1.25.1
- mockery/mockery: ^1.6.12
- pestphp/pest: ^3.8.4|^4.1.2
Suggests
None
Provides
None
Conflicts
None
Replaces
None
- dev-main
- v0.1.0
- dev-cursor/ci-pest-coverage-6412
- dev-cursor/shared-command-base-6412
- dev-cursor/conduit-ecosystem-docs-6412
- dev-cursor/cf-setup-auth-6412
- dev-cursor/dns-tunnel-crud-6412
- dev-cursor/scaffold-cleanup-6412
- dev-cursor/agent-json-contract-6412
- dev-cursor/phar-release-install-6412
- dev-cursor/hero-readme-demo-6412
- dev-cursor/tunnel-expose-workflow-6412
- dev-cursor/fix-composer-lock-6412
This package is auto-updated.
Last update: 2026-09-13 00:48:56 UTC
README
Lightweight Cloudflare management CLI built with Laravel Zero and Saloon.
Installation
Binary (recommended)
Download cf from Releases, then:
chmod +x cf sudo mv cf /usr/local/bin/cf
Requires PHP 8.3+ (zlib). Export CLOUDFLARE_API_TOKEN and CLOUDFLARE_ACCOUNT_ID before running commands.
Composer
composer require conduit-ui/cloudflare
# or globally:
composer global require conduit-ui/cloudflare
From source
git clone https://github.com/conduit-ui/cloudflare.git
cd cloudflare
composer install
Build a local PHAR after composer install with composer build (or php cf app:build cf). Artifact: builds/cf.
Configuration
Run setup first to validate credentials and write .env:
./cf setup
# or non-interactive (agents/CI):
./cf setup --token=cf_xxx --account-id=abc123 --non-interactive
./cf setup --token=cf_xxx --account-id=abc123 --non-interactive --json
You can also copy .env.example and edit by hand:
cp .env.example .env # CLOUDFLARE_API_TOKEN=your_token_here # CLOUDFLARE_ACCOUNT_ID=your_account_id
Get credentials from:
- API Token: https://dash.cloudflare.com/profile/api-tokens
- Account ID: Right sidebar on any zone page
Token Permissions
| Command | Required Permission |
|---|---|
zones |
Zone:Read |
dns:* |
DNS:Edit |
tunnel:* |
Cloudflare Tunnel:Edit |
Agent JSON output
Pass --json for a stable envelope on stdout: {"ok":true,"data":...} on success, {"ok":false,"error":"..."} on failure (exit 0 / 1). See docs/agent-output.md.
Commands
Setup
./cf setup # Interactive auth onboarding
./cf setup --non-interactive --token=... --account-id=...
Zones
./cf zones # List all zones ./cf zones --json # Agent JSON envelope
DNS Records
./cf dns:list <zone> # List records (zone ID or domain) ./cf dns:list jordanpartridge.us --type=A # Filter by type ./cf dns:create <zone> A api 1.2.3.4 # Create A record ./cf dns:create <zone> CNAME www example.com --proxied ./cf dns:update <zone> <id> A api 5.6.7.8 # Update record (PUT) ./cf dns:update <zone> <id> A api 5.6.7.8 --proxied --ttl=300 --json ./cf dns:delete <zone> <id> # Delete record (prompts) ./cf dns:delete <zone> <id> --force --json # Skip confirmation
Tunnels
./cf tunnel:list # List all tunnels ./cf tunnel:get <id> # Get tunnel details ./cf tunnel:get <id> --json ./cf tunnel:create <name> # Create tunnel (prints token/credentials) ./cf tunnel:expose <name> [hostname] [url] # Create + route + cloudflared steps ./cf tunnel:delete <id> # Delete tunnel
Expose a local app
One guided flow: create a tunnel, print the connector token, and (when a hostname is given) attempt remote ingress + DNS CNAME via the API. Falls back to exact cloudflared commands when the API cannot route.
# Default local service: http://localhost:8000 ./cf tunnel:expose my-app # Hostname + custom local URL ./cf tunnel:expose my-app app.example.com http://localhost:3000 # Full create payload (token, credentials_file, routing results) ./cf tunnel:expose my-app app.example.com --json
Then run cloudflared with the printed token:
cloudflared tunnel run --token <token-from-output>
If DNS was not created via API:
cloudflared tunnel route dns my-app app.example.com
tunnel:create masks secrets in the summary table and prints full token / credentials once. Use --json for the agent envelope ({"ok":true,"data":...}).
Architecture
app/
├── Commands/ # CLI commands
├── Integrations/Cloudflare/
│ ├── CloudflareConnector.php # Saloon connector
│ ├── Resources/ # API resource classes
│ └── Requests/ # Individual API requests
Development
PR quality is quality-runners (Pint, Pest, PHPStan, Rector on the clone host). Until that runner is subscribed to this repo, GitHub Actions still runs Pint --test and Pest as a residual. Local ./bin/ci is the full set.
Locally:
composer install ./bin/ci
License
MIT