Cheela Labs
REFERENCE

Configuration

cheela.config.ts is evaluated through tsx at deploy time, after .env is loaded. defineConfig is a type helper with no hidden behaviour.

The file

cheela.config.ts
import { defineConfig } from "@cheela/cli";

export default defineConfig({
  apiKey: process.env.CHEELA_API_KEY!,
  endpoint: "https://app.example.com/cheela/execute",
  runtime: ".cheela/runtime.ts",

  website: {
    name: "Acme Storefront",
    description: "Order lookup and catalog search for Acme.",
    url: "https://www.acme.com",
    contact: "support@acme.com",
  },

  adp: {
    namespace: "com.acme",
  },

  generators: {
    disabled: [],
  },
});

It must default-export the config object. Validation failures list every failing field with its own message rather than stopping at the first.

apiKey

apiKeystringrequired

The runtime’s deploy key, starting ch_sk_. Authorises cheela deploy and cheela status.

Read it from the environment. Committing it lets anyone overwrite your runtime’s capability set.

TypeScript
apiKey: process.env.CHEELA_API_KEY!,

endpoint

endpointstring

The public HTTPS address where this runtime serves capability calls, e.g. https://app.example.com/cheela/execute. Published with the deployment.

Optional here only because passing endpoint to POST /v1/runtimes at registration is the alternative. A runtime with neither cannot receive capability requests.

Must be an absolute URL using https://. http:// is accepted only for localhost, 127.0.0.1, and [::1].

Why https is enforced

The request signature protects integrity, not confidentiality. Capability inputs, outputs, and the end user’s credential travel in the request body. For a local runtime, use a tunnel rather than plain HTTP.

runtime

runtimestringdefault ".cheela/runtime.ts"

Path to the module exporting your Runtime, relative to the project root.

The module must default-export a Runtime, or export one named runtime. Anything else fails with a message naming the path it tried.

website

Descriptive information about your product, used to build the public capability manifest. Required if you publish one.

website.namestringrequired

Your product’s name, as it should appear to other agents.

website.descriptionstring

One line on what this runtime does.

website.urlstring

Your product’s homepage. Must be a valid URL.

website.contactstring

How to reach you about the capabilities — usually an email address.

This maps to the manifest’s provider block, where “provider” means who operates the system. It has nothing to do with model providers.

adp

Agent Discovery Specification settings.

adp.namespacestringrequired

Reverse-DNS style prefix, e.g. com.acme. Published capability names are built as namespace.capability.

Required if the adp block is present at all. This is where the dots the specification needs come from — capability names themselves may not contain any.

adp.idstring

Manifest identity. Defaults to namespace, which is almost always what you want.

There is no endpoint field here

The address the world calls to reach a capability is the broker’s, and only the control plane knows it. Asking for it produced manifests advertising placeholder addresses, because it reads like the top-level endpoint above — which points the opposite way.

generators

generators.disabledstring[]

Built-in generators to skip, by name: capability-manifest, runtime-manifest, openapi, adp.

generators.customGenerator[]

Additional generators, appended to the built-ins rather than replacing them.

Each needs a name, an inputs() function used for cache invalidation, and a generate() function returning files. A name colliding with an existing generator is an error, not an override.

TypeScript
generators: {
  disabled: ["openapi"],
  custom: [
    {
      name: "typed-client",
      inputs: (context) => context.capabilities.map((c) => c.capability.name),
      generate: (context) => [
        { path: "typed-client/client.ts", contents: render(context.capabilities) },
      ],
    },
  ],
},

Functions are not schema-validatable data, so custom generators are structurally checked at load time instead — a value that is not generator-shaped is rejected with a message saying which methods were missing.

Fields that do not exist

Two are conspicuously missing, and both were removed rather than never added.

  • provider and model. Executions run on Cheela’s own OpenRouter credential so tokens can be metered and billed. A runtime choosing its own model would be choosing how much Cheela pays. The registration API rejects these too, rather than accepting a live credential and silently dropping it.
  • tier. Your plan is a billing fact about your account, not something a deployment request gets to assert.

Older examples may still show provider and model in a config block. They are no longer valid — remove them. See Architecture for why.