Examples

Simple block

Minimal ingredient — a multi-source package that exposes one port and runs a single command.

# stackie.redis.yml
stackie.redis:
  # Package sources — Stackie tries each in order until one succeeds
  sources:
    brew:                  # macOS / Linux: install via Homebrew
      name: redis
      version: latest
    scoop:                 # Windows: install via Scoop
      name: redis
      version: latest

  # Named ports — users reference as ${serves.PORT}; also whitelisted in the sandbox
  serves:
    PORT:
      port: 6379
      type: db

  # Main process — supervised and restarted on failure
  command:
    - "redis-server"
    - "--port"
    - "${serves.PORT}"
Full-featured block

Production-grade ingredient with multi-source install, init steps, named paths, environment variables, a health check, and sandbox permissions.

# stackie.postgres.yml
stackie.postgres:
  # Package sources — Stackie tries each in order until one succeeds
  sources:
    system:                # Primary: pre-built binary from supercache CDN
      name: postgres
      version: "18.3"
    brew:                  # Fallback: Homebrew (macOS / Linux)
      name: postgresql
      version: latest

  # Named string variables — override per stack node with vars:
  vars:
    USER: "postgres"
    DB: "postgres"
    PASSWORD: "postgres"

  # Named ports — access as ${serves.PORT} inside command / init / environment
  serves:
    PORT:
      port: 5432
      type: db

  # Named filesystem paths — resolved at runtime against the sandbox data directory
  paths:
    data: "/var/lib/postgresql/data"

  environment:
    POSTGRES_USER: "${vars.USER}"
    POSTGRES_DB: "${vars.DB}"
    POSTGRES_PASSWORD: "${vars.PASSWORD}"
    PGDATA: "${paths.data}"

  # One-time setup — runs only when the cluster does not yet exist
  init:
    - if:
        not_exists: "${paths.data}/PG_VERSION"
        then:
          - run:
              binary: "initdb"
              args: ["-D", "${paths.data}", "-U", "${vars.USER}", "--encoding=UTF8"]
          - append_file:
              path: "${paths.data}/pg_hba.conf"
              content: "host all all 127.0.0.1/32 md5\n"

  # Main process — Stackie supervises this and restarts it on failure
  command:
    - "postgres"
    - "-D"
    - "${paths.data}"
    - "-p"
    - "${serves.PORT}"

  # Health check — Stackie waits until this passes before marking the block healthy
  health_check:
    type: command
    command: ["pg_isready", "-h", "127.0.0.1", "-p", "${serves.PORT}", "-U", "${vars.USER}"]
    interval: 10
    timeout: 5
    retries: 10
    start_period: 5

  # Sandbox permissions — PostgreSQL creates socket files in /tmp
  allow:
    mode: "merge"
    permissions:
      - path: "/tmp"
        mode: "rw"

Block YAML Format

Reference for Stackie block YAML files generated from the Rust Serde contract.

Top-Level Shape

A block file contains one stackie.* top-level key. That key becomes Block.name.

YAML key stackie.<block-name>
Value type Block

Block Fields

A block defines how a single service is installed, configured, and run on each platform.

Blocks published to the stackie. namespace (e.g., stackie.postgres) are managed through the Stackie ingredient registry and supercache CDN — they install in seconds with no source compilation. First-party blocks (any name not starting with stackie. or gateway.) describe services you own and run from a local path:. Gateway blocks (gateway.) proxy cloud provider APIs into your local stack.

# tool
boolean|null optional

If true, this is a dependency-only block (no command block) Cannot be added directly to recipes, only via depends_on

# command
CommandSpec|null optional

Command to execute (supports variable interpolation) Can be: array of strings, single string, or object with posix/windows scripts Example: ["postgres", "-D", "${paths.DATA_DIR}", "-p", "${ports.PORT}"] Example: { "posix": "#!/bin/sh\nmkdir -p /tmp", "windows": "mkdir C:\\tmp" }

# vars
object|null optional

String variables (accessed as ${vars.NAME}) Example: { "USER": "postgres", "DB": "postgres" }

# serves
object|null optional

Named port configurations (accessed as ${serves.NAME} or legacy ${ports.NAME}) Example: { "PORT": { "port": 5432, "type": "db" }, "ADMIN_PORT": { "port": 5433, "type": "db" } }

# paths
object|null optional

Named filesystem paths (accessed as ${paths.NAME}) Example: { "DATA_DIR": "/var/lib/postgresql/data", "CONFIG": "/etc/postgresql" }

# init
InitSection|null optional

Initialization operations or commands (run once on first start).

Supports two formats:

New declarative format (preferred): Cross-platform operations executed natively in Rust. F0

Legacy format (deprecated, for backward compatibility): Platform-specific shell commands. F1

# allowed_env
array|null optional

Environment variables allowed for ${env()} interpolation.

In addition to built-in safe variables (PATH, HOME, JAVA_HOME, etc.), blocks can declare additional environment variables they need access to. This provides a whitelist mechanism for environment variable access in declarative operations.

allowed_env: - CUSTOM_CONFIG_PATH - MY_API_KEY 

Only variables in the built-in safe list OR declared here can be accessed via ${env(VAR_NAME)} interpolation. This prevents accidental leakage of sensitive environment variables.

# environment
object|null optional

Environment variables (supports variable interpolation in values) Example: { "POSTGRES_USER": "${vars.USER}", "POSTGRES_DB": "${vars.DB}" }

# sources
object|null optional

Package sources for multi-source support (dependency tree system) Maps source names (e.g., "brew", "npm") to package definitions Example: { "brew": { "name": "postgresql", "version": "latest" } }

# tools
array|null optional

Runtime tool requirements for this block.

Declares tools that must be installed before this block can run. Stackie will automatically install these tools if they're not present.

tools: - java: "21"      # Requires Java 21 (Temurin) - go              # Requires any Go version - python: "3.11"  # Requires Python 3.11 
# depends_on
array|null optional

Block dependencies (loaded before this block) Example: ["stackie.config-loader", "stackie.redis"]

# platforms
PlatformSupport|null optional

Platform support flags

# health_check
HealthCheck|null optional

Health check configuration for monitoring block availability Example: { "type": "tcp", "port": 5432, "interval": 30 }

# allow
AllowBlock|null optional

Additional sandbox permissions (use sparingly) Defines non-standard filesystem permissions required by this block. Only use for exceptional cases where block needs access beyond default sandbox policy. Example: { "mode": "merge", "permissions": [{ "path": "/bin", "mode": "rx" }] }

# mocker
MockerConfig|null optional

Mocker configuration for Docker Engine API compatibility. Maps Docker image names to this Stackie block, enabling docker CLI drop-in replacement. Example: { "images": ["postgres", "library/postgres"], "version_regex": "^(\\d+\\.\\d+)" }

# runtime
boolean|null optional

Marks this block as a language runtime that can host user code.

When true, the user-code detector treats this block as a candidate for Pattern A (bind-mount + command) and Pattern B (Dockerfile FROM) translation. Runtime blocks must set mocker.code_mount to indicate the expected mount path.

Not a security boundary — the sandbox decision is made by the caller.

Example: true for Node.js, Python, Go SDK blocks.

# emoji
string|null optional

Optional emoji icon for CLI display. Should be a single unicode emoji character that represents this block. Example: "🐘" for PostgreSQL, "🔴" for Redis, "🐬" for MySQL

# default_hooks
object|null optional

Default lifecycle hooks for all instances of this block

These hooks run automatically at lifecycle points unless overridden. Stack-level hooks can extend or replace these defaults.

# consumes
map<string, ConsumesEntry> optional

Default consumes declarations: services this block needs at runtime.

Declares the types of services this block requires when used in a managed stack. The pipeline integration reads these and auto-wires the connections using type-based matching. Stack-level consumes: overrides take precedence.

consumes: db: port_type: db   # needs any block that serves a db port 
# tool_env
object|null optional

Environment variables to set when this tool is active.

Keys are environment variable names (e.g., JAVA_HOME, GOROOT). Values support ${install_path} interpolation and can be platform-conditional for cases like macOS Java which needs Contents/Home appended to the install path.

Only meaningful on tool: true blocks.

tool_env: JAVA_HOME: linux: "${install_path}" macos: "${install_path}/Contents/Home" windows: "${install_path}" PATH: "${install_path}/bin" 
  • PlatformOrString for the type used as values
# tool_license
ToolLicenseInfo|null optional

License metadata for pre-flight acceptance prompts.

When set, stackie will prompt the user to accept the license before installing this tool. Only meaningful on tool: true blocks.

  • ToolLicenseInfo for the type definition
# tool_versions
array|null optional

Supported versions for stackie tool versions display.

Lists available versions with short aliases for user convenience. Only meaningful on tool: true blocks.

  • ToolVersionEntry for the entry type
# tool_dir_name
string|null optional

On-disk directory name under ~/.stackie/tools/ for backward compatibility.

Defaults to the block name suffix when not set (e.g., java.sdkjava.sdk). Set this to preserve existing tool installations when a block is renamed or to match a legacy naming convention.

For example: the java.sdk block sets this to "temurin" so that existing Temurin installations at ~/.stackie/tools/temurin/ are preserved.

Only meaningful on tool: true blocks.

Validation Rules

block.definition · Block

Block definition validation

Validate invariants for a parsed block definition.

This rule enforces the Stackie block namespace, requires at least one package source for registry-backed blocks, and validates any custom sandbox permission declarations.

Nested Types

# AllowBlock

Sandbox permission block with merge/replace semantics

Defines additional sandbox permissions required by an block. Can be merged with default permissions or replace them entirely.

# mode
string optional

How to combine with default/stack permissions ("merge" or "replace") Default: "merge"

# permissions
array<SandboxPermission> required

List of filesystem paths with permission modes

# ArchUrls

Architecture-specific URL mapping

Maps CPU architectures to download URLs. Use when a package has different binaries for different architectures.

# amd64
string|null optional

URL for x86_64/amd64 architecture

# arm64
string|null optional

URL for aarch64/arm64 architecture

# CommandSpec

Command specification for blocks

Supports three formats: 1. Simple array: cross-platform binary command with arguments 2. Single string: cross-platform single command 3. Platform-specific: object with posix and windows shell scripts

# ConsumesEntry

Describes how a block consumes a port served by another block in the stack. Appears in the consumes: map of a block node under a logical name (e.g., DB). The interpolation engine resolves ${consumes.DB} to the actual port number.

String shorthand — the value is used as the block name:

consumes: db: neon                     # ${consumes.db.PORT} storage: stackie.minio       # ${consumes.storage.API} 

Typed struct — provides additional filtering options:

consumes: db: { port_type: db }              # match any block with a db-type port store: { block_override: stackie.minio }  # explicit block reference 
# port_type
string|null optional

Filters the consumed port by type (e.g., "db", "web"). When set, only ports matching this type are considered. When omitted, any port from the matched block is accepted.

# block_override
string|null optional

Explicitly names the block that provides this port, bypassing automatic resolution. Also set automatically when the string shorthand form is used (e.g., db: neon sets block_override to "neon").

If both block_override and port_type are set, block_override selects the block and port_type filters which port within it is used.

# Ecosystem

Value Description
"go"

Go compiled binaries (always platform-specific)

"node"

Node.js packages (Next.js standalone builds, etc.) May be universal or platform-specific depending on native dependencies

"system"

System binaries (brew, apt, etc. - compiled for target platform)

"elixir"

Elixir/Erlang packages

"rust"

Rust packages (crates)

"python"

Python packages (pip/pypi)

"java"

Java/JVM packages

"bespoke"

Bespoke/custom packages that don't fit other categories

# HealthCheck

Health check configuration

Defines how to verify that a sandbox is running and healthy. Used by the daemon to monitor sandbox status.

# interval
integer optional

How often to perform health checks (seconds) Default: 30 seconds

# timeout
integer optional

How long to wait for response (seconds) Default: 5 seconds

# retries
integer optional

Number of consecutive failures before marking unhealthy Default: 3 retries

# start_period
integer optional

Grace period before starting health checks (seconds) Allows time for sandbox to initialize Default: 0 seconds

Accepted shapes

Execute a command and check exit code Example: { "type": "command", "command": ["pg_isready", "-h", "localhost"] }

required: <code class="icode">command</code>, <code class="icode">type</code>

Check HTTP endpoint Example: { "type": "http", "url": "http://localhost:8080/health" }

required: <code class="icode">type</code>, <code class="icode">url</code>

Check TCP port connectivity Example: { "type": "tcp", "port": 5432 } or { "type": "tcp", "port": "${ports.PORT}" }

required: <code class="icode">port</code>, <code class="icode">type</code>

Check if a process is running by name Example: { "type": "process", "process_name": "postgres" }

required: <code class="icode">process_name</code>, <code class="icode">type</code>

# HookDefinition

Runs a handler (sql or shell) against files fetched from a source (git, web, or local) after block initialisation completes.

after_init: - handler: sql source: type: git url: "https://github.com/supabase/postgres" reference: "v15.1.0.117" files: - "migrations/db/init-scripts/*.sql" order: 1 timeout_secs: 120 
# handler
string required

Handler type: "sql", "shell", or "write_file"

# source
string optional

Source type: "git", "web", or "local" Optional for write_file handler which uses path/content instead

# source_config
SourceConfig optional

Source configuration Optional for write_file handler which uses path/content instead

# files
array<string> optional

File patterns to process (glob) Optional for write_file handler which uses path/content instead

# path
string|null optional

Target path for write_file handler Supports variable interpolation (${paths.}, ${vars.}, ${ports.*})

# content
string|null optional

Content to write for write_file handler Supports variable interpolation (${paths.}, ${vars.}, ${ports.*})

# order
integer optional

Execution order (lower = earlier)

# continue_on_error
boolean optional

Continue executing hooks if this one fails

# timeout_secs
integer|null optional

Timeout for this hook in seconds

# InitSection

One-time setup steps that run before the block starts for the first time. Use the declarative format for all new blocks.

init: - ensure_dir: "${paths.data}" - copy: from: "${install.config}/app.conf" to: "${paths.config}/app.conf" 
init: - posix: mkdir -p ${paths.data} windows: if not exist "${paths.data}" mkdir "${paths.data}" 

# MockerConfig

Maps Docker image names to this block, enabling Docker CLI and docker-compose to work transparently with Stackie's Docker Engine API.

mocker: version_regex: "^(\\d+(?:\\.\\d+)*)" images: - postgres - name: library/postgres version_regex: "^(\\d+)" - name: docker.io/library/postgres 
# version_regex
string|null optional

Default regex for extracting version from Docker image tags. Applied to all images unless overridden. Example: ^(\d+(?:\.\d+)*) extracts "15.2" from "postgres:15.2-alpine"

# images
array<MockerImage> optional

Docker image name aliases that map to this block. Supports both simple strings and extended objects.

# code_mount
string|null optional

Container path where user source code is mounted.

When non-None, this block is treated as a user-code runtime block. The user-code detector uses this path to validate bind-mount targets (Pattern A) and to set the default working directory for translated blocks.

Example: /app for Node.js, /workspace for Go.

# default_command
array|null optional

Default entrypoint command for runtime blocks.

When a container or pod is started with this block's image but no explicit command, this default is used by the user-code detector translation.

Example: ["node", "index.js"] for Node.js, ["python", "main.py"] for Python.

# run_whitelist
array|null optional

Package manager commands that mocker is allowed to execute during Dockerfile RUN interception (Tier-1 whitelist).

Only argv[0] is matched. Commands not in this list produce a Tier-2 diagnostic pointing users at tools:.

Example: ["npm", "yarn", "pnpm", "npx"] for Node.js.

# MockerImage

An entry in mocker.images. Use a plain string for the common case; use the extended object form to override version_regex for a specific image.

# Simple — image name only images: - postgres - redis

# Extended — override version_regex for this image images: - name: postgres version_regex: "^(\\d+)" - name: library/postgres version_regex: "^(\\d+\\.\\d+)" 

# Operation

A single step in an init: sequence. Operations run in order before the block starts for the first time.

init: - ensure_dir: "${paths.data}" - copy: from: "${install.config}/app.conf" to: "${paths.config}/app.conf" - run: binary: "${install.bin}/init-db.sh" unless_exists: "${paths.data}/initialized" - if: not_exists: "${paths.data}/initialized" then: - ensure_dir: "${paths.data}/sub" 

Accepted shapes

Create a directory and all parent directories if they don't exist.

Equivalent to mkdir -p on Unix systems.

- ensure_dir: "${paths.data}" 
  • Creates the directory and all missing parent directories - No error if the directory already exists - Path is validated against sandbox boundaries before creation

required: <code class="icode">ensure_dir</code>

Copy a single file from source to destination.

Equivalent to cp on Unix systems.

- copy: from: "${install.config}/nginx.conf" to: "${paths.config}/nginx.conf" 
  • Overwrites destination if it exists - Creates parent directories of destination automatically - Preserves file permissions on Unix

required: <code class="icode">copy</code>

Recursively copy a directory from source to destination.

Equivalent to cp -r on Unix systems.

- copy_dir: from: "${install.config}/templates" to: "${paths.config}/templates" 
  • Recursively copies all contents - Copies symlinks as symlinks (does not follow) - Overwrites existing files

required: <code class="icode">copy_dir</code>

Write content to a file, overwriting if it exists.

Equivalent to cat > file on Unix systems.

- write_file: path: "${paths.config}/server.conf" content: | setting=value port=${ports.HTTP} 
  • Creates parent directories automatically - Overwrites file if it exists - Uses UTF-8 encoding

required: <code class="icode">write_file</code>

Append content to a file, creating it if it doesn't exist.

Equivalent to echo >> file on Unix systems.

- append_file: path: "${paths.data}/pg_hba.conf" content: "host all all 0.0.0.0/0 md5" 
  • Creates file if it doesn't exist - Appends content to end of file - Uses UTF-8 encoding

required: <code class="icode">append_file</code>

Replace text in a file using regex pattern matching.

Equivalent to sed -i on Unix systems.

- replace_in_file: path: "${paths.config}/jvm.options" pattern: "file=logs/gc.log" replacement: "file=${paths.logs}/gc.log" 
  • In-place replacement (no backup file created) - Pattern is a regular expression - Replaces all occurrences in the file

required: <code class="icode">replace_in_file</code>

Remove a file or directory.

Equivalent to rm -rf on Unix systems.

- remove: "${paths.logs}/*" 
  • Supports glob patterns for matching multiple files - No error if path doesn't exist - Removes symlink itself, not the target - Removes directories recursively

required: <code class="icode">remove</code>

Execute a binary and wait for completion.

Used for initialization scripts that need to run before the main service starts.

- run: binary: "${install.bin}/kafka-storage.sh" args: ["format", "-t", "${uuid()}", "-c", "${paths.config}/server.properties"] 
  • Executes binary with provided arguments - Waits for completion - Returns error if exit code is non-zero - Captures stdout/stderr for logging - Optional working directory for command execution

required: <code class="icode">run</code>

Execute a binary with environment variable mapping (for command: section).

This operation is used in the command: section when environment variables need to be set before executing the main service process.

command: - exec: binary: "${install.bin}/elasticsearch" env: ES_JAVA_HOME: "${env(JAVA_HOME)}" ES_TMPDIR: "${paths.tmp}" args: - "-Ehttp.port=${ports.HTTP}" - "-Epath.data=${paths.data}" 
  • Sets environment variables before execution - On Unix: uses execvp() for process replacement - On Windows: uses spawn() + wait (transparent to YAML author) - Never returns on success (becomes the service process)

required: <code class="icode">exec</code>

Conditional execution based on file/directory existence.

Allows branching logic in initialization based on whether a path exists.

- if: not_exists: "${paths.data}/initialized" then: - run: binary: "${install.bin}/init.sh" - write_file: path: "${paths.data}/initialized" content: "true" else: - remove: "${paths.logs}/*" 
  • Evaluates condition (exists or not_exists) - Executes then operations if condition is true - Executes else operations if condition is false (optional) - Supports nested conditionals

required: <code class="icode">if</code>

# PlatformOrString

An environment variable value that can be either a plain string or platform-conditional.

Mirrors the pattern used by sources.web.url for per-platform URL specification, but applied to environment variable values in Block::tool_env.

tool_env: GOROOT: "${install_path}" 
tool_env: JAVA_HOME: linux: "${install_path}" macos: "${install_path}/Contents/Home" windows: "${install_path}" 
  • PlatformUrl for the same pattern applied to download URLs - Block::tool_env for the field on the Block struct

# PlatformSupport

Platform support flags for blocks

Indicates which operating systems an block can run on.

# macos
boolean optional
# windows
boolean optional
# linux
boolean optional

# PlatformUrl

URL for a specific platform - can be a single string or arch-specific

# PlatformUrls

Platform-specific URL mapping

Maps operating systems to download URLs. Each platform can have either a simple URL or architecture-specific URLs.

# linux
PlatformUrl|null optional

URL(s) for Linux

# macos
PlatformUrl|null optional

URL(s) for macOS

# windows
PlatformUrl|null optional

URL(s) for Windows

# PortConfig

Port configuration with number and type

# port
integer required

Port number

# type
PortType|null optional

Port type classification (optional, defaults to None for backward compatibility)

# PortType

Port type classification

Value Description
"web"

Web service port (HTTP, HTTPS, WebSocket, etc.)

"db"

Database port

"admin"

Administration/management port

"api"

API endpoint port

"metrics"

Metrics/monitoring port (Prometheus, StatsD, etc.)

"grpc"

gRPC service port

"messaging"

Message queue/broker port (AMQP, MQTT, STOMP, etc.)

"misc"

Miscellaneous port

# SandboxPermission

Sandbox permission for block-level access control

Defines filesystem paths that require non-standard sandbox permissions beyond the default sandbox policy. Use sparingly - only for exceptional cases where an block needs specific system access.

# path
string required

Absolute filesystem path

# mode
string required

Permission mode: combination of r/w/x (e.g., "rwx", "rx", "r")

# Sha256ArchHashes

Architecture-level SHA256 hashes

# amd64
string|null optional

Hash for AMD64/x86_64 architecture

# arm64
string|null optional

Hash for ARM64/aarch64 architecture

# Sha256Hash

SHA256 hash specification for archive verification

Supports two levels of granularity: 1. Simple: Single hash for all platforms (when same archive for all) 2. Platform/Arch: Different hashes per platform and architecture

# Sha256PlatformHashes

Platform-level SHA256 hashes

# macos
Sha256ArchHashes|null optional

Hashes for macOS (by architecture)

# linux
Sha256ArchHashes|null optional

Hashes for Linux (by architecture)

# windows
Sha256ArchHashes|null optional

Hashes for Windows (by architecture)

# SourceConfig

Content source configuration for hooks

Defines where to fetch hook content from. Each variant maps to a ContentSource implementation in the handlers module.

use stackie::hooks::SourceConfig;

// Git source for upstream scripts let git = SourceConfig::Git { url: "https://github.com/supabase/postgres".to_string(), reference: Some("v15.1.0.117".to_string()), sparse_paths: None, };

// Local source for custom scripts let local = SourceConfig::Local { path: "/opt/stackie/scripts".to_string(), }; 

Accepted shapes

Fetch content from a Git repository

Uses the GitSource implementation which: - Clones/fetches the repository - Checks out the specified reference - Reads files from the working tree

required: <code class="icode">type</code>, <code class="icode">url</code>

Fetch content from a web URL

Uses the WebContentSource which: - Downloads files via HTTP/HTTPS - Supports basic authentication - Caches downloaded content

required: <code class="icode">type</code>, <code class="icode">url</code>

Read content from local filesystem

Uses the LocalContentSource which: - Reads files from the specified directory - Supports glob patterns - Fast and reliable for local scripts

required: <code class="icode">path</code>, <code class="icode">type</code>

No external source - content is provided inline

Used by handlers like write_file that don't fetch content from an external source but instead receive content directly in the hook definition.

required: <code class="icode">type</code>

# SourceDefinition

Source definition for a package manager within an block

This represents how an block can be installed from a specific source. For example, postgres might have a brew source with package name "postgresql" and version "15".

# name
string required

Package name in the source system Example: "postgresql" for brew, "@nestjs/core" for npm

# version
string required

Version or version constraint Example: "15", "^2.1.0", "latest"

# cache
boolean optional

Whether this source should be cached on the supercache CDN

Defaults to true. When enabled, stackie will check the supercache CDN first before falling back to the direct source URL. This provides faster, more reliable downloads through a nearby CDN.

Set to false to opt out of CDN caching for sources that should always be fetched directly from upstream (e.g., rapidly changing packages).

Package manager sources (brew, scoop, pip, etc.) ignore this field as they are inherently non-cacheable.

# url
WebUrl|null optional

Download URL for web sources (optional, used by web source type)

Supports three formats: - Simple string: Same URL for all platforms - Platform map: Different URLs per OS - Platform+Arch map: Different URLs per OS and architecture

# tap
string|null optional

Homebrew tap (optional, used by brew source type) Example: "mongodb/brew", "hashicorp/tap"

# ecosystem
Ecosystem|null optional

Ecosystem type for supercache sources

Required when using supercache source type to specify which ecosystem the package belongs to (go, node, python, java, etc.)

# platform_specific
boolean|null optional

Override whether this package is platform-specific

When set, overrides the ecosystem's default platform-specificity. Use this for Node packages with native dependencies that require platform-specific builds.

# source_url
string|null optional

Source URL for fallback compilation (optional)

For Go packages: The Go module path used for go install when falling back from cached binaries to source compilation. Example: "github.com/supabase/auth", "github.com/traefik/traefik/v3"

For other ecosystems: May be used for source compilation fallback.

# after_install
array|null optional

Commands to run after installation completes

These commands run in the installation directory after the source has been downloaded/installed. Useful for: - Running npm install for Node.js projects - Running npm run build to compile TypeScript - Running pip install -r requirements.txt for Python projects - Any post-installation setup required before the package can be used

# repo
string|null optional

GitHub repository for github-releases source (owner/repo format)

Used by the github-releases source type to construct download URLs. Format: "owner/repo" (e.g., "PostgREST/postgrest")

# archive_pattern
string|null optional

Archive filename pattern for github-releases source

Supports placeholders: - {version} - version tag (e.g., "v12.2.8") - {platform} - platform name (e.g., "linux", "macos", "windows") - {arch} - architecture (e.g., "x86_64", "aarch64")

# sha256
Sha256Hash|null optional

SHA256 hash verification for downloaded archives

Supports two formats: - Simple string: Single hash for all platforms (when URL is same for all) - Platform/arch map: Different hashes for different platform/arch combinations

Required for github-releases source. Optional but recommended for web source.

# StringOrU16

A value that can be either a string or a u16 (for port numbers that support variable interpolation)

This allows YAML health check ports to be specified as either: - Numeric: port: 6379 - Variable reference: port: "${ports.PORT}"

Accepted shapes

A numeric port value

required: <code class="icode">Number</code>

A string that may contain variable references like "${ports.PORT}"

required: <code class="icode">String</code>

# ToolLicenseInfo

License metadata for tool blocks requiring acceptance prompts.

Stores the minimal information needed to display a license acceptance prompt before a tool is installed. Use tool_license on tool: true blocks to require explicit user acceptance before installation.

tool_license: name: "GPL v2 with Classpath Exception" url: "https://www.gnu.org/licenses/old-licenses/gpl-2.0.html" publisher: "Adoptium" 
  • ToolVersionEntry for version listing - Block::tool_license for the field on the Block struct
# name
string required

Human-readable license name (e.g., "MIT License", "GPL v2 with CE")

# url
string required

URL to the full license text

# publisher
string required

Publisher or organisation that holds the license (e.g., "Adoptium", "Microsoft")

# ToolRequirement

A runtime tool requirement for a block.

Blocks can declare tool requirements to ensure the necessary runtime environment is available before the block starts.

tools: - java: "21"      # Requires Java 21 - go              # Requires any Go version - python: "3.11"  # Requires Python 3.11 

Supports two YAML formats: - String format: - java (tool name only, any version) - Map format: - java: "21" (tool name with specific version)

The tool name is stored as a plain string and validated against TOOL_REGISTRY at runtime.

# tool_name
string required

The tool name, e.g. "java", "python", "node", "go", "erlang". Normalised from aliases: "temurin" is stored as "java".

# version
string|null optional

Optional version requirement (e.g., "21", "3.11").

# ToolVersionEntry

A supported version entry for stackie tool versions display.

Provides both a short alias (for user input) and the full version string (for download URL construction and version pinning).

tool_versions: - alias: "21" version: "21.0.4" - alias: "17" version: "17.0.12" 
  • ToolLicenseInfo for license metadata - Block::tool_versions for the field on the Block struct
# alias
string required

Short alias used in stackie tool install {name} {alias} (e.g., "21", "3.12")

# version
PlatformOrString required

Full version string used in download URLs, or platform-conditional version map.

Plain strings work as before. Use a platform map when a version is unavailable on a specific OS (e.g., Erlang OTP 28 has no macOS Intel builds):

- alias: "28" version: linux: "28.0.0" macos: "27.2.4" windows: "28.0.0" 

# WebUrl

URL specification for web sources

Supports three levels of granularity: 1. Simple: Single URL for all platforms/architectures (e.g., Java JARs) 2. Platform: Different URLs per platform (linux, macos, windows) 3. Full: Different URLs per platform AND architecture