CLI surface
Every command also responds to afk <command> --help.
Setup and diagnostics
Section titled “Setup and diagnostics”afk init [--provider <aws|gcp|cloudflare|local>] [--region <region>] # one-time setup in a repo (scaffolds config + Backend infra) # --provider defaults to aws; --region applies to provider=aws|gcp # GCP: resolves the project from active gcloud config, creates the GCS state bucket # CF: derives accountId from the token and merges the cloudflare config block # local: writes backend=local + a local config block (no cloud infra)afk provision # stand up the active Backend's infra (idempotent) # AWS: terraform init && apply (VPC, IAM, sweeper Lambda, DynamoDB) # GCP: terraform apply (APIs, VPC+NAT+IAP, SAs, Firestore, Artifact Registry, reconcile Cloud Function) # CF: create D1+KV, migrate, deploy the launcher Worker, set # CF_API_TOKEN, write workerUrl (run after `afk golden build`) # local: no-op (nothing to stand up)afk doctor # check dependencies, Backend creds, Golden Image presence + ageafk config # print resolved config (debug)afk destroy [--yes] # tear down the active Backend's infra # without --yes: dry-run, prints what would be deleted # (per-Backend specifics in each backend doc's Teardown section)Golden Images
Section titled “Golden Images”afk golden build # build the Golden Image for the active Backend # AWS: an AMI tagged afk:golden=true # GCP: a GCE custom image labelled afk-golden=true # CF: a Container image in the CF managed registryafk golden ls # list Golden Images for the active Backendafk golden rm <id-or-tag> # delete a Golden Imageafk build [--ref <ref>] # explicit container image build + push (afk run also builds if needed)afk run <command…> # launch a Run --ref <branch|sha|tag> # defaults to current local branch --instance-type <type> # AWS/GCP: overrides project default EC2 instance type / GCE machine type --on-demand # AWS/GCP: on-demand capacity (pricier, not preemptible; Spot by default) --instance-tier <tier> # CF only: overrides project default CF Containers tier --timeout <hours> # overrides default (4h) --retain # AWS/GCP: keep the instance (stopped) after the Run ends so # `afk attach` can resume it for post-mortem inspection; implies # --on-demand (Spot can't retain), reclaimed after the retention period --follow / -f # stream logs until the Run ends (default: launch and exit)afk session # launch an Interactive Run: a box with no command that you attach into --ref <branch|sha|tag> # same source-clone as `afk run` --instance-type <type> # AWS/GCP machine size --spot # use Spot (On-Demand by default — a reclaim would kill your session) --timeout <hours> # wall-clock cap before reclaim (default 24h) --retain # keep the box (stopped) past its timeout so you can `afk attach` later --detach / -d # launch without attaching (default: auto-attach once RUNNING)afk ls [--all] [--status <s>] # list Runs (yours by default; --all = team-wide if permitted)afk history [--since <duration>] [--branch <b>] # archived Runs from the active Backend's history store # (DynamoDB on AWS, Firestore on GCP, D1 on CF, ~/.afk on Local)afk attach <run-id> [--service <name>] [--host] # interactive shell. Default: docker exec into main service. # --service <name>: attach to a sidecar instead. # --host: drop to the Run's compute-primitive host shell. # On a retained Run (AWS/GCP --retain): resumes the stopped instance # for post-mortem inspection; re-stops it on detach.afk logs <run-id> [--follow] [--service <name>] [--since <duration>] # tail logs from the active Backend's log store # (per-backend storage detail in the backend docs)afk kill <run-id> # terminate the Run's compute primitive (retained or not)afk session-artifact [--out <dir>] <run-id> # download the Run's Session Artifact(s) # writes to ./session-artifacts/ by default; # collected best-effort from the main service at Run end; # Owner-scoped like `afk logs`Secrets
Section titled “Secrets”afk secrets put <name> [value] # write to the active Backend's secret store # - value omitted: prompts on stdin (hidden) OR reads stdin if piped # - inline value: visible in `ps`; prefer stdin for real secretsafk secrets ls # list stored secret namesafk secrets rm <name> # delete from the active Backend's secret storeafk team add <name> [--principal <principal>] # admin: provision a developer on the active Backend --principal <principal> # AWS: optional — trust an existing ARN instead of creating an IAM user # GCP: required — an existing IAM member string to bind the # afk-developer role to (user:… or serviceAccount:…) # CF: n/a — a CF Access service token is created from <name>afk team ls # admin: list membersafk team rm <name> # admin: revoke accessGlobal flags
Section titled “Global flags”--json # machine-readable JSON output--verbose / -v # debug logging--quiet / -q # errors only--local # run this command on the Local Backend (your own Docker # daemon), overriding the persisted backend for this invocationCommand semantics worth knowing
Section titled “Command semantics worth knowing”afk run "<command>"andafk run <command> <args…>both work. The container’s CMD becomessh -c "<joined command>", so quoting and shell features (&&,|,$VARS) work as you’d expect.- The region a cloud command operates on comes from
afk.config.json→aws.region/gcp.region(zone/machine type live in thegcpblock). There is no per-command--regionflag (apart fromafk init, which writes the region into the renderedbackend.tfand scaffolded config). aws,gcp,cloudflare, andlocalBackends are supported; Azure VMs are still anticipated.--localoverrides the persisted backend for one invocation and may appear anywhere on the line.
All AWS calls go through the standard credential chain (AWS_PROFILE, env vars,
IMDS). Developers act under an IAM role provisioned by the Terraform. All
Cloudflare calls go through the launcher Worker, authenticated by a per-developer
Cloudflare Access service token (provisioned by afk team add) — the CLI never
talks to the CF control-plane API directly except during afk init /
afk golden build. The team commands require admin permissions on either
Backend.