Skip to main content

Overview

cowboy init creates a project: a directory whose root holds a cowboy.toml manifest. Project commands (cowboy check, cowboy build, cowboy run, cowboy test, cowboy deploy, cowboy actor call <target>, and so on) find the root by walking up from the current directory to the nearest cowboy.toml, then operate on actor targets: named units of Python source that each compile to one deployable actor.

Layout

The examples curriculum projects under examples/core/ have the same shape: a cowboy.toml, one actors/<name>/main.py per actor, and tests/test_<name>.py.

The manifest

The minimal manifest, the one cowboy init writes, is a single line:
schema_version is the only required key. The CLI parses versions 1 through 4 and writes 2 for every new project; [offchain] and uses_offchain need schema 2, [workloads] needs schema 3 and [web] needs schema 4, and each is rejected in an older file with a hint naming the version that unlocks it. Unknown keys anywhere in the file are rejected, so a typo fails at parse time instead of being silently ignored.

Conventional targets

With no [actors.<name>] declarations, targets come from the filesystem: A name that appears in both forms is an error (conventional actor target '<name>' has both a directory and flat entrypoint). Entries under actors/ whose names are not valid target names are ignored, and symlinked entrypoints are refused. A project can hold at most 64 targets. Target names match [a-z][a-z0-9_]* and are at most 64 bytes. cowboy init <actor> additionally refuses Python keywords and the reserved names actors, main, offchain and tests.

Explicit targets

Declare a target when its entrypoint does not follow the convention, or when it needs library roots:
In schema 2 an explicit declaration takes precedence over a conventional target of the same name and the two kinds can coexist. In schema 1 a name that is both conventional and declared is an error (target '<name>' is both conventional and explicitly configured).

Off-chain configuration

cowboy init --offchain adds an [offchain] table. An empty table selects the defaults: the Python runtime (CPython 3.12), the offchain/ package as the context, the runner’s default resource class, and the offchain-images CBFS volume for the project’s image deltas. The optional keys:
volumes also accepts the shorthand volumes = ["scratch:rw"], a name:mode entry (ro, rw or wo) resolved under the calling actor. At most 8 volumes are allowed. A target that imports from the offchain package is inferred to use off-chain functions even when the manifest has no [offchain] table; the defaults then apply.

Selecting a target

Commands that take a TARGET argument resolve it in this order:
  1. The name you pass (cowboy deploy hello).
  2. Otherwise, the single target whose source_root contains the current directory.
  3. Otherwise, the project’s only target.
  4. Otherwise an error: project contains no actor targets, or actor target is ambiguous; discovered: billing, hello. Run \deploy billing“.
In a one-actor project cowboy deploy, cowboy check and cowboy actor inspect therefore need no argument at all.

Local state under .cowboy/

.cowboy/ is per-developer state and is git-ignored by the scaffold:
  • config.json: environments (rpc_url, key, optional watchtower_registry and identity) and which one is active. Written by cowboy init --env, cowboy env add, cowboy env use and cowboy deploy --env. See Key auto-discovery.
  • No key is kept here: each environment’s key names a key in the CLI keystore, ~/.cowboy/keys/<name> (default default), written by cowboy wallet create. A leftover .cowboy/key is not read, and a project that keeps one while naming no key is refused (key_unavailable, project_key_file).
  • deploy/<env>/<target>.project.json: the latest and any pending deployment of a target on an environment. Commands that take a project target (cowboy actor call hello, cowboy actor inspect hello) resolve the actor’s address from this record for the active environment.
  • local/offchain-env: the worker environment for native off-chain runs.
  • Build output from cowboy build, which the scaffolded pyproject.toml excludes from ruff and basedpyright.
Of the files these commands write, only offchain.lock (written by cowboy build at the project root) is meant to be committed.