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

# Automation and CI

> Run Narya from a pipeline with one command and an exit code, put work on a clock, and orchestrate several agents from a script.

A pipeline drives Narya the way you do: the binary, a prompt, a credential in the environment, and an exit code.

## One turn from a command line

***

`narya -p "<prompt>"` runs one turn and answers on standard output. Its flags:

* `--repo <path>` sets the working repository, and defaults to the working directory.
* `--model <id>` chooses the model.
* `--agent <name>` runs the turn under a named agent.
* `--session <id>` continues an existing session.
* `--style <name>` names a response style you declared as `[styles.<name>]` in `config.toml`. It cannot join `--session`.
* `--json` switches the output to a machine shape.

## Exit codes

***

| Code  | Meaning                                                                                                                |
| ----- | ---------------------------------------------------------------------------------------------------------------------- |
| `0`   | The turn ran to its end. The answer is on standard output.                                                             |
| `1`   | The turn failed. A key the provider rejected lands here.                                                               |
| `2`   | Usage, configuration, or a store that another Narya process holds. No credential for the resolved provider lands here. |
| `130` | Interrupted. The transcript survives, and `--session` resumes it.                                                      |

The two credential failures carry different codes on purpose. An absent key exits `2`, and a rejected key exits `1`. Retry on `1`. On `2`, read the message first: a held store clears on its own, and a missing credential does not.

<Warning>
  A turn that stops early still exits `0`. Three endings do this: an output ceiling, the provider's content filter, and a spend ceiling. The exit code alone cannot tell a cut answer from a complete one. Narya names the first two on standard error, and `--json` carries all three as `stopReason` on the `turn-finished` event.
</Warning>

## The two shapes of `--json`

***

`narya -p --json` streams one event envelope per line on standard output. Each line carries `id`, `type` and `timestamp`. A line adds `sessionId` and `laneId` when the event belongs to a session or a lane. `payload` is `null` when the event carries no body. Plain output carries the main lane alone. The stream carries every lane, so select on `laneId`. These are the same event envelopes the host streams on [its API](/en/narya/the-host-api), so a pipeline and a client read one format.

Every other command answers with one document. The actions share one envelope:

```json theme={null}
{"command":"narya retention run","result":"swept","changed":{},"exitCode":0}
```

`result` is one word to branch on. `changed` appears only on a run that changed something. A non-zero exit carries `reason` instead.

`narya schedule add`, `narya schedule rm`, `narya schedule budget` and `narya export` publish their own document on success, and print the envelope only on failure. Branch on the exit code for those four, never on `result`.

Under `--json`, standard output carries the document or the stream and nothing else. Sentences for a person go to standard error.

## The credential on a runner

***

Put the provider key in your CI secret store and hand it to the step as `<PROVIDER>_API_KEY`. The process that calls the supplier reads that variable from its own environment, so a runner with no host running consults no keychain and stores nothing.

```yaml theme={null}
name: narya review

on: pull_request

permissions:
  contents: read

jobs:
  review:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
        with:
          fetch-depth: 0
          persist-credentials: false

      # Add a step here that places your licensed narya binary on PATH.
      - name: Ask Narya
        env:
          ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
          # Pass the ref through env, never into the script text. A ref with
          # shell metacharacters would run as script on this runner.
          BASE_REF: ${{ github.base_ref }}
        run: |
          narya -p "Read the changes on this branch against origin/$BASE_REF.
          Name every change that breaks a caller, with the file and why."
```

The step fails when Narya exits non-zero, and the answer lands in the job log.

<Note>
  Narya reads the branch's own history, so check out the full branch.
</Note>

## Schedules

***

Put work on the host's clock.

* `narya schedule add "<prompt>" --every <duration>` repeats on an interval, and `--at <RFC3339>` fires once.
* Add `--repo <path>`, `--agent <name>` or `--budget <usd>` to either form.
* `narya schedule list` lists what exists, and `narya schedule rm <schedule-id>` removes one.
* `narya schedule budget <schedule-id> on <usd>` or `off` changes the ceiling on an existing schedule.

Narya refuses to create a schedule in a directory nobody trusts. All four verbs talk to the running host.

The spend ceiling is on by default. If you set no `--budget`, the schedule takes the operator's default, `$5.00` per fire, as `[schedules] ceiling_usd`. If you set a number, Narya keeps it. If you set `0`, Narya stores the schedule and refuses to fire it until you set a budget.

## Workflows

***

A workflow is a JavaScript program that orchestrates agents. Start one by path or as inline source, over the host API. Narya refuses an invalid program before anything runs.

A workflow program calls four capabilities:

* `agent(step, agent, task)` runs one agent.
* `agents([...])` runs one wave, read in the order you asked.
* `step(name, value)` records a step.
* `args` hands the program its own run's arguments.

Three ceilings are constants, and no setting changes them: 72 hours per run, 4,096 host calls, and 4 hours per step. Narya snapshots the source at submission, so a resumed run uses the source that was submitted.
