Stacks

Run Atlas Headless in CI in a JavaScript Project (2026)

Updated 8 min read

Atlas runs headless in CI through `atlas run`, which is built for exactly that. Its default mode is non-interactive: it sends a single prompt, streams events to stdout, and exits when the session goes idle, so a JavaScript pipeline step behaves like any other command. `atlas run` supports --format json for raw event streaming, --command for slash-command execution, and --continue or --session for resumption, so a step can be replayed or resumed. In a JavaScript repo that means Atlas can run after `pnpm install`, before or after `pnpm vitest run`, with its output parsed by a later step and prettier applied to whatever it wrote.

How do you run Atlas non-interactively in a CI pipeline?

`atlas run` is the non-interactive entrypoint: invoke it with the prompt as an argument and it sends exactly 1 prompt, streams events to stdout, and exits when the session goes idle. That is the contract a CI step needs, with no TTY, no keypress, and no job hanging on a permission prompt nobody will answer.

In a JavaScript pipeline, put `atlas run` in the same job that already runs `pnpm install` and `pnpm vitest run`, so the working tree Atlas sees is the one the tests see. Because the session exits when it goes idle, the step's exit is a real signal rather than a timeout. Keep the prompt narrow and mechanical: "update the failing snapshot in src/components and explain what changed" is a CI-shaped task, while "improve the codebase" is not. Atlas is a terminal-native TUI in interactive use, but `atlas run` is the headless path, and it is the one that belongs in a pipeline definition next to your pnpm commands.

How do you parse Atlas's output in a JavaScript CI step?

Atlas streams machine-readable events when you pass --format json to `atlas run`, so a later pipeline step can parse the event stream rather than read prose. In a 2026 JavaScript repo the natural consumer is a small Node script that reads stdout, filters the events it cares about, and turns them into a check annotation or a comment.

Prose output is for humans; --format json is for the next step. Pipe the raw event stream to a file, then let a JavaScript step read it with `node scripts/parse-atlas.mjs` and decide what to do: fail the job, post a summary, or write a report artifact. Keep the parser in the repo alongside your other tooling so `prettier` formats it and `vitest` can test it, because a parser that silently returns an empty array on a schema change is worse than no parser. `atlas run` streams events to stdout, so the parser can also consume the stream live rather than after the fact when a long job needs progress reporting.

How do you configure permissions for a headless Atlas run?

Atlas requires the tools a headless job needs to be pre-approved in the permission config, because a headless run has nobody to answer an ask prompt. Every Atlas tool call is gated against 3 rule types, allow, ask, and deny, before it runs, so an unconfigured CI job stalls on the first edit rather than proceeding unsafely.

Permissions are the difference between a CI job that works and one that hangs. Decide up front what the job may do: allow bash for `pnpm vitest run` and `pnpm prettier --write`, allow read and grep, and decide deliberately whether edit is allowed or denied. A job that only reviews the diff should deny edit outright, which makes it structurally incapable of writing to your JavaScript source. A job that fixes lint errors needs edit allowed for src/**, and nothing else. The permission model is the security boundary for the entire headless run, and it is not optional: with no human present, ask is functionally a deadlock, so every tool the prompt might reach for must be resolved to allow or deny before the job starts.

How do you set the model for an Atlas run in GitHub CI?

Atlas's GitHub path requires the model in provider/model form and rejects anything else, so in 2026 a bare model name still will not start the job. Passing the fully qualified provider/model string is a one line change in the workflow YAML, and it is the difference between a green run and an immediate rejection.

Explicit model selection also makes a JavaScript pipeline reproducible. A job pinned to a specific provider/model behaves the same on rerun, which matters when the step's output is being parsed with --format json by a downstream script and consumed by a check. In interactive use Atlas lets you switch the active model and provider on the fly with favorites and recents, but a CI job should never be implicit about which model ran, because the reason a step's behavior changed between Tuesday and Thursday should never be a silent model default. Put the provider/model string in the workflow next to the `pnpm` version pin and treat both as part of the pipeline's contract.

How do you resume or replay an Atlas CI run?

Atlas resumes or forks a prior session with 3 flags, --continue, --session, and --fork, when a JavaScript job needs to build on an earlier run. A pipeline that ran `atlas run` in one step and `pnpm vitest run` in the next can hand the test failures back into the same session rather than starting cold.

Session continuity is what turns a single-shot command into a pipeline. Use --continue to pick up the previous session, --session to target a specific one by id, and --fork to branch from a session without disturbing it, which is useful when you want two candidate fixes explored from the same starting state. In practice a JavaScript job might run `atlas run` to make a change, run `pnpm vitest run` to test it, and then resume with the failing output to iterate. Atlas snapshots file changes as git patches, so edits made by a headless run can be diffed and rolled back, and Atlas reads git branches, status, and diffs, so the job can inspect exactly what it wrote before opening a pull request.

Step by step

  1. 01Add a CI step in the same job that runs `pnpm install`, so the working tree Atlas sees is the tree your JavaScript tests see.
  2. 02Invoke `atlas run` with the prompt as an argument; the default mode is non-interactive, sends one prompt, and exits when the session goes idle.
  3. 03Pass --format json when a later pipeline step needs to parse the event stream rather than read prose, and pipe the stream to a file the next step reads.
  4. 04Set the model explicitly: the GitHub path requires provider/model form and rejects anything else, so a bare model name fails the job immediately.
  5. 05Pre-approve the tools the job needs through the permission config, because a headless run has nobody to answer an ask prompt; allow bash for `pnpm vitest run` and decide deliberately whether edit is allowed.
  6. 06Use --command when the job should execute a slash command rather than a free-form prompt.
  7. 07Parse the JSON event stream with a small Node script such as `node scripts/parse-atlas.mjs`, kept in the repo so `prettier` formats it and `vitest` tests it.
  8. 08Resume or fork a prior session with --continue, --session, or --fork when a later step needs to hand `pnpm vitest run` failures back into the same Atlas session.

Frequently asked questions

how to run an AI coding agent headless in CI
Use `atlas run`. Its default mode is non-interactive: it sends a single prompt, streams events to stdout, and exits when the session goes idle. Pass --format json when a later step needs to parse the events, and pre-approve permissions before the job starts.
how do I get machine-readable output from atlas run
Pass --format json. `atlas run` then emits the raw event stream to stdout, which a JavaScript step can consume with a Node script rather than parsing prose. Keep the parser in the repo so prettier formats it and vitest tests it.
why does my headless Atlas run hang in CI
A headless run has nobody to answer an ask prompt. Every Atlas tool call is permission-gated against allow, ask, and deny rules before it runs, so every tool the prompt might reach for must be pre-approved to allow or deny in the permission config before the job starts.
does atlas run need a model flag in GitHub Actions
Yes. Set the model explicitly, because the GitHub path requires provider/model form and rejects anything else. Pinning the provider/model string alongside your pnpm version pin also keeps the pipeline reproducible across reruns.
can I resume an Atlas CI session from a later pipeline step
Yes. Use --continue to pick up the previous session, --session to target one by id, and --fork to branch from a session without disturbing it. That lets a `pnpm vitest run` failure be handed back into the same Atlas session rather than starting cold.
can atlas run execute a slash command in CI
Yes. `atlas run` supports --command for slash-command execution, so a pipeline step can invoke a defined command rather than a free-form prompt, which makes the step's behavior easier to keep stable across runs.
how do I review what Atlas changed during a CI run
Atlas snapshots file changes as git patches so edits can be diffed and rolled back, and Atlas reads git branches, status, and diffs. A headless job can therefore inspect exactly what it wrote before opening a pull request.
how do I start Atlas in a JavaScript project
Run atlas where your package.json lives. Atlas maps your modules, npm scripts, and bundler config, and you can have it modernize callbacks to async/await or add tests, reviewing each diff before it is written.

Try Atlas in your terminal

The terminal-native AI coding agent. Free core, single binary.

Install Atlas

Related 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 JavaScript in 2026

In 2026, Atlas empowers JavaScript developers with a terminal-native AI coding agent. It indexes code by AST, uses local embeddings, and offers permission-gated tools for safe, efficient development.

Document a JavaScript Module with a README Using Atlas (2026)

How Atlas writes a README for a JavaScript module in 2026: enumerate exports with the lsp tool, read the source, verify every sample with vitest and pnpm.

Trace a Runtime Bug from a Stack Trace in JavaScript with Atlas (2026)

Go from a production JavaScript stack trace to the responsible line in 2026 with no debugger attached. Atlas reads each frame at its offset and pins the fix with vitest.

Plan a Multi-File Change Before Editing in JavaScript with Atlas in 2026

Plan a multi-file JavaScript change before editing in 2026. Atlas's plan agent denies edit outside .atlas/plans/*.md, and plan_exit gates the build agent handoff.

Refactor a Legacy Module in JavaScript with Atlas (2026)

Refactor a legacy JavaScript module with Atlas in 2026: enumerate callsites with the lsp tool, restructure with apply_patch, and prove behavior with vitest.

Upgrade a Dependency and Fix the Breakage in JavaScript with Atlas (2026)

Atlas upgrades a JavaScript dependency through pnpm, fetches the release notes with webfetch, and fixes every callsite the build and vitest report, one diff at a time.

Research a Third-Party API Before Integrating It in JavaScript with Atlas (2026)

Atlas uses websearch and webfetch to pull live API docs into context before you write JavaScript, so your Node or browser integration matches the real endpoints in 2026.

Browse this resource hub