Automated Build Validation

⚠️ build is just a descriptive name for any action automatically performed on certain events. These actions don’t need to generate any binary output — the only requirement is to provide logs which could be automatically parsed for errors and warnings.

Auto-validation of project file updates

This gives you unlimited flexibility to automatically validate model output, project and skill updates. Even when it comes to manual validation, you could use builds for augmented validation — making the model prepare a list of hot spots to check, or detailed reports and instructions for manual review.

A good idea is to always look for ways to automate and augment validation, as it really saves your time and energy in the long run. You don’t even need to be creative — just ask models to do that for you, using .xedant/README.md as a reference.

Automated build validation is the core of Xedant Code’s validation pipeline. Instead of waiting for models to call npm test or dotnet build, automated builds run on every file change the AI makes in corresponding folders — compiling, linting, type-checking, and testing your code without any intervention. The raw build output is then parsed into structured errors and warnings (using flexible parsing rules you could easily update) that feed into chat back at the end using AutoFix feature and the build panel for immediate manual review. You don’t need to wait for chat to end to review errors and send your feedback — that’s what message queue is about. Just send your feedback and go away — it would be sent to the chat automatically at the end.

Because of that, you get much faster chat completions, lower costs and faster post-chat validation because the background-rebuilt app could be fully re-deployed the moment AI generates its final summary. It’s especially effective when having multiple build types and linters as they all run in parallel instead of sequential model-initiated execution.

Visual noise is also much lower — you see models doing your tasks, not struggling with calling linters and builders several times in a row. To make it even more effective, you should add a rule into CLAUDE.md to never build or lint manually, and use hooks to prevent models from doing that if they forget.


Build Configuration

Builds are configured in .xedant/build.yml. Each build defines a command, which events trigger it, and optional settings for delay, timeout, and path normalization. Two types exist: command builds (shell execution) and prompt builds (AI-driven validation — covered in the Automated Prompt Builds guide).

build:
  task-name:
    path: "src/"              # Working directory for the command
    command: "npm run check"  # Shell command to execute
    delay: 3                 # Seconds to wait before triggering (default: 3)
    timeout: 60              # Maximum execution time in seconds (default: 60)
    watch: "*.ts *.js"      # File wildcards or build names (space or comma separated), or `chat` for monitoring current chat completion
    commandOutput: ""         # Path to additional output file (optional)
    ignore: []                # Regex patterns to filter from errors/warnings
    replacements:             # Find/replace in output paths
      - find: "/tmp/build"
        replace: "/project"
    stopStrings: []           # Strings that abort the build immediately
    display: always           # UI visibility: always, errors, warnings, never
    autofix: always           # AutoFix participation: always, errors, warnings, never
    startSound: ""            # Sound when build starts (built-in or custom name)
    endSound: ""              # Sound when build finishes (built-in or custom name)
    soundVolume: 1.0          # Volume 0-1 for build sounds

Build Triggers

The watch field supports three trigger types:

  • File wildcards — Glob patterns like *.ts *.svelte. The build watches the path folder for matching file changes and executes the command relative to it, triggering after its configured delay
  • Parent build names — Reference another build by name. This build triggers only after the parent completes successfully, enabling ordered pipelines
  • chat — Special trigger that fires when the user’s chat session completes. Available for all build types and deploys

A build can watch file changes, parent builds, or chat completions — each build watches exactly one type of event. If you need a build to activate on a combination of events, duplicate it with different watch commands. This is intentional: single-responsibility builds are easier to debug and monitor. To reduce duplication, use a parent-child scheme: create multiple lightweight no-op parent builds that each watch one event type, then have a single child build watch all of them — it triggers whenever any parent completes, running your command only once. Set display: never on the parent builds to keep them hidden from the build panel.

When multiple files change during the delay countdown, the timer resets. If files change while a build is running, the running build is cancelled and restarted with the new changes.

⚠️ watch: chat enables automatically launching builds at the end of any user-initiated (not subagent) chat. Use it for heavy validation that should not re-run on every file update — prompt builds, security audits, expensive analysis, or anything that takes too long for file-watch triggers.

It only triggers once higher-level pipelines are finished: all queued user messages are processed first (they always go into the chat before anything else), and the AutoFix pipeline has fully completed with no remaining errors or warnings. There’s no point launching heavy operations in a “dirty” state — those issues will be automatically fixed by your feedback or the AutoFix pipeline.

Display and AutoFix Control

Each build has two control fields that determine its behavior in the UI and with AutoFix:

  • display — Controls when the build appears in the build panel: always (default), errors (only when errors exist), warnings (errors or warnings), or never (hidden)
  • autofix — Controls whether AutoFix feeds this build’s errors to the AI: always (default), errors, warnings, or never. Use never for builds whose output requires manual review, like prompt builds, security tests, high-level analysis

You can also control the AutoFix pipeline in real-time using the AutoFix toggle below the message input field in the chat. Toggling it off disables sending AutoFix build errors and warnings into the chat until you turn it on again. This is helpful when you stop the chat in the middle and don’t want to be interrupted by AutoFix attempts to fix broken incomplete project state.

Build Chaining

Builds could be chained together by watching other builds instead of files. The system resolves dependencies automatically and runs builds in the correct order:

build:
  compile:
    command: "dotnet build"
    watch: "*.cs"

  inspect:
    command: "jb inspectcode Code.sln -f=Xml --verbosity=ERROR -o=bin/inspectcode.xml"
    commandOutput: "/tmp/code/builds/inspect/bin/inspectcode.xml"
    watch: compile        # Runs only after compile succeeds

  test:
    command: "dotnet test --no-build"
    watch: compile        # Runs only after compile succeeds

The Build Parser

Build output is stored in .xedant/build/ with three files per task: {task-name}.output.txt (full command output), {task-name}.errors.txt (parsed errors), and {task-name}.warnings.txt (parsed warnings).

The build parser converts raw command output into structured errors and warnings. It reads .xedant/build.parser, which uses [ERROR]/[/ERROR] and [WARNING]/[/WARNING] blocks containing sequential regex patterns. The parser reloads automatically when the file changes — no restart needed.

⚠️ Don’t try to edit parser files manually — ask the AI model to do it for you. The easiest way: select any unparsed text in build output (Build Panel or output dialog) and click the floating Fix parser button — it sends the selected text to the AI with a properly formatted prompt to update build.parser. Alternatively, use .xedant/README.md as a reference in chat.

Parser Format

  • Comment lines starting with # are ignored
  • Single-line patterns — A regex that must match exactly one output line
  • Multi-line patterns — Wrapped in {{...}}, matches zero or more consecutive lines that follow the inner regex
# TypeScript errors with indented context
[ERROR]
.*\.ts.*              # Matches a line containing a .ts file path
Error.*               # Matches a line containing "Error"
{{^\s+}}              # Matches zero or more lines starting with whitespace
[/ERROR]

# C# compiler errors (MsBuild format)
[ERROR]
\[MsBuild\].*\(\d+,\d+\)->\(\d+,\d+\)\s+CS\d+\:.*
[/ERROR]

# Python ruff errors
[ERROR]
[A-Z]\d+\s+(\[\*\]\s+)?.*
\s*-->.*
{{^\s+.*|\d+\s+\|.*}}
[/ERROR]

# Warnings
[WARNING]
\(\d+,\d+\): warning
[/WARNING]

The parser works sequentially: at each output line, it tries each block’s patterns in order. When all patterns in a block match consecutively, those lines are extracted as one error and the parser advances past them. Earlier blocks take priority — once a match is found, later blocks are skipped for those lines.

Path Replacements

Builds often run in temporary directories, so error paths don’t match your actual project files. The replacements field remaps paths:

build:
  client-build:
    path: "client/"
    command: "npm run build"
    watch: "*.ts *.svelte"
    replacements:
      - find: "/tmp/code/builds/client-build"
        replace: "/project/client"

Replacements are applied before parsing, so error locations point to the correct files in your project.


Config Validation

Xedant Code automatically validates all .xedant/ configuration files when you save them. Nine validators run on every save, each targeting a specific config file:

  • build.yml — YAML syntax, requires command or prompt, warns on unknown properties
  • deploy.yml — YAML syntax, warns on unknown properties
  • project.yml — YAML syntax, requires name, warns on unknown properties
  • hooks.yml — YAML syntax, warns on unknown event types and properties
  • mcp.yml — YAML syntax, warns on unknown top-level keys and server properties
  • skills.yml — YAML syntax, warns if enabled is missing
  • environments.yml — YAML syntax, warns on unknown properties
  • providers.yml — YAML syntax, warns on unknown provider and environment properties
  • *.parser — Block pairing ([ERROR]/[/ERROR]), regex validity, patterns outside blocks

Validation results appear in the Build Panel alongside your regular builds. Error messages reference the relevant section in .xedant/README.md so you can look up the correct format.

⚠️ Config validation errors and warnings are excluded from the AutoFix pipeline on purpose, to prevent polluting existing chats not related to Xedant Code configs. In case of config validation issues, create a fresh chat, click on error/warning badges in the build panel, then the Send button in the errors and warnings tabs in the output dialog. Or copy/paste output manually, if that’s more convenient for you. Config builds are also hidden by default from the UI to minimize visual noise — you’ll see them only when validation issues exist.


The AutoFix Feedback Loop

AutoFix bridges builds and the AI model, creating a self-correcting validation loop. When enabled, AutoFix polls builds at a configurable interval, checks for errors and warnings, and injects them as chat messages for the AI to fix. For full details on AutoFix behavior, limitations, and manual error submission, see AutoFix.

  • Idle-only processing — AutoFix only injects errors when no active AI session is running, preventing conflicts
  • Dependency-aware — AutoFix checks that all parent builds have completed before processing a child build’s errors
  • Error priority — Errors are sent before warnings. AutoFix won’t address warnings until all errors are resolved
  • Duplicate detection — Checks the last 10 messages for identical content to prevent infinite loops
  • Autofix mode — Each build’s autofix field controls whether it participates: always, errors, warnings, or never

⚠️ Warnings are auto-fixed in a special way — they always come with a requirement to fix, not ignore them. Otherwise models would often skip them as non-important.


Effective Validation Patterns

Layer multiple quality gates for comprehensive coverage. Each build catches different categories of problems:

The more automated builds you have — the higher quality of final result you get. It directly translates into saving your time and getting better code and UI automatically. Don’t be lazy in this part, experiment more with various ways to extend automated validation. Even when it comes to manual validation, you could always simplify your life by semi-automated approach — make prompt builds spot potential errors and warnings, then review them first instead of re-checking everything from scratch after each update.

  • Compiler + linter + type checker + tests — Four independent checks, each catching what the others miss. The more builds you add, the more automated feedback AutoFix receives
  • Chain builds in dependency order — Compile first, then lint, then test. Each step only runs when the previous one succeeds, avoiding cascading noise
  • Add parser patterns for your tools — If your build output isn’t being parsed correctly, ask the AI model to add patterns to build.parser. The parser reloads automatically on save
  • Use path replacements for containerized builds — If builds run in Docker or temp directories, map paths back to your project so error locations are accurate
  • Set display: never for noisy builds — Keep the build panel clean by hiding builds whose output you rarely need to inspect manually

For the complete build feature reference, see Build & Deploy. For the AutoFix feedback loop, see AutoFix. For runtime error monitoring, see Deploy Output Monitoring.