> ## Documentation index
> Fetch the complete documentation index at: https://haarness.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Schedule a recurring run on this computer

A schedule runs a prompt in a folder on a timetable: every morning, every hour, or once at a set
time. Each run starts a new chat that you can open afterwards. Schedules run on this computer, so
it has to be on and you have to be logged in.

To keep schedules running while your computer is off, use
[Cloud schedules](https://haarness.ai/docs/cloud/schedules.md) instead.

## Create a schedule

Run this from the folder the schedule should work in:

```sh
haarness schedule add --name morning-review \
  --cron '0 9 * * 1-5' \
  --model openai/gpt-5.6 \
  --prompt 'Review this repository and list anything urgent'
```

Haarness prints the new schedule's ID and a one-line summary. This one runs at 09:00, Monday to
Friday.

You can write the timing in words instead:

```sh
haarness schedule add --model openai/gpt-5.6 \
  --natural 'every day at 8am to summarise the commits from yesterday'
```

Start the phrase with `in`, `every` or `on`, and put the prompt after `to`. Upper or lower case
does not matter, and the prompt keeps the case you typed. The phrase must match one of these
forms:

| Phrase | Runs |
| --- | --- |
| `in 30 minutes to …` | Once, 30 minutes from now |
| `every 15 minutes to …` | Every 15 minutes (also `hours`, `days`) |
| `every day at 8am to …` | Daily; `18:30` works too |
| `every monday at 9am to …` | Weekly on that day |
| `on 2026-11-02T09:00:00+01:00 to …` | Once, at that time |

Everything after `to` is the prompt. `on 2026-11-02 to …` with only a date runs at midnight,
local time. `--natural` replaces `--prompt`, `--every`, `--cron` and `--at`; it cannot be combined
with them.

You can also ask for a schedule in a chat ("every Monday at 9am, check for outdated
dependencies"), or use `/schedules` in the [terminal UI](https://haarness.ai/docs/tui/slash-commands.md). Both create
the same kind of schedule.

## Name a schedule

Commands that act on one schedule take its name or its ID, so two schedules cannot share a name.
Give one with `--name`, or put `named "…"` in the phrase:

```sh
haarness schedule add \
  --natural 'every day at 8am to check CI named "ci-check"'
```

A name you choose is refused if another schedule already has it. Without a name, the schedule is
named after the start of its prompt, and gets a number, such as `check deps 2`, if that name is
taken.

## Choose when it runs

Pick one of these:

| Flag | Example | Runs |
| --- | --- | --- |
| `--every` | `--every 30m` | At a fixed interval: `m`, `h` or `d` |
| `--cron` | `--cron '0 9 * * 1-5'` | On a five-field cron timetable |
| `--at` | `--at 2026-11-02T09:00:00+01:00` | Once, at that time |
| `--natural` | `--natural 'every day at 8am to …'` | A phrase from the table above |

The shortest interval is one minute. Cron fields take numbers, `*`, lists (`1,3`), ranges
(`1-5`) and steps (`*/15`); day names are not accepted, and both `0` and `7` mean Sunday.

### Time zones

Cron times and phrases such as `every day at 8am` use your computer's local time. `--at` takes
a full timestamp with its UTC offset, so it means the same moment anywhere.

`--timezone Europe/Paris` sets an IANA time zone for cron schedules. It is applied on Linux
only. On macOS and Windows the schedule keeps using local time.

### One-off runs

A schedule made with `--at`, `in …` or `on …` runs once. The time must be at least one minute
in the future. After the run, the schedule turns itself off and stays in the list until you
remove it.

## See your schedules

```sh
haarness schedule list
haarness schedule get morning-review     # every setting, as JSON
```

Each line of `list` shows the ID, name, timing, whether it is enabled, the model and the folder.
Commands that act on one schedule take its name or its ID.

## Run it now

```sh
haarness schedule run morning-review
```

The run starts straight away, even if the schedule is turned off. The command waits for it to
finish and then prints the result, including the agent's reply and the chat ID. Add `--json` for
the whole run record.

## Check what happened

```sh
haarness schedule history morning-review
haarness schedule history morning-review --limit 5 --json
```

Each line shows the outcome (`Success`, `Failed` or `Skipped`), when it finished, the chat ID and
any error. To read the whole conversation, open that chat from the schedule's folder:

```sh
haarness --thread <chat-id>
```

Scheduled chats are titled `Schedule: <name> · <date and time>`, such as
`Schedule: morning-review · Nov 2, 09:00`, so they are easy to spot in `haarness sessions list`.
In Desktop they appear under **Scheduled** in the sidebar.

```sh
haarness schedule logs morning-review             # where its log file is
haarness schedule logs morning-review --tail 20   # the last 20 lines
haarness schedule logs morning-review --open      # also show it in your file manager
```

## Pause, change or remove it

```sh
haarness schedule disable morning-review
haarness schedule enable morning-review
haarness schedule update morning-review --cron '30 8 * * 1-5'
haarness schedule remove morning-review
```

`update` takes the same flags as `add`, plus `--enable` and `--disable`. Anything you leave out
keeps its current value.

## What a scheduled run can do

A scheduled run has nobody to talk to, so it:

- **approves permission prompts on its own,** once each, and saves no rule. Rules set to `deny`
  still block. This is permission inside Haarness only; it does not grant anything at the
  operating-system level. Read [Permissions](https://haarness.ai/docs/security/permissions.md) before scheduling a prompt
  that edits files or runs commands.
- **refuses what only a person may approve,** such as a Haarness Cloud action that spends money or
  deletes something, a website in your Chrome you have not set to **Always allow**, or an edit to
  Haarness's own settings. It does not wait for you: the agent is told to leave that for an
  interactive chat, and the run goes on.
- **cannot ask you questions.**
- **uses the folder's project configuration,** unless you created the schedule with
  `--disable-project-config`.
- **is skipped if the previous run is still going.** History records it as `Skipped`.

## Make sure it can reach the model

Pass `--model provider/model`. Without it, the run uses the default model of the schedule's
folder.

A scheduled run starts outside your shell, so API keys that you only export in a shell profile
may not be available to it. Store the credential with `haarness auth login <provider>` first. See
[Connect a provider](https://haarness.ai/docs/start/connect-a-provider.md).

## What it uses on your OS

Haarness registers each schedule with your operating system's own scheduler: launchd on macOS,
systemd user timers on Linux, and Task Scheduler on Windows. Nothing else needs to keep running.

A schedule made while `HAARNESS_HOME` is set is stored under that folder, and its runs use the same
folder, so their chats and credentials are found there.

On Windows, cron schedules must be daily or weekly: the day-of-month and month fields must be
`*`.

## Reference

| Flag | Means |
| --- | --- |
| `--name` | Name to refer to it by; must be unique |
| `--prompt` | What the run asks the agent |
| `--model` | `provider/model` to use |
| `--agent`, `--variant` | Agent profile and reasoning variant |
| `--directory` | Folder to run in (default: current) |
| `--every`, `--cron`, `--at`, `--natural` | When it runs |
| `--timezone` | IANA time zone for cron (Linux only) |
| `--disabled` | Create it turned off (`add` only) |

## Related

- To repeat a prompt inside the chat you are in, use `/loop 10m <prompt>` in the terminal UI.
  `/loop stop` ends it.
- [Run a prompt from a script or CI](https://haarness.ai/docs/cli/headless-runs.md)
- [Cloud schedules](https://haarness.ai/docs/cloud/schedules.md)
