To run Atlas headless in CI in a Python repo, invoke `atlas run` with your prompt as an argument. Its default mode is non-interactive: it sends a single prompt, streams events to stdout, and exits when the session goes idle. In a Python pipeline that means one CI step sits between `uv` dependency installation and `pytest`, and the whole thing exits on its own. Add --format json when a later step must parse the event stream, set the model in provider/model form, and pre-approve the tools the job needs, because a headless run has nobody to answer an ask prompt.
How do I run Atlas non-interactively in a Python CI pipeline?
Atlas runs headless through `atlas run`, whose default mode is non-interactive: it sends a single prompt, streams events to stdout, and exits when the session goes idle. In a 2026 Python pipeline that step drops in between `uv` installing dependencies and `pytest` executing the suite.
A Python CI job usually has three phases: install with `uv`, check with `ruff format`, and verify with `pytest`. `atlas run` slots in as a fourth. Because the default mode of `atlas run` sends exactly one prompt and exits when the session goes idle, no runner-level timeout wrapper or fake TTY is required. Give it a prompt like "add type hints to the payments module and keep pytest green", and the job returns when Atlas stops working. The command also accepts --command for slash-command execution when the pipeline should run a saved command rather than free prose, so a repeated Python chore can live as a command instead of a prompt string copied across workflows.
How do I get machine-readable output from atlas run in CI?
Pass --format json to `atlas run` when a later pipeline step needs to parse the event stream rather than read prose. That is step 2 of the documented 2026 headless workflow, and in a Python pipeline the downstream step is usually a script that loads the events and fails the job before `pytest` even starts.
The default `atlas run` output is a human-readable stream, which is what you want when a developer is reading CI logs. --format json is what you want when a machine is reading them. With --format json, the raw event stream is emitted so a following step can consume it. On a Python repo, that consumer is naturally a Python script invoked through `uv`, reading stdin and deciding whether the run produced edits worth pushing. Keep the raw stream as a build artifact: when a headless run does something unexpected in a `pyproject.toml`-based project, the JSON events are the record of what tools ran and in what order.
Why does the GitHub path reject my model string?
Atlas requires the model in provider/model form and rejects anything else, so set the model explicitly in every headless Python job in 2026. CI has no interactive picker: a bare model name with no provider prefix is refused up front rather than silently defaulting to something you did not choose.
Model selection is a common first failure for a headless Atlas run. Interactively, Atlas lets you switch the active model and provider on the fly with favorites and recents, so a developer rarely types a full identifier. In CI there is no picker and no recents list, so `atlas run` needs the model given explicitly and in provider/model form. Set it once in the workflow file next to the `uv` and `pytest` steps, treat it like any other pinned build input, and the job either uses the model you named or fails loudly instead of drifting.
How do permissions work when Atlas runs headless with no human present?
Every Atlas tool call is permission-gated against allow, ask, and deny rules before it runs. In a headless Python job, pre-approve the tools the job needs through the permission config: a run that hits an ask rule at 2am has nobody to answer it and will not proceed on its own.
The tools this workflow uses are bash, read, edit, and todowrite. Decide in advance which of those the CI job is allowed to use and encode it in the permission config as allow rules. A Python job that should run `pytest` and `ruff format` but never touch the network needs bash allowed for those commands and anything riskier on deny. The permission gate is the safety boundary that makes headless operation reasonable: Atlas also computes a unified diff for every file edit, so even in CI the change is a reviewable patch rather than an opaque mutation of `src/`.
Can a CI job resume or replay a previous Atlas session?
Yes. `atlas run` supports 3 resumption flags, --continue, --session, and --fork, so a pipeline step can be replayed or resumed. A Python workflow that runs `pytest` in one job and repairs failures in the next can carry the same Atlas session across both instead of restarting cold with no memory.
Resumption matters when a single Python pipeline has stages. Suppose stage one asks Atlas to bump type coverage in a package with a `pyproject.toml`, and stage two runs `pytest` and finds two failures. Rather than describing the whole change again, the second stage resumes with --continue or targets the exact prior run with --session, and Atlas already has the context of what it edited. --fork branches from a prior session when you want a variant without disturbing the original. Atlas also snapshots file changes as git patches, so edits made in a resumed run can be diffed and rolled back rather than hand-reverted.
Step by step
- 01Invoke `atlas run` with the prompt as an argument in your CI step; the default mode is non-interactive, sends one prompt, and exits when the session goes idle.
- 02Set the model explicitly in provider/model form; the GitHub path rejects anything else, so a bare model name fails the job immediately.
- 03Pass --format json when the next pipeline step must parse the event stream instead of reading prose, and archive the stream as a build artifact.
- 04Pre-approve the tools the job needs (bash, read, edit, todowrite) through the permission config, because a headless run has nobody to answer an ask prompt.
- 05Install the Python dependencies with `uv` before the Atlas step so `pytest` and `ruff format` are on PATH when Atlas shells out through bash.
- 06Have the job run `pytest` through bash and, if the suite is red, let Atlas track distinct failures in a todowrite list before it edits anything.
- 07Run `ruff format` as the last check so the diff Atlas produced matches the repo's formatting before it is committed.
- 08Resume or fork the prior run with --continue, --session, or --fork when a later stage needs to build on what the earlier stage did.
Frequently asked questions
- how to run atlas in github actions for a python project
- Call `atlas run` with the prompt as an argument. Its default mode is non-interactive, so it sends one prompt, streams events to stdout, and exits when the session goes idle. Set the model in provider/model form, and put the step after `uv` installs your dependencies so `pytest` is available.
- atlas run --format json output parsing
- --format json makes `atlas run` emit the raw event stream instead of prose, which is what you use when a later pipeline step parses the output rather than a human reading it. On a Python repo the consumer is usually a small script run through `uv`.
- why does atlas reject my model name in ci
- The GitHub path requires the model in provider/model form and rejects anything else. Set it explicitly in the workflow. Interactively Atlas lets you switch model and provider on the fly with favorites and recents, but a headless run has no picker to fall back on.
- how do i approve atlas tool calls in a headless run
- Every Atlas tool call is permission-gated against allow, ask, and deny rules before it runs. Pre-approve the tools the job needs through the permission config, because a headless run has nobody to answer an ask prompt and will not proceed past one.
- can atlas resume a previous session in a pipeline
- Yes. `atlas run` supports --continue and --session for resumption and --fork to branch from a prior run, so a pipeline step can be replayed or resumed rather than restarted with no context.
- how do i make atlas run pytest and ruff format in ci
- Allow the bash tool for those commands in the permission config, then prompt Atlas to run `pytest` and `ruff format`. Install first with `uv` so both are on PATH inside the job container before Atlas shells out.
- does atlas work in a repo with only requirements.txt
- Yes. Run atlas in a repo with a `pyproject.toml` or `requirements.txt` and it reads your package layout, virtualenv, and installed dependencies. Neither file format is required over the other.
- can atlas run a slash command instead of a prompt in ci
- Yes. `atlas run` supports --command for slash-command execution, so a repeated Python chore can be stored as a command and invoked by name from the pipeline instead of pasting the same prompt string into several workflows.
Try Atlas in your terminal
The terminal-native AI coding agent. Free core, single binary.
Install AtlasRelated guides
Run Atlas Headless in CI with Atlas (2026 Workflow)
How to run Atlas headless in CI in 2026: atlas run sends one prompt and exits when the session goes idle, with --format json, --command, and --continue for pipeline steps.
Atlas for Python in 2026
Atlas is a terminal-native AI coding agent for Python in 2026. Run it in a repo with a pyproject.toml or requirements.txt and review every diff before it lands.
Audit a Python Repo with Parallel Subagents in Atlas (2026)
Audit a Python repo with parallel Atlas subagents in 2026. Slice by package, launch read-only explore tasks, and merge findings without flooding your context.
Plan a Multi-File Change Before Editing in Python with Atlas in 2026
Plan a multi-file Python change before editing in 2026. Atlas's plan agent denies edit for every path except .atlas/plans/*.md, then plan_exit hands off to build.
Automate GitHub Issue and Pull Request Triage in Python with Atlas (2026)
Wire the atlas github command into a Python repo's workflow in 2026. Require MODEL in provider/model form, gate on write permission, and verify with pytest and ruff format.
Onboard to an Unfamiliar Python Codebase with Atlas in 2026
Onboard to an unfamiliar Python codebase in 2026. Atlas uses codebase_search, glob, read, and lsp to map a pyproject.toml repo without opening every module.
Review a pull request in Python with Atlas (2026)
Review a Python pull request in 2026 with Atlas: read the changed .py files in full, check callers with findReferences, and run pytest before you approve the diff.
Self-Review Your Working Diff Before Committing in Python With Atlas (2026)
How to self-review a Python working diff before committing with Atlas in 2026: read the whole diff, grep for leftover breakpoints, then run pytest and ruff format.