Build & Deploy

What Are Builds?

In Xedant Code, a “build” is an automated validator that checks what the AI has done. Despite the name, builds don’t need to compile anything or produce binary output — they just need to run a command and report errors and warnings in a structured format that the build parser can recognize.

Think of builds as quality gates. Each one is a separate automated check that runs whenever relevant files change. A compiler catching syntax errors is a build. A linter flagging unused variables is a build. A test runner failing on an assertion is a build. A security scanner finding vulnerabilities is also a build. They’re all the same thing — a command that produces structured error output.

Builds are configured in .xedant/build.yml in your project root. Each build defines a command to run, which files to watch, and parsing rules in .xedant/build.parser that extract errors and warnings from the command’s output. When the AI modifies your project, Xedant detects the file changes and triggers the appropriate builds automatically.

The real power comes from AutoFix. When AutoFix is enabled, any errors or warnings from your builds are automatically fed back to the AI model as chat messages. The model sees the exact error output, understands what went wrong, and attempts a fix — which triggers the builds again, creating a feedback loop. The more builds you add, the more automated validation the model gets, and the better your results become.


Build Configuration

Builds are defined in .xedant/build.yml. Each build is a named task with a shell command, file patterns to watch, and optional settings. You don’t need to create or edit this file manually — use the Fix build.yml with AI button (sparkle icon) in the Build Panel header to ask the AI to configure builds for your project.

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
    startSound: ""            # Sound when build starts (built-in or custom name)
    endSound: ""              # Fallback sound when build finishes (used when no result-specific sound is set)
    successSound: ""          # Sound when build succeeds (overrides endSound)
    warningSound: ""          # Sound when build completes with warnings (overrides endSound)
    errorSound: ""            # Sound when build fails (overrides endSound)
    soundVolume: 1.0          # Volume 0-1 for build sounds

Each setting controls a specific part of the build lifecycle:

  • path — The working directory where the command runs. Defaults to the project root
  • command — The shell command to execute. This can be any command available in your environment
  • delay — Seconds to wait after detecting a file change before triggering. This prevents rapid-fire builds when multiple files change at once. Default is 3 seconds
  • timeout — Maximum execution time in seconds. If the command exceeds this, it’s killed. Default is 60 seconds
  • watch — File glob patterns (like *.ts *.js) or the name(s) of parent build(s) (like server-build,client-copy). When watching another build, this build triggers only after the parent completes successfully
  • commandOutput — Path to an additional output file to parse. Some tools write results to files instead of stdout (like JetBrains inspectcode producing XML). Set this to point to that file and the parser will extract errors from it
  • ignore — Regex patterns to filter out from errors and warnings. Use this to suppress known false positives or noise from specific tools
  • replacements — Find/replace pairs that remap paths in the output. Essential when builds run in temporary directories (Docker containers, isolated build folders) so that error locations point to your actual project files
  • stopStrings — Strings that abort the build immediately when detected in the output (for example, "The operation was canceled")
  • startSound — Sound to play when the build starts (built-in name like "complete" or custom sound from .xedant/sounds/)
  • endSound — Fallback sound to play when the build finishes. Used when none of the result-specific sounds are set
  • successSound — Sound to play when the build succeeds. Takes priority over endSound
  • warningSound — Sound to play when the build completes with warnings. Takes priority over endSound
  • errorSound — Sound to play when the build fails. Takes priority over endSound
  • soundVolume — Volume for build sounds (0-1, default 1.0)

Builds can chain together to create ordered pipelines. Instead of watching files, a build can watch another build:

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

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

The build system watches your project files using file system monitors. When a file matching a build’s watch pattern changes, the system starts a countdown timer for that build’s delay. If more matching files change during the countdown, the timer resets. Once the countdown completes, the build command executes. If files change while the build is running, the running build is cancelled and restarted with the new changes.

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

You don’t need to create or edit build.yml manually. The .xedant/README.md file documents the complete format — just ask the AI model to add or modify builds for you and it will use that documentation to get it right.


Parser Files

Xedant Code uses three parser files to extract errors and warnings from text output. All three share the same format and are fully self-documented with inline comments — you don’t need to edit them manually. If you add custom validators with unfamiliar output formats, or if your deployed application produces errors in a format the parser doesn’t recognize, just ask the AI model to update the parser for you.

The easiest way to fix parser patterns is directly from the output: select text in any build, deploy, or script output area and a floating Fix parser button appears. Click it and the AI receives the selected text along with a properly formatted prompt to update the corresponding parser file — no typing required.

Parser format

Each parser file contains [ERROR] and [WARNING] blocks. Inside each block, lines are regex patterns that the parser tries to match sequentially against the command output:

  • Comment lines starting with # are ignored — the parser files use these to document what each pattern matches
  • Single-line patterns — A regex that must match exactly one output line. The parser tries the next pattern on the next line
  • Multi-line patterns — Wrapped in {{...}}, matches zero or more consecutive lines that follow the inner regex. This is how you capture indented context after an error header, stack traces, or any multi-line error output

Here’s a concrete example showing how patterns capture a TypeScript error with its indented context:

# TypeScript errors
[ERROR]
.*\.ts.*              # Matches a line containing a .ts file path
Error.*               # Matches a line starting with "Error"
{{^\s+}}              # Matches zero or more lines starting with whitespace (context)
[/ERROR]

The parser works by iterating through the output lines. At each position, it tries each [ERROR] 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. The [WARNING] blocks work identically. This means patterns that appear earlier in the file take priority — the parser stops trying additional blocks once it finds a match.

The parser reloads its rules automatically when the file changes, so edits take effect immediately without restarting anything.

build.parser

The .xedant/build.parser file extracts errors and warnings from build command output. It ships with patterns for common compilers and tools — C# (MsBuild, CSC), TypeScript, Svelte, Vite, Python (ruff), and ReSharper — but you can add patterns for any tool your project uses.

# cs errors - MsBuild format with file path and (line,col)->(line,col) CSxxxx:
[ERROR]
\[MsBuild\].*\(\d+,\d+\)->\(\d+,\d+\)\s+CS\d+\:.*
[/ERROR]

# Python ruff errors (F/E codes) - with file location and context
[ERROR]
[A-Z]\d+\s+(\[\*\]\s+)?.*
\s*-->.*
{{^\s+.*|\d+\s+\|.*}}
[/ERROR]

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

deploy.parser

The .xedant/deploy.parser file extracts errors and warnings from your deployed application’s runtime output. It handles common runtime error patterns — unhandled exceptions, stack traces, database connection failures, HTTP error codes, and application crashes — across different platforms:

# Unhandled exceptions (full stack trace)
[ERROR]
Unhandled exception\.
{{\S.*}}
[/ERROR]

# ASP.NET Error log level (Serilog/ILogger)
[ERROR]
^err\:.*
{{^\s+\S.*}}
[/ERROR]

# HTTP 500 internal server errors
[ERROR]
.*status code 500
[/ERROR]

# Connection refused errors
[ERROR]
Connection refused
[/ERROR]

# SQL database exceptions
[ERROR]
SqlException\:.*
{{^\s+\S.*}}
[/ERROR]

# Warning log level
[WARNING]
^warn\:.*
{{^\s+\S.*}}
[/WARNING]

output.parser

The .xedant/output.parser file is a catch-all for generic script output — shell errors, Python tracebacks, Node.js exceptions, npm failures, and other common error formats. It’s used when parsing output that doesn’t fit into the build or deploy categories:

# Shell command not found
[ERROR]
.*command not found
[/ERROR]

# Python tracebacks
[ERROR]
^Traceback \(most recent call last\)\:
{{.*}}
[/ERROR]

# npm ERR!
[ERROR]
^npm ERR\!.*
[/ERROR]

# Python warnings
[WARNING]
.*Warning\:.*
{{^\s+.*}}
[/WARNING]

Config Validation

Xedant Code automatically validates all .xedant/ configuration files when you save them. Validation runs as a build-like process and results appear in the Build Panel alongside your regular builds — errors in red, warnings in yellow.

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 on unknown properties, warns if enabled is missing
  • environments.yml — YAML syntax, warns on unknown properties (expects variables)
  • providers.yml — YAML syntax, warns on unknown provider and environment properties
  • *.parser — block pairing ([ERROR]/[/ERROR]), regex validity, patterns outside blocks

Error and warning messages reference the relevant section in .xedant/README.md so you can look up the correct format:

Error: build.yml - 'lint': Missing required field 'command' or 'prompt' (see .xedant/README.md#buildyml)
Warning: deploy.yml - 'staging': Unknown property 'restart' (see .xedant/README.md#deployyml)
Warning: skills.yml - 'my-skill': Missing 'enabled' property (see .xedant/README.md#skillsyml)

There’s nothing to configure — just edit your config files and validation triggers automatically on save. Fix any errors and the validation will clear on the next check.


Deploy Configuration

Deploys are configured in .xedant/deploy.yml. Xedant Code supports two deployment methods: debug for local development and docker for remote container deployments.

Debug deploy (local)

Debug deploys run your application directly on the local machine. This is the most common method during development:

deploy:
  my-app:
    method: "debug"            # Required: must be "debug"
    os: "linux"                # "linux" or "windows" (default: "linux")
    path: "./server"           # Path to application files
    command: "dotnet run"      # Command to start the application
    delay: 3                   # Delay before starting (default: 3)
    timeout: 60                # Max execution time (default: 60)
    watch: "build-app"         # Build name(s) (space or comma separated), or `chat`
    shallowCopy: true          # Copy only changed files (default: true)
    url: "https://app.example.com/"  # Optional URL for link button
    startSound: ""            # Sound when deploy starts (built-in or custom name)
    endSound: ""              # Sound when deploy finishes (built-in or custom name)
    soundVolume: 1.0          # Volume 0-1 for deploy sounds
    environment:                # Environment variables for the process
      - APP_KEY=your-key
      - APP_DB=/path/to/database

Key settings:

  • watch — List of build names (space or comma separated), or chat to trigger on user chat completion. The deploy starts or restarts automatically when all listed builds complete successfully
  • shallowCopy — When enabled, copies only the changed files to the deploy directory on each restart, which is significantly faster than a full copy
  • url — Optional URL to your deployed application. Shown in the UI as a clickable button that opens the app in a new browser tab
  • environment — Environment variables passed to the deployed process
  • startSound — Sound to play when the deploy starts (built-in name like "complete" or custom sound from .xedant/sounds/)
  • endSound — Sound to play when the deploy finishes
  • soundVolume — Volume for deploy sounds (0-1, default 1.0)

Docker deploy (remote)

Docker deploys push your application to a remote server as a container. This is useful for staging and production environments:

deploy:
  my-docker:
    method: "docker"             # Required: must be "docker"
    os: "linux"
    host: "server.com"          # Remote host
    username: "deploy"           # SSH username
    sshKeyPath: "~/.ssh/key"    # SSH key path
    sshPort: 22                  # SSH port (default: 22)
    imageName: "app:latest"      # Docker image name
    containerName: "myapp"       # Container name
    dockerfilePath: "./Dockerfile"
    buildContext: "."             # Build context (default: ".")
    buildArgs:                    # Docker build arguments
      - NODE_ENV=production
    environmentVariables:         # Container environment variables
      - PORT=3000
      - DATABASE_URL=postgresql://...
    portMappings:                 # Host:Container port mappings
      "8080": "3000"
    volumeMappings:               # Host:Container volume mappings
      "/var/log/app": "/app/logs"
    networks:                     # Docker networks
      - myapp-network
    pullLatestImage: true         # Pull base image before build (default: true)
    removeExistingContainer: true # Remove old container before deploy (default: true)
    healthCheckPath: "/"          # Health check endpoint (default: "/")
    healthCheckInterval: 30       # Health check interval in seconds (default: 30)
    healthCheckRetries: 3         # Health check retries (default: 3)
    localSourcePath: "."          # Local path to deploy from
    remoteWorkDir: "/tmp/deploy"  # Remote working directory
    excludePaths:                 # Paths to exclude from rsync
      - ".git"
      - "node_modules"
      - ".xedant"

Deploy output is stored in .xedant/deploy/{deploy-name}.log for runtime output, plus client-side debug logs at {domain}.log (auto-truncated at 100MB).

You don’t need to create or edit deploy.yml manually. The .xedant/README.md file documents both deployment methods completely — just ask the AI model to set up or modify your deployment configuration and it will handle the details.


Controlling Builds and Deploys

The Status Panel at the bottom of your screen provides real-time control and monitoring for both builds and deploys. It updates automatically via live connections — no refreshing needed.

Build controls

The Build tab shows all configured builds as an accordion list. Each item displays its name, status icon, and error/warning count badges.

  • Rebuild — Hover over any finished build to reveal a rebuild button. Click it to manually trigger a new build (disabled while a build is running)
  • View output — Click a build’s name to open its full output in a dialog with three tabs: Log (raw output, last 2000 lines), Errors (parsed errors, red highlights), Warnings (parsed warnings, yellow highlights)
  • Jump to errors — Click the error or warning count badge to open the output dialog directly on that tab
  • Copy — Copies the current tab’s content to your clipboard
  • Send to chat — Sends errors or warnings to the AI as a message wrapped in a build.log code block. Warnings get “fix warnings, don’t ignore them” appended. Content limited to first 20KB

The Build Panel header also has a Fix build.yml with AI button (sparkle icon) next to the Edit build.yml button. It appends a prompt to the chat input asking the AI to configure automated builds for your project, using .xedant/README.md as reference.

In build output dialogs and the Build Panel’s error/warning sections, selecting any text reveals a floating Fix parser button. Clicking it sends the selected text to the AI with a prompt to update build.parser — so you don’t have to manually type parser fix requests.

Builds that complete without issues auto-collapse. Builds with errors or warnings stay expanded so you can address them immediately.

Deploy controls

The Deploy tab shows each configured deployment with its name, status, and action buttons:

  • Start — Launches the application. Runtime output begins streaming in real-time
  • Stop — Gracefully shuts down the running application
  • Restart — Stops and immediately starts again (also triggered automatically when watched builds complete)
  • Open URL — If a URL is configured in deploy.yml, a button opens your deployed application in a new browser tab
  • View output — Opens a dialog with Log, Errors, and Warnings tabs, just like the build output dialog. Deploy output is parsed in real-time using deploy.parser — runtime errors like unhandled exceptions, database connection failures, and HTTP 500 errors are detected and highlighted. Selecting text in the output reveals a floating Fix parser button to update deploy.parser

You can resize the Status Panel or collapse it entirely to get more screen space. On mobile, the Build and Deploy panels stack vertically below the main content.


Creative Builds

The term “build” is just a name. You can create builds that do anything that produces structured error output. Here are some examples that go beyond traditional compilation:

Linters and formatters

build:
  eslint:
    path: "client/"
    command: "npx eslint src/ --format stylish"
    watch: "*.ts *.svelte"

  ruff:
    path: "src/"
    command: "ruff check ."
    watch: "*.py"

Type checkers

build:
  typecheck:
    path: "client/"
    command: "npx tsc --noEmit"
    watch: "*.ts"

Test runners

build:
  tests:
    path: "server/"
    command: "dotnet test --no-build"
    watch: compile

Security scanners

build:
  audit:
    path: "./"
    command: "npm audit"
    watch: "package.json"

Custom project validators

You can write your own validation scripts that check project-specific rules — naming conventions, required file structures, API contract compliance, or any invariant your project must maintain. As long as the script outputs errors in a format the parser can match, it works as a build. If your validator’s output format isn’t recognized, ask the AI model to add the appropriate patterns to build.parser.

Each build you add increases the amount of automated feedback the AI model receives through AutoFix. A project with a compiler build, a linter build, a type checker build, and a test runner build gives the model four independent quality checks — each one catching different categories of problems that the others might miss.


Auto-Rebuild and AutoFix

When the AI modifies your project files, Xedant detects the changes and triggers the relevant builds automatically. You don’t need to run any commands or click any buttons — the entire validation cycle runs on its own.

Here’s the automated workflow:

  1. AI modifies files — The model makes code changes to your project
  2. Builds trigger — Xedant detects file changes and starts the appropriate builds after their configured delays
  3. Output is parsed — The build parser extracts errors and warnings from each build’s output
  4. AutoFix checks results — If any builds produced errors, AutoFix wraps them in a markdown code block and sends them as a chat message to the AI model. Warnings get “fix warnings, don’t ignore them” appended
  5. AI fixes the issues — The model sees the error output, understands what went wrong, and makes corrections
  6. Builds retrigger — The fixes cause new file changes, which restart the cycle
  7. Success — When all builds pass without errors, the cycle ends and your application redeploys

This feedback loop runs entirely without your involvement. AutoFix only processes when no active AI session is running, checks for duplicate errors in the last 10 messages to prevent infinite loops, and respects a concurrency limit. You can watch it unfold in the Build Panel and chat history, or simply check back later to see the results.

Learn more about AutoFix configuration and limitations