> ## Documentation Index
> Fetch the complete documentation index at: https://docs.heylua.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# lua compile

> Bundle the project into dist-v2/ and sync primitive names and versions into lua.skill.yaml

`lua compile` builds every primitive reachable from the `LuaAgent` in `src/index.ts` into `dist-v2/`. It is a local build: nothing is sent to the platform and nothing changes for end users. `lua push`, `lua test`, and `lua chat` run it for you.

*Verified against lua-cli 3.33.0.*

## Synopsis

```bash theme={null}
lua compile [--verbose] [--debug] [--sync]
```

## Description

The compiler reads `src/index.ts`, follows the `LuaAgent` to its [skills](/concepts/skills-and-tools) and tools, [webhooks](/concepts/webhooks), [triggers](/concepts/triggers), [jobs](/concepts/jobs), [workflows](/concepts/workflows), [processors](/concepts/processors), [MCP servers](/concepts/mcp-servers), [devices](/concepts/devices) and device triggers, and [voices](/concepts/voice), validates each one, and bundles it with esbuild. A primitive that is not registered on the agent is not compiled. Validation errors are listed with file and line, and the command ends with `✖ compile_failed`.

Output goes to `dist-v2/`, which the command adds to `.gitignore`:

| Path                                 | Contents                                                                                                                                      |
| ------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------- |
| `dist-v2/manifest.json`              | Every primitive with its kind, name, description, artifact path, source path, and content hash; the agent entry carries the persona and model |
| `dist-v2/artifacts/<kind>/<name>.js` | One minified bundle per primitive, with a source map                                                                                          |
| `dist-v2/sources/`                   | Project files stored by content hash, the basis of the source backup                                                                          |

After bundling, the command syncs [`lua.skill.yaml`](/reference/cli/lua-skill-yaml): a row for each compiled primitive with its name and version, a new row for anything new, and no row for anything removed from the code. Server ids are never written here; `lua push` registers new primitives. When the project files differ from the last backup it prints ``📦 Project sources changed. Run `lua push backup` to sync.``

`--sync` needs a credential and an `agentId`; without them the check is skipped silently and the command still exits 0, so a CI job that must fail on drift runs [`lua sync --check`](/reference/cli/sync) instead. It compares the agent's name, persona, model, and governance with the server before compiling and prints the differences with the `lua sync` commands that resolve them. It reads only and never stops the build.

The line ``ℹ️  Server sync skipped — nothing was sent to the server; `lua push` publishes.`` in the output means the compile did not reconcile ids and versions with the server; `lua push`, `lua sync`, and `lua chat -e sandbox` run that reconciliation as part of their own compile.

## Arguments

None.

## Options

| Option      | Description                                                                                                      | Default      |
| ----------- | ---------------------------------------------------------------------------------------------------------------- | ------------ |
| `--verbose` | Print each phase and primitive, then the artifact tree with sizes                                                | summary only |
| `--debug`   | `--verbose` plus esbuild debug output, preserved temporary files, the output size, and stack traces under errors | off          |
| `--sync`    | Report agent-level drift against the server before compiling                                                     | off          |

## Examples

Compile and print the summary:

```bash theme={null}
lua compile
```

```text Output theme={null}
🔄 Syncing YAML with manifest...✅ YAML synced with manifest
ℹ️  Server sync skipped — nothing was sent to the server; `lua push` publishes.
✅ Compiled 8 primitives (1 agent, 1 skill, 3 tools, 1 webhook, 1 preprocessor, 1 postprocessor) in 642ms
✨ Tip: run `lua test` to verify your tools work locally before pushing.
```

See what was bundled and where:

```bash theme={null}
lua compile --verbose
```

```text Output theme={null}
📁 Scanning source files...
🤖 Agent detected with 8 primitives
✅ Validating primitives...
📦 Bundling primitives...
   📦 Agent: helpdesk-triage
   📦 Skill: tickets
   📦 Tool: create_ticket
…
```

Report drift first and keep CI logs quiet:

```bash theme={null}
LUA_NO_HINTS=1 lua compile --sync --ci
```

## Exit codes

| Code | When                                                                           |
| ---- | ------------------------------------------------------------------------------ |
| `0`  | Compiled; drift reported by `--sync` is not an error                           |
| `1`  | `compile_failed`: a validation or bundling error, listed before the typed line |
| `2`  | Unknown option                                                                 |

## See also

* [`lua test`](/reference/cli/test) — run what you compiled
* [`lua push`](/reference/cli/push) — push it
* [`lua sync`](/reference/cli/sync) — resolve the drift `--sync` reports
* [Project structure](/get-started/project-structure)
