docs lemcli.md

lemcli field guide

lemcli is the scriptable client for the same LEMC job surfaces people use in the browser. It is the preferred bridge for an agent that needs to discover and call deterministic compute.

Install a release

Use the first-party installer or choose the Linux amd64 or arm64 CLI from the release page. The installer resolves the active release manifest, selects the local architecture, verifies the published SHA-256 value, and refuses an incomplete release.

curl -fsSL https://letemcook.dev/lemcli/install.sh | bash
lemcli version

The installer downloads the platform-qualified artifact, verifies its published SHA-256 digest, renames it to lemcli, and installs it at /usr/local/bin/lemcli so it is available on PATH.

All six native CLI binaries and the Linux AMD64 LEMC server images advance as one release set. The server itself is not yet offered for ARM hosts.

Client and recipe architectures are independent. An ARM64 lemcli asks the selected server for its recipe platform and builds Linux AMD64 by default. ARM64-only recipe images fail before promotion; a multi-platform index must contain a validated AMD64 child digest.

Connect and authenticate

Run bare lemcli or lemcli init. First-use onboarding asks for the LEMC server origin, account, username, and a password with terminal echo disabled. The password is never stored. These are ordinary sequential commands, not alternative setup modes.

lemcli init

LEMC server URL: https://cook.acme.example
Account: acme
Username: jared
Password: ••••••••••••••••
✓ Context "default" is ready

printf '%s\n' "$LEMC_PASSWORD" | \
  lemcli auth login \
    --username owner \
    --password-stdin

lemcli auth whoami --format=json

The stored context tells subsequent commands which server and account to use. Agents should verify identity before discovering or running actions.

Bootstrap a GCP cookbook without exposing its key

Google does not enforce one downloaded key filename. Keep the protected file outside the cookbook's Git checkout, give it the descriptive name gcp-service-account.json, declare only GCP_SERVICE_ACCOUNT_JSON in YAML, and bind the bytes after the remote cookbook exists.

mkdir gcp-server-lifecycle && cd gcp-server-lifecycle
git init
ls -1
cookbook.yaml
terraform/

test -f ../credentials/gcp-service-account.json
chmod 600 ../credentials/gcp-service-account.json

lemcli cookbooks create \
  --name "GCP Server Lifecycle" --format=json

export COOKBOOK_UUID="<returned-cookbook-uuid>"
lemcli cookbooks push "$COOKBOOK_UUID" --file cookbook.yaml
lemcli cookbooks secrets set "$COOKBOOK_UUID" \
  GCP_SERVICE_ACCOUNT_JSON \
  --file ../credentials/gcp-service-account.json

git status --short
# Only cookbook.yaml and terraform/ belong in this checkout.

An agent may write the declaration, inspect names-only binding status, and drive the reviewed server action, but the protected file remains outside the working tree and is supplied through a separate human-controlled input. Cookbook YAML, Git history, command arguments, responses, logs, and artifacts never contain the plaintext value. For a real credential test, prefer the server job: LEMC injects the binding inside the job and returns redacted output. A local lemcli dev run is not an isolation boundary from an unrestricted agent running as the same OS user.

The source checkout also provides maintained GCP and AWS projects in examples/cookbooks/. Their YAML declares only secret names and uses local :dev image references until lemcli cookbooks images push replaces them with managed digests. Run examples/cookbooks/scripts/validate.sh and lemcli dev load … --dry-run before adapting one.

Discover targets and actions

lemcli apps list --format=json
lemcli cookbooks list --format=json

lemcli jobs surface app \
  --uuid "$APP_UUID" \
  --scope individual \
  --format=json

The surface is the machine-readable counterpart to an app page. Read it before submitting.

  • Pages include human-facing title/wiki context.
  • Actions include stable ID, kind, page, scope, recipe, and form fields.
  • Only actions authorized for the current caller should be selectable.
  • The action ID lets jobs run fill page, scope, and recipe without guesswork.

Run and follow

lemcli jobs run app \
  --uuid "$APP_UUID" \
  --action "$ACTION_ID" \
  --set environment=production \
  --follow \
  --follow-timeout 2m \
  --render html \
  --format=json
FlagPurpose
--actionUse a runnable action ID returned by jobs surface.
--setSupply one declared form value as KEY=VALUE; repeat as needed.
--idempotency-keyIdentify an admission retry; generated when omitted.
--followFollow authorized task output over /cli/ws after submission.
--render htmlRender the LEMC HTML verb stream in a terminal-appropriate form.
--format=jsonReturn structured command output for programmatic callers.

Do not pass runner mode, runner ID, or execution mode. Those choices belong to the server/operator.

Inspect the result

Preserve the task ID returned at submission and use it for durable reads.

lemcli jobs status app \
  --uuid "$APP_UUID" \
  --page 1 \
  --scope individual \
  --task-id "$TASK_ID" \
  --format=json

lemcli jobs logs app \
  --uuid "$APP_UUID" \
  --page 1 \
  --scope individual \
  --recipe "check release readiness" \
  --task-id "$TASK_ID"

lemcli jobs artifacts list app \
  --uuid "$APP_UUID" \
  --page 1 \
  --scope individual \
  --task-id "$TASK_ID"

A complete caller checks more than a process exit:

  • submission accepted and task ID recorded;
  • expected system and recipe steps reached terminal state;
  • terminal status and terminal reason agree with the intended outcome;
  • rendered output is complete and user-visible errors are absent;
  • required logs and artifacts exist in durable storage.

Minimal agent loop

list targets
  → inspect surface JSON
    → choose an authorized action
      → validate requested values against its form
        → run with an idempotency key
          → follow events to terminal state
            → inspect status, reason, logs, and artifacts
              → report the task ID and evidence

Keep planning and execution separate. The model can explain why it chose an action; LEMC supplies the evidence for what that action did.