timeless playbooks init to
create it with the default playbooks, use timeless config set <key> <value> for
scalar keys, or edit it by hand at any time. Every command reads it on startup and
falls back to built-in defaults for anything you leave out.
Location
The config file isconfig.yaml inside the Timeless config directory, resolved in
this order:
$TIMELESS_CONFIG_DIR$XDG_CONFIG_HOME/timeless~/.config/timeless
.env, then the real environment. The .env is a local-development convenience read
from your current working directory — not the config directory — and it only fills
in TIMELESS_* variables that are not already set, so an explicit shell export always
wins. A missing .env is silently ignored.
What it contains
omitempty, so a freshly bootstrapped file only lists what was
actually set — an absent key reads as its default rather than an empty value.
Freshness window
An event-driven pass compares each leased event’s meeting time against this window. Older events are acknowledged and skipped: consumed for good, but no playbook runs and no artifact is written, so returning after days away gets you recaps for recent meetings instead of a burst of dozens. Skips are reported asexpired and are not
failures — the pass still exits 0.
It is a single global window — there is no per-playbook or per-type override, though
playbooks run --max-age overrides it for one pass. A
malformed value (24, 1 day, -1h) stops the command rather than falling back,
because silently guessing a window would destroy deliverables. Avoid going below ~4h: a
transcript event fires after the meeting ends, so a long meeting’s event is already
hours old when it arrives.
Logging
The CLI writes a local diagnostic log tologs/timeless.log inside the config
directory, rotating at 5 MB and keeping 3 generations. It is on by default — a log you
have to enable first cannot answer a question about what already happened. The
logging: block is hand-edited only (not a config set key):
level tunes volume, never content depth. No level records prompt text, harness output,
or meeting content — that ceiling is not configurable.
Update keys are inert
update.auto, update.notify, and update.check_interval are still accepted,
validated, and reported by config list, but setting them changes nothing: CLI
self-update was removed. The desktop app’s updater owns updating, and the bundled binary
must never swap itself — that would break the app’s signature. If you want to change
update behavior, that is an app setting, not a CLI one.
Environment overrides
A few settings can be overridden per-invocation without editing the file:What you can customize
- Harness and model — switch the default engine or model for every playbook, or
override them per playbook with its own
harness/model. - Playbooks — change a prompt, retime a trigger (
on.every,on.schedule), park one withplaybooks disable, or add a playbook. See Playbooks. - Output mode — set
output: jsonto always emit JSON, or leave it onauto. - Freshness window — widen
events.max_agefor a backlog, or set0to never skip. - Logging — turn the diagnostic log down to
error, or off.
timeless config set accepts exactly seven keys: events.max_age, harness,
harness_model, output, and the three inert update.* keys. Everything else is
hand-edited — playbooks and logging are nested, and base_url is env-driven.timeless status --json to confirm the CLI still loads cleanly.
base_url, output, harness, and harness_model all have built-in defaults, so
a minimal config file is valid — you only need to write the keys you want to change.