Metadata-Version: 2.4
Name: orchestra-cli
Version: 0.3.2
Summary: Orchestra CLI. Perform operations with Orchestra locally.
Author-email: Orchestra Technologies <support@getorchestra.io>
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Requires-Dist: click
Requires-Dist: httpx>=0.28.1
Requires-Dist: pydantic>=2.13.4
Requires-Dist: pyyaml>=6.0.2
Requires-Dist: typer>=0.16.0

# orchestra-cli

Orchestra CLI for working with Orchestra pipelines from your terminal.

Two entrypoints are available: `orchestra` and `orchestra-cli` (they are equivalent).

See [`AGENTS.md`](AGENTS.md) for contributor and AI agent guidance (environment setup, code conventions, testing).

## Installation

```bash
pip install orchestra-cli
```

Or with pipx:

```bash
pipx install orchestra-cli
```

## Environment variables

- `ORCHESTRA_API_KEY`: Required for actions that call the API (`pipeline import`, `pipeline new`, `pipeline update`, `pipeline migrate`, `pipeline get`, `pipeline list`, `pipeline delete`, `pipeline run`, `pipeline build`).
- `BASE_URL`: Optional. Override the default Orchestra host (`https://app.getorchestra.io`) for non‑production/testing.

## Command structure

Commands follow a `noun verb` shape. The current nouns are `pipeline` and `task`:

| Command                              | Description                                                                                 |
| ------------------------------------ | ------------------------------------------------------------------------------------------- |
| `orchestra pipeline validate <file>` | Validate a pipeline YAML locally against the Orchestra API schema.                          |
| `orchestra pipeline import`          | Register a pipeline YAML (from a git repo) with Orchestra under an alias.                   |
| `orchestra pipeline get`             | Fetch one pipeline by path, alias, or pipeline ID.                                          |
| `orchestra pipeline list`            | Fetch the pipelines visible to the current API key as JSON.                                 |
| `orchestra pipeline new`             | Create an Orchestra-backed pipeline from a local YAML file.                                 |
| `orchestra pipeline update`          | Update an existing Orchestra-backed pipeline from a local YAML file.                        |
| `orchestra pipeline migrate`         | Migrate an Orchestra-backed pipeline to git-backed storage.                                 |
| `orchestra pipeline delete`          | Delete an existing pipeline by alias.                                                       |
| `orchestra pipeline run`             | Start a pipeline run by alias, optionally pinning branch/commit and waiting for completion. |
| `orchestra pipeline build`           | Validate local YAML, create or update a draft pipeline, and start that draft version.       |
| `orchestra task logs`                | Fetch or follow logs for a single task run.                                                 |

Use `orchestra --help`, `orchestra <noun> --help`, or `orchestra <noun> <verb> --help` for built-in help.

### Legacy command names

The previous flat command names continue to work as hidden top-level aliases so existing scripts keep running:

| Legacy alias                | New canonical form            |
| --------------------------- | ----------------------------- |
| `orchestra validate`        | `orchestra pipeline validate` |
| `orchestra import`          | `orchestra pipeline import`   |
| `orchestra fetch-pipelines` | `orchestra pipeline list`     |
| `orchestra create-pipeline` | `orchestra pipeline new`      |
| `orchestra update-pipeline` | `orchestra pipeline update`   |
| `orchestra delete-pipeline` | `orchestra pipeline delete`   |
| `orchestra run`             | `orchestra pipeline run`      |

New code and documentation should prefer the noun/verb form.

---

## pipeline validate

Validate a YAML file against the Orchestra API schema.

```bash
orchestra pipeline validate path/to/pipeline.yaml
# or
orchestra-cli pipeline validate path/to/pipeline.yaml
```

Options

- `file` (positional): Path to the YAML file to validate.

Behavior

- Prints a success message on valid input.
- On validation errors, prints the failing location(s), readable messages, and a YAML snippet when possible.
- Exit codes: `0` on success, `1` on invalid file/validation failure/HTTP error.

Example output (failure)

```text
❌ Validation failed with status 422
Error at: pipeline.tasks[0].type
  Invalid task type "foo"

YAML snippet:
pipeline:
  tasks:
    - type: foo
```

---

## pipeline import

Create (import) a pipeline in Orchestra by referencing a YAML file inside a git repository. The command infers your repository host/provider, default branch, and YAML path relative to the repo root.

```bash
export ORCHESTRA_API_KEY=...  # required

orchestra pipeline import \
  --alias my-pipeline \
  --path ./pipelines/pipeline.yaml \
  --working-branch my-feature-branch   # optional; defaults to current local branch
# or
orchestra-cli pipeline import -a my-pipeline -p ./pipelines/pipeline.yaml
```

Options

- `-a, --alias` (required): The alias you want to register the pipeline under.
- `-p, --path` (required): Path to the YAML file. Must be inside a git repository.
- `-w, --working-branch` (optional): Branch to associate as the working branch for this pipeline import. If omitted, the current local git branch is used.

Notes

- The YAML is validated with the API before import; failures are printed clearly.
- Git details are detected automatically:
  - Supported providers: GitHub, GitLab, Azure DevOps.
  - The default branch is detected from `origin`.
  - The working branch defaults to your current local branch when not specified.
  - The YAML path is computed relative to the repository root.
- On success, the command prints the created pipeline ID (or a success message).
- Exit codes: `0` on success, `1` on failure.

Common errors

- Missing `ORCHESTRA_API_KEY`.
- Not running inside a git repository, or no `origin` remote configured.
- Could not detect storage provider or default branch.

---

## pipeline new

Create an Orchestra-backed pipeline directly from a local YAML file.

```bash
export ORCHESTRA_API_KEY=...

orchestra pipeline new \
  --alias my-pipeline \
  --path ./pipelines/pipeline.yaml \
  --publish            # optional, defaults to --no-publish
```

Options

- `-a, --alias` (required): Pipeline alias.
- `-p, --path` (required): Path to pipeline YAML file.
- `--publish/--no-publish` (optional, default `--no-publish`): Whether the pipeline is published.

Behavior

- Validates YAML against the Orchestra schema endpoint before creating.
- Sends pipeline data to `POST /pipelines` with `storage_provider=ORCHESTRA`.
- On success, prints the pipeline edit URL (`/pipelines/{pipeline_id}/edit`) when an ID is returned.
- Exit codes: `0` on success, `1` on failure.

---

## pipeline get

Fetch one pipeline using the shared pipeline selector flags.

```bash
export ORCHESTRA_API_KEY=...

orchestra pipeline get --alias my-pipeline
orchestra pipeline get --pipeline-id f374e795-50aa-4aeb-9936-d68d2b90475c
orchestra pipeline get --path ./pipelines/pipeline.yaml
```

Options

- `-a, --alias` (optional): Pipeline alias.
- `-i, --pipeline-id` (optional): Pipeline ID.
- `-p, --path` (optional): Path to pipeline YAML file. Inside a git repository, this resolves to `repository` and `yaml_path`; outside a git repository, the CLI prompts to use a generated alias.

Behavior

- Resolves the selector using the shared rules: alias first, then pipeline ID, then path.
- Sends `GET /api/engine/public/pipeline` with the resolved selector.
- Prints the returned pipeline metadata in a labeled, human-readable format.
- Exit codes: `0` on success, `1` on failure.

---

## pipeline list

Fetch the pipelines available to the current Orchestra API key.

```bash
export ORCHESTRA_API_KEY=...

orchestra pipeline list
```

Behavior

- Sends `GET /api/engine/public/pipelines`. Responses always include each pipeline's latest run metadata.
- Prints the response payload as pretty JSON for scripting and inspection.
- Exit codes: `0` on success, `1` on failure.

---

## pipeline update

Update an existing pipeline from a local YAML file.

```bash
export ORCHESTRA_API_KEY=...

orchestra pipeline update \
  --alias my-pipeline \
  --path ./pipelines/pipeline.yaml \
  --no-publish         # default
```

Options

- `-a, --alias` (optional): Pipeline alias.
- `-i, --pipeline-id` (optional): Pipeline ID.
- `-p, --path` (required): Path to pipeline YAML file.
- `--publish/--no-publish` (optional, default `--no-publish`): Whether the pipeline is published.
- `--force/--no-force` (optional, default `--no-force`): Skip interactive confirmation prompts when the CLI generates aliases or performs git-backed commit/branch fallback actions.

Behavior

- Validates YAML against the Orchestra schema endpoint before updating.
- Resolves the pipeline selector with shared rules (alias, then pipeline ID, then `repository + yaml_path` from `--path` inside git).
- Fetches pipeline metadata from `GET /pipeline` before mutating.
- If the pipeline is Orchestra-backed, updates it through `PUT /pipelines` using `alias` or `pipeline_id`.
- If the pipeline is git-backed, applies the same commit/push protection flow as `pipeline build`, then reports the branch + commit used.
- For Orchestra-backed success, prints the pipeline edit URL (`/pipelines/{pipeline_id}/edit`) when an ID is returned.
- Exit codes: `0` on success, `1` on failure.

---

## pipeline migrate

Migrate an existing Orchestra-backed pipeline to git-backed storage.

```bash
export ORCHESTRA_API_KEY=...

orchestra pipeline migrate \
  --alias my-pipeline \
  --path ./pipelines/pipeline.yaml
```

Options

- `-p, --path` (required): Target YAML path inside your git repository.
- `-a, --alias` (optional): Pipeline alias selector.
- `-i, --pipeline-id` (optional): Pipeline ID selector.
- `--default-branch` (optional): Defaults to your git remote default branch.
- `--working-branch` (optional): Defaults to your current git branch (unless it matches default branch).

Behavior

- Requires a git repository and a resolvable `origin` remote.
- Fetches the selected pipeline, verifies it is Orchestra-backed, then downloads pipeline YAML from Orchestra.
- If published and latest versions differ, prompts which version to migrate.
- If a local file already exists at `--path` and differs, prompts to overwrite, keep local, or choose a new path.
- Commits and pushes the selected YAML path before calling `PATCH /pipelines/storage-settings`.
- If push is blocked by branch protection, suggests a new migration branch and offers to retry there.
- Prints a compare/PR link when migration is pushed to a non-default branch.

---

## pipeline delete

Delete a pipeline by alias.

```bash
export ORCHESTRA_API_KEY=...

orchestra pipeline delete --alias my-pipeline
```

Options

- `-a, --alias` (required): Pipeline alias to delete.

Behavior

- Sends `DELETE /pipelines/{alias}` with API key authentication.
- Deletes the pipeline resolved by alias within the authenticated account.
- On success, exits with code `0` after printing a confirmation message.
- Exit codes: `0` on success, `1` on failure.

---

## pipeline run

Start a pipeline run by alias. Optionally specify a branch and/or commit. By default, the command waits and polls the run status until completion.

```bash
export ORCHESTRA_API_KEY=...

# Start and wait for completion
orchestra pipeline run --alias my-pipeline

# Start without waiting (prints run id and exits)
orchestra pipeline run -a my-pipeline --no-wait

# Start for a specific branch/commit
orchestra pipeline run -a my-pipeline -b feature/my-change -c 0123abc
```

Options

- `-a, --alias` (required): Pipeline alias to run.
- `-b, --branch` (optional): Git branch name to associate with this run.
- `-c, --commit` (optional): Commit SHA to associate with this run.
- `--wait/--no-wait` (default: `--wait`): Poll until the run ends.
- `--force/--no-force` (default: `--no-force`): Skip confirmation if local git warnings are detected.

Behavior

- Prints the run ID when known and a link to the run lineage page.
- When waiting, polls status every ~5s until a terminal state:
  - `SUCCEEDED` (exit `0`), `WARNING` (exit `0`), `SKIPPED` (exit `0`)
  - `FAILED` or `CANCELLED` (exit `1`)
- When not waiting, exits after start and prints the run ID.

Non-interactive usage

- If your repo has warnings (e.g., uncommitted changes), the CLI prompts for confirmation unless `--force` is provided. For CI or scripts, pass `--force` or ensure a clean repo.

---

## pipeline build

Validate a local pipeline YAML, create or update its draft pipeline definition, then start that draft version. This is intended for quick local iteration without publishing a pipeline first.

```bash
export ORCHESTRA_API_KEY=...

# Build from a local YAML file and wait for completion.
# Alias is optional; if omitted, the CLI resolves the pipeline from the shared selector rules
# and generates an alias from --path when it needs to create a new draft.
orchestra pipeline build --path ./pipelines/pipeline.yaml

# Build a specific existing pipeline by alias or pipeline ID
orchestra pipeline build --path ./pipelines/pipeline.yaml --alias my-pipeline
orchestra pipeline build --path ./pipelines/pipeline.yaml --pipeline-id f374e795-50aa-4aeb-9936-d68d2b90475c

# Run against a specific branch/commit override
orchestra pipeline build -p ./pipelines/pipeline.yaml -a my-pipeline -b feature/my-change -c 0123abc
```

Options

- `-p, --path` (required): Path to pipeline YAML file.
- `-a, --alias` (optional): Pipeline alias. You can omit this flag entirely and still build from `--path` alone—the CLI resolves the target using the shared selector rules and only prompts for or generates an alias when it must create a new draft pipeline.
- `-i, --pipeline-id` (optional): Pipeline ID.
- `-b, --branch` (optional): Git branch name to associate with the draft run.
- `-c, --commit` (optional): Commit SHA to associate with the draft run.
- `--wait/--no-wait` (default: `--wait`): Poll until the run ends.
- `--force/--no-force` (default: `--no-force`): Skip confirmation if local git warnings are detected.

Behavior

- Validates the local YAML with the schema endpoint before any pipeline mutation.
- Treats `--alias` as optional and resolves the target pipeline using the shared selector rules: alias first, then pipeline ID, then path.
- When only `--path` is provided inside a git repository, the CLI looks up the existing pipeline using `repository` + `yaml_path`.
- When the pipeline does not exist, the CLI creates a draft Orchestra-backed pipeline from the local YAML, generating an alias from `--path` via the shared selector helper when needed.
- When the pipeline exists and is Orchestra-backed, the CLI updates that draft and starts the returned `versionNumber`, preserving the same wait, polling, and branch/commit override behavior as `pipeline run`.
- Existing git-backed pipelines reuse the same commit + branch-protection logic as `pipeline update`, then run using the resolved branch/commit target.
- Exit codes follow `pipeline run`: success terminal states return `0`; failed or cancelled runs return `1`.

---

## task logs

Fetch or follow logs for a single task run.

```bash
export ORCHESTRA_API_KEY=...

# Select a log file interactively, then follow it
orchestra task logs --task-run-id 3d68b5dc-54eb-43db-8294-4734d032ff92

# Follow a specific log file
orchestra task logs -tr 3d68b5dc-54eb-43db-8294-4734d032ff92 -f main.log

# Print the current contents once without waiting for new lines
orchestra task logs -tr 3d68b5dc-54eb-43db-8294-4734d032ff92 -f main.log --no-watch
```

Options

- `-tr, --task-run-id` (required): Task run ID to fetch logs for.
- `-f, --filename` (optional): Specific log filename to fetch.
- `--no-watch` (optional): Print the current log content once instead of waiting for new lines.

Behavior

- Resolves the task run's pipeline run ID automatically.
- If no filename is provided, lists available log files and prompts for a selection.
- By default, polls the log download endpoint using byte ranges and prints only new content as it arrives until the file is complete.
- Press `Ctrl+C` to stop following logs.

---

## Examples

```bash
# Validate a pipeline file
orchestra pipeline validate ./examples/etl.yaml

# Import a pipeline and capture the created ID
PIPELINE_ID=$(orchestra pipeline import -a finance-etl -p ./pipelines/etl.yaml)

# Start a run and wait for completion
orchestra pipeline run -a finance-etl

# Start a run and exit immediately
orchestra pipeline run -a finance-etl --no-wait

# Build a draft pipeline from local YAML and let the CLI generate an alias if needed
orchestra pipeline build -p ./pipelines/etl.yaml

# Follow task run logs
orchestra task logs -tr 3d68b5dc-54eb-43db-8294-4734d032ff92 -f main.log
```

---

## Development

- Make sure [uv](https://github.com/astral-sh/uv) is installed
- Use `uv pip install -e ".[dev]"` to install the CLI in editable mode for development
- For local development, run `uv run orchestra` to start the CLI
  - you can use `uv run --env-file .env ...` to run the CLI with env vars
- For testing, run `uv run pytest`
- For linting, run `uv run ruff check .`
- For formatting, run `uv run black --check .`
- For type checking, run `uv run pyright`

## Building and Releasing

- Bump the version in `pyproject.toml` or by running `uv version --bump <major/minor/patch>`
- Run `uv sync` to install the dependencies
- Run `uv build` to build the CLI
- Run `uv publish` to publish the CLI (you will need to pass the `--token` flag)

**Note: Failure to bump the version will result in a failed release.**
