> ## 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.

# Changelog

> Release notes and version history for lua-cli

## Unreleased

### ✨ New Features

<AccordionGroup>
  <Accordion title="WhatsApp template image/video/document headers">
    Send templates with media-rich headers. Create a template with `format: 'IMAGE'`, `'VIDEO'`, or `'DOCUMENT'` and provide a sample media URL for approval (must be publicly reachable HTTPS and within Meta's size/MIME limits).

    When sending, use `values.header.image_url` for IMAGE templates, `values.header.video_url` for VIDEO templates, or `values.header.document_url` (with optional `document_filename`) for DOCUMENT templates:

    ```typescript theme={null}
    // Send with video header
    await Templates.whatsapp.send(channelId, 'product_demo', {
      phoneNumbers: ['+447551166594'],
      values: {
        header: { video_url: 'https://example.com/product-demo.mp4' },
        body: { product_name: 'Acme Widget' }
      }
    });

    // Send with document header
    await Templates.whatsapp.send(channelId, 'invoice', {
      phoneNumbers: ['+447551166594'],
      values: {
        header: {
          document_url: 'https://example.com/invoice-12345.pdf',
          document_filename: 'invoice-12345.pdf'
        },
        body: { order_number: '12345' }
      }
    });
    ```

    See the [Templates API](/api/templates#media-headers) for creation details and size limits.
  </Accordion>
</AccordionGroup>

### 🔧 Improvements

<AccordionGroup>
  <Accordion title="Pasted and dragged images in emails now reach your agent">
    Images embedded in an email body — for example pasted or dragged into Gmail compose — previously arrived as just a `[image: …]` text placeholder, with no image part. They are now forwarded to your agent as image parts, the same way paperclip attachments are.

    The rules:

    * The embedded image must be referenced in the email's HTML body and be at least 1 KB (spacer pixels are filtered out)
    * Up to 10 embedded images per email are forwarded; regular attachments are unaffected
    * Remote-hosted images (e.g. Gmail signature images, which are hosted rather than embedded) are not fetched
    * Attachments mislabeled as embedded content by some clients are detected and forwarded as normal attachments

    The `[image: …]` placeholder still appears in the message text — use the image part, not the placeholder. See [Email Channel → Attachments and Embedded Images](/channels/email#attachments-and-embedded-images).
  </Accordion>
</AccordionGroup>

## v3.17.2

**Released:** June 1, 2026

### 🐛 Fixes

<AccordionGroup>
  <Accordion title="GitHub account linking now works">
    `lua git auth github` now links your GitHub account reliably using GitHub's
    device flow — a code is shown in your terminal that you enter at
    [github.com/login/device](https://github.com/login/device).

    ```bash theme={null}
    lua git auth github
    # Open https://github.com/login/device and enter the code: WDJB-MJHT
    # ✓ Logged in to GitHub as @your-username.
    ```

    See the [Git Command](/cli/git-command) documentation for the full
    workflow.
  </Accordion>
</AccordionGroup>

### ✨ New Features

<AccordionGroup>
  <Accordion title="Enable auto-push with one command">
    `lua git connect --auto-push` enables pushing each auto-commit to your
    linked GitHub repository. It checks that a GitHub account is linked and that
    your `origin` is a GitHub HTTPS remote before turning auto-push on, so a
    missing link or remote is reported immediately.

    ```bash theme={null}
    lua git auth github                   # link GitHub (once)
    git remote add origin https://github.com/<owner>/<repo>.git
    lua git connect --auto-push           # enable auto-commit + auto-push
    ```

    The `git` block in `lua.skill.yaml` is managed by these commands — you no
    longer need to edit it by hand. See the [Git Command](/cli/git-command)
    documentation for details.
  </Accordion>
</AccordionGroup>

## v3.17.1

**Released:** May 29, 2026

### ✨ New Features

<AccordionGroup>
  <Accordion title="LuaAgent({ modelSettings }) — per-call sampling settings">
    Set sampling settings once on the agent instead of overriding them in every skill. Supports `temperature`, `topP`, `topK`, `maxOutputTokens`, `presencePenalty`, `frequencyPenalty`, `stopSequences`, and `seed` — forwarded to the model on every chat turn.

    ```typescript theme={null}
    import { LuaAgent, type AgentModelSettings } from 'lua-cli';

    export const agent = new LuaAgent({
      name: 'role-scorer',
      persona: SCORING_PERSONA,
      modelSettings: {
        temperature: 0.2,
        maxOutputTokens: 4096,
      },
      skills: [scoreRoleSkill],
    });
    ```

    Obviously-broken values (non-finite numbers, `temperature` outside `0..2`, `topP` outside `0..1`, non-positive `maxOutputTokens`, non-string `stopSequences`) are rejected at construction time. Provider-specific range checks are deferred to the provider.
  </Accordion>

  <Accordion title="AI.generate({ structuredOutput }) — JSON Schema-constrained output">
    Constrain the model response to a JSON Schema. The parsed object lands on `result.output`. No more "respond with JSON only" prompts and no more `JSON.parse` boilerplate.

    ```typescript theme={null}
    import { AI } from 'lua-cli';
    import { z } from 'zod';
    import { zodToJsonSchema } from 'zod-to-json-schema';

    const Sentiment = z.object({
      sentiment: z.enum(['positive', 'negative', 'neutral']),
      score: z.number().min(0).max(1),
    });

    const result = await AI.generate({
      prompt: 'Analyze: "the food was incredible"',
      temperature: 0,
      structuredOutput: {
        schema: zodToJsonSchema(Sentiment) as Record<string, unknown>,
      },
    });

    const parsed = Sentiment.parse(result.output);
    ```

    On Google models, the auto-injected `google_search` tool is suppressed when `structuredOutput` is set (Vertex does not allow mixing function-calling tools with `google_search`).
  </Accordion>

  <Accordion title="Named type exports for AI and LuaAgent">
    `AiGenerateInput`, `AiGenerateOutput`, `AiGenerateStructuredOutput`, `AgentModelSettings`, and sub-shapes (`AiGenerateJsonSchema`, `AiGenerateSource`, `AiGenerateToolCall`, `AiGenerateToolResult`) are now importable directly from `lua-cli`.

    ```typescript theme={null}
    import {
      AI,
      LuaAgent,
      type AiGenerateInput,
      type AiGenerateOutput,
      type AgentModelSettings,
    } from 'lua-cli';

    const opts: AiGenerateInput = {
      prompt: 'Score this JD',
      structuredOutput: { schema: jdScoreSchema },
    };

    const result: AiGenerateOutput = await AI.generate(opts);
    ```
  </Accordion>
</AccordionGroup>

## v3.5.0-alpha.2

### 🔧 Improvements

<AccordionGroup>
  <Accordion title="Email channel now exposes parsed message metadata">
    `Lua.request.webhook.payload` is now populated for inbound emails with a JMAP-aligned object containing parsed message metadata.

    ```typescript theme={null}
    import { Lua } from 'lua-cli';

    const webhook = Lua.request.webhook;

    if (Lua.request.channel === 'email' && webhook) {
      const { messageId, inReplyTo, references, subject, from, to } = webhook.payload;

      // Use metadata to build threaded replies
      const replySubject = subject?.startsWith('Re:') ? subject : `Re: ${subject}`;
      const threadId = inReplyTo ?? messageId;

      return { threadId, replySubject };
    }
    ```

    Access the Message-ID for deduplication, full RFC 5322 header list via `headerLines`, and all threading metadata (`messageId`, `inReplyTo`, `references`). See the [API reference](/api/lua#email-metadata) for the complete shape and AgentMail divergence note.
  </Accordion>
</AccordionGroup>

## v3.16.0

**Released:** May 19, 2026

### ✨ New Features

<AccordionGroup>
  <Accordion title="Voice agents via LuaVoice">
    Define voice agents in TypeScript alongside your `LuaAgent`. Supports cascaded (STT/LLM/TTS) and realtime (speech-to-speech) shapes, with hooks for `onEnter`, `onUserTurnCompleted`, `onExit`, and voice-only tools.

    ```typescript theme={null}
    import { LuaVoice } from 'lua-cli';

    export default new LuaVoice({
      name: 'support-line',
      llm: 'openai/gpt-5.1-chat-latest',
      stt: 'deepgram/nova-3',
      tts: 'elevenlabs/eleven_turbo_v2_5:pwMBn0SsmN1220Aorv15',
      turnDetection: 'vad',
      greeting: "Hi, this is your support line — how can I help?",
    });
    ```

    Reference the voice from your `LuaAgent`'s `voices: [supportVoice]`. `lua push` ships it through the same versioned-primitive flow as skills and webhooks.
  </Accordion>

  <Accordion title="lua channels phone — interactive phone-number provisioning">
    Buy, bind, list, and release phone numbers from the CLI:

    ```bash theme={null}
    lua channels
    # → ☎️ Manage phone numbers
    # → Search available numbers / Purchase / Bind / List / Release
    ```

    SMS-capable numbers route through Vonage; voice-only routes through LiveKit-native PSTN. The bind action wires the number directly to your agent for inbound calls.
  </Accordion>

  <Accordion title="lua voice test — deterministic voice-agent testing">
    Test voice agents with text input and event-stream assertions, runnable in CI:

    ```typescript theme={null}
    import { runVoice, expectContainsMessage, expectCalledTool } from 'lua-cli/voice/test';
    import supportVoice from '../src/voices/support.voice';

    test('greets and books appointment', async () => {
      const result = await runVoice(supportVoice, {
        turns: ['I need to book an appointment', 'Tomorrow at 2pm'],
      });
      expectContainsMessage(result, 'appointment');
      expectCalledTool(result, 'create_booking');
    });
    ```
  </Accordion>

  <Accordion title="lua voice terminal / lua voice browser — local dev">
    Talk to your voice agent during development without going through a phone number:

    ```bash theme={null}
    lua voice terminal   # CLI mode
    lua voice browser    # Opens an embedded UI in your browser
    ```
  </Accordion>

  <Accordion title="lua logs --type calls — voice call logs">
    View voice call logs from the CLI:

    ```bash theme={null}
    lua logs --type calls
    ```

    Also available as a choice in the interactive `lua logs` picker.
  </Accordion>

  <Accordion title="lua-cli/voice — LiveKit plugin namespaces">
    Re-exports of LiveKit's plugin namespaces from `lua-cli` so you don't need a direct LiveKit dependency in your project:

    ```typescript theme={null}
    import { LuaVoice } from 'lua-cli';
    import { deepgram, elevenlabs, inference } from 'lua-cli/voice';

    export default new LuaVoice({
      stt: new deepgram.STT({ model: 'nova-3', language: 'en' }),
      tts: new elevenlabs.TTS({ model: 'eleven_turbo_v2_5', voice: '...' }),
      llm: new inference.LLM({ model: 'openai/gpt-5.1-chat-latest' }),
    });
    ```
  </Accordion>

  <Accordion title="Subclass-with-field-override — share logic across agents">
    Factor shared tool / skill / webhook / etc. logic into a base class in a workspace package, then extend per-agent with field initializers:

    ```typescript theme={null}
    // shared/SharedSearchTool.ts
    export abstract class SharedSearchTool implements LuaTool {
      name = 'search';
      ragSearchPath: string = '/default';
      async execute(input: { query: string }) {
        return { results: await fetch(this.ragSearchPath, /* ... */) };
      }
    }

    // agents/customer-a/src/tools/SearchTool.ts
    export class CustomerASearchTool extends SharedSearchTool {
      ragSearchPath = '/customer-a';
    }
    ```

    Works for every primitive type. The compiler walks the full `extends` chain, including transitive extends through shared intermediates.
  </Accordion>
</AccordionGroup>

### 🔧 Improvements

<AccordionGroup>
  <Accordion title="Voice version updates take effect immediately">
    Publishing a new voice version with `lua push voice` is enough — the next
    call uses the new version. No need to re-push the agent.
  </Accordion>
</AccordionGroup>

### 📝 Notes

<AccordionGroup>
  <Accordion title="Server compatibility">
    Voice agents require the latest server-side endpoints. Self-hosted Lua
    deployments must deploy the latest server before publishing voice agents via
    `lua push`.
  </Accordion>
</AccordionGroup>

***

## v3.15.3

**Released:** May 12, 2026

### ✨ New Features

<AccordionGroup>
  <Accordion title="lua push --include-source / --no-include-source">
    After a primitive push, the CLI now also attaches the gzipped workspace archive to each skill's per-skill source store, so the Builder UI's source panel stays in sync with your CLI edits.

    ```bash theme={null}
    lua push skill                       # default: source attach included
    lua push skill --no-include-source   # skip the attach (CI loops, etc.)
    lua push all                         # same default behavior
    ```

    The attach is non-fatal — if it fails, the push is still considered successful, because the primitive is already deployed and the agent-level backup already succeeded. The per-skill store is a denormalized projection for the Builder UI, not the canonical source store.
  </Accordion>
</AccordionGroup>

***

## v3.15.2

**Released:** May 8, 2026

<Warning>
  If you're upgrading from v3.15.1, upgrade directly to v3.15.2 (or later).
  v3.15.1 has a startup crash on fresh installs from npm.
</Warning>

### 🐛 Bug Fixes

<AccordionGroup>
  <Accordion title="lua-cli no longer crashes on startup with Cannot find package 'axios'">
    v3.15.1 shipped with a missing runtime dependency that crashed **every** CLI command on a fresh `npm install lua-cli@3.15.1`, not just the new `lua source` subcommands. v3.15.2 removes the dependency entirely — the affected paths now use the same HTTP layer as the rest of the CLI, so install size and dependency footprint are unchanged from v3.15.0.

    If you were stuck on v3.15.0 because of this, you can upgrade safely now:

    ```bash theme={null}
    npm install -g lua-cli@latest
    ```
  </Accordion>
</AccordionGroup>

***

## v3.15.1

**Released:** May 7, 2026

<Warning>
  This release has a startup crash on fresh installs from npm. Upgrade directly
  to v3.15.2 or later.
</Warning>

### ✨ New Features

<AccordionGroup>
  <Accordion title="lua source list and lua source rollback">
    Two new subcommands for working with your agent's backup version history.

    **List versions:**

    ```bash theme={null}
    lua source list                # most recent 50 versions
    lua source list --all          # full history
    lua source list --limit 100    # custom cap
    ```

    The currently active version is starred in the output.

    **Roll back to a past version:**

    ```bash theme={null}
    lua source rollback --version 12          # confirms before applying
    lua source rollback --version 12 --force  # skip the confirmation
    ```

    Rollback downloads the chosen version's files into your local workspace and then auto-pushes the rolled-back state as the next version. History is append-only — the original `v12` is never overwritten. After a rollback you have an explicit new version at the head representing "we returned to v12 on this date."
  </Accordion>

  <Accordion title="Auto-backup-push after every primitive push">
    `lua push <primitive>` now always runs a fresh-from-disk backup-push as the final step. If the backup fails, the command exits non-zero.

    No more silent partial success where the primitive landed on the server but your local source never reached the canonical store. This makes the CLI a reliable single source of truth for "this version was pushed from this machine in this state."
  </Accordion>

  <Accordion title="--fresh flag on lua push backup">
    Builds the backup manifest by walking your project directory directly from disk, instead of reading the compiled manifest.

    ```bash theme={null}
    lua push backup --fresh
    ```

    Always-on for the auto-backup hook; opt-in for explicit `lua push backup` calls. Use this when files have been written by the Builder or by any other out-of-band path that bypassed `lua compile`.
  </Accordion>
</AccordionGroup>

### 🔧 Improvements

<AccordionGroup>
  <Accordion title="lua init restores from the latest active backup">
    Init's restore step now hits the active manifest endpoint, which reflects every successful push from any platform — CLI, Builder chat, dashboard edits.

    Previously, `lua init` against a Builder-managed agent could restore a backup days or weeks behind the actual runtime state because the Builder's writes weren't reaching the legacy backup manifest reliably.
  </Accordion>

  <Accordion title="activeVersion tracked in lua.skill.yaml">
    After `lua init` and after every successful `lua push`, the CLI records the
    server's active backup version into your local `lua.skill.yaml`. Foundation
    for future staleness warnings ("local is behind server") and for cross-machine
    drift recovery.
  </Accordion>

  <Accordion title="Fresh backups now include Builder-written files">
    The new fresh-from-disk walker enumerates source files directly, so files written by the Builder (or any out-of-band edit) make it into your backup. Per-file cap: 256 KB. Skipped: `node_modules`, `.git`, `dist`, `dist-v2`, `.env`, and lockfiles.

    Previously, the reconcile-only path re-hashed files already in the compiled manifest, missing anything written outside `lua compile`.
  </Accordion>
</AccordionGroup>

### 🐛 Bug Fixes

<AccordionGroup>
  <Accordion title="lua init no longer crashes on transient restore failures">
    Network timeouts or missing blobs during the post-init backup restore are now caught and logged. `lua init` continues with an empty workspace and tells you what failed, instead of aborting with an unhandled exception.
  </Accordion>

  <Accordion title="Compiled output excluded from fresh backups">
    The `dist-v2` directory is no longer accidentally pulled into fresh backups. Previously, every fresh backup included the entire compiled tree (bundles, per-file source copies, the manifest), inflating per-push size and contradicting the intent that compiled artifacts stay separate.
  </Accordion>
</AccordionGroup>

***

## v3.15.0

**Released:** May 6, 2026

### ✨ New Features

<AccordionGroup>
  <Accordion title="Duplicate an existing agent">
    Clone an entire agent into a new one in a single command:

    ```bash theme={null}
    lua init --from-agent-id <existing-agent-id>
    ```

    The duplicated agent includes its persona, skills, MCP servers, env vars, and a full project backup that is restored locally so you can `lua push` immediately. The new agent inherits its source's LLM model — `lua init` no longer prompts for a model.

    Opt-in flags add more buckets to the copy:

    ```bash theme={null}
    lua init --from-agent-id <id> \
      --include-resources \
      --include-custom-data \
      --include-inquiry-form \
      --include-devices \
      --include-ecommerce-catalog
    ```

    Cross-org duplicates are supported by adding `--org-id <target-org-id>`.

    The interactive `lua init` flow (no flags) now offers "Duplicate an existing agent" as a third choice alongside "Create a new agent" and "Use one of your existing agents".
  </Accordion>

  <Accordion title="Channel-aware personas">
    Persona and skill context can now be split per channel using an object form. The previous string form keeps working — adopt the object form only where you need it.

    ```ts theme={null}
    new LuaAgent({
      // string form (still works)
      persona: 'You are a helpful assistant…',

      // or split per channel
      persona: {
        base: 'Shared persona for all channels',
        voice: 'Speak naturally, no markdown, no bullet lists',
        text: 'Use markdown headers and bullet lists where helpful'
      },
    });
    ```

    Useful when a voice agent needs different phrasing than the same agent's chat surface. The CLI pushes voice-only personas correctly (previously they could be skipped as empty), and `lua sync --pull` round-trips the object form back to your source file with all channel branches preserved.

    The new `PersonaText` type is exported from `lua-cli` for use in your own typings.
  </Accordion>
</AccordionGroup>

### 🔧 Improvements

<AccordionGroup>
  <Accordion title="Clearer authentication errors">
    When a command hits a 401 from the server, `lua-cli` now distinguishes between two very different conditions and tailors the remediation hint accordingly:

    * **API key invalid or expired** — `Authentication failed. Run \`lua auth configure\` to set a new API key.\`
    * **API key valid, but no access to this agent** — `Access denied for this agent. Run \`lua agents\` to list agents you can access, or \`lua init\` to switch projects.\`

    Previous versions printed a single generic message for both, sending users to a dead-end remediation flow when their key was actually fine.
  </Accordion>

  <Accordion title="Postprocessor priority is preserved on push">
    Setting `priority` on a `LuaPostprocessor` now correctly ships to production. In previous versions, the field was silently dropped during compile, so postprocessors always ran in their default order regardless of declared priority.

    No code change needed — re-run `lua push` and your existing `priority` declarations now take effect.
  </Accordion>

  <Accordion title="More resilient backup restore">
    Restoring a project backup from an older agent no longer aborts mid-restore with `incorrect header check` when one of its stored blobs was archived without compression. Uncompressed blobs are now passed through verbatim.

    Affects `lua init --restore-sources`, `lua init --from-agent-id`, and any other path that restores a project backup.
  </Accordion>

  <Accordion title="Object personas round-trip faithfully">
    Two related fixes for the new channel-aware persona shape:

    * **Voice-only personas now push.** A persona of just `{ voice: '...' }` (no `base`, no `text`) is correctly applied. Earlier this was silently skipped as empty.
    * **`lua sync --pull` preserves all channel branches.** Pulling an object-form persona from the server and writing it back to local source no longer drops `voice` or `text`.
  </Accordion>
</AccordionGroup>

### 🐛 Bug Fixes

<AccordionGroup>
  <Accordion title="lua production no longer prints [object Object] for channel-aware personas">
    `lua production` now correctly displays personas using the new object form, instead of crashing on `.length` / `.substring()` calls or printing the literal string `[object Object]`.
  </Accordion>

  <Accordion title="Skills without a context push correctly under stricter validation">
    Skills that don't define a `context` now push without error. Previously the
    CLI would send an empty string and the server would reject it under the new
    stricter persona/context validator.
  </Accordion>

  <Accordion title="lua init writes valid TypeScript for string-form personas">
    The source-write path for string-form personas now produces a properly-quoted literal under all edit paths, instead of occasionally emitting unquoted text that broke compilation.
  </Accordion>
</AccordionGroup>

***

## v3.14.0

**Released:** May 5, 2026

### 🔧 Improvements

<AccordionGroup>
  <Accordion title="Reliable push for large agents">
    `lua push` now reliably uploads agents of any size, including those with many tools or large code bundles.

    Previously, agents that exceeded the upload size limit would fail mid-push with a "request too large" error. This no longer happens — pushes succeed regardless of total bundle size.

    Applies to every primitive type:

    * skills (and their tools)
    * webhooks
    * jobs
    * preprocessors / postprocessors
    * devices and device triggers

    No configuration or command change required. Just run `lua push` as usual.
  </Accordion>

  <Accordion title="Faster, leaner pushes">
    Duplicate copies of code bundles have been removed from the push payload across all primitive types. Each push is now hundreds of KB to several MB smaller, which makes pushes faster — especially on slow connections.

    Sandbox sessions launched by `lua chat` benefit from the same reduction.

    No action needed; the change is automatic with this release.
  </Accordion>
</AccordionGroup>

***

## v3.13.0

**Released:** April 29, 2026

### ✨ New Features

<AccordionGroup>
  <Accordion title="lua status / lua describe — full agent state at a glance">
    A new `lua status` command (alias: `lua describe`) dumps the full state of your agent in one shot — no more running five separate commands to understand what's going on.

    ```bash theme={null}
    lua status           # human-readable table
    lua describe         # same output via alias
    lua status --json    # machine-readable JSON (schemaVersion: 1)
    ```

    What it shows:

    * **Environment** — CLI version, install method, Node version, API base, env overrides
    * **Updates** — current vs latest published version
    * **Auth** — key source, email, user ID, org list, server reachability
    * **Project** — config path, agent name/ID, manifest primitive count
    * **Primitives** — per-type sync table: local version, server version, status (synced / ahead / behind / not deployed) for skills, webhooks, jobs, preprocessors, postprocessors, MCP servers, devices, device triggers
    * **Persona** — synced / drifted
    * **Backup** — synced / out-of-sync
    * **Telemetry** — enabled/disabled
    * **Next steps** — actionable hints based on current state

    The `--json` flag outputs a stable JSON document (`schemaVersion: 1`) suitable for LLM agent consumption or CI dashboards. All progress output is suppressed in JSON mode.
  </Accordion>

  <Accordion title="Fuzzy command suggestions">
    Mistyped commands now show a "Did you mean X?" suggestion instead of a bare error:

    ```bash theme={null}
    lua stauts   # → error: unknown command 'stauts' (Did you mean: status?)
    lua pish     # → error: unknown command 'pish' (Did you mean: push?)
    lua logss    # → error: unknown command 'logss' (Did you mean: logs?)
    ```

    Works for top-level commands and constrained argument values (log types, primitive kinds, environments) across all 22 commands.
  </Accordion>

  <Accordion title="Alias shorthands for common CLI arguments">
    Common aliases are now accepted everywhere constrained argument values are expected:

    | Alias      | Expands to         |
    | ---------- | ------------------ |
    | `pp`       | `postprocessor`    |
    | `pre`      | `preprocessor`     |
    | `prod`     | `production`       |
    | `skills`   | `skill` (plural)   |
    | `webhooks` | `webhook` (plural) |
    | `jobs`     | `job` (plural)     |

    For example: `lua logs --type pp` is equivalent to `lua logs --type postprocessor`.
  </Accordion>

  <Accordion title="Post-deploy debug coaching">
    Every push, deploy, chat, compile, sync, and test surface now provides contextual guidance after the operation:

    * **Error paths** — `💡 Diagnose: run \`lua logs --type X --name Y --limit 10\`\` pointing at the right log stream for what just failed.
    * **Success paths** — `✨ Tip: run \`lua logs --limit 10\`\` nudges you to verify production execution.
    * **`lua chat`** — after each conversation turn, silently probes for `agent_error` logs. If any fired during that turn, prints: `⚠️ N new agent error(s) — run \`lua logs --type agent\_error\` to inspect.\`
    * **`lua compile`** — tip to run `lua test` after a successful compile.
    * **`lua sync --push`** — tip to verify with `lua logs` after pushing.

    To suppress all hints (for CI scripts): `LUA_NO_HINTS=1 lua push all`
  </Accordion>

  <Accordion title="lua test --json and shape headers">
    Two improvements to `lua test` output:

    **Shape headers** — the tool return value is now prefixed with its type and field names:

    ```
    Tool returned: Object — fields: success, message, data
    Tool returned: Array[3] of UserDataInstance — fields: id, name, email
    ```

    **`--json` flag** — outputs pure JSON on stdout, with all progress and compile output redirected to stderr. Enables clean piping:

    ```bash theme={null}
    lua test skill --name myTool --input '{"userId":"123"}' --json | jq '.data'
    ```
  </Accordion>
</AccordionGroup>

***

### 🐛 Bug Fixes

<AccordionGroup>
  <Accordion title="Compiler: variable reference resolution (major fix)">
    Primitive arrays defined outside the agent config object previously caused primitives to be silently dropped from the compiled manifest. All of the following patterns now resolve correctly:

    ```typescript theme={null}
    // Variable reference
    const myTools = [new GetUserTool(), new UpdateUserTool()];
    export default new LuaAgent({ tools: myTools });

    // Spread
    export default new LuaAgent({ tools: [...baseTools, new CustomTool()] });

    // Cross-file import
    import { sharedTools } from './shared/tools';
    export default new LuaAgent({ tools: sharedTools });

    // new ImportedClass() pattern
    import { GetUserTool } from './tools/GetUserTool';
    export default new LuaAgent({ tools: [new GetUserTool()] });
    ```

    Previously, using any of these patterns would cause the compile to succeed (`✅ Compiled N primitives`) but with the primitives silently absent from the manifest — resulting in a broken agent after push.
  </Accordion>

  <Accordion title="Version collision auto-retry">
    `lua push all` now automatically retries once when it encounters an "already exists" version collision. It re-fetches the current highest server version, bumps to the next one, and retries — resolving the most common `lua push all` failure without any user intervention.

    Additionally, sandbox versions (e.g. `1.0.21-sandbox`) are now correctly excluded when calculating the next production version bump.
  </Accordion>

  <Accordion title="Orphaned primitives: delete and trigger">
    Primitives that exist on the server but not in your local YAML are now shown in interactive delete and trigger menus, clearly marked as `[server only]`. Previously these orphaned primitives were invisible in menus, making them impossible to delete or trigger interactively.

    Non-interactive delete (`lua preprocessors delete --preprocessor-name X`) also now falls back to server data for all primitive types.

    The orphan warning message now shows the exact delete command to use:

    ```
    ⚠️  Found preprocessors on server not in your local code:
       - user-context
       To remove from server: lua preprocessors delete --preprocessor-name user-context
       To restore source from backup: lua sync --accept
    ```
  </Accordion>

  <Accordion title="lua compile: tools no longer get empty schemas on corrupted installs">
    `zod` is now bundled with the CLI. Previously, if your `node_modules/zod` was corrupted — by a partial install, a dependency conflict, or switching branches mid-install — every tool got an empty `inputSchema: {}` and the compile printed `✅ Compiled N primitives` anyway, shipping a broken agent silently.

    Now:

    * The bundled copy is used first and is immune to `node_modules` corruption.
    * A local `node_modules` fallback is tried second.
    * If both fail, compile aborts immediately with a clear reinstall hint before any primitive is processed.
  </Accordion>

  <Accordion title="Monorepo backup, log types, and other fixes">
    * **Monorepo backup** — `lua push backup` now captures source files imported from cross-package paths in a monorepo and restores them to `.lua/external/` on `lua sync --accept`.
    * **Log type `runtime`** — The log source previously called `mastra` is now `runtime`. Use `lua logs --type runtime` (was `--type mastra`).
    * **New log types** — `lua logs --type rag` and `lua logs --type device-trigger` are now valid filter values.
    * **Startup warnings eliminated** — Extraneous warnings that appeared on every CLI command have been removed.
    * **Skill sandbox stale ID** — Sandbox sessions that expire after 24 hours no longer show a misleading "run lua push first" message. The CLI now recovers automatically.
    * **`lua init` template fixes** — `Data.update` and `Products.search` usage in the scaffolded template was corrected.
  </Accordion>
</AccordionGroup>

***

## v3.12.3

**Released:** April 24, 2026

### ✨ New Features

<AccordionGroup>
  <Accordion title="heylua and lua-ai as additional CLI aliases">
    lua-cli now installs three binary aliases pointing to the same entry point:
    `lua`, `heylua`, and `lua-ai`. Users who have the Lua programming language
    interpreter installed (which also claims the `lua` command) can run `heylua`
    or `lua-ai` without any conflict or post-install workaround. Existing
    scripts using `lua` continue to work unchanged.
  </Accordion>
</AccordionGroup>

***

## v3.12.2

**Released:** April 23, 2026

### ✨ New Features

<AccordionGroup>
  <Accordion title="@filepath attachments in lua chat">
    Attach images and documents to any chat message using `@<path>` syntax — in both interactive and non-interactive mode.

    ```bash theme={null}
    # Interactive mode
    @screenshot.png what's wrong with this UI?
    check @report.pdf and tell me what you see

    # Non-interactive mode
    lua chat -m "@screenshot.png what do you see?" -e production
    lua chat -m "compare @before.png and @after.png" -e sandbox
    ```

    Images are sent as vision inputs; documents and text files are sent as file parts. The `@` token is stripped from the message text — only the file is forwarded alongside any remaining text.

    Supported types include: `.png`, `.jpg`, `.gif`, `.webp`, `.heic`, `.pdf`, `.docx`, `.xlsx`, `.ppt`, `.csv`, `.json`, `.html`, `.txt`, `.md`, `.eml`, and more. Files with unsupported extensions are left in your message as plain text. Email addresses (`user@example.com`) are never mistaken for file paths.

    Maximum attachment size: **10 MB** per file. Multiple attachments per message are supported.
  </Accordion>
</AccordionGroup>

***

## v3.12.1

**Released:** April 22, 2026

### 🐛 Bug Fixes

<AccordionGroup>
  <Accordion title="lua init no longer waits 30 seconds after creating an agent">
    Agent creation previously ended with a 30-second blind sleep. That wait has been removed — `lua init` now completes immediately after the server responds. The agent persona is read directly from the create API response.
  </Accordion>

  <Accordion title="Model set at agent creation time">
    The chosen model is now sent in the initial create request instead of a follow-up PATCH call, eliminating a window where the agent could briefly exist without a model.
  </Accordion>
</AccordionGroup>

***

## v3.12.0

**Released:** April 22, 2026

### ✨ New Features

<AccordionGroup>
  <Accordion title="lua triggers — pause and resume integration triggers">
    `lua triggers` is now a top-level command (alias for `lua integrations webhooks`) that lets you manage your integration triggers directly from the CLI.

    New `pause` and `resume` subcommands let you suspend or restore triggers individually or for an entire connection:

    ```bash theme={null}
    lua triggers                               # interactive menu
    lua triggers list                          # list all triggers with status
    lua triggers pause   --webhook-id <id>     # pause a single trigger
    lua triggers resume  --webhook-id <id>     # resume a single trigger
    lua triggers pause   --connection-id <id>  # pause all triggers on a connection
    lua triggers resume  --connection-id <id>  # resume all triggers on a connection
    lua triggers pause   --webhook-id <id> --reason "Maintenance window"
    ```

    The trigger list now displays rich status icons — ✅ active, ⏸️ paused, 💳 credit-suspended, 🔴 unhealthy — so you can see trigger health at a glance.

    The connect flow is also updated: triggers are opt-in by default (none pre-selected), giving you explicit control over which events wake your agent.
  </Accordion>
</AccordionGroup>

### 🐛 Bug Fixes

<AccordionGroup>
  <Accordion title="Skills compilation — skills now push correctly">
    Skills (`defineSkill`) were silently dropped from the compiled manifest because they were fed through esbuild like tools and webhooks. Skills are metadata-only (name, description, context, tool refs) and do not contain executable code. They now produce a JSON metadata artifact and flow through the full pipeline. Resolves the circular failure: `lua push skill` → "no server ID, run lua compile" → "not found in manifest".
  </Accordion>

  <Accordion title="MCP server ID tracking in lua.skill.yaml">
    MCP server IDs are now written back to `lua.skill.yaml` immediately after a successful push, so the server is never treated as an orphan on its first deploy. Re-pushes are fully idempotent.
  </Accordion>
</AccordionGroup>

***

## v3.11.0

**Released:** April 21, 2026

### ✨ New Features

<AccordionGroup>
  <Accordion title="Agents.invoke API for agent-to-agent calls (BAC-107)">
    Added a reusable agent invocation surface callable from within a LuaSkill, LuaWebhook, LuaJob, or any other primitive:

    ```typescript theme={null}
    await Agents.invoke(targetAgentId, prompt)
    await Agents.invoke(targetAgentId, { messages, systemPrompt })
    ```
  </Accordion>

  <Accordion title="Standalone defineDeviceTrigger primitive">
    Added support for device triggers as a first-class primitive decoupled from
    defineDevice, compiled and pushed like webhooks.
  </Accordion>

  <Accordion title="Governance SDK Integration">
    Added `lua governance add` and `lua governance remove` commands to configure runtime enforcement of governance policies for your agents.
  </Accordion>
</AccordionGroup>

### 🐛 Bug Fixes

<AccordionGroup>
  <Accordion title="Device Trigger Names">
    Allowed underscores in device trigger names.
  </Accordion>

  <Accordion title="Push Backup Refusal">
    Push-backup refusal message now shows project hashes instead of misleading timestamps.
  </Accordion>
</AccordionGroup>

***

## v3.10.0

**Released:** April 16, 2026

### ✨ New Features

<AccordionGroup>
  <Accordion title="lua models command — manage your agent's LLM model (LUA-268)">
    Manage the LLM model for your agent directly from the CLI.

    ```bash theme={null}
    lua models                           # list all approved models
    lua models set                       # interactive model picker
    lua models set --model openai/gpt-4o # non-interactive
    lua models unset                     # revert to platform default
    lua models list --json               # machine-readable output
    ```

    `lua models list` shows all approved models grouped by provider, with the current model highlighted. `lua models set` writes the chosen model into your `src/index.ts` and syncs it to the server. `lua models unset` removes the model property and clears it on the server.
  </Accordion>

  <Accordion title="lua devices command — bidirectional agent-device communication">
    Full CLI for managing devices connected to your agent. Devices are a new first-class primitive type that enables your agent to send commands to physical or virtual hardware and receive trigger payloads from them.

    ```bash theme={null}
    lua devices list [--group <name>]
    lua devices status --device-name <name>
    lua devices enable --device-name <name>
    lua devices disable --device-name <name>
    lua devices remove --device-name <name> [--force]
    lua devices test --device-name <name> [--payload <json>] [--timeout <ms>]
    lua devices test-trigger --device-name <name> [--payload <json>]
    ```

    Push device definitions with `lua push device` or include them in `lua push all`. Connect hardware or virtual devices using `@lua/device-client`.

    All actions support interactive mode — omit `--device-name` to choose from a picker.
  </Accordion>

  <Accordion title="Sync pull conflict guard">
    `lua sync --accept` now detects files you have modified locally since the last `lua push backup` and refuses to overwrite them.

    ```bash theme={null}
    lua sync --accept          # guarded pull — fails if local changes detected
    lua sync --accept --force  # bypass the guard and overwrite local changes
    ```

    After every successful `lua push backup`, a local cache of file hashes is stored in `.lua/backup-manifest.json`. The guard compares this cache against your current files and only flags files that were actually modified.

    If no backup has been run yet, the pull proceeds with a warning rather than failing.
  </Accordion>

  <Accordion title="Persona guide template for new agents (LUA-271)">
    New agents created via `lua init` now receive a structured persona template instead of `"Placeholder persona"`. The template includes suggested sections — identity, tone, audience, capabilities, boundaries, and guidelines — each with guidance notes to help you write an effective persona. It is designed to be reshaped or replaced entirely.
  </Accordion>
</AccordionGroup>

### 🐛 Bug Fixes

<AccordionGroup>
  <Accordion title="Sync conflict detection always triggered even with no local changes">
    The backup conflict detector used full 64-character SHA-256 hashes when reading files from disk, while the backup manifest stored 16-character truncated hashes (matching the compiler format). Every comparison failed, so every file appeared as a conflict regardless of whether anything had actually changed. Fixed by aligning the detector to use the same 16-char hash as the manifest.
  </Accordion>

  <Accordion title="lua sync --accept exited 0 in CI even when restore failed">
    When a backup restore failed (network error, missing manifest), the CLI printed "Sync complete" and exited with code 0 — silently masking the failure. When drift included source-bearing primitives but no backup was available, the missing count was also never incremented. Both failure paths now correctly propagate the error so CI/CD pipelines can detect a failed pull.
  </Accordion>
</AccordionGroup>

### 🔧 Improvements

<AccordionGroup>
  <Accordion title="--force flag for lua sync to bypass conflict guard">
    Use `lua sync --accept --force` (or `lua sync --force`) to intentionally
    overwrite local changes when pulling from the server.
  </Accordion>
</AccordionGroup>

***

## v3.9.3

**Released:** April 15, 2026

### ✨ New Features

<AccordionGroup>
  <Accordion title="Model selection in lua init (LUA-262)">
    Choose your agent's LLM model during `lua init`.

    **Interactive mode:** a searchable, provider-grouped model list appears after org and name selection. Select a model or skip to use the server default.

    **Non-interactive mode:**

    ```bash theme={null}
    lua init --model openai/gpt-4o
    lua init --agent-name "My Bot" --org-id org123 --model anthropic/claude-3-5-sonnet
    ```

    The selected model is written into your generated `src/index.ts` and synced to the server. Works correctly across fresh init, re-init, backup restore, and agent-switch flows.
  </Accordion>
</AccordionGroup>

### 🐛 Bug Fixes

<AccordionGroup>
  <Accordion title="MCP sync pull now works">
    `lua sync --accept` and interactive pull for MCP servers were silently no-ops — servers created via the dashboard were never written to local YAML even when drift was detected. Fixed: MCP servers missing locally are now correctly added to YAML on pull.
  </Accordion>

  <Accordion title="lua push mcp suggestion fix">
    During `lua sync`, the push suggestion for MCP servers was `lua push mcpServer --name "X"` (invalid command). Fixed to `lua push mcp --name "X"`.
  </Accordion>
</AccordionGroup>

### 🔧 Improvements

<AccordionGroup>
  <Accordion title="lua init wording clarity">
    The option to use an existing agent now reads "Use one of your existing
    agents" instead of "Extend one of your existing agents". The word "extend"
    implied inheritance; the actual behavior is source restore or template
    scaffold.
  </Accordion>
</AccordionGroup>

***

## v3.9.0

**Released:** April 13, 2026

### 🔧 Improvements

<AccordionGroup>
  <Accordion title="CI/CD-friendly authentication — no keychain required (LUA-258)">
    `keytar` (OS keychain) has been removed. The CLI now works on headless Debian, Docker, and VMs without any native system dependencies.

    API key resolution order:

    1. `LUA_API_KEY` environment variable
    2. `~/.lua-cli/credentials` file (written by `lua auth configure`)
    3. `.env` file values

    ```bash theme={null}
    # Option 1 — environment variable (CI/CD, Docker)
    export LUA_API_KEY=your-api-key

    # Option 2 — interactive setup (local dev)
    lua auth configure

    # Option 3 — .env file
    echo "LUA_API_KEY=your-api-key" >> .env
    ```

    <Note>
      **Upgrading from v3.8.x or earlier?** Run `lua auth configure` once to store your key in the new location. Your previous key stored in the OS keychain is not migrated automatically.
    </Note>
  </Accordion>
</AccordionGroup>

***

## v3.8.0

**Released:** April 8, 2026

### ✨ New Features

<AccordionGroup>
  <Accordion title="Webhook event subscriptions (BAC-131)">
    Subscribe your webhooks to WhatsApp message lifecycle events dispatched when Meta sends status callbacks.

    ```bash theme={null}
    lua webhooks events list-events               # See all subscribable event types
    lua webhooks events subscribe <webhook-id>    # Subscribe to events
    lua webhooks events unsubscribe <webhook-id>  # Remove subscriptions
    ```

    Supported events: `sent`, `delivered`, `read`, `failed`, `played`.
  </Accordion>

  <Accordion title="Generic multi-primitive deploy (BAC-137)">
    `lua deploy` now mirrors `lua push [type]` — deploy any primitive interactively or directly:

    ```bash theme={null}
    lua deploy                    # Interactive type selection
    lua deploy skill              # Deploy a skill version
    lua deploy webhook            # Deploy a webhook version
    lua deploy job                # Deploy a job version
    lua deploy preprocessor       # Deploy a preprocessor version
    lua deploy postprocessor      # Deploy a postprocessor version
    lua deploy persona            # Deploy a persona version
    lua deploy all --force        # Deploy latest of everything
    ```

    New generic flags: `--name` (replaces `--skill-name`) and `--set-version` (replaces `--skill-version`). Deprecated aliases kept for backwards compatibility.
  </Accordion>
</AccordionGroup>

### 🐛 Bug Fixes

<AccordionGroup>
  <Accordion title="Jobs short flags and live status (BAC-94)">
    `lua jobs deploy -i myJob -v latest` now works correctly — `-i` and `-v` are registered as short flags for `--job-name` and `--job-version`. The activate/deactivate selection list now shows the live server status badge next to each job.
  </Accordion>

  <Accordion title="Active version comparison for all primitives">
    Jobs, preprocessors, and postprocessors were comparing the wrong ID against
    `activeVersionId`, causing the active version to not be highlighted correctly.
    Fixed to use the version's own ID in all cases.
  </Accordion>

  <Accordion title="Webhook unsubscribe event type validation">
    Invalid event types passed to `lua webhooks events unsubscribe` now show a clear validation error instead of a misleading "not subscribed" message.
  </Accordion>
</AccordionGroup>

***

## v3.7.5

**Released:** March 30, 2026

### ✨ New Features

<AccordionGroup>
  <Accordion title="Per-agent message batching (BAC-113)">
    Agents can now have individual batching configuration for message debouncing. New `lua chat` flags for testing:

    ```bash theme={null}
    lua chat --batch           # Enable message batching in chat session
    lua chat --delay 2000      # Set first-message delay (ms)
    ```

    Batching config is set per-agent with fallback to environment variables.
  </Accordion>
</AccordionGroup>

***

## v3.7.4

**Released:** March 27, 2026

### 🐛 Bug Fixes

<AccordionGroup>
  <Accordion title="Keychain authentication reliability">
    Fixed several issues that could cause API key saves to silently fail on macOS. The auth flow now correctly reports errors and clears stale data on re-authentication.
  </Accordion>

  <Accordion title="Inline comment stripping in .env files">
    `.env` parsing now correctly strips inline comments: `LUA_API_KEY=abc # my comment` resolves to `abc`.
  </Accordion>
</AccordionGroup>

***

## v3.7.3

**Released:** March 24, 2026

### 🔧 Improvements

<AccordionGroup>
  <Accordion title="HTTP retry with exponential backoff">
    Automatic retries with backoff for transient server failures (429, 500–504). Max 3 retries, never retries client errors. Improves reliability for flaky network conditions.
  </Accordion>

  <Accordion title="Reduced package size">
    Removed the `lua dev` web UI command and unused dependencies, significantly reducing install size.
  </Accordion>
</AccordionGroup>

### 🐛 Bug Fixes

<AccordionGroup>
  <Accordion title="Chat stream timeout">
    Chat sessions now have a 5-minute timeout instead of hanging indefinitely on
    unresponsive connections.
  </Accordion>
</AccordionGroup>

***

## v3.7.2

**Released:** March 24, 2026

### ✨ New Features

<AccordionGroup>
  <Accordion title="Isolated AI text generation — AI.generate (BAC-14)">
    New `AI.generate` API for running text generation from within tools, aligned with Vercel AI SDK `generateText` semantics.

    **Simplified — returns plain text:**

    ```typescript theme={null}
    // Single argument: prompt is the user message
    const text = await AI.generate('Summarize the latest AI news.');

    // Two arguments: system instruction + user content (string or multimodal parts)
    const text2 = await AI.generate(
      'You are a helpful assistant.',
      [{ type: 'text', text: 'What products do you recommend?' }]
    );
    ```

    **Full options — returns rich result:**

    ```typescript theme={null}
    const result = await AI.generate({
      model: 'google/gemini-2.0-flash',
      system: 'You are concise.',
      prompt: 'What is the weather in London?',
    });

    result.text           // Generated text
    result.finishReason   // 'stop', 'length', etc.
    result.usage          // { promptTokens, completionTokens, totalTokens }
    result.sources        // Google Search grounding URLs (when available)
    ```

    **Supported providers:** `google/*` (Vertex AI), `openai/*`, `anthropic/*` — with automatic fallback if the requested provider's API key is missing.

    Google Search grounding is automatically attached for Google models.
  </Accordion>
</AccordionGroup>

### 🔧 Improvements

<AccordionGroup>
  <Accordion title="Lazy keytar loading for WebContainer support">
    Keytar is now loaded on demand and skipped entirely when `LUA_SKIP_KEYCHAIN` is set. Fixes `MODULE_NOT_FOUND` errors in StackBlitz WebContainers and browser sandboxes.

    ```bash theme={null}
    export LUA_SKIP_KEYCHAIN=1
    lua --version    # Now works without keytar.node
    ```
  </Accordion>
</AccordionGroup>

***

## v3.7.0

**Released:** March 20, 2026

### ✨ New Features

<AccordionGroup>
  <Accordion title="Chat thread isolation">
    Use `lua chat -t` or `--thread <id>` for isolated sessions. `lua chat clear --thread <id>` clears one thread. Omit the thread ID with `-t` to auto-generate a UUID.

    ```bash theme={null}
    lua chat --thread my-test
    lua chat -t
    lua chat clear --thread my-test --force
    ```
  </Accordion>

  <Accordion title="Auto-clear chat history">
    `--clear` / `--clear-thread` clear history when the session ends—useful after testing without running `lua chat clear` separately.

    ```bash theme={null}
    lua chat --clear
    lua chat -t my-test --clear
    ```
  </Accordion>
</AccordionGroup>

### 🐛 Bug Fixes

<AccordionGroup>
  <Accordion title="Model cleared when removed from agent">
    Pushing after removing `model` from your agent now clears the server-side model (BAC-87).
  </Accordion>

  <Accordion title="Features help and examples">
    Help text and examples reference current feature names (e.g. `inquiry` instead of deprecated `tickets`).
  </Accordion>
</AccordionGroup>

***

## v3.6.7

**Released:** March 15, 2026

### 🐛 Bug Fixes

<AccordionGroup>
  <Accordion title="MCP integrations defaults (BAC-83)">
    Connecting integrations defaults to exposing full MCP tool payloads (hide sensitive off). `defer_tools` is aligned with Unified.to expectations.
  </Accordion>

  <Accordion title="Skill tool references">
    Compiling skills resolves tool references more reliably for imports and dependencies.
  </Accordion>
</AccordionGroup>

***

## v3.6.6

**Released:** March 11, 2026

### ✨ New Features

<AccordionGroup>
  <Accordion title="Agent error filter in logs">
    Added `lua logs --type agent_error` to filter logs for execution errors in
    tools, webhooks, and jobs.
  </Accordion>
</AccordionGroup>

### 🐛 Bug Fixes

<AccordionGroup>
  <Accordion title="Cron timezone and logs">
    Fixed timezone handling for cron schedules and improved error logging for
    failed cron jobs.
  </Accordion>
</AccordionGroup>

***

## v3.6.5

**Released:** March 10, 2026

### 🔧 Improvements

<AccordionGroup>
  <Accordion title="Internal URL resolution">
    Extended base URLs for internal service discovery.
  </Accordion>
</AccordionGroup>

***

## v3.6.1

**Released:** March 2, 2026

### 🐛 Bug Fixes

<AccordionGroup>
  <Accordion title="Job Schedule Fields Now Preserved">
    `interval` and `once` job schedules now compile and push correctly. Previously, the `seconds` field (interval) and `executeAt` field (once) were silently dropped during compilation, causing `lua push job` to fail with:

    ```
    Push Error: Interval seconds must be at least 60
    ```

    All three schedule types now work as documented:

    ```typescript theme={null}
    // Interval — seconds now correctly sent to server
    schedule: { type: 'interval', seconds: 300 }

    // Once — executeAt now correctly sent to server
    schedule: { type: 'once', executeAt: new Date(Date.now() + 3600000) }

    // Cron — was already working
    schedule: { type: 'cron', expression: '0 9 * * *' }
    ```
  </Accordion>

  <Accordion title="Agent Imported Primitive Resolution">
    Agents that reference imported primitives using instantiation patterns in
    their config arrays (e.g. `jobs: [new MyJob()]`) now correctly resolve and
    compile.
  </Accordion>

  <Accordion title="CLI Exits Immediately">
    The CLI now exits immediately after completing a command. Previously, a background timer kept the process alive for up to \~1s after all work was done.
  </Accordion>
</AccordionGroup>

***

## v3.6.0

**Released:** February 27, 2026

### ✨ New Features

<AccordionGroup>
  <Accordion title="Agent Model Selection">
    `LuaAgent` now supports a `model` property to control which AI model your agent uses. Specify a static model string or a dynamic resolver function.

    ```typescript theme={null}
    import { LuaAgent } from 'lua-cli';

    // Static model
    export const agent = new LuaAgent({
      name: 'my-agent',
      persona: 'You are a helpful assistant.',
      model: 'openai/gpt-4o',
    });

    // Dynamic model based on channel
    export const agent = new LuaAgent({
      name: 'my-agent',
      persona: 'You are a helpful assistant.',
      model: async (request) => {
        if (request.channel === 'whatsapp') return 'openai/gpt-4o-mini';
        return 'openai/gpt-4o';
      },
    });
    ```

    Supported providers: `google/*`, `openai/*`, `anthropic/*`. Default: `google/gemini-2.5-flash`.
  </Accordion>

  <Accordion title="Usage Telemetry">
    lua-cli now collects usage data to help improve the developer experience. A new `lua telemetry` command lets you control data collection:

    ```bash theme={null}
    lua telemetry          # Show current status
    lua telemetry on       # Enable telemetry
    lua telemetry off      # Disable telemetry
    ```

    Or set `LUA_TELEMETRY=false` in your environment. See [Telemetry](/cli/utility-commands#lua-telemetry) for details.
  </Accordion>
</AccordionGroup>

### 🔧 Improvements

<AccordionGroup>
  <Accordion title="keytar as Optional Dependency">
    `keytar` (OS keychain access) is now optional. Fixes installation on CI/CD
    systems without native build tools. Falls back to environment variables or
    `.env` file.
  </Accordion>
</AccordionGroup>

***

## v3.5.0

**Released:** February 20, 2026

### ✨ New Features

<AccordionGroup>
  <Accordion title="User Lookup by Email or Phone">
    The `User.get()` method now supports looking up users by email address or phone number, in addition to userId.

    ```typescript theme={null}
    import { User } from 'lua-cli';

    // Look up by email
    const user = await User.get({ email: 'customer@example.com' });

    // Look up by phone (both formats work)
    const user = await User.get({ phone: '+1234567890' });

    // Handle not found (returns null, doesn't throw)
    if (!user) {
      return { error: 'User not found' };
    }
    ```

    Useful for webhooks receiving contact info from external systems.
  </Accordion>

  <Accordion title="Integrations Command">
    Connect your agent to 250+ third-party services via [Unified.to](https://unified.to). When you connect an account, an MCP server is automatically created to expose tools to your agent.

    ```bash theme={null}
    lua integrations              # Interactive mode
    lua integrations connect      # Connect (OAuth or API token)
    lua integrations list         # List connected accounts
    lua integrations webhooks     # Manage webhook triggers
    lua integrations mcp          # Manage MCP servers
    ```

    **Key Features:**

    * OAuth and API token authentication
    * Automatic MCP server creation and activation per connection
    * Event-driven webhook triggers that wake up your agent
    * Server-side finalization for reliable connection setup

    See the [Integrations Command](/cli/integrations-command) documentation.
  </Accordion>

  <Accordion title="Webhook Triggers for Integrations">
    Event-driven triggers that wake up your agent when events occur in connected services.

    ```bash theme={null}
    # Connect with triggers (all selected by default in interactive mode)
    lua integrations connect --integration linear --auth-method oauth --scopes all \
      --triggers task_task.created,task_task.updated

    # Use custom webhook URL instead of agent trigger
    lua integrations connect --integration linear --auth-method oauth --scopes all \
      --triggers task_task.created --custom-webhook --hook-url https://my-server.com/webhook
    ```

    * Triggers pre-selected by default in interactive mode
    * Choose between "Agent wake-up" mode or custom webhook URLs
    * Friendly labels for OAuth scopes and webhook events
    * JSON output: `lua integrations webhooks list --json`
  </Accordion>

  <Accordion title="Project Backup & Restore">
    Back up your project source files to cloud storage and restore them on any machine.

    ```bash theme={null}
    # Backup project sources
    lua push backup

    # Restore on new machine
    lua init --agent-id abc123 --restore-sources
    ```

    **Key Features:**

    * Content-addressed storage with automatic deduplication
    * S3 direct upload — no file size limits
    * Efficient incremental backups (only changed files uploaded)
    * Full project recovery on new machines

    See the [Skill Management](/cli/skill-management#lua-push-backup) documentation.
  </Accordion>

  <Accordion title="CI/CD Mode (--ci flag)">
    New global `--ci` flag makes the CLI fail loudly on missing required arguments instead of silently hanging in non-TTY environments.

    ```bash theme={null}
    # In CI/CD pipelines
    lua --ci push skill --name mySkill --set-version ${{ github.sha }} --force

    # In local development (interactive prompts work normally)
    lua push skill
    ```

    See the [Non-Interactive Mode](/cli/non-interactive-mode#cicd-mode-ci-flag) documentation.
  </Accordion>

  <Accordion title="Self-Update Command">
    New `lua update` command for self-updating from npm, plus a background outdated version warning on every command.

    ```bash theme={null}
    lua update   # Force-fetch latest version and install
    ```

    * Background version check with 24h file cache (zero latency impact)
    * Alpha users stay on alpha channel, stable users stay on latest
    * Boxed warning to stderr when outdated
  </Accordion>

  <Accordion title="Agents Discovery Command">
    New `lua agents` command lists all organizations and agents you have access to.

    ```bash theme={null}
    lua agents            # Formatted output
    lua agents --json     # JSON output for scripting
    ```

    See the [Utility Commands](/cli/utility-commands#lua-agents) documentation.
  </Accordion>

  <Accordion title="Variable References in Primitive Config">
    You can now define primitive properties using variables and imports — not just inline literals.

    ```typescript theme={null}
    const MY_SCHEDULE = { type: 'cron', expression: '0 9 * * *' };
    const MY_TOOLS = [calculatorTool, weatherTool];
    import { RETRY_CONFIG } from './config';

    export const myJob = defineJob({
      schedule: MY_SCHEDULE,        // ✅ variable reference
      retry: RETRY_CONFIG,          // ✅ imported constant
      execute: async () => { ... }
    });
    ```

    **Supported for:** job schedule/retry, skill tools arrays, MCP server resolver functions, and all agent config arrays.
  </Accordion>

  <Accordion title="Complete Push All — Persona & Backup Included">
    `lua push all` now pushes everything including persona and backup:

    ```bash theme={null}
    lua push all --force                # All primitives + persona + backup
    lua push all --force --auto-deploy  # Also deploys persona to production
    ```

    Persona and backup failures are non-fatal — the rest of the push completes normally.
  </Accordion>

  <Accordion title="Auto-Add dist-v2/ to .gitignore">
    The CLI now automatically adds `dist-v2/` to your `.gitignore`: - **New
    projects**: Included in `lua init` template - **Existing projects**: Added
    after first successful compilation - Idempotent and safe to run multiple times
  </Accordion>

  <Accordion title="MCP and Mastra Log Types">
    ````bash lua logs --type mcp # View MCP tool execution logs lua logs --type theme={null}
    mastra # View Mastra AI runtime logs lua logs --user-id user_123456 # Filter
    by user ID ```
    </Accordion>

    <Accordion title="Non-Interactive Configure Command">
    ```bash lua configure --api-key YOUR_API_KEY # Direct setup lua configure
    --email user@example.com # Request OTP lua configure --email user@example.com
    --otp 123 # Verify OTP ```
    </Accordion>

    <Accordion title="Non-Interactive Sandbox View Commands">
      ```bash
      lua persona sandbox view    # Print persona and exit
      lua skills sandbox view     # List local skills and exit
    ````
  </Accordion>
</AccordionGroup>

### 🔧 Breaking Changes

<Warning>
  These changes may affect existing scripts and workflows. Please update
  accordingly.
</Warning>

<AccordionGroup>
  <Accordion title="Push Flag: --version renamed to --set-version">
    ```bash theme={null}
    # Old (no longer works)
    lua push skill --name mySkill --version 1.0.5

    # New (correct)
    lua push skill --name mySkill --set-version 1.0.5
    ```

    **Reason:** Avoids confusion with the global `--version` flag that shows CLI version.
  </Accordion>

  <Accordion title="Compile Sync: --no-sync changed to --sync (opt-in)">
    ```bash theme={null}
    # Old behavior (sync ran by default)
    lua compile             # Checked for drift

    # New behavior (sync is opt-in)
    lua compile             # No drift check (fast)
    lua compile --sync      # Enable drift check
    ```

    **New flag:** `--verbose` for detailed compilation output.
  </Accordion>
</AccordionGroup>

### 🚀 Improvements

<AccordionGroup>
  <Accordion title="Version Conflict Avoidance in Push">
    `lua push --force` now automatically checks the server for the highest existing version.

    **Benefit:** Prevents "Version already exists" errors during automated deployments.
  </Accordion>

  <Accordion title="Sync Compiles Before Checking Drift">
    `lua sync` now runs compilation first for more accurate drift detection.
  </Accordion>

  <Accordion title="Chat Preprocessor Block Response">
    Chat now displays preprocessor block response text instead of showing empty
    responses.
  </Accordion>

  <Accordion title="Consistent Error Messages">
    All errors now go through standardized formatting for clearer, more actionable messages.
  </Accordion>
</AccordionGroup>

### ⚡ Performance

<AccordionGroup>
  <Accordion title="Parallel Server Sync During Compilation">
    * **Before**: 6 sequential HTTP calls (\~3-6s)
    * **After**: All fetched in parallel (\~1s)
  </Accordion>

  <Accordion title="Batch Version Checks in Push All">
    One HTTP call per primitive type instead of one per entity.
  </Accordion>

  <Accordion title="Lazy Authentication">
    No upfront validation call. The first API call validates the key.
  </Accordion>
</AccordionGroup>

### 🐛 Bug Fixes

* **Job Creation**: Fixed `__exports` naming collision when primitives called `Jobs.create()` at runtime
* **Backup Size Limit**: S3 presigned uploads fix "request entity too large" for large projects
* **MCP Server Duplicates**: Intelligent URL merging handles concurrent MCP creation flows
* **Email Channels**: Aligned with updated API schema (mode selection, displayName, response types)
* **Agent Config Arrays**: Defining `jobs: MY_JOBS` via variables no longer silently empties the agent
* **Webhook headerSchema**: Header validation schemas now correctly pushed to server
* **Tool Conditions**: Tools without `condition()` no longer fail at runtime
* **MCP Server Push**: Fixed detection, manifest metadata, and push pipeline (3 bugs)
* **Auth Errors**: `AuthenticationError` properly propagated; 403 Forbidden handling added
* **Compile Sync**: Handlers no longer overwrite each other's IDs
* **Marketplace**: Only shows skills with published and approved versions
* **Test Command**: Fixed preprocessor test handling for object format

### 📝 Interface Updates

* Added `UserLookupOptions` for email/phone lookup
* Added `EmailChannelMode`, `CreateGeneratedEmailChannelResponse`, `CreateExistingEmailChannelResponse`
* Added `MCPServerSource` enum for tracking MCP server origin
* Updated `User.get()` return type to `UserDataInstance | null`
* Added `'mcp'` and `'mastra'` to log type enums

***

## v3.4.0

**Released:** January 22, 2026

### ✨ New Features

<AccordionGroup>
  <Accordion title="Non-Destructive Compile Sync">
    The `lua compile` command now uses a safer, non-destructive sync pattern. Instead of automatically deleting primitives on the server that aren't in your local code, it now:

    * **Warns** about orphaned primitives (skills, webhooks, jobs, MCP servers)
    * **Suggests** using explicit delete commands
    * **Filters** warnings to CLI-sourced skills only (ignores marketplace and manual skills)

    This prevents accidental data loss and gives you full control over what gets removed.
  </Accordion>

  <Accordion title="New Delete Commands">
    Explicit delete commands for managing primitives no longer in your local code:

    ````bash # Delete a skill from the server lua skills delete --skill-name theme={null}
    my-old-skill # Delete a webhook lua webhooks delete --webhook-name old-webhook
    # Delete a job lua jobs delete --job-name deprecated-job ``` **Features:** -
    Server lookup for orphaned items not in local YAML - Interactive mode with
    confirmation prompts - `--force` flag for non-interactive deletion
    </Accordion>

    <Accordion title="Streamable HTTP MCP Transport">
      Added support for the modern Streamable HTTP transport (MCP spec 2025-03-26):
      
      ```typescript
      const server = new LuaMCPServer({
        name: 'my-api',
        transport: 'streamable-http',  // New transport type
        url: 'https://mcp.example.com/mcp',
        headers: () => ({
          'Authorization': `Bearer ${env("API_KEY")}`
        })
      });
    ````

    **Supported transports:**

    * `'streamable-http'` - Modern MCP standard (recommended)
    * `'sse'` - Legacy Server-Sent Events transport

    <Warning>
      **stdio transport removed:** Local MCP servers using `stdio` transport are not supported yet. Use remote servers with `streamable-http` or `sse` instead.
    </Warning>
  </Accordion>
</AccordionGroup>

### 🐛 Bug Fixes

* **Push**: Fixed crash when pushing primitives without a version field. First push now defaults to version `0.0.1` and shows "(none - first push)" in prompts.

### 📝 Interface Updates

* Added `MCPStreamableHttpServerConfig` interface for streamable-http transport
* Updated `MCPTransport` type to `'sse' | 'streamable-http'`
* Added `SkillSource` type: `'cli' | 'marketplace' | 'manual'`
* Removed `MCPStdioServerConfig` (stdio not supported yet)

***

## v3.3.0

**Released:** January 20, 2026

### ✨ New Features

<AccordionGroup>
  <Accordion title="Complete Non-Interactive Mode for All Commands">
    All CLI commands now support full non-interactive operation, enabling seamless automation for AI IDEs, CI/CD pipelines, and shell scripting.

    **Design Patterns:**

    * Consistent option naming: `--<entity>-name` and `--<entity>-version`
    * `--force` flag for skipping confirmation prompts
    * `--json` flag for machine-readable output
    * Action arguments for entity management (view, versions, deploy, activate, deactivate)

    ```bash theme={null}
    # Entity management
    lua skills view
    lua skills versions --skill-name mySkill
    lua skills deploy --skill-name mySkill --skill-version 1.0.3

    # Init command
    lua init --agent-id abc123
    lua init --agent-name "My Bot" --org-id org1

    # Sync command
    lua sync --check    # CI drift detection
    lua sync --accept   # Auto-sync from server

    # Test command
    lua test skill --name get_weather --input '{"city": "London"}'

    # Logs command
    lua logs --type skill --name mySkill --limit 10 --json
    ```

    See the [Non-Interactive Mode Guide](/cli/non-interactive-mode) for complete documentation.
  </Accordion>

  <Accordion title="User Message and Agent Response Log Types">
    The logs command now supports filtering by user messages and agent responses:

    ````bash lua logs --type user_message --limit 20 lua logs --type agent_response theme={null}
    --limit 20 ``` - 💬 **User Messages**: View incoming user messages with
    channel and userId info - 🤖 **Agent Responses**: View AI-generated responses
    with distinct coloring
    </Accordion>

    <Accordion title="Function-Based Environment Resolution for MCP Servers">
      MCP server configurations now support dynamic environment variable resolution using the `env()` API:
      
      ```typescript
      const mcpServer = new LuaMCPServer({
        name: 'mongo-mcp',
        transport: 'stdio',
        command: 'npx',
        args: ['-y', '@mongodb/mcp-server'],
        env: () => ({
          MDB_CONNECTION_STRING: env("MDB_CONNECTION_STRING")
        })
      });
    ````

    Also supported for SSE transport with `url` and `headers` resolver functions.
  </Accordion>

  <Accordion title="Products.get() Filter Support">
    Added filter support to `Products.get()` with backward compatibility:

    ```typescript theme={null}
    // Backward compatible
    const products = await Products.get(1, 10);

    // New approach with filters
    const products = await Products.get({
      page: 1,
      limit: 10,
      filter: {
        category: 'electronics',
        inStock: true
      }
    });
    ```
  </Accordion>
</AccordionGroup>

### 🐛 Bug Fixes

* **Chat**: Allow `lua chat` to work without mandatory skills - agents can now have only webhooks, jobs, or processors
* **Commands**: Normalized action handling for case-insensitive action comparisons

### 🔧 Improvements

* **Chat Command**: Informational message when defaulting to sandbox environment
* **Chat Command**: Improved visual separation between compile logs and chat response
* **Env Command**: Proper error handling for save/delete operations
* **Push Command**: Shared helper functions reduce code duplication

***

## v3.2.0

**Released:** January 13, 2026

### ✨ New Features

<AccordionGroup>
  <Accordion title="Sync Command for Drift Detection">
    New `lua sync` command to detect drift between server and local code:

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

    **Features:**

    * Compare agent name and persona between server state and local code
    * Fetch latest published persona version (excludes drafts and rollbacks)
    * Show colored line-by-line diff for easy comparison
    * Interactive resolution: update local from server or continue with local
    * Integrated into compile flow with `--no-sync` and `--force-sync` flags
  </Accordion>

  <Accordion title="Chat History Clear Command">
    New `lua chat clear` command to clear conversation history:

    ```bash theme={null}
    # Clear all conversation history
    lua chat clear

    # Clear history for a specific user
    lua chat clear --user user@example.com
    ```

    Accepts userId, email, or mobile number as the identifier.
  </Accordion>

  <Accordion title="Lua Runtime API with Channel Type">
    New `Lua` namespace for runtime access:

    ```typescript theme={null}
    import { Lua } from 'lua-cli';

    // Access channel information
    const channel = Lua.request.channel; // 'dev', 'webchat', 'whatsapp', etc.
    ```

    Channel is typed as a union type: `'dev' | 'webchat' | 'whatsapp' | 'messenger' | 'voice' | 'api' | 'email'`
  </Accordion>

  <Accordion title="Lua.request.webhook for Raw Webhook Payload">
    Access raw webhook payloads in tool execute functions:

    ```typescript theme={null}
    import { Lua } from 'lua-cli';

    // Access raw webhook payload when triggered by webhook
    const webhookPayload = Lua.request.webhook;
    ```
  </Accordion>

  <Accordion title="Marketplace Pagination">
    Browse marketplace skills now supports pagination:

    * Navigate through pages with Previous/Next options
    * Shows page info (Page X/Y) and total count
    * Configurable page size (default: 10 items)
  </Accordion>
</AccordionGroup>

### 🔧 Improvements

* **Simplified Agent Creation**: Streamlined `lua init` flow with cleaner prompts
* **Better TypeScript Support**: Improved handling of path aliases and variable references in your code

### 🐛 Bug Fixes

* Fixed sync command occasionally showing false drift detection
* Fixed skill publishing issues
* Fixed compilation when skills are defined inline vs imported from separate files

***

## v3.1.0

**Released:** December 7, 2025

### ✨ New Features

<AccordionGroup>
  <Accordion title="MCP Server Support">
    New `LuaMCPServer` class for integrating Model Context Protocol servers with your agent:

    ```typescript theme={null}
    import { LuaMCPServer, LuaAgent } from 'lua-cli';

    const docsServer = new LuaMCPServer({
      name: 'lua-docs',
      transport: 'sse',
      url: 'https://docs.heylua.ai/mcp/sse'
    });

    export const agent = new LuaAgent({
      mcpServers: [docsServer]
    });
    ```

    **CLI commands:**

    * `lua mcp` - List, activate, deactivate, or delete MCP servers
    * `lua push mcp` - Push individual MCP servers
    * MCP servers included in `lua push all --force`
  </Accordion>

  <Accordion title="Tool Conditions">
    Tools can now have a `condition` function that determines if the tool is available:

    ```typescript theme={null}
    const adminTool = new LuaTool({
      name: 'admin-tool',
      condition: async () => {
        const user = await User.get();
        return user.data?.isAdmin === true;
      },
      execute: async (input) => { return 'admin action completed'; }
    });
    ```

    Use conditions to dynamically enable/disable tools based on user subscription, verification status, feature flags, or region.
  </Accordion>

  <Accordion title="CDN API">
    New `CDN` namespace for uploading and retrieving files:

    ```typescript theme={null}
    import { CDN } from 'lua-cli';

    // Upload a file
    const file = new File([buffer], 'image.png', { type: 'image/png' });
    const fileId = await CDN.upload(file);

    // Get file
    const file = await CDN.get(fileId);
    ```
  </Accordion>

  <Accordion title="Jobs API Enhancements">
    New methods for job management:

    ```typescript theme={null}
    // Get all jobs
    const jobs = await Jobs.getAll();

    // Activate/deactivate job scheduling
    await job.activate();
    await job.deactivate();

    // Manually trigger execution
    await job.trigger();
    ```
  </Accordion>

  <Accordion title="Evaluations Dashboard">
    New `lua evals` command opens the Evaluations Dashboard with your agent
    pre-configured. `bash lua evals `
  </Accordion>

  <Accordion title="Templates API">
    New `Templates` namespace for WhatsApp template messaging:

    ```typescript theme={null}
    import { Templates } from 'lua-cli';

    // List templates
    const result = await Templates.whatsapp.list(channelId);

    // Send template message
    await Templates.whatsapp.send(channelId, templateId, {
      phoneNumbers: ['+447551166594'],
      values: { body: { name: 'John' } }
    });
    ```
  </Accordion>

  <Accordion title="Marketplace CLI">
    New `lua marketplace` command for discovering, installing, and publishing
    skills: **For Creators:** - Publish skills to the global marketplace - Version
    management with semantic versioning - Environment variable configuration per
    version **For Installers:** - Browse and search for verified skills - Smart
    installation with dependency checks - Interactive environment variable
    configuration
  </Accordion>

  <Accordion title="Enhanced Logs Command">
    The `lua logs` command now features: - Interactive filtering by primitive type
    (Skills, Jobs, Webhooks, etc.) - Live data from API including dynamically
    created jobs - Context-aware log display with detailed metadata
  </Accordion>

  <Accordion title="Immutable User Profile">
    New `user._luaProfile` property for read-only core user data:

    ```typescript theme={null}
    const userId = user._luaProfile.userId;        // ✅ Recommended
    const fullName = user._luaProfile.fullName;
    const emails = user._luaProfile.emailAddresses;

    // user.userId still works but is deprecated
    ```
  </Accordion>
</AccordionGroup>

### 💥 Breaking Changes

<Warning>These changes may require updates to your existing code.</Warning>

<AccordionGroup>
  <Accordion title="JobInstance Restructured">
    `JobInstance` now receives the full `Job` entity with `activeVersion`:

    ```typescript theme={null}
    // Before
    const schedule = job.schedule;
    const id = job.jobId;

    // After
    const schedule = job.activeVersion.schedule;
    const id = job.id;
    await job.trigger(); // New method
    ```
  </Accordion>

  <Accordion title="welcomeMessage Removed from LuaAgent">
    The `welcomeMessage` field has been removed from `LuaAgent` configuration: -
    For voice: use `voiceConfig.welcomeMessage` - For chat widgets: use
    `WebchatChannelConfig.welcomeMessage`
  </Accordion>

  <Accordion title="Webhook Execute Signature Changed">
    Webhook execute functions now receive a single event object:

    ```typescript theme={null}
    // Before
    execute: async (query, headers, body) => {
      // handle webhook
    }

    // After
    execute: async (event) => {
      const { query, headers, body, timestamp } = event;
      // handle webhook
    }
    ```
  </Accordion>

  <Accordion title="PreProcessor Response Redesigned">
    `PreProcessorResult` now uses a discriminated union:

    ```typescript theme={null}
    // Block response
    return { action: 'block', response: 'Blocked' };

    // Proceed response
    return {
      action: 'proceed',
      modifiedMessage: [{ type: 'text', text: '...' }]
    };
    ```

    * `modifiedMessage` is now `ChatMessage[]` (array)
    * Added `priority` field for execution order
    * Removed `context` field
  </Accordion>
</AccordionGroup>

### 🔧 Improvements

* **Data API Type Safety**: `searchText` parameter added to `Data.create()` and `Data.update()`, `data` parameter type changed to `Record<string, any>`
* **PostProcessor Simplified**: Return type now requires `modifiedResponse: string`, removed `async` field
* **Compilation**: Handle `.js` extensions for Node16/NodeNext module resolution
* **Template**: Minimal by default, use `--with-examples` flag for examples
* **Web UI**: React Query, Sonner toasts, improved env panels, docs in toolbar

### 🛠️ Refactoring

* Removed `context` field from webhooks, jobs, and postprocessors
* Removed `version` field from `LuaSkill`, `LuaJob`, and processor configurations
* Improved push command: displays both `webhookId` and `webhook-name` URL formats
* Rewritten `interfaces/jobs.ts` to match `lua-api` DTOs exactly

***

## v3.0.3

**Released:** October 30, 2025

### 🎯 User API Enhancement

Enhanced `User.get()` method now accepts an optional `userId` parameter:

```typescript theme={null}
// Get current user (existing behavior)
const userData = await User.get();

// NEW: Get specific user by ID
const specificUser = await User.get('user_123456');
```

**Use Cases:**

* Fetch data for specific users in admin tools
* Access user information in webhooks/jobs
* Multi-user data operations
* User management features

<Note>
  This enhancement allows tools, webhooks, and jobs to access any user's data,
  enabling more sophisticated multi-user scenarios.
</Note>

***

## v3.0.2

**Released:** October 30, 2025

### 🚀 Major Improvements to Compilation System

This release brings comprehensive dependency bundling, debug mode, enhanced validation, and critical bug fixes.

<AccordionGroup>
  <Accordion title="Comprehensive Dependency Bundling">
    All components now properly bundle external dependencies:

    * ✅ **LuaWebhooks** bundle dependencies (e.g., Stripe, axios)
    * ✅ **LuaJobs** bundle dependencies
    * ✅ **PreProcessors** bundle dependencies (e.g., lodash)
    * ✅ **PostProcessors** bundle dependencies (e.g., date-fns)
    * ✅ **Nested Jobs** (`Jobs.create()`) independently bundle their own dependencies

    **Impact:** All compiled components are now truly portable and self-contained, requiring no dependency installation on deployment targets.
  </Accordion>

  <Accordion title="Debug Mode">
    Added `--debug` flag to `lua compile` command: `bash lua compile --debug #
          or LUA_DEBUG=true lua compile ` **Features:** - Verbose step-by-step logging

    * Shows detected imports and dependencies - Displays bundle sizes
      (uncompressed and compressed) - Preserves temp files for inspection - Shows
      timing information for each component - Full error stack traces
  </Accordion>

  <Accordion title="Enhanced Validation">
    * **tsconfig.json validation** - Clear error if missing or invalid - **Empty
      bundle detection** - Warns about suspiciously small bundles (under 100 bytes)
    * **Bundle output validation** - Ensures esbuild creates valid output - **Null
      config handling** - Graceful compilation without lua.skill.yaml - **Safe
      optional chaining** - Fixed crash when agentData is null
  </Accordion>

  <Accordion title="Improved Error Handling">
    Context-aware error messages with actionable hints: - Dependency resolution
    failures → "Run npm install" - TypeScript syntax errors → "Check syntax in
    filename.ts" - Missing files → Shows expected path - Full stack traces in
    debug mode
  </Accordion>

  <Accordion title="Import Resolution">
    Enhanced `resolveImportPath()` to support:

    * `.ts`, `.tsx`, `.js`, `.jsx` files
    * Directory imports (`index.ts`, `index.tsx`, `index.js`)

    **Critical Fix:** Relative imports now work correctly in Jobs, Webhooks, and Processors:

    ```typescript theme={null}
    // ✅ Now works perfectly
    import { MyService } from "../services/MyService";
    // ✅ Also works
    import { MyService } from "@/services/MyService";
    ```
  </Accordion>
</AccordionGroup>

### 🐛 Bug Fixes

* Fixed null reference error when compiling without LuaAgent
* Fixed crash when lua.skill.yaml is missing
* Fixed compilation with empty agent name/persona
* **Critical:** Fixed relative import resolution in all component types

### 🧹 Code Quality

* Removed obsolete `dynamic-job-bundler.ts`
* Extracted common helpers (`extractRelevantImports`, `bundleAndCompressExecuteFunction`)
* Reduced bundling.ts from 1,149 to 1,036 lines (9.8% reduction)
* Added 27 comprehensive tests for bundling, execution, validation, and relative imports

***

## v3.0.0

**Released:** October 2025

### 🎉 Major Release

Version 3.0.0 focuses on developer experience, deployment automation, and real-time chat capabilities.

### ✨ New Features

<AccordionGroup>
  <Accordion title="LuaAgent - Unified Configuration">
    The flagship feature: a single, intuitive way to configure your entire agent.

    **Before (v2.x):**

    ```typescript theme={null}
    export const skill1 = new LuaSkill({ name: 'skill1', tools: [] });
    export const skill2 = new LuaSkill({ name: 'skill2', tools: [] });
    export const webhook1 = new LuaWebhook({ name: 'webhook1', execute: async () => 'ok' });
    ```

    **After (v3.0.0):**

    ```typescript theme={null}
    export const agent = new LuaAgent({
      name: 'my-assistant',
      persona: 'You are a helpful AI assistant...',
      skills: [skill1, skill2],
      webhooks: [webhook1],
      jobs: [job1],
      preProcessors: [processor1],
      postProcessors: [processor2]
    });
    ```

    **Benefits:**

    * Single source of truth
    * Clearer organization
    * Automatic YAML synchronization
    * Better IDE support
  </Accordion>

  <Accordion title="Streaming Chat Interface">
    Real-time chat responses with improved UX: `bash lua chat ` - ✅ Animated
    typing indicator while waiting - ✅ Text streams character-by-character - ✅
    Sandbox and production environment selection - ✅ Uses `/chat/stream` endpoint
    for real-time updates
  </Accordion>

  <Accordion title="Batch Deployment">
    New command for deploying all components without prompts: `bash # Push all
          with auto-versioning lua push all --force # Push and deploy to production lua
          push all --force --auto-deploy ` **What it does:** 1. Compiles project 2.
    Reads all components from `lua.skill.yaml` 3. Increments patch versions
    automatically 4. Pushes all components to server 5. Deploys to production (if
    `--auto-deploy`) **Features:** - Auto-bumps patch versions (e.g., `1.0.0` →
    `1.0.1`) - Perfect for CI/CD pipelines - Retry mechanism with exponential
    backoff
  </Accordion>

  <Accordion title="API Key Fallback">
    Flexible authentication with multiple sources (priority order): 1. **System
    Keychain** (macOS Keychain, Windows Credential Vault, Linux libsecret) 2.
    **Environment Variable** (`LUA_API_KEY`) 3. **.env File** (`LUA_API_KEY=...`)
    **Usage in CI/CD:** `bash export LUA_API_KEY=your-key lua push all --force   --auto-deploy `
  </Accordion>

  <Accordion title="Auto-Sync YAML and Code">
    Bidirectional synchronization ensures consistency:

    **On `lua init`:**

    * Agent name, persona → YAML + `index.ts` LuaAgent

    **On `lua compile`:**

    * LuaAgent persona → YAML

    No manual synchronization needed!
  </Accordion>
</AccordionGroup>

### 🔧 Improvements

<AccordionGroup>
  <Accordion title="Enhanced Bundling">
    * Excluded lua-cli internals from bundles
    * Reduced bundle sizes by 50-70%
    * Fixed relative import issues
    * Proper sandbox globals (tools use sandbox-provided APIs)
  </Accordion>

  <Accordion title="Jobs.create() Fixes">
    * `code` field now properly compressed and included - Execute function
      properly converts to strings - Excludes lua-cli imports from job execute
      functions - Better metadata support for passing data
  </Accordion>

  <Accordion title="Developer Experience">
    * Comprehensive template with 30+ example tools
    * Quick Start Guide for new users
    * TypeScript examples with best practices
    * CI/CD integration examples
  </Accordion>
</AccordionGroup>

### 🐛 Bug Fixes

**Bundling:**

* Fixed `Cannot find module '../services/ApiService'` in pre-bundled tools
* Fixed `process.cwd is not a function` in sandbox execution
* Fixed lua-cli API code being bundled into tools

**Push & Deploy:**

* Fixed webhooks and jobs not found during `push all`
* Fixed missing `tools` array causing validation errors
* Fixed deployment timing issues with retry mechanism

**Chat:**

* Fixed welcome message reading from `lua.skill.yaml`
* Fixed streaming endpoint integration
* Fixed typing indicator cleanup on errors

### 💥 Breaking Changes

<Warning>These changes require updates to your existing code.</Warning>

<AccordionGroup>
  <Accordion title="LuaAgent Required">
    **Old Way:**

    ```typescript theme={null}
    export const skill1 = new LuaSkill({ name: 'skill1', tools: [] });
    export const skill2 = new LuaSkill({ name: 'skill2', tools: [] });
    ```

    **New Way:**

    ```typescript theme={null}
    export const agent = new LuaAgent({
      skills: [skill1, skill2]
    });
    ```

    **Migration:**

    1. Wrap your existing skills in a `LuaAgent`
    2. Add `name` and `persona` fields
    3. Run `lua compile` to sync with YAML
  </Accordion>

  <Accordion title="Chat Endpoint Changed">
    * Old: `/chat/generate/:agentId` - New: `/chat/stream/:agentId` No action
      needed - handled automatically by CLI.
  </Accordion>

  <Accordion title="Jobs.create() Signature">
    Jobs must use `metadata` for data passing:

    ```typescript theme={null}
    await Jobs.create({
      metadata: { userId: input.userId },
      execute: async (job) => {
        const userId = job.metadata.userId;
      }
    });
    ```
  </Accordion>
</AccordionGroup>

### 📊 Statistics

| Metric            | Before  | After          |
| ----------------- | ------- | -------------- |
| Bundle overhead   | \~500KB | 50-70% smaller |
| Compilation speed | -       | 30% faster     |
| Template examples | 5       | 30+            |
| CLI commands      | -       | 25+            |

***

## Upgrade Guides

### From v3.0.x to v3.1.0

```bash theme={null}
npm install lua-cli@3.1.0
```

**Required changes:**

1. Update `JobInstance` access patterns (use `activeVersion.schedule`, `id` instead of `jobId`)
2. Update webhook execute functions to use event object
3. Update PreProcessor responses to use discriminated union
4. Remove `welcomeMessage` from LuaAgent (configure on channel/voice instead)

### From v2.x to v3.0.0

```bash theme={null}
npm install lua-cli@3.0.0
```

**Required changes:**

1. Wrap skills in a `LuaAgent` configuration
2. Update jobs to use `metadata` for data passing
3. Run `lua compile` to sync with YAML

```typescript theme={null}
// src/index.ts
import { LuaAgent } from 'lua-cli';

export const agent = new LuaAgent({
  name: 'my-agent',
  persona: 'Your agent persona...',
  skills: [
    /* your existing skills */
  ],
});
```
