Invowkfile Schema Reference
:::warning Alpha — Schema May Change The invowkfile schema is still evolving. Fields, types, and validation rules may change between releases as we stabilize the format. Always check the changelog when upgrading. :::
Complete reference for the invowkfile schema. Invowkfiles use CUE format for defining commands. Invowkfiles are validated as closed structs, so unknown fields cause a validation error.
Root Structure
Every invowkfile must define at least one command in cmds:
#Invowkfile: {
default_shell?: string // Optional - override default shell
workdir?: string // Optional - default working directory
env?: #EnvConfig // Optional - global environment
depends_on?: #DependsOn // Optional - global dependencies
cmds: [...#Command] // Required - at least one command
}
:::note Module Metadata Lives in invowkmod.cue
Fields like module, version, description, and requires belong in invowkmod.cue and are rejected in invowkfile.cue.
:::
default_shell
Type: string
Required: No
Default: System default
Override the default shell for native runtime execution.
default_shell: "/bin/bash"
default_shell: "pwsh"
workdir
Type: string
Required: No
Default: Invowkfile directory
Default working directory for all commands. Can be absolute or relative to the invowkfile location. When present, the value must contain at least one non-whitespace character.
workdir: "./src"
workdir: "/opt/app"
env
Type: #EnvConfig
Required: No
Global environment configuration applied to all commands. See EnvConfig.
depends_on
Type: #DependsOn
Required: No
Global dependencies that apply to all commands. See DependsOn.
cmds
Type: [...#Command]
Required: Yes (at least one)
List of commands defined in this invowkfile. See Command.
:::caution Migration Note
The field name is cmds, not commands. Using commands will cause a CUE validation error because the invowkfile schema is closed and commands is not a supported field.
:::
Command
Defines an executable command:
#Command: {
name: string // Required
description?: string // Optional
category?: string // Optional - groups in listing
implementations: [...#Implementation] // Required - at least one
env?: #EnvConfig // Optional
workdir?: string // Optional
depends_on?: #DependsOn // Optional
flags?: [...#Flag] // Optional
args?: [...#Argument] // Optional
watch?: #WatchConfig // Optional - file-watching
}
name
Type: string (pattern: ^[a-zA-Z][a-zA-Z0-9_ -]*$)
Required: Yes
The command identifier. Must start with a letter.
name: "build"
name: "test unit" // Spaces allowed for subcommand-like behavior
name: "deploy-prod"
description
Type: string
Required: No
Help text for the command. When provided, it must be non-empty (validated by regex pattern ^\s*\S.*$ -- whitespace-only strings are rejected).
description: "Build the application for production"
category
Type: string
Required: No
Groups this command under a heading in invowk cmd listing output. When provided, it must be non-empty (validated by regex pattern ^\s*\S.*$ — whitespace-only strings are rejected).
cmds: [
{
name: "build"
category: "Development"
implementations: [...]
},
{
name: "test unit"
category: "Development"
implementations: [...]
},
{
name: "deploy"
category: "Operations"
implementations: [...]
},
]
implementations
Type: [...#Implementation]
Required: Yes (at least one)
The executable implementations. See Implementation.
env
Type: #EnvConfig
Required: No
Environment configuration for this command. Command-level env is applied before implementation-level env. See EnvConfig.
workdir
Type: string
Required: No
Working directory for command execution. Overrides root-level workdir but can be overridden by implementation-level workdir. Can be absolute or relative to the invowkfile location.
depends_on
Type: #DependsOn
Required: No
Dependencies that must be satisfied before running this command. See DependsOn.
flags
Type: [...#Flag]
Required: No
Command-line flags for this command. See Flag.
:::warning Reserved Flags The following flags are reserved by invowk and cannot be used in user-defined commands:
ivk-env-file(-e),ivk-env-var(-E)ivk-env-inherit-mode,ivk-env-inherit-allow,ivk-env-inherit-denyivk-workdir(-w),ivk-runtime(-r),ivk-from(-f)ivk-force-rebuild,ivk-container-name,ivk-dry-runivk-watch(-W)ivk-verbose(-v),ivk-config(-c),ivk-interactive(-i)help(-h),version
Additionally, any flag starting with the ivk-, invowk-, or i- prefix is reserved for system flags.
:::
args
Type: [...#Argument]
Required: No
Positional arguments for this command. See Argument.
watch
Type: #WatchConfig
Required: No
File-watching configuration for this command. When defined, patterns controls which files are watched. When --ivk-watch is passed without a watch config, invowk falls back to watching all files (**/*) in the working directory. See WatchConfig.
{
name: "dev"
description: "Run development server with auto-reload"
watch: {
patterns: ["src/**/*.go", "*.go"]
debounce: "1s"
clear_screen: true
ignore: ["vendor/**"]
}
implementations: [{
script: {content: "go run ./cmd/server"}
runtimes: [{name: "native"}]
platforms: [{name: "linux"}, {name: "macos"}]
}]
}
Implementation
Defines how a command is executed:
#Implementation: {
script: #ImplementationScript // Required - content or file
runtimes: [...#RuntimeConfig] & [_, ...] // Required - runtime configurations
platforms: [...#PlatformConfig] & [_, ...] // Required - at least one platform
env?: #EnvConfig // Optional
workdir?: string // Optional
depends_on?: #DependsOn // Optional
timeout?: #DurationString // Optional - max execution time
}
script
Type: closed object with exactly one of content or file, plus optional interpreter
Required: Yes
The executable script source. Use script.content for inline shell text and module-contained script.file references inside invowk modules. Root/project invowkfiles cannot use script.file; old script: "..." strings are rejected. Use script.interpreter to explicitly run the resolved script content with Python, Node.js, Ruby, PowerShell, or another supported interpreter.
// Inline script
script: {content: "echo 'Hello, World!'"}
// Multi-line script
script: {content: """
echo "Building..."
go build -o app .
echo "Done!"
"""}
// Explicit interpreter on inline script
script: {content: "print('hello')", interpreter: "python3"}
// Module-contained script file reference
script: {file: "scripts/build.sh"}
script: {file: "scripts/deploy.py", interpreter: "python3"}
script.interpreter
Type: string
Available for: implementation scripts and custom check scripts
Default: "auto" (detect from shebang)
Specifies how to execute the resolved script content. The value may be auto or a supported interpreter such as python3, node, pwsh, or /usr/bin/env perl -w. Runtime configs do not accept interpreter.
A concrete script.interpreter takes precedence over shebang detection. If it differs from the resolved script's shebang interpreter or arguments, invowk validate and --ivk-dry-run report an advisory warning while keeping validation successful. Omitted script.interpreter and interpreter: "auto" are shebang-driven and do not warn.
// Auto-detect from shebang
script: {content: """
#!/usr/bin/env python3
print("hello")
""", interpreter: "auto"}
// Specific interpreter
script: {content: "print('hello')", interpreter: "python3"}
script: {content: "console.log('hello')", interpreter: "node"}
script: {content: "puts 'hello'", interpreter: "/usr/bin/ruby"}
// With arguments
script: {content: "print('hello')", interpreter: "python3 -u"}
script: {content: "print qq(hello\n)", interpreter: "/usr/bin/env perl -w"}
runtimes
Type: [...#RuntimeConfig]
Required: Yes (at least one)
The runtimes that can execute this implementation. The first runtime is the default.
// Native only
runtimes: [{name: "native"}]
platforms: [{name: "linux"}, {name: "macos"}]
// Multiple runtimes
runtimes: [
{name: "native"},
{name: "virtual-sh"},
]
platforms: [{name: "linux"}, {name: "macos"}]
// Container with options
runtimes: [{
name: "container"
image: "debian:stable-slim"
volumes: ["./:/app"]
}]
platforms: [{name: "linux"}]
platforms
Type: [...#PlatformConfig]
Required: Yes (at least one)
Specify which operating systems this implementation supports. Platform entries can also carry virtual-runtime filesystem settings for that OS through virtual.filesystem.
// Linux and macOS only
platforms: [
{name: "linux"},
{name: "macos"},
]
env
Type: #EnvConfig
Required: No
Environment configuration for this implementation. Merged with command-level env: implementation files are loaded after command-level files, and implementation vars override command-level vars. See EnvConfig.
workdir
Type: string
Required: No
Working directory for this implementation. Overrides both root-level and command-level workdir settings. Can be absolute or relative to the invowkfile location.
depends_on
Type: #DependsOn
Required: No
Dependencies that must be satisfied before running this implementation. Combined with root-level and command-level depends_on. Always validated against the host system, regardless of the selected runtime. To validate dependencies inside the runtime's environment (e.g., inside a container), use depends_on inside the runtime block instead. See DependsOn.
timeout
Type: #DurationString
Required: No
Maximum execution duration. Must be a valid Go duration string (e.g., "30s", "5m", "1h30m"). When exceeded, the command is cancelled and returns a timeout error. The timeout value is validated early (before dependency checks) to fail fast on invalid values. See DurationString.
{
name: "build"
implementations: [{
script: {content: "make build"}
runtimes: [{name: "native"}]
platforms: [{name: "linux"}, {name: "macos"}]
timeout: "5m"
}]
}
RuntimeConfig
Configuration for a specific runtime:
// Shared base fields (all runtimes)
#RuntimeConfigBase: {
name: #RuntimeType
env_inherit_mode?: "none" | "allow" | "all"
env_inherit_allow?: [...string] // Requires env_inherit_mode: "allow"
env_inherit_deny?: [...string]
}
// Native runtime: no additional fields
#RuntimeConfigNative: close({
#RuntimeConfigBase
name: "native"
})
// Virtual-sh runtime
#RuntimeConfigVirtualSh: close({
#RuntimeConfigBase
name: "virtual-sh"
allowed_binaries?: [...string]
binary_lookup_mode?: "host" | "strict"
})
// Virtual-lua runtime
#RuntimeConfigVirtualLua: close({
#RuntimeConfigBase
name: "virtual-lua"
allowed_binaries?: [...string]
binary_lookup_mode?: "host" | "strict"
cpu_limit?: uint
memory_limit?: string
})
// Container runtime: exactly one source + extras
#RuntimeConfigContainerBase: {
#RuntimeConfigBase
name: "container"
enable_host_ssh?: bool
volumes?: [...string]
ports?: [...string]
depends_on?: #DependsOn // validated inside the container environment
}
#RuntimeConfigContainerWithImage: close({
#RuntimeConfigContainerBase
image: string
containerfile?: _|_
})
#RuntimeConfigContainerWithContainerfile: close({
#RuntimeConfigContainerBase
containerfile: string
image?: _|_
})
#RuntimeConfigContainer: #RuntimeConfigContainerWithImage | #RuntimeConfigContainerWithContainerfile
// Discriminated union of all runtime types
#RuntimeConfig: #RuntimeConfigNative | #RuntimeConfigVirtualSh | #RuntimeConfigVirtualLua | #RuntimeConfigContainer
name
Type: "native" | "virtual-sh" | "virtual-lua" | "container"
Required: Yes
The runtime type.
env_inherit_mode
Type: "none" | "allow" | "all"
Available for: native, virtual-sh, virtual-lua, container
Default: all for native/virtual-sh/virtual-lua, none for container
Controls whether the host environment is inherited by the runtime.
env_inherit_allow
Type: [...string]
Available for: native, virtual-sh, virtual-lua, container
Allowlist of host env vars. This field requires env_inherit_mode: "allow" in the same runtime configuration.
env_inherit_deny
Type: [...string]
Available for: native, virtual-sh, virtual-lua, container
Denylist of host env vars (applies to any mode).
runtimes: [{
name: "container"
image: "debian:stable-slim"
env_inherit_mode: "allow"
env_inherit_allow: ["TERM", "LANG"]
env_inherit_deny: ["AWS_SECRET_ACCESS_KEY"]
}]
platforms: [{name: "linux"}]
allowed_binaries
Type: [...string]
Available for: virtual-sh, virtual-lua
Default: []
Host binaries that a virtual runtime may execute. The default is deny-all. Named entries are resolved with binary_lookup_mode; absolute entries must match the executable path. ["*"] is an explicit opt-out that allows every host binary and should be avoided for shared modules.
binary_lookup_mode
Type: "host" | "strict"
Available for: virtual-sh, virtual-lua
Default: "host"
Controls how named allowed_binaries entries are resolved. host uses the effective PATH. strict uses platform system paths only.
cpu_limit / memory_limit
Type: uint / byte-size string
Available for: virtual-lua
Optional golua execution limits. Omit or set cpu_limit: 0 / empty memory_limit for no explicit quota.
enable_host_ssh
Type: bool
Available for: container
Default: false
Enable SSH access from container back to the host. When enabled, Invowk starts an SSH server and provides credentials via environment variables:
INVOWK_SSH_ENABLEDINVOWK_SSH_HOSTINVOWK_SSH_PORTINVOWK_SSH_USERINVOWK_SSH_TOKEN
runtimes: [{
name: "container"
image: "debian:stable-slim"
enable_host_ssh: true
}]
platforms: [{name: "linux"}]
containerfile / image
Type: string
Available for: container
Specify exactly one container source. image and containerfile are mutually exclusive.
containerfile must be a relative path under the invowkfile directory. Invowk rejects absolute paths and any raw path segment equal to .., including backslash-separated segments, before resolving the path. Names that merely contain consecutive dots are valid, so Containerfile..backup and docker/v1..2/Containerfile are accepted.
// Use a pre-built image
image: "debian:stable-slim"
// Build from a Containerfile
containerfile: "./Containerfile"
containerfile: "./docker/Dockerfile.build"
persistent
Type: {create_if_missing?: bool, name?: string}
Available for: container
Reuse a long-lived container instead of creating an ephemeral container per invocation. When create_if_missing is true, Invowk creates and labels a managed container if it does not exist. If name is omitted, Invowk derives a stable invowk-* name from the fully-qualified command namespace.
Use --ivk-container-name to target a pre-existing running container from the CLI. Explicit names must use portable Docker/Podman naming: lowercase letters, digits, ., _, or -, starting with a lowercase letter or digit.
persistent: {
create_if_missing: true
name: "myproject-build" // Optional portable Docker/Podman name
}
volumes
Type: [...string]
Available for: container
Volume mounts in host:container[:options] format.
volumes: [
"./src:/app/src",
"/tmp:/tmp:ro",
"${HOME}/.cache:/cache",
]
ports
Type: [...string]
Available for: container
Port mappings in host:container format.
ports: [
"8080:80",
"3000:3000",
]
depends_on
Type: #DependsOn
Available for: container
Required: No
Dependencies validated inside the container environment. Unlike root/command/implementation-level depends_on (which always check the host), container runtime-level depends_on validates against the container's own environment — useful for verifying that the container image has the required tools, files, and configuration.
Only checked when the container runtime is selected at execution time.
PlatformConfig
#PlatformConfig: {
name: "linux" | "macos" | "windows"
virtual?: {
filesystem?: {
access?: "restricted" | "full"
paths?: [string]: string // Uppercase logical names, e.g. CACHE
}
}
}
virtual.filesystem.access
Type: "restricted" | "full"
Required: No
Default: "restricted"
Controls virtual-runtime filesystem access for the selected platform. In restricted mode, VM-controlled file operations can access only implicit safe roots plus the platform's virtual.filesystem.paths roots. In full mode, VM-controlled file operations may access normalized host filesystem paths after resolver checks. This is not process isolation; use the container runtime for isolation.
virtual.filesystem.paths
Type: map of uppercase logical names to string paths Required: No
Logical path handles exposed to virtual runtimes. Keys must be safe environment suffixes such as CACHE or DB_ROOT; Invowk exposes each mapping as INVOWK_PATH_<KEY> and resolves it through invowk.path("<KEY>/file") in virtual-lua. Values are platform-local string paths in the selected platform entry.
EnvConfig
Environment configuration:
#EnvConfig: {
files?: [...string] // Dotenv files to load
vars?: [string]: string // Environment variables
}
files
Dotenv files to load. Files are loaded in order; later files override earlier ones.
env: {
files: [
".env",
".env.local",
".env.${ENVIRONMENT}?", // '?' means optional
]
}
vars
Environment variables as key-value pairs.
env: {
vars: {
NODE_ENV: "production"
DEBUG: "false"
}
}
DependsOn
Dependency specification:
#DependsOn: {
tools?: [...#ToolDependency]
cmds?: [...#CommandDependency]
filepaths?: [...#FilepathDependency]
capabilities?: [...#CapabilityDependency]
custom_checks?: [...#CustomCheckDependency]
env_vars?: [...#EnvVarDependency]
}
ToolDependency
#ToolDependency: {
alternatives: [...string] & [_, ...] // At least one - tool names
}
depends_on: {
tools: [
{alternatives: ["go"]},
{alternatives: ["podman", "docker"]}, // Either works
]
}
CommandDependency
:::caution Field Name
The field name for command dependencies is cmds, not commands. Using commands will cause a CUE validation error because the dependency schema is closed and commands is not a supported field.
:::
#CommandDependencyRef: #BareCommandDependencyRef | #SourceQualifiedCommandDependencyRef
#BareCommandDependencyRef: string
#SourceQualifiedCommandDependencyRef: string // @source command
#CommandDependency: {
alternatives: [...#CommandDependencyRef] & [_, ...]
}
Command alternatives are dependency references. A bare reference such as "build" or "test unit" resolves only inside the declaring command's own source. Cross-source dependencies use explicit @source command syntax, such as "@tools lint" or "@com.company.tools lint". The older space-prefixed form is not source-qualified: "tools lint" is a single bare command name.
FilepathDependency
#FilepathDependency: {
alternatives: [...string] & [_, ...] // File/directory paths
readable?: bool
writable?: bool
executable?: bool
}
CapabilityDependency
#CapabilityDependency: {
alternatives: [...("local-area-network" | "internet" | "containers" | "tty")] & [_, ...]
}
EnvVarDependency
#EnvVarDependency: {
alternatives: [...#EnvVarCheck] & [_, ...]
}
#EnvVarCheck: {
name: string // Environment variable name
validation?: string // Regex pattern
}
CustomCheckDependency
#CustomCheckDependency: #CustomCheck | #CustomCheckAlternatives
#CustomCheck: {
name: string // Check identifier
script: #CustomCheckScript
expected_code?: int // Expected exit code (default: 0)
expected_output?: string // Regex to match output
}
#CustomCheckScript: close({
content: string
file?: _|_
interpreter?: string
}) | close({
file: string
content?: _|_
interpreter?: string
})
#CustomCheckAlternatives: {
alternatives: [...#CustomCheck] & [_, ...]
}
Flag
Command-line flag definition:
#Flag: {
name: string // POSIX-compliant name
description: string // Help text
default_value?: string // Default value
type?: "string" | "bool" | "int" | "float"
required?: bool
short?: string // Single character alias
validation?: string // Regex pattern
}
| Property | Required | Description |
|---|---|---|
name | Yes | Flag name (alphanumeric, hyphens, underscores) |
description | Yes | Help text (must be non-empty) |
type | No | string, bool, int, float (default: string) |
default_value | No | Default if not provided (cannot combine with required) |
required | No | Must be provided (cannot combine with default_value) |
short | No | Single-letter alias (a-z or A-Z) |
validation | No | Regex pattern for value validation |
flags: [
{
name: "output"
short: "o"
description: "Output file path"
default_value: "./build"
},
{
name: "verbose"
short: "V"
description: "Enable verbose output"
type: "bool"
},
]
Argument
Positional argument definition:
#Argument: {
name: string // POSIX-compliant name
description: string // Help text
required?: bool // Must be provided
default_value?: string // Default if not provided
type?: "string" | "int" | "float"
validation?: string // Regex pattern
variadic?: bool // Accepts multiple values (last arg only)
}
| Property | Required | Description |
|---|---|---|
name | Yes | Argument name (alphanumeric, hyphens, underscores) |
description | Yes | Help text (must be non-empty) |
type | No | string, int, float (default: string; bool not supported) |
default_value | No | Default if not provided (cannot combine with required) |
required | No | Must be provided (cannot combine with default_value) |
variadic | No | Accept multiple values (only allowed on the last argument) |
validation | No | Regex pattern for value validation |
args: [
{
name: "target"
description: "Build target"
required: true
},
{
name: "files"
description: "Files to process"
variadic: true
},
]
Environment Variables for Arguments:
INVOWK_ARG_<NAME>- The argument value- For variadic:
INVOWK_ARG_<NAME>_COUNT,INVOWK_ARG_<NAME>_1,INVOWK_ARG_<NAME>_2, etc.
WatchConfig
File-watching configuration for automatic command re-execution:
#WatchConfig: {
patterns: [...string] & [_, ...] // Required - glob patterns to watch
debounce?: #DurationString // Optional - default "500ms"
clear_screen?: bool // Optional - default false
ignore?: [...string] // Optional - merged with built-in defaults
}
patterns
Type: [...string] (at least one)
Required: Yes
Glob patterns for files to watch. Patterns support ** for recursive matching (e.g., "src/**/*.go", "*.ts"). Paths are relative to the effective working directory of the command.
debounce
Type: #DurationString
Required: No
Default: "500ms"
Delay before re-executing after a file change is detected. See DurationString.
clear_screen
Type: bool
Required: No
Default: false
When true, clears the terminal before each re-execution.
ignore
Type: [...string]
Required: No
Additional glob patterns for files/directories to exclude from watching. These are merged with built-in defaults (**/.git/**, **/node_modules/**, **/__pycache__/**, **/*.swp, **/*.swo, **/*~, **/.DS_Store).
DurationString
// #DurationString — shared by timeout and debounce
// Valid examples: "500ms", "30s", "5m", "1h30m", "2.5s"
#DurationString: string & =~"^([0-9]+(\\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$"
Shared type used by #Implementation.timeout and #WatchConfig.debounce. Valid examples: "500ms", "30s", "5m", "1h30m", "2.5s".
Complete Example
env: {
files: [".env"]
vars: {
APP_NAME: "myapp"
}
}
cmds: [
{
name: "build"
description: "Build the application"
flags: [
{
name: "release"
short: "R"
description: "Build for release"
type: "bool"
},
]
implementations: [
{
script: {content: """
if [ "$INVOWK_FLAG_RELEASE" = "true" ]; then
go build -ldflags="-s -w" -o app .
else
go build -o app .
fi
"""}
runtimes: [{name: "native"}]
platforms: [{name: "linux"}, {name: "macos"}]
},
{
script: {
content: """
$flags = if ($env:INVOWK_FLAG_RELEASE -eq "true") { "-ldflags=-s -w" } else { "" }
go build $flags -o app.exe .
"""
interpreter: "pwsh"
}
runtimes: [{name: "native"}]
platforms: [{name: "windows"}]
},
]
depends_on: {
tools: [{alternatives: ["go"]}]
}
},
]