Hey Pepper

Your AI chief of staffDocs

Hey Pepper
Day to day

Routines

A routine is a small program you write to do a job, such as downloading a weekly report from a site you log in to. The Mac runs it on a schedule, and Pepper watches it. Every field and rule is in Routines.

A routine is a fixed program that runs without an AI model, so it costs no tokens. When it breaks, it should say so, by exiting with an error or printing a needs_you line, rather than improvise. Pepper never sends anything to anyone but you. A routine you write can send things to other people, and its settings file, ROUTINE.md, says what it sends.

Each routine is one folder under Pepper's data folder, data/routines/ by default (or $PEPPER_DATA_DIR/routines/ if you set that). Set PEPPER_ROUTINES_DIR to keep them somewhere else. The folder name is the routine's name.

routines/
  weekly-report/
    ROUTINE.md     you write it: settings and a paragraph in plain words
    run            you write it: the program, in any language
    state/         the routine's own files: cursors, downloads. Pepper never reads it
    status.json    Pepper writes it after every run
    log/           Pepper keeps the last 30 runs here

ROUTINE.md starts with a few settings:

---
name: weekly-report
description: Download the weekly sales report and file it in Documents
schedule: "0 8 * * 1"        # 08:00 every Monday, in your time zone
timeout: 2m
sends: []
---
Logs in to the reporting site and saves the newest report. The password is in the Keychain
under "pepper.weekly-report". If the login breaks, run ./run login in this folder.

The paragraph under the settings is for you: what it does, where its secrets are, and how to fix it.

  • The routine gets none of Pepper's keys. It starts with a bare environment: the path, your home folder and user name, your language, a temp folder, your time zone, and its own name and folder. Its own secrets go in the macOS Keychain or a private file in its folder.
  • Pepper reads ROUTINE.md and status.json, and keeps what the program prints. The program's output goes to log/, and the last lines of any errors go into status.json; Pepper also keeps small .lock and .paused markers in the folder. It never opens state/. Keep secrets out of ROUTINE.md and out of what run prints.
  • Everything the routine writes about itself, such as its description or summary, is shown as text. Pepper treats it like any other text from outside and never acts on it.

Steps marked You are ones only you can do.

  1. Create the starter files. This writes a ROUTINE.md and a run that prints a greeting as its summary:

    npm run routines new weekly-report
  2. You: write the program in run and fill in ROUTINE.md. Store any password in the Keychain yourself.

  3. Run it once and read the result:

    npm run routines run-now weekly-report

    If it controls another app, such as Mail, macOS asks for permission the first time. You: run it once by hand at the Mac and allow it.

  4. Schedule it:

    npm run routines install weekly-report

    Install checks the folder first and, if something is wrong, stops and tells you why. Run it again whenever you change schedule in ROUTINE.md; editing the file alone doesn't change when the Mac runs it.

Make run safe to repeat: record what it did in state/ only once it's done.

Warning

Never put a real routine in the Pepper repository. Keep them in the data folder, or in a private repository of your own.

The Routines tab on the dashboard lists every routine with a description, a schedule in plain words (or the cron line when it can't be put plainly), what it last did, and a state:

StateMeans
okThe last run worked.
runningA run is in progress.
failedThe last run exited with an error, timed out, or died.
lateA run was due and nothing ran for longer than expect_every (twice the gap between runs unless you set it, so two weeks for a weekly routine). Usually the Mac slept.
brokenROUTINE.md or run breaks the rules; the tab says how.
pausedYou paused it.
not run yetInstalled; waiting for the first run.
not installedThe folder exists but nothing schedules it, including after uninstall.

A routine that sends something shows a small label for each thing listed under sends in its ROUTINE.md, such as "sends email". That list is your description of the routine, not a limit Pepper enforces.

A routine can end its run by printing one line of JSON. Its summary shows on the tab. Use needs_you when you want Pepper to ask you to take action:

{"summary": "no new report", "needs_you": "Login expired: run ./run login"}

When a routine is late, failed, broken, or sets needs_you, Pepper tells you in three places:

  • on the Today page, at the top, as "Routine weekly-report needs you: Login expired: run ./run login";
  • in your next brief, as one "Routines:" line;
  • as a count on the Routines tab.

A healthy routine never raises an alert. It still appears in status lists and on Connections when it sends something, and the brief's Routines line may count it among the ones that are fine. Use needs_you only when you must act.

On the Routines tab, each row has Pause (or Resume when the routine is paused) and Run now (unless the routine is broken, paused or already running). Run now starts the routine the same way the schedule does; refresh in a moment for the result.

From a terminal on the Mac:

CommandDoes
npm run routines statusEvery routine's state, as on the tab
npm run routines pause weekly-reportStops new runs without removing the schedule; a run already underway finishes
npm run routines resume weekly-reportStarts them again
npm run routines uninstall weekly-reportRemoves the schedule; the folder stays

In Telegram, /routines shows the same list. Pausing Pepper with /halt does not pause your routines, but it does stop Run now on the dashboard. Pause each routine separately.