Runcastle

Manifest reference

Every field of workflow.json, generated from the manifest schema — the same schema that validates your package locally and at publish time.

Add the $schema field to get editor autocomplete and inline validation:

{
  "$schema": "https://runcastle.dev/schema/v1.json",
  "schemaVersion": 1,
  ...
}

Top-level fields

$schemastringoptional

Optional JSON Schema URL so editors provide autocomplete and inline validation.

schemaVersionnumberrequired

Manifest format version. Always 1 for now.

Allowed values: 1

namestringrequired

Human-readable display name shown on cards and the detail page.

slugstringrequired

URL-safe identifier [a-z0-9-]{3,64}, unique per author; forms the install handle author/slug.

versionstringrequired

Strict semver (e.g. 1.2.0). Versions are immutable — republishing a version is rejected with 409.

descriptionstringrequired

One-paragraph summary (max 280 chars) shown on cards and in search.

licensestringrequired

SPDX license identifier for the package contents (e.g. MIT).

tagsstring[]optional

Up to 8 tags from an open vocabulary, used for browse filters and search.

sandboxProvidersstring[]optional

Sandbox environments the workflow supports (subset of docker | podman | vercel | custom).

Allowed values: docker, podman, vercel, custom

filesstring[]required

Exhaustive list of files the package installs, relative to the package root (all under .sandcastle/).

repositoryDirectorystringoptional

Directory within the repository containing the package, when it isn't at the repo root.

homepagestringoptional

Optional project homepage URL (http(s) only).

postInstallNotesstringoptional

Plain text printed by the CLI after a successful install (printed, never executed).

sandcastle

sandcastleobjectrequired

Compatibility block describing the Sandcastle runtime the workflow targets.

sandcastle.packageNamestringoptional

The orchestration package. Defaults to @ai-hero/sandcastle.

sandcastle.versionRangestringrequired

Semver range of Sandcastle versions the workflow is tested against (e.g. >=0.12.0 <0.13.0).

sandcastle.entrypointstringoptional

Path to the orchestration entrypoint that calls run(). Defaults to .sandcastle/main.ts.

agents

agentsobject[]optional

The agents the workflow orchestrates — declared metadata cross-checked against the entrypoint.

agents[].rolestringrequired

The agent's role name as used in the orchestration code (e.g. planner, implementer, reviewer).

agents[].providerstringrequired

Agent factory / provider used for this role.

Allowed values: claude-code, codex, pi, opencode, cursor, copilot

agents[].modelstringrequired

Model identifier passed to the provider (e.g. claude-opus-4-8).

agents[].parallelbooleanoptional

Whether this role fans out into parallel instances.

env

envobject[]optional

Environment variables the user must provide; cross-checked against .env.example.

env[].namestringrequired

Environment variable name (shell-safe identifier).

env[].requiredbooleanrequired

Whether the workflow fails without this variable set.

env[].descriptionstringoptional

What the variable is for — shown to installers.

disclosures

disclosuresobjectrequired

The declared side-effect surface (hooks, network, shell expansion). Mismatches with detected behavior block publish.

disclosures.hostHooksstring[]optional

Every host.* hook command run on the consumer's machine, verbatim as string literals.

disclosures.sandboxHooksstring[]optional

Every sandbox.* hook command run inside the sandbox, verbatim as string literals.

disclosures.networkAccessstringoptional

Free-text note describing what the workflow accesses over the network.

disclosures.usesShellExpansionbooleanoptional

Whether any prompt file contains !`command` shell-expansion blocks.

topology

topologyobjectoptional

The node/edge graph describing the orchestration shape. Optional — drives the site diagram, cards, and OG images.

topology.nodesobject[]required

Graph nodes — one per agent role or auxiliary step.

topology.nodes[].idstringrequired

Unique node identifier, referenced by edges.

topology.nodes[].rolestring | nullrequired

The agent role this node represents, or null for non-agent nodes (e.g. a git step).

topology.nodes[].labelstringrequired

Display label rendered in the diagram.

topology.nodes[].kindstringoptional

Optional node flavor (e.g. "git") — non-agent nodes get a muted rendering.

topology.nodes[].fanOutbooleanoptional

Marks a node that fans out into parallel instances — rendered as a stacked card.

topology.edgesobject[]required

Directed edges between node ids.

topology.edges[].fromstringrequired

Source node id.

topology.edges[].tostringrequired

Target node id.

topology.edges[].labelstringoptional

Optional edge label (e.g. a condition).

topology.edges[].loopbooleanoptional

Marks a feedback edge (e.g. reviewer sending work back) — rendered dashed.