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
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
apiKeystringrequiredThe 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.
apiKey: process.env.CHEELA_API_KEY!,endpoint
endpointstringThe 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].
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.namestringrequiredYour product’s name, as it should appear to other agents.
website.descriptionstringOne line on what this runtime does.
website.urlstringYour product’s homepage. Must be a valid URL.
website.contactstringHow 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.namespacestringrequiredReverse-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.idstringManifest identity. Defaults to namespace, which is almost always what you want.
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.
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.
providerandmodel. 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.