Skip to main content

Delta CLI

Durable per-step execution budgets are declared in pyproject.toml; see step timeouts for precedence, runtime limits and rollout.

Delta CLI is a command line interface for the Delta service.

This repository contains the Delta command router, version output, and browser-based CLI authentication.

Features

  • Built-in help via delta --help and per-command --help
  • Version output via delta version and delta --version
  • OAuth login with Authorization Code + PKCE
  • One-shot 127.0.0.1:8400 callback server or an optional Console callback handoff
  • Session storage in ~/.trampoline-ai/delta/auth.json with owner-only permissions
  • Automatic bearer authentication for service API commands

Project selectors

--project accepts a stable ID beginning with proj_ or an exact project name in the selected organization. Quote names containing spaces, for example delta flows list --org ORG --project "Daily reports". Names are resolved through the same paginated API as delta projects list; unknown names fail with no project named NAME in ORG; see delta projects list. Duplicate names fail with the matching IDs so you can select one explicitly. IDs bypass the lookup, including legacy proj_ IDs without a project record. Configuration and DELTA_PROJECT selectors follow the same rule.

This applies to deploy, runs, flows, deployments, schedules, and webhooks. For env commands, --project remains a boolean scope flag; --project-id accepts an ID or name.

Terminal UI (delta tui, opt-in)

uv tool install trampoline-delta
# In the workflow project, add avalanche-ai>=0.15.0 and run uv sync.
delta tui --org ORG --project "Daily reports"
delta tui --org ORG --project PROJECT --flow hello --run RUN --read-only

The CLI has no [tui] extra and its base dependency closure contains no Avalanche, PredictRLM, DSPy, LiteLLM or Textual. delta tui launches the project's <project root>/.venv/bin/python, or the explicit --python PATH. It requires avalanche-ai>=0.15.0, TuiExtensions v1 and the revamped store contract in that interpreter. A subprocess preflight fails before authentication or HTTP if these are missing; add the dependency to the project and run uv sync. The CLI never installs, syncs or relocks on TUI launch. There is no legacy fallback. The standalone provider/launcher ships in the Delta wheel and is loaded by absolute path; Delta need not be installed in the project. Credentials pass only through the child environment, never its argv. The terminal is inherited, child exit codes propagate, and Ctrl-C/teardown terminates its process group.

Authentication, DELTA_TOKEN, upward delta.toml discovery, org selection and project ID/exact-name resolution are shared with the other commands. Conflicting flow/run links are refused. Use the command palette for provider panels and explicit actions. Catalogs pin the finalized deployment used to discover them; unknown historical deployment/flow/timestamps remain unknown in the inspector.

  • Project history is paged; existing APIs without snapshot revisions expose incomplete loaded windows, not a fictitious stable full-history snapshot.
  • Selecting a run loads its detail once, then reduces its contiguous fact SSE. Resume uses that run's Last-Event-ID, never another run's maximum sequence. There is no periodic resource GET or network health/ping loop. A stream reset rereads selected detail and installs its hydrated nodes/error in the baseline before ACK; a terminal frame reuses the last fact ID, not a new data position. Covered pre-cut states are not replayed over that baseline, and queued detail updates are released once. Missing optional project events keeps project scope stale but does not prevent selected-run fact reconciliation.
  • Observation reads are auxiliary: any non-2xx (including 503 observation_integrity, observation_unavailable or observation_pending) leaves the fact stream and baseline intact. Log/trace detail shows observation unavailable: <reason> without inventing trace/evidence or changing execution status. Failed attempt identities are cached; only node selection or explicit refresh permits a reread. There are no automatic observation retries, including when Retry-After is supplied. A known CONSOLE-owned read-before-archive race can briefly return observation_integrity; this client does not read spill storage or hide a failed completion-log/trace proof.
  • Project notices, live activity, original inputs, effective capabilities and org discovery are negotiated. Unsupported panels/streams are hidden; Server availability reports “not available on this server.” The shared CONSOLE project-feed adapter follows its frozen contract, including opaque cursors. M1 notices concern runs only. Catalog/schedule/env reads refresh on selection, reset/reconnect or explicit panel refresh, never on a timer.
  • --read-only, or lack of server-verified run:create, disables all backend mutations. Without a capabilities endpoint, actions remain unavailable with a reason; decoded JWT claims never grant permission. Downloads separately need verified storage:read, an explicit destination and confirmation.
  • Start previews schema-validated input and pins deployment + SID. Retry the same intent and exact payload after an uncertain result or 429 run_rate_limited; Retry-After is shown, with no automatic replacement intent. Cancel retains its command ID; 202 means requested, not terminated. Only genuinely resolvable legacy waits are offered. Schedules have disable only, never enable/toggle.
  • Env inspection retains names/flags/provenance only and immediately discards values. Observations pin node/attempt/auth; absent/truncated traces are not manufactured. Live activity and retained terminal traces are separate surfaces.

Local headless proof

make dev, then make dev-hello ARGS='--tui', extends the existing real Compose hello fixture with Textual Pilot navigation, a live DAG through fact SSE, a strict single selected-detail GET assertion, resize, and read-only checks. The Pilot runs through the wheel's absolute-path tui_entry.py loader in the fixture's project .venv, with -I so neither the project nor scripts/dev/runtime.py can shadow Avalanche's packages. The fixture uses published Avalanche 0.15.0 without wheel/index overrides. Check other lanes' Compose stacks and use an owned project name before starting it. The fixture also deploys tui-agent: two deterministic JSON DummyLM actions (plan/code), with no external LM calls. The Pilot opens its native agent trace inspector and checks hydrated iteration code/output and retained usage. tui-failing-agent deliberately uses incompatible DummyLM output to exhaust three real agent attempts. The Pilot forces one provider reset at the first retry, lets the run seal while baseline loading is paused, then checks a complete hydrated failed baseline, exact ACK, once-only buffered detail delivery, failed DAG/history, and the native node-detail error. This is a controlled reset cut, not a claim to reproduce every spontaneous transport failure. Existing success-path request-count assertions are unchanged. Cancel uses the provider when capabilities permit it; otherwise the authorized fixture client performs the write and the Pilot asserts its cancel control is disabled. New-stream checks that lack server support are reported NOT RUN, not counted as passing. Allow-all Compose is not a Clerk permission proof.

Schedules (/v1)

CLI 0.3.9 builds containing scheduled dispatch add delta schedules create, list, get and disable. The server must also contain the dispatch capability; older versions only store schedule metadata. See scheduled flows for pinned-deployment examples, idempotency keys, cron/timezone semantics, permissions and restart/missed-window behavior.

Runs (/v1)

delta runs starts and inspects runs of deployed flows using the committed merged OpenAPI contract. Use delta runs --help for the seven run commands.

Start a deployed flow, then follow the returned run ID:

delta deploy . --org ORG --project PROJECT
RUN=$(delta runs start --flow hello --input '{"name":"Ada"}' \
  --org ORG --project PROJECT)
delta runs events "$RUN" --org ORG --project PROJECT
delta runs outputs "$RUN" --org ORG --project PROJECT --json

start selects the newest finalized deployment containing the flow; use --deployment D to pin one. --input must be a JSON object. The supplied --sid S or a fresh cli-<hex> SID is printed to stderr before submission. Retry with the same --sid and input/deployment after a lost response; no automatic retry is made. Human stdout is only the run_id; --json prints the exact generated create response (201 accepted or 200 existing replay).

delta runs get RUN --org ORG --project PROJECT --json
delta runs outputs RUN --org ORG --project PROJECT
delta runs artifacts RUN --org ORG --project PROJECT
delta runs start --flow process_document --input '{}' --file document=./report.pdf \
  --org ORG --project PROJECT
delta runs download RUN --out ./downloads --org ORG --project PROJECT
delta runs download RUN --path .outputs/STEP/ATTEMPT/INVOCATION/FIELD/result.pdf \
  --out ./downloads --org ORG --project PROJECT
# Legacy single-file form remains available:
delta runs download RUN INV reports/result.txt --dest ./result.txt \
  --org ORG --project PROJECT
delta runs cancel RUN --cmd-id retry-stable-id --org ORG --project PROJECT
delta runs events RUN --last-event-id 12 --max-reconnects 3 \
  --org ORG --project PROJECT --json

All commands use existing delta login, DELTA_TOKEN/--token, local project/user config and DELTA_ORG/DELTA_PROJECT resolution. Explicit org/project flags work outside a local checkout. The default API host is https://api.avalanche.run, the authenticated /v1 release host. Until it is bound to the /v1 gateway, point commands at https://v2-gateway-staging.avalanche.run with --api-url or DELTA_API_URL. API URL precedence (highest first): --api-url, DELTA_API_URL, project delta.toml api_url, user ~/.config/trampoline-ai/delta/config.toml api_url, then the default. --api-url accepts an origin or its /v1 base. --json prints generated model JSON without filling absent fields; events are JSON lines.

Starting a run through the selected edge project establishes its binding. Reads of a run not bound to that project report 404 run_not_found, including cancel/events before the rollout gate. Outputs/artifacts/download are live. Until runtime R16-d, cancel/events report 503 durable_runs_upstream_unavailable as not yet available on this deployment, with exit status 1. Other errors preserve the edge {detail} and runtime/new-route {reason} families.

Cancel prints its supplied or once-generated cmd_id to stderr, does not retry, and tells you to retry with the SAME --cmd-id on ambiguous outcome 503. A 202 records the command; it does not prove child termination. SSE ignores heartbeat comments, checks contiguous fact IDs, resumes exclusively after the last delivered ID, and stops on terminal/stream_end/stream_error. Reconnects are bounded by a total count (default 3); stream_error exits 1. Requests have 15-second HTTPX budgets; SSE reads allow 60 seconds, above the 45-second upstream idle bound.

Download gets a JSON descriptor from the edge, then uses its exact signed URL and headers directly against storage, without the edge bearer. Bytes must match the immutable file size and SHA-256 before exclusive atomic publication. Existing files/symlinks and racing destination creators are never overwritten. Destination parents must exist. JSON download output is the descriptor and can contain a signed URL: treat that output as sensitive.

Generation and opt-in evidence

From the monorepo root:

uv run --frozen --package trampoline-delta python apps/cli/tools/generate_v1_client.py --write
uv run --frozen --package trampoline-delta python apps/cli/tools/generate_v1_client.py --check
uv run --frozen python apps/cli/tools/e2e_durable_run.py --help

datamodel-code-generator==0.83.0 generates the reachable component closure for Pydantic v2/Python 3.13. Narrow, schema-derived post-processing preserves conditional and composition constraints with Draft 2020-12 entrypoint validators, PEP 695 aliases for hashable dictionary keys, Pydantic recursive JsonValue, compiled regex patterns, and unchanged URI/date-time strings. No DTO fields are handwritten. --check regenerates in memory and verifies frozen/merged/overlay hashes against spec bytes, info fields and apps/api/openapi/SHA256SUMS. Builds verify committed module digests and spec identities without requiring codegen at wheel runtime; the generated models, constants and digest inventory ship in the wheel.

The E2E driver requires --base, --org, --project, --run, --wrong-project and --evidence; supply --binding/--path together or auto-select the first file. It uses only DELTA_TOKEN, the generated models and the CLI client, compares outputs at equal watermarks, verifies direct-storage bytes, and requires the same run to return 404 run_not_found under the wrong project for all six exact routes. Default evidence expects gated cancel/events. --runtime-enabled mutates the selected owned fixture by cancelling it and observes incremental SSE (30-second / 20-frame smoke bound). Evidence includes candidate identity, all three spec hashes, rerun arguments, status observations and cleanup, without payloads, bearer tokens, signed URLs/query strings or headers. Do not run against a live host without explicit fixture authorization.

Requirements

  • Python 3.13+
  • uv

Installation

From this directory, install the CLI in editable mode:

uv tool install -e .

You can also run the CLI directly during development:

uv run --with-editable . delta --help
uv run --with-editable . delta version

Authentication Setup

The CLI uses a public OAuth application. Do not use secret keys for interactive CLI user login.

The local session is stored in ~/.trampoline-ai/delta/auth.json. Delta creates the containing directory with mode 0700 and writes the credential file atomically with mode 0600.

Create an OAuth application in the same auth project as ../console:

  • Default redirect URI: http://127.0.0.1:8400/callback
  • Console callback URI for --manual-callback: https://cloud.avalanche.run/oauth/callback
  • Public client: enabled
  • PKCE required: enabled
  • Scopes: profile email offline_access user:org:read

A Clerk administrator must register the applicable redirect URI before its login mode can succeed.

The production issuer, public OAuth client ID, and callback port are built in. Sign in without configuration:

delta login

For another deployment, override the public auth configuration explicitly:

export DELTA_AUTH_ISSUER_URL="https://your-auth-issuer.example.com"
export DELTA_AUTH_CLIENT_ID="your_oauth_client_id"

For local development in this monorepo, the CLI can also derive the issuer from DELTA_AUTH_PUBLISHABLE_KEY.

Command Overview

delta deploy

Deployment discovery runs only in the project's interpreter, not the CLI's installation. Install avalanche-ai==0.15.0 and your workflow dependencies in the project, then run uv sync there before deploying. The CLI never syncs, installs, or relocks the project. The CLI wheel itself has no Avalanche, DSPy, PredictRLM, or LiteLLM dependency.

The default interpreter is .venv/bin/python (.venv\Scripts\python.exe on Windows). For a nonstandard environment, set python = "path/to/venv/bin/python" in the root of delta.toml, or DELTA_PROJECT_PYTHON (takes precedence). Relative paths are project-root-relative. DELTA_DISCOVERY_TIMEOUT sets the positive, finite timeout in seconds (default 30), including imports, builders and metadata. User workflow code executes in a subprocess, not a security sandbox.

delta init adds [tool.uv] exclude-dependencies = ["litellm"] to pyproject.toml, preserving existing exclusions and formatting. Commit that change and re-sync the project yourself; it does not change pip wheel metadata.

Build and upload the committed source and wheelhouse, then finalize the deployment through /v1. Deploy prints the deployment ID and finalized state; --json keeps the deployment, source, flows, bundle, finalize request, diagnostics and git metadata.

delta deploy . --org ORG --project PROJECT
delta deploy . --org ORG --project PROJECT --env-file .env.production --json
delta deployments list --org ORG --project PROJECT
delta flows list --org ORG --project PROJECT
delta flows get FLOW --org ORG --project PROJECT --deployment-id DPL

Flow list/get use --deployment-id when supplied; otherwise the CLI reads all finalized deployment pages and selects the newest created_at (deployment ID breaks ties). Flow requests always send that explicit deployment ID. Human flow continuations include it; keep the same --deployment-id when using a JSON next_cursor. An empty deployment catalog reports an error asking you to deploy.

Runs target finalized deployments; /v1 has no "live" deployment or set-live step.

Dependencies

Deploy includes the project's frozen uv.lock dependency closure as verified runtime-target wheels. Runtime-provided packages are omitted only at matching versions; conflicts print the complete [tool.uv] constraint-dependencies fix. Use the version your runtime reports, then uv lock and commit the result. See Flow dependencies for the constraint block, binary-wheel/system-library limits and the imageio-ffmpeg==0.6.0 example.

delta version

Shows the installed Delta CLI version.

delta auth login

Signs in to Delta through your browser.

delta login

The CLI uses the registered callback port 8400. Pass --callback-port 0 for a random loopback port when another provider supports RFC 8252 loopback redirects.

Use --no-browser to print the sign-in URL instead of opening it:

delta auth login --no-browser

Use the Console callback when the browser cannot reach the local loopback listener:

delta auth login --manual-callback

Manual callback sign-in requires Delta CLI 0.1.6 or newer. Older CLI releases cannot complete this handoff; upgrade the CLI and start sign-in again if the Console reports that an upgrade is required.

Complete sign-in in the browser, select Copy response at the Console callback page, then paste only that response into Delta's hidden terminal prompt. Never copy, paste, log, or share the raw browser callback URL. The response is bound to the in-memory PKCE sign-in attempt; do not paste it into logs or chat.

delta auth status

Shows whether you are signed in.

delta auth whoami

Shows the signed-in account.

delta auth logout

Signs out of Delta.

delta --help

Shows available commands and global options.

Service API commands automatically load and refresh the signed-in session from ~/.trampoline-ai/delta/auth.json. An explicit --token wins, then a nonblank DELTA_TOKEN, then the saved session; the user TOML configuration rejects plaintext tokens.

The API enforces the selected Clerk organization and its role permissions. The signed-in user must belong to the requested organization, and that role must include the Delta action used by the service command.

Listing pages

Collection commands accept --limit (default 100, maximum 500) and --cursor. Human output prints the next continuation; list JSON is now an {items,next_cursor} envelope. HttpDeploymentApi returns a list-compatible ApiPage exposing next_cursor; iterating it makes no additional requests.

Live paging continues after the last returned item. Refresh without a cursor to see newer items that sort before that position. Filtered pages may contain no items and still have a continuation.

Webhook URLs now include organization, project and flow scope: /v2/hooks/orgs/ORG/projects/PROJECT/flows/FLOW/[CONFIGURED_PATH/]TOKEN. Use the complete URL returned by the API; opaque-only URLs are removed.

Metadata

Release files for trampoline-delta 0.6.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for trampoline-delta 0.6.1
File Size Uploaded Provenance
trampoline_delta-0.6.1.tar.gz 270.1 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for trampoline-delta 0.6.1
File Interpreter ABI Platform
trampoline_delta-0.6.1-py3-none-any.whl Python 3 none any Details

Total release size: 517.9 kB

Release files / trampoline_delta-0.6.1.tar.gz

Download URL trampoline_delta-0.6.1.tar.gz
Size 270.1 kB
Tags Source
SHA-256 checksum
How to use checksums
2e9b11a16b3dfdd7a52c464eccd8111cdc08eb2773565edcc6d30f816ff32bf4
BLAKE2b-256 checksum
How to use checksums
dfc17bea52be98f3669245ecebacefca482e3e316a72b833ddaedf0a25d8132b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 25, 2026.

Transparency log

Release files / trampoline_delta-0.6.1-py3-none-any.whl

Download URL trampoline_delta-0.6.1-py3-none-any.whl
Size 247.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
aefc48548d1355642424b405556a74fd7b84da82b566a761b1bdb925f2b74011
BLAKE2b-256 checksum
How to use checksums
da906d9150f8026977a1c0b8bcb3abaa1f840c2965171ae22d253fe051e6498c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 25, 2026.

Transparency log

Security for trampoline-delta 0.6.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for trampoline_delta-0.6.1.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 25, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.6.1 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page