Skip to content

v0.5.0

Choose a tag to compare

@jrandolf jrandolf released this 24 Feb 21:01
· 14 commits to main since this release
627a3dc

Earl v0.5.0 is a milestone release that fundamentally expands how you manage multi-environment configurations and enterprise secrets — while making the whole experience faster and more robust. Named environments let a single template target production, staging, and local dev without duplicating a line of HCL. Five external secret-manager backends mean secrets can live in 1Password, Vault, AWS, GCP, or Azure and flow into your templates with zero changes to the call site. A compiled catalog cache makes CLI startup near-instant, Bash sandboxes gained hard memory and CPU limits, and optional parameters now cleanly omit themselves from requests rather than sending empty strings. On top of all that, a new Recall.ai template and a full suite of agent skills round out the release. There's something here for every Earl user.


✨ New Features

Named Environments

Define named variable sets at the provider level and switch between them with a single flag. One template, one command, every environment — no copy-paste required.

version  = 1
provider = "myapi"

environments {
  default = "production"
  secrets = ["myapi.prod_token", "myapi.staging_token"]

  production {
    base_url = "https://api.myservice.com"
    token    = "{{ secrets['myapi.prod_token'] }}"
  }

  staging {
    base_url = "https://staging.myservice.com"
    token    = "{{ secrets['myapi.staging_token'] }}"
  }
}

command "list_widgets" {
  title   = "List widgets"
  summary = "Fetch all widgets for the current account"

  operation {
    protocol = "http"
    method   = "GET"
    url      = "{{ vars.base_url }}/widgets"

    auth {
      kind   = "bearer"
      secret = "{{ vars.token }}"
    }
  }
}
# Hit staging
earl call --env staging myapi.list_widgets

# Hit production (default)
earl call --yes --json myapi.list_widgets

Resolution order: --env flag → [environments] default in config.toml → template default → none. Commands that need a fundamentally different operation for an environment (different URL shape, different protocol) can use per-command environment override blocks.

External Secret Manager Support

Secrets no longer have to live in the OS keychain. Five backends are now available, each behind a URI scheme:

Backend URI scheme
1Password Connect op://vault/item/field
HashiCorp Vault vault://host/secret/path
AWS Secrets Manager aws://region/secret-name
GCP Secret Manager gcp://project/secret/version
Azure Key Vault az://vault-name/secret-name

Just reference the URI wherever you'd use a plain secret name:

annotations {
  secrets = ["op://Engineering/GitHub Token/credential"]
}

auth {
  kind   = "bearer"
  secret = "op://Engineering/GitHub Token/credential"
}

Plain secret names (no ://) continue to use the OS keychain — fully backward compatible. All URI path segments are validated at load time to prevent injection.

Compiled Catalog Cache

Earl now persists a compiled, rkyv-serialized snapshot of your template catalog to ~/.cache/earl/catalog-N.bin. On subsequent invocations, if nothing has changed, the catalog loads in microseconds instead of re-parsing every .hcl file. The cache invalidates automatically whenever any file's mtime changes, and a safe atomic temp-file + rename write prevents corruption.

Bash Sandbox Resource Limits

Bash protocol templates can now cap memory and CPU usage in addition to wall-clock time and output size:

command "run_analysis" {
  operation {
    protocol = "bash"

    bash {
      script = "python3 /opt/scripts/analyse.py {{ args.input_file }}"
    }

    sandbox {
      max_time_ms      = 30000   # wall-clock limit
      max_cpu_time_ms  = 10000   # CPU time limit (RLIMIT_CPU)
      max_memory_bytes = 134217728  # 128 MB address-space cap (RLIMIT_AS)
      max_output_bytes = 1048576    # 1 MB stdout limit
    }
  }
}

Limits follow the existing most-restrictive-wins policy between per-template values and global config.toml settings.

Recall.ai Integration

A full 14-command template for Recall.ai is now bundled — covering bot creation, scheduling, status polling, recording control, transcript retrieval, and more. An accompanying agent skill gives AI agents step-by-step guidance for the record → wait → transcribe workflow.

Earl Agent Skills Suite

Five new agent skills shipped for common onboarding and maintenance tasks:

  • setup-earl — installs Earl and wires up MCP in one shot
  • create-template — scaffolds a new HCL template from a description
  • migrate-to-earl — converts existing curl/fetch calls into Earl templates
  • troubleshoot-earl — diagnoses keychain, template, and MCP issues
  • secure-agent — reviews templates for security best practices

⚡ Improvements

Graceful Optional Parameters

Optional parameters without defaults no longer appear as empty strings in requests. Earl now uses UndefinedBehavior::Chainable in the Jinja environment so undefined optional params evaluate to null, and null values are silently omitted from query strings and headers. The | default('') workarounds that littered example templates are gone. Additionally, all args.IDENT references in a template are validated against declared params at load time — typos are caught immediately, not at the moment an agent fires the call.


🐛 Bug Fixes

  • Fixed a race condition in 1Password env-var resolver tests when run in parallel (--test-threads contention on the same env-var key).
  • Fixed release workflow: replaced a non-existent peter-evans/workflow-dispatch action with a direct gh CLI call.
  • Made crate publishing idempotent — re-running the release workflow no longer fails when a version already exists on crates.io.

Install / Upgrade

# Shell one-liner (macOS & Linux)
curl -fsSL https://raw.githubusercontent.com/brwse/earl/main/scripts/install.sh | bash

# Or via cargo
cargo install earl

Full documentation at brwse.github.io/earl.