Tiny curl wrapper so cron jobs, deploy scripts, and shell pipes can drive clawdforge without dragging in Python or Go. Surface mirrors the server: cf healthz cf run "<prompt>" [--model] [--system] [--timeout] [--files t1,t2] cf run - # prompt via stdin (long prompts) cf upload <path> [--ttl 3600] cf admin token-mint <name> [--ip-cidrs cidr1,cidr2] cf admin token-list cf admin token-revoke <name> Configuration via env or ~/.config/clawdforge/cf.env: CLAWDFORGE_URL, CLAWDFORGE_TOKEN, CLAWDFORGE_ADMIN_TOKEN Output: JSON to stdout (pipe to jq freely), errors to stderr, exit codes 0/1/2/3/4/5 mapping clearly to transport/usage/auth/4xx/5xx. No deps beyond curl + POSIX tools. jq is optional (only used for prettier error output if available). Smoke-tested against live clawdforge on Lucy: healthz green, /run with small prompt returns parsed JSON in 2-7s, /run with stdin large prompts relies on clawdforge's server-side stdin path (>64KB), admin token-list returns the cauldron token row. Build/install: sudo install -m 755 clients/bash/cf /usr/local/bin/cf |
||
|---|---|---|
| .. | ||
| cf | ||
| README.md | ||
cf — bash CLI for clawdforge
Single-file shell client for clawdforge. Wraps curl so you
can drive clawdforge from cron jobs, deploy scripts, one-off pipes, or any
shell where pulling in a Python/Go runtime is overkill.
Install
sudo install -m 755 cf /usr/local/bin/cf
Or just symlink into ~/bin:
ln -s "$(pwd)/cf" ~/bin/cf
No dependencies beyond curl + standard POSIX tools. jq is optional —
used for prettier error output if available, never required.
Configuration
Reads from env or ~/.config/clawdforge/cf.env (env wins on conflict):
| Variable | Default | Purpose |
|---|---|---|
CLAWDFORGE_URL |
http://192.168.0.5:8800 |
clawdforge base URL |
CLAWDFORGE_TOKEN |
— | per-app bearer; required for /run, /files |
CLAWDFORGE_ADMIN_TOKEN |
— | bootstrap admin bearer; required for cf admin * |
Example cf.env:
CLAWDFORGE_URL=http://192.168.0.5:8800
CLAWDFORGE_TOKEN=cf_AbCd...
CLAWDFORGE_ADMIN_TOKEN=...
Commands
cf healthz
cf run "<prompt>" [--model sonnet] [--system "..."] [--timeout 60] [--files token1,token2]
cf run - # read prompt from stdin (any size)
cf upload <path> [--ttl 3600]
cf admin token-mint <name> [--ip-cidrs cidr1,cidr2]
cf admin token-list
cf admin token-revoke <name>
Output is JSON to stdout — pipe to jq for shaping. Errors go to stderr.
Exit codes
| Code | Meaning |
|---|---|
| 0 | ok |
| 1 | curl/transport failure |
| 2 | usage error (bad/missing args) |
| 3 | missing required token |
| 4 | HTTP 4xx (auth, not found, bad request) |
| 5 | HTTP 5xx (server / claude failure) |
Examples
Health check in a cron preamble
cf healthz | jq -e '.claude_present' >/dev/null || { echo "clawdforge not ready"; exit 1; }
One-shot prompt with JSON output
cf run 'Reply with JSON: {"city":"Lake Elsinore","feel":"summer"}' --model sonnet \
| jq -r '.result.city'
Long prompt via stdin (anything bigger than the OS argv limit)
cat <<'PROMPT' | cf run - --timeout 180
You are a precise recipe parser. Given the following text…
…
PROMPT
The bash CLI doesn't do anything special for size — it relies on clawdforge's server-side stdin path for prompts > 64KB.
Upload a file then attach it to a run
ft=$(cf upload /tmp/recipe.png --ttl 3600 | jq -r '.file_token')
cf run "extract the recipe from this image as JSON" --files "$ft" --timeout 120
Mint a per-app token
cf admin token-mint johnny5 --ip-cidrs 172.24.0.0/16
# → {"name":"johnny5","token":"cf_...","ip_cidrs":["172.24.0.0/16"]}
Pattern: bash-only no-jq fallback
If you can't install jq, parse with read:
read -r status size < <(cf upload "$path" | grep -o '"file_token":"[^"]*"\|"size":[0-9]*' | tr '\n' ' ')
But really, install jq.
License
Same as the rest of clawdforge (MIT).