Trill

Debugging

Trill has three tools for understanding what your workflow does before (or while) it runs: dry-run, debug mode, and JSON debug mode.

Dry Run

See the execution plan without running anything:

trill run workflow.yaml --dry-run

This shows:

Useful for verifying that dependencies are correct and steps are ordered how you expect.

Debug Mode

Step through each step interactively:

trill run workflow.yaml --debug

Before each step, trill pauses and shows:

You choose what to do:

CommandEffect
r or EnterRun this step
sSkip this step
cContinue — run all remaining steps without pausing
iInspect — show detailed debug information
qQuit — abort the entire workflow

After each step completes, trill shows the result: status, duration, exit code, and any outputs produced.

Debug mode works with approval steps too. The debug hook fires first (you can skip or quit), then if you choose to run, the approval prompt appears.

JSON Debug Mode

For LLM agents and automation:

trill run workflow.yaml --debug --json

Every interaction becomes a JSON object on stdout, and responses are JSON objects on stdin. No terminal colors, no interactive prompts — just structured data.

Step Events

Before each step, trill emits:

{
  "event": "step_pending",
  "job": "build",
  "step": "compile",
  "template": "cargo build --release",
  "command": "cargo build --release",
  "env": {"CARGO_INCREMENTAL": "0"},
  "context": {
    "local": true,
    "env": {},
    "jobs": {},
    "steps": {}
  },
  "condition": null,
  "depends_on": []
}

Respond with an action:

{"action": "run"}

Available actions: run, skip, continue, quit.

After the step completes:

{
  "event": "step_done",
  "step": "compile",
  "status": "succeeded",
  "duration_ms": 1234,
  "exit_code": 0,
  "outputs": {},
  "extensions": null,
  "output": "   Compiling  trill v0.1.0\n    Finished release [optimized] target(s)",
  "output_truncated": false
}

The output and output_truncated fields are only present when captured output is available. extensions is null when no extension jobs were added, or a list of job names when extension jobs were injected.

Respond with a post-step action (or send an empty line / {"action": "continue"} to proceed):

{"action": "continue"}

Available post-step actions: continue, abort, extend.

The extend action injects new jobs into the DAG (same format as $STEP_EXTEND_FILE, but in JSON):

{
  "action": "extend",
  "jobs": {
    "hotfix": {
      "depends_on": ["build"],
      "steps": [{"name": "patch", "run": "echo patching"}]
    }
  }
}

The abort action cancels the remaining steps immediately:

{"action": "abort"}

On invalid input or parse errors, trill defaults to continue.

Approval Events

Approval steps emit:

{
  "event": "approval_required",
  "job": "deploy",
  "step": "approve",
  "prompt": "Deploy to production?",
  "fields": [
    {"name": "environment", "type": "select", "options": ["staging", "production"]}
  ]
}

Respond:

{"action": "approve", "outputs": {"environment": "production"}}

Or:

{"action": "reject"}

Workflow Summary

When the workflow finishes:

{
  "event": "workflow_done",
  "success": true,
  "duration_ms": 5432
}

Combining Debug and Approval

Debug hooks fire before approval handlers. The flow for an approval step in debug mode:

  1. Debug hook shows step info, you choose Run/Skip/Quit
  2. If Run: approval handler prompts for input
  3. Debug hook shows the result (approved/rejected, outputs)

This means you can skip approval steps during debugging without needing to go through the approval flow.

Next Steps