If true, this is a dependency-only block (no command block) Cannot be added directly to recipes, only via depends_on
Examples
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}" 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 command 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 String variables (accessed as ${vars.NAME}) Example: { "USER": "postgres", "DB": "postgres" }
serves Named port configurations (accessed as ${serves.NAME} or legacy ${ports.NAME}) Example: { "PORT": { "port": 5432, "type": "db" }, "ADMIN_PORT": { "port": 5433, "type": "db" } }
paths Named filesystem paths (accessed as ${paths.NAME}) Example: { "DATA_DIR": "/var/lib/postgresql/data", "CONFIG": "/etc/postgresql" }
init 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 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.
Example
allowed_env: - CUSTOM_CONFIG_PATH - MY_API_KEY
Security
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 Environment variables (supports variable interpolation in values) Example: { "POSTGRES_USER": "${vars.USER}", "POSTGRES_DB": "${vars.DB}" }
sources 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 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.
Examples
tools: - java: "21" # Requires Java 21 (Temurin) - go # Requires any Go version - python: "3.11" # Requires Python 3.11 depends_on Block dependencies (loaded before this block) Example: ["stackie.config-loader", "stackie.redis"]
platforms Platform support flags
health_check Health check configuration for monitoring block availability Example: { "type": "tcp", "port": 5432, "interval": 30 }
allow 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 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 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 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 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.
Example F0
consumes 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.
Example
consumes: db: port_type: db # needs any block that serves a db port tool_env 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.
Example
tool_env: JAVA_HOME: linux: "${install_path}" macos: "${install_path}/Contents/Home" windows: "${install_path}" PATH: "${install_path}/bin"
See Also
PlatformOrStringfor the type used as values
tool_license 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.
See Also
ToolLicenseInfofor the type definition
tool_versions Supported versions for stackie tool versions display.
Lists available versions with short aliases for user convenience. Only meaningful on tool: true blocks.
See Also
ToolVersionEntryfor the entry type
tool_dir_name On-disk directory name under ~/.stackie/tools/ for backward compatibility.
Defaults to the block name suffix when not set (e.g., java.sdk → java.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 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 How to combine with default/stack permissions ("merge" or "replace") Default: "merge"
permissions 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.
Example F0
# 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.
YAML Forms
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 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 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 How often to perform health checks (seconds) Default: 30 seconds
timeout How long to wait for response (seconds) Default: 5 seconds
retries Number of consecutive failures before marking unhealthy Default: 3 retries
start_period 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.
Example YAML
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 Handler type: "sql", "shell", or "write_file"
source Source type: "git", "web", or "local" Optional for write_file handler which uses path/content instead
source_config Source configuration Optional for write_file handler which uses path/content instead
files File patterns to process (glob) Optional for write_file handler which uses path/content instead
path Target path for write_file handler Supports variable interpolation (${paths.}, ${vars.}, ${ports.*})
content Content to write for write_file handler Supports variable interpolation (${paths.}, ${vars.}, ${ports.*})
order Execution order (lower = earlier)
continue_on_error Continue executing hooks if this one fails
timeout_secs 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.
Declarative format (preferred)
init: - ensure_dir: "${paths.data}" - copy: from: "${install.config}/app.conf" to: "${paths.config}/app.conf"
Legacy format (deprecated)
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 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 Docker image name aliases that map to this block. Supports both simple strings and extended objects.
code_mount 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 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 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.
YAML Syntax
- ensure_dir: "${paths.data}"
Behavior
- 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.
YAML Syntax
- copy: from: "${install.config}/nginx.conf" to: "${paths.config}/nginx.conf"
Behavior
- 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.
YAML Syntax
- copy_dir: from: "${install.config}/templates" to: "${paths.config}/templates"
Behavior
- 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.
YAML Syntax
- write_file: path: "${paths.config}/server.conf" content: | setting=value port=${ports.HTTP}
Behavior
- 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.
YAML Syntax
- append_file: path: "${paths.data}/pg_hba.conf" content: "host all all 0.0.0.0/0 md5"
Behavior
- 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.
YAML Syntax
- replace_in_file: path: "${paths.config}/jvm.options" pattern: "file=logs/gc.log" replacement: "file=${paths.logs}/gc.log"
Behavior
- 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.
YAML Syntax
- remove: "${paths.logs}/*"
Behavior
- 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.
YAML Syntax
- run: binary: "${install.bin}/kafka-storage.sh" args: ["format", "-t", "${uuid()}", "-c", "${paths.config}/server.properties"]
Behavior
- 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.
YAML Syntax
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}"
Behavior
- Sets environment variables before execution - On Unix: uses
execvp()for process replacement - On Windows: usesspawn()+ 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.
YAML Syntax
- 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}/*"
Behavior
- Evaluates condition (exists or not_exists) - Executes
thenoperations if condition is true - Executeselseoperations 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.
Examples
Plain string (same on all platforms)
tool_env: GOROOT: "${install_path}"
Platform-conditional (macOS Java needs Contents/Home appended)
tool_env: JAVA_HOME: linux: "${install_path}" macos: "${install_path}/Contents/Home" windows: "${install_path}"
See Also
PlatformUrlfor the same pattern applied to download URLs -Block::tool_envfor the field on the Block struct
# PlatformSupport
Platform support flags for blocks
Indicates which operating systems an block can run on.
# PlatformUrl
URL for a specific platform - can be a single string or arch-specific
Examples F0
# PlatformUrls
Platform-specific URL mapping
Maps operating systems to download URLs. Each platform can have either a simple URL or architecture-specific URLs.
Example F0
linux URL(s) for Linux
macos URL(s) for macOS
windows URL(s) for Windows
# PortConfig
Port configuration with number and type
# 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.
# Sha256ArchHashes
Architecture-level SHA256 hashes
# 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
Examples
Level 1: Simple (all platforms use same archive) F0
Level 2: Platform + Architecture specific F1
# Sha256PlatformHashes
Platform-level SHA256 hashes
macos Hashes for macOS (by architecture)
linux Hashes for Linux (by architecture)
windows 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.
Examples
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 Package name in the source system Example: "postgresql" for brew, "@nestjs/core" for npm
version Version or version constraint Example: "15", "^2.1.0", "latest"
cache 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.
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
Examples F0
tap Homebrew tap (optional, used by brew source type) Example: "mongodb/brew", "hashicorp/tap"
Ecosystem type for supercache sources
Required when using supercache source type to specify which ecosystem the package belongs to (go, node, python, java, etc.)
Examples F0
platform_specific 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.
Examples F0
source_url 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 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
Examples F0
repo 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")
Examples F0
archive_pattern 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")
Examples F0
sha256 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.
Examples F0
# 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.
Example YAML
tool_license: name: "GPL v2 with Classpath Exception" url: "https://www.gnu.org/licenses/old-licenses/gpl-2.0.html" publisher: "Adoptium"
See Also
ToolVersionEntryfor version listing -Block::tool_licensefor the field on the Block struct
# 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.
Examples
tools: - java: "21" # Requires Java 21 - go # Requires any Go version - python: "3.11" # Requires Python 3.11
Formats
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.
# 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).
Example YAML
tool_versions: - alias: "21" version: "21.0.4" - alias: "17" version: "17.0.12"
See Also
ToolLicenseInfofor license metadata -Block::tool_versionsfor the field on the Block struct
alias Short alias used in stackie tool install {name} {alias} (e.g., "21", "3.12")
version 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
Examples
Level 1: Simple (all platforms) F0
Level 2: Platform-specific F1
Level 3: Platform + Architecture F2