Cori
Reference

On-disk layout

Everything under ~/.cori/ — what each file and directory is for.

Cori's state is in ~/.cori/. There is no database, no SQLite, no migrations. All state is plain files (TOML, JSON). Your workflow folders are separate — Cori reads from them but never writes to them.

Directory tree

~/.cori/
  config.toml                  # Your configuration (temporal, llm providers, remotes)
  cache/
    <compiled-workflow-hash>/   # Compiled TypeScript step files, one dir per workflow version
    remote/
      <host>/<owner>/<repo>/   # Fetched remote workflow content
      pins.json                # Pinned ref → commit SHA mappings
      trust.json               # First-run trust decisions per remote
  runs/
    <run-key>/
      <utc-timestamp>.json     # JSON run trace for each execution
  credentials/
    index.json                 # OAuth token metadata (owner, expiry) — tokens in OS keychain
    secrets-index.json         # Which LLM providers have keys — keys in OS keychain
    llm-secrets.json           # 0600 file fallback for LLM keys (headless machines only)
  cluster/
    <queue-name>.json          # Per-task-queue worker registry entries
  schedules/
    <id>.json                  # Schedules (cron + identity), managed by the Cori desktop app or written by hand
  runtime/                     # Ephemeral runtime state for in-progress runs
  state/
    temporal-dev.pid           # PID of the auto-spawned dev Temporal, if any

Key entries

config.toml

Your configuration. Read and written by cori config get/set. Contains non-secret configuration only (endpoint host, allowed remote hosts) — never credentials. Secrets live in the OS keychain via cori login, and cori config set refuses secret keys.

cache/

Compiled workflow artifacts. Each subdirectory corresponds to a specific workflow version (keyed by content hash). Cori compiles TypeScript step files here on first use and reuses the cache on subsequent runs.

cache/remote/ holds fetched remote workflow content. pins.json maps mutable refs (@v1) to the resolved commit SHAs. trust.json records your first-run consent decisions.

runs/<key>/<utc>.json

One JSON file per workflow execution. The run key encodes the workflow identity (local path hash or remote ref). The filename is the UTC timestamp of the run start. See Run trace for the file's contents.

There is no database. Run history is a flat directory of JSON files.

credentials/

Non-secret indexes of stored credentials, so cori status / cori check and the desktop app can answer "is this provider configured?" without unlocking the keychain:

  • index.json — OAuth token metadata (server, owner, expiry).
  • secrets-index.json — which LLM providers have a stored API key.

The actual secrets are in the OS keychain (Keychain Access on macOS, Credential Manager on Windows, libsecret on Linux) under the cori service. On machines without a usable keychain — headless Linux, CI — keys land in llm-secrets.json with file mode 0600 instead; that file does not exist otherwise.

cluster/<queue>.json

Per-task-queue worker registration. Updated when cori work or cori work --shared starts or stops.

schedules/<id>.json

Schedule intent registered through the Cori desktop app (or written by hand). id is sha256(source + cron)[..12]. Each entry holds the workflow source (path or remote ref), cron expression, IANA timezone, owning identity (task queue), enabled flag, and the most recent fire status. The cron driver inside the desktop app (or cori work) scans this directory every 30 seconds and fires entries whose identity matches its task queue. Missed fires while neither is running are not caught up — for hands-off scheduled workflows, keep the desktop app or a cori work process online.

Run key shape

For local workflows: local/<path-hash>

For remote workflows: remote/<host>/<owner>/<repo>[/<subpath>]@<resolved-sha>

Cache key shape

Compiled workflow cache keys are content-addressed (based on the hash of the step files and manifest). Changing a step file produces a new cache entry; the old one is retained until Cori cleans up stale entries.

On this page