Skip to content

Overnight runs

An overnight run is one long task that the agent works on alone. You give it the task, a folder, a time limit and, in the terminal, a money cap. It runs until the work is done, a limit is reached, or it needs you. When it ends you get a report, in the terminal or in Telegram.

Overnight runs are built on the durable task queue. An overnight run is a background task with a few extra guards: a budget, a time limit, and a rule for actions that would normally ask you.

Start a run from the terminal

Terminal window
atomic-agent overnight "migrate the tests to vitest" --budget 5 --hours 8 --dir ~/work/app --detach

atag overnight is the same command. The task text is the only required argument.

FlagDefaultWhat it does
--budget <usd>agent.task.maxCostUsd (0 = no cap)Money cap for the run, in US dollars. With no cap the start line says “no money cap”.
--hours <h>8Time limit in hours, from 1 minute (about 0.017) to 168 (one week).
--dir <path>current folderWorking folder for the session and every tool.
--notify telegramoffSend the report to your paired Telegram chat when the run ends.
--detachoffRun in the background. Prints the task id, the log path (<stateDir>/logs/overnight-<id>.log) and the atomic-agent task show <id> command to check on it.
--no-approvaloffAllow every action for this run, with no questions. See Approvals.

In the foreground the command prints one line per step to stderr, with the step number, the elapsed time and the spend so far:

[step 12 | 14m | $0.42 of $5.00] read src/app.ts

When the run ends it prints a summary to stdout. The exit code is 0 only if the task completed. Press Ctrl+C once to cancel the run and a second time to quit. From another terminal, atomic-agent task cancel <id> stops a detached run within about 5 seconds.

Approvals during a run

Nobody is at the keyboard to answer an approval prompt, so the overnight command does not ask. By default every action that needs approval is denied. Each denied action is printed as it happens, as “needs approval: <tool> (<reason>); denied, nobody is there to answer” (with --detach it goes to the log file), and the summary at the end counts them. With --notify telegram the Telegram report also shows them under Needs you. That way you can see what the agent wanted to do and decide in the morning.

Actions your approval level and saved rules already allow still run.

Budgets and time limits

A budget caps what one task or turn may spend. When the cap is reached, the agent writes a short summary of where it stopped and ends with a line such as stopped: spent $3.02 of $3.00 budget. A budget-stopped task goes to blocked with budget_spent: $X of $Y. Say continue to pick it up again with a fresh budget, or raise the cap.

There are three ways to set a cap:

  • --budget on atomic-agent overnight.
  • --max-cost-usd <n> and --max-duration <dur> on atomic-agent task create. Durations take 90s, 30m, 8h or 1h30m; a bare number means seconds.
  • agent.task.maxCostUsd in config.json. The default is 0, which means no cap.
Terminal window
atomic-agent task create --message "refresh the changelog" --max-cost-usd 2 --max-duration 1h30m

atomic-agent task show <id> prints maxCostUsd, maxDurationMs and spentUsd for the task.

Keep these limits in mind:

  • Spend is an estimate. It is computed from the provider’s price list, not from your bill.
  • Only the main loop counts. Memory lookups, context compaction summaries and Fusion workers are not included in the spend. Fusion has its own turn caps.
  • A run can end slightly over the cap, by the cost of the closing summary.
  • Local models count as $0, so a money cap never stops a run on a local model. Use the time limit there.
  • agent.task.maxCostUsd applies to every turn, including normal chat turns, once you set it.

Crashes and restarts

Background tasks save a checkpoint after every finished step. If the agent crashes, is killed or the app restarts in the middle of a background task, the task continues from the last finished step instead of starting again. The resumed run starts with a note that says it was interrupted after step N and must not redo finished work.

KeyDefaultWhat it does
agent.task.resumeInterruptedtrueResume an interrupted task from its last checkpoint. false restores the old behaviour, a fresh re-run.
agent.task.maxResumes3How many times one task may resume. After that it gives up with “gave up: the agent stopped under this task N times”. 0 gives up at the next crash.

Checkpoints cover background tasks only. Resuming a terminal atomic-agent overnight run after a crash has not been tested yet, so do not count on it for this preview. An interactive chat that was cut off is not resumed, and there is no Continue button for it. A step that was cut off before any record of it was written runs again from the start.

Reports in Telegram

With --notify telegram (or the Telegram switch in the desktop dialog), a finished task sends a report to your paired Telegram chat. The report has these parts:

  • In words: a short summary.
  • Done: what was finished, such as files changed and tests run.
  • Failed: what did not work.
  • Needs you: what is waiting for a person, for example “Stopped at the budget limit” or “Stopped at the time limit”.

A meta line shows the attempt, the time taken, the number of steps and why it stopped. /status in Telegram also lists the background tasks that are running now.

By default a report is sent as soon as the task ends, even at 3 a.m. To hold reports at night, set quiet hours with an environment variable:

Terminal window
export ATOMIC_AGENT_TASKS_REPORT_QUIET_HOURS=23:00-08:00

Reports for tasks that finish inside that window are held and sent together when the window ends. A single held report goes out as a normal report. Several are sent as “Morning report: N tasks finished during quiet hours”, with counts of completed, failed and blocked tasks, split into numbered parts if they do not fit in one message. Quiet hours are off unless you set this variable. There is no config key or desktop switch for them, and the overnight command does not turn them on.

Keep going until done with /goal

/goal is a TUI command for work in an ordinary chat. You give the chat a checklist, and it keeps working round after round until every item is done, it needs you, or it reaches 10 rounds.

/goal all API routes return JSON errors; the README lists every route; check: npm test

Put one item per line or separate items with ;. An item that starts with check: is a shell command that must pass. Checks run in your real working folder with a 5 minute timeout.

CommandWhat it does
/goal <items>Set the checklist and start.
/goal check add <cmd>Add a shell check.
/goal check clearRemove all shell checks.
/goal statusShow progress, for example Goal: 3/5 criteria green · round 2/10.
/goal pause, /goal resumePause and continue.
/goal clearDrop the goal.

The active model judges whether each item is done. Every round is a model call plus a judge call, so on a cloud model a goal costs more than a single turn. /goal is available in the TUI only. The desktop app and Telegram do not have it, and the overnight command does not use it.

Long work is not taken for a loop

The agent has a loop guard that stops it when it repeats the same action with no progress. It now judges repeats on recent steps only. Re-running tests after edits, polling a long build or checking git status now and then no longer trips it. A deliberate poll, such as sleep 60 && tail build.log, is stopped after 20 identical answers instead of 5. Real loops are still stopped.

Run overnight in the desktop app

In the desktop app, open the + menu in the composer and choose Run overnight.

FieldWhat to enter
TaskWhat the agent should do, for example “Fix the failing tests and write down what you changed”.
FolderWhere it works. The default is the chat’s folder. Choosing another folder here does not change the chat’s folder.
Time limit, hoursFrom 0.5 to 24, default 8.
Send the morning report to TelegramOn by default when Telegram is paired. The report is sent when the run ends.

Press Start (or Cmd/Ctrl+Enter). A small card in the bottom-left corner shows the run’s state and elapsed time, with Open and Stop buttons. The run also appears in Tasks.

Get updates by email

One email when a new version comes out.