Workflow File

workflow.yaml
version: "1"
state:
  schema: []
templates: []
nodes: []
A workflow has four top-level keys:
KeyRequiredPurpose
versionDeclare workflow schema version (default: "1").
stateDeclares shared-state schema.
templatesRe-usable blocks.
nodesExecutable DAG.

Shared State

version: "1"
state:
  schema:
    - name: shards
      type: array
      items:
        type: object
        properties:
          team:    { type: string }
          shardId: { type: string }
nodes: []
You can also declare state schema using an object map:
version: "1"
state:
  schema:
    shards:
      type: array
      items:
        type: object
        properties:
          team:    { type: string }
          shardId: { type: string }
nodes: []

Nodes & Steps

Nodes

Nodes are execution units in your workflow. They can be automatic or manual, depend on other nodes, and may define strategy (e.g., matrix), trigger, runtime, env, and an ordered list of steps.
version: "1"
nodes:
  - id: build
    name: Build
    type: automatic
    steps:
      - name: npm install
        run: npm ci
id
string
required
Unique within the workflow.
name
string
required
Display name.
type
string
automatic (default) or manual.
depends_on
string[]
Upstream node IDs.
trigger
object
{ type: manual } → approval gate.
strategy
object
Matrix configuration.
steps
array
required
Ordered list of steps.
runtime
object
Container/runtime configuration (e.g., Docker).
env
object
Environment variables for the node or step.

Step

Steps are the atomic actions inside a node; they run sequentially and each step performs one action All step types support the following field:
if
string
Conditional expression to gate the step. if is evaluated before executing any step type.Expression evaluation supports referencing params.x and state.x, and any matrix value keys (injected as-is). Supported operators include ==, !=, >, <, &&, and ||.Example: params.autoAIReview.See Variable resolution for the full expression and interpolation grammar.
Runs shell commands on the host. Use for setup/cleanup, invoking external tools, or glue logic between transformations.
steps:
  - name: Install dependencies
    run: |
      npm install
      npm run build
name
string
required
Step label.
run
string
Inline shell command to execute.
env
object
Step-level environment variables applied to the process environment for this run step.
Executes ast-grep using a YAML config. Use for fast, declarative pattern matching and structured find/replace.
steps:
  - name: Apply ast-grep rules
    ast-grep:
      config_file: "rules/config.yml"
      base_path: "./src"
      include:
        - "**/*.js"
      exclude:
        - "**/*.test.js"
ast-grep.config_file
string
required
Path to the ast-grep configuration file (.yaml).
ast-grep.include
string[]
Include glob patterns.
ast-grep.exclude
string[]
Exclude glob patterns.
ast-grep.base_path
string
Base path for resolving globs.
ast-grep.max_threads
number
Maximum concurrent threads.
Runs a TypeScript/JavaScript codemod powered by ast-grep. Use when you need programmatic logic beyond YAML rules.
steps:
  - name: Run jssg codemod
    js-ast-grep:
      js_file: "scripts/codemod.ts"
      base_path: "."
      language: "typescript"
      include:
        - "**/*.ts"
        - "**/*.tsx"
js-ast-grep.js_file
string
required
Path to the JS/TS file that implements the codemod.
js-ast-grep.language
string
Target language (e.g., typescript, javascript, etc.).
js-ast-grep.include
string[]
Include glob patterns.
js-ast-grep.exclude
string[]
Exclude glob patterns.
js-ast-grep.base_path
string
Base path for resolving globs.
js-ast-grep.max_threads
number
Maximum concurrent threads.
js-ast-grep.dry_run
boolean
default:"false"
Perform a dry run without applying changes.
Runs another codemod by package name (or local path). Use to compose larger migrations by chaining codemods.
steps:
  - name: Run registry codemod
    codemod:
      source: "@scope/package@1.2.3"
      args: ["--flag", "value"]
      env:
        NODE_ENV: production
      working_dir: "."
codemod.source
string
required
Codemod source (registry package or local path).
codemod.args
string[]
CLI arguments passed to the codemod.
codemod.env
object
Environment variables used during execution.
codemod.working_dir
string
Working directory for execution.
env
object
Step-level environment variables. For codemod steps, these are forwarded to the invoked workflow as parameters with an env_ prefix (e.g., FOOenv_FOO). They are not applied to the OS environment of the nested workflow.
Calls an AI agent with a prompt. Use for generating change plans or reviews; validate outputs and prefer dry runs in critical paths.
steps:
  - name: Review diffs with AI
    ai:
      prompt: |
        Summarize risky changes and suggest tests.
      model: "gpt-4o"
ai.prompt
string
required
Prompt to send to the AI agent.
ai.model
string
default:"gpt-4o"
Model identifier. Overrides LLM_MODEL if set.
ai.system_prompt
string
System prompt to scope the AI agent’s behavior.
ai.max_steps
number
default:"30"
Maximum number of agent steps before stopping.
ai.llm_protocol
string
default:"openai"
LLM provider/protocol. Supported: openai, anthropic, azure_openai.
ai.endpoint
string
LLM base URL. If omitted, defaults to the provider’s standard endpoint for the selected protocol. You can override with a custom endpoint.
ai.api_key
string
API key to access the LLM.The AI step requires valid LLM credentials. Provide them via environment variables:
LLM_API_KEY=YOUR_KEY
LLM_PROVIDER=openai
LLM_MODEL=gpt-4o
LLM_BASE_URL=https://api.openai.com/v1
LLM_BASE_URL is optional. If omitted, defaults to the provider’s standard endpoint for the selected protocol. You can override with a custom endpoint.

Matrix Strategy

version: "1"
state:
  schema:
    - name: shards
      type: array
      items:
        type: object
        properties:
          team: { type: string }
          shardId: { type: string }
nodes:
  - id: matrix-codemod
    name: Matrix Codemod
    strategy:
      type: matrix
      from_state: shards
    steps:
      - name: Codemod
        run: node codemod.js --team=$team --shard=$shardId
When the array referenced by from_state changes, Codemod CLI:
  1. Creates new tasks for new items.
  2. Marks tasks as WontDo if their item is removed.
  3. Leaves existing tasks untouched if their item remains.
Matrix nodes have a master task that tracks the status of all generated tasks.

Manual Trigger

version: "1"
nodes:
  - id: manual-approval
    name: Manual Approval
    trigger:
      type: manual
    steps:
      - name: Wait for approval
        run: echo "Waiting for manual approval"
Manual tasks are assigned unique UUIDs. You can resume:
  • All paused tasks:
    npx codemod workflow resume -i <run-id> --trigger-all
    
  • A specific task:
    npx codemod workflow resume -i <run-id> -t <task-uuid>
    

State Updates

SyntaxMeaningExample
KEY=VALSet state key to valuecount=10
KEY@=VALAppend value to array at state keyshards@={"team":"core","shardId":"1"}
Dot notationSet nested state fieldsconfig.retries=5
JSON valuesUse valid JSON for objects/arraysuser={"name":"Alice","id":123}
All state updates must be valid JSON if not a primitive. Updates are applied only if the task exits successfully.
Planned feature: containerized execution (e.g., Docker/Podman). Currently, workflows run in the host shell. When available, you’ll be able to specify a runtime per node or template.
Workflow state is persisted after every task. If interrupted, you can resume from the last saved state—no work is lost.
For matrix nodes, a master task aggregates the status of all generated tasks.
If all child tasks complete, the master is Completed. If any fail, the master is Failed.
If your workflow has a cycle:
nodes:
  - id: a
    name: Task A
    depends_on: [b]
    steps:
      - name: Task A
        run: echo "Task A"
  - id: b
    name: Task B
    depends_on: [a]
    steps:
      - name: Task B
        run: echo "Task B"
You’ll see:
 Workflow definition is invalid
Error: Cyclic dependency detected: a b a
This error is shown when you run npx codemod workflow validate or npx codemod workflow run on a workflow with a cyclic dependency.

Task Statuses

Pending
Queued; waiting for runner.
Running
Currently executing.
Completed
Succeeded; diff applied.
Failed
Script exited non-zero; diff discarded.
AwaitingTrigger
Waiting for manual approval.
Blocked
Dependencies not finished.
WontDo
Matrix item removed; task skipped.

Variable Resolution

  • Parameter: ${{params.branch}} — Supplied at runtime
  • Environment: ${{env.CI}} — Host env var
  • Shared State: ${{state.counter}} — Live JSON value
  • In matrix tasks, each object key becomes an environment variable (e.g., $team, $shardId, …). Inside steps, variables are unprefixed.
  • Operators (==, !=, >, <, &&, ||) are supported inside string interpolations like ${{ ... }} for resolving parameters, state, and matrix values.

Roadmap

Container runtime support

Support for runtime: docker and other container runtimes, allowing tasks to run in isolated environments.

Nested matrix strategies

Support for matrix strategies within matrix strategies, enabling more complex task fan-out.

Next Steps