Skip to main content
Version: 0.1.0-alpha.1

Invkfile Format

Invkfiles are written in CUE, a powerful configuration language that's like JSON with superpowers. If you've never used CUE before, don't worry - it's intuitive and you'll pick it up quickly.

Why CUE?

We chose CUE over YAML or JSON because:

  • Built-in validation - CUE catches errors before you run anything
  • No indentation nightmares - Unlike YAML, a misplaced space won't break everything
  • Comments! - Yes, you can actually write comments
  • Type safety - Invowk™'s schema ensures your invkfile is correct
  • Templating - Reduce repetition with CUE's powerful templating

Basic Syntax

CUE looks like JSON, but more readable:

// This is a comment

// Lists use square brackets
cmds: [
{
name: "hello"
description: "A greeting command"
}
]

// Multi-line strings use triple quotes
script: """
echo "Line 1"
echo "Line 2"
"""

Key differences from JSON:

  • No commas needed after fields (though they're allowed)
  • Trailing commas are fine
  • Comments with //
  • Multi-line strings with """

Schema Overview

Every invkfile follows this structure:

// Root level
default_shell?: string // Optional: override default shell
workdir?: string // Optional: default working directory
env?: #EnvConfig // Optional: global environment config
depends_on?: #DependsOn // Optional: global dependencies

// Required: at least one command
cmds: [...#Command]

The ? suffix means a field is optional.

Namespaces via Modules

Invkfiles define commands without a namespace. If you want namespacing, put your commands in a module and define the module ID in invkmod.cue.

See Commands and Namespaces for module naming rules and command prefixes.

Commands Structure

Each command has this structure:

{
name: string // Required: command name
description?: string // Optional: help text
implementations: [...] // Required: how to run the command
flags?: [...] // Optional: command flags
args?: [...] // Optional: positional arguments
env?: #EnvConfig // Optional: environment config
workdir?: string // Optional: working directory
depends_on?: #DependsOn // Optional: dependencies
}

Implementations

A command can have multiple implementations for different platforms/runtimes:

{
name: "build"
implementations: [
// Unix implementation
{
script: "make build"
runtimes: [{name: "native"}]
platforms: [{name: "linux"}, {name: "macos"}]
},
// Windows implementation
{
script: "msbuild /p:Configuration=Release"
runtimes: [{name: "native"}]
platforms: [{name: "windows"}]
}
]
}

Invowk automatically picks the right implementation for your platform.

Scripts

Scripts can be inline or reference external files:

Inline Scripts

// Single line
script: "echo 'Hello!'"

// Multi-line
script: """
#!/bin/bash
set -e
echo "Building..."
go build ./...
"""

External Script Files

// Relative to invkfile location
script: "./scripts/build.sh"

// Just the filename (recognized extensions)
script: "deploy.sh"

Recognized extensions: .sh, .bash, .ps1, .bat, .cmd, .py, .rb, .pl, .zsh, .fish

Complete Example

Here's a full-featured invkfile:

// Global environment
env: {
vars: {
APP_NAME: "myapp"
LOG_LEVEL: "info"
}
}

// Global dependencies
depends_on: {
tools: [{alternatives: ["sh", "bash"]}]
}

cmds: [
{
name: "build"
description: "Build the application"
implementations: [
{
script: """
echo "Building $APP_NAME..."
go build -o bin/$APP_NAME ./...
"""
runtimes: [{name: "native"}]
platforms: [{name: "linux"}, {name: "macos"}, {name: "windows"}]
}
]
depends_on: {
tools: [{alternatives: ["go"]}]
filepaths: [{alternatives: ["go.mod"]}]
}
},
{
name: "deploy"
description: "Deploy to production"
implementations: [
{
script: "./scripts/deploy.sh"
runtimes: [{name: "native"}]
platforms: [{name: "linux"}, {name: "macos"}]
}
]
depends_on: {
tools: [{alternatives: ["docker", "podman"]}]
cmds: [{alternatives: ["build"]}]
}
flags: [
{name: "env", description: "Target environment", required: true},
{name: "dry-run", description: "Simulate deployment", type: "bool", default_value: "false"}
]
}
]

CUE Tips & Tricks

Reduce Repetition

Use CUE's templating to avoid repetition:

// Define a template
_nativeUnix: {
runtimes: [{name: "native"}]
platforms: [{name: "linux"}, {name: "macos"}]
}

cmds: [
{
name: "build"
implementations: [
_nativeUnix & {script: "make build"}
]
},
{
name: "test"
implementations: [
_nativeUnix & {script: "make test"}
]
}
]

Validation

Run your invkfile through the CUE validator:

cue vet invkfile.cue path/to/invkfile_schema.cue -d '#Invkfile'

Or just try to list commands - Invowk validates automatically:

invowk cmd

Next Steps