clawdforge/clients/bash
Kayos 347fddea0f clients/bash: cf — single-file bash CLI for clawdforge
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
2026-04-28 22:25:50 -07:00
..
cf clients/bash: cf — single-file bash CLI for clawdforge 2026-04-28 22:25:50 -07:00
README.md clients/bash: cf — single-file bash CLI for clawdforge 2026-04-28 22:25:50 -07:00

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).