Capora docs Agent docs Sign in
Documentation

Not a drive. A base.

A Space is more than where your files and work output live. With workflows, the filesystem itself becomes a running system — save a file and the pipeline that watches it runs. Session after session with your agents, it accumulates into your — or your team's — own home base you keep building on, not a pile of outputs. Every write is versioned.

The model in one minute

Space
Your base — one content-addressed filesystem that stores your files and the system that runs them. Globally-unique name (like an S3 bucket), so remote://<space> addresses it with no owner prefix.
Save point
Every write records an immutable version. Diff, restore, or read a file as it was — history is free.
Session
The work thread a write belongs to. Required before any write, so on shared ground every change carries a stated intent and an owner.
Workflow
A trigger — a file change or a cron — plus one entry script, run in a container with your secrets. Saving a watched file is what fires it.

Install the CLI

The CLI is a single self-contained binary (no runtime needed). The installer detects your OS/arch and puts capora on your PATH.

1 · Install

# installs the capora binary to /usr/local/bin (sudo fallback → ~/.local/bin)
curl -fsSL https://capora.cc/install | sh

capora help
capora update     # upgrade later, in place (sudo if needed)
# Windows: download https://capora.cc/dl/capora-windows-amd64.exe onto your PATH

2 · Sign in

Get a token from the web console — sign in, open Connect an agent, and generate one (starts with cpt_). Then hand it to the CLI, easiest first:

# 1 · recommended (esp. for agents): save the console token to ~/.capora/config
capora login --token cpt_xxxxxxxxxxxxxxxxxxxx

# 2 · or, stateless (CI / ephemeral shells) — nothing written to disk
export CAPORA_URL=https://capora.cc
export CAPORA_TOKEN=cpt_xxxxxxxxxxxxxxxxxxxx

capora whoami                      # confirm: user + Space + server
Human at a terminal? plain capora login opens the browser to authorize and saves the token for you. An agent should skip the browser flow — get a token from the console and use capora login --token … (or the env vars). Env vars always take precedence over the saved config; reads on public Spaces need no token.

Using the CLI

Capora is a netdisk: your Space is a remote filesystem you operate on directly with S3-style commands. Remote paths are written remote://<space>/<path>; anything without that prefix is a local path. There's no pull/save dance — every write is versioned automatically. (Want git semantics on your own machine? Just use git.)

Copy files up, down, and around

capora session start --message "add the todo app"  # open a session — required before any write
capora cp ./apps/todo remote://<you>/apps        # upload a folder → remote apps/todo/
capora ls remote://<you>/apps                    # browse the remote tree
capora cp remote://<you>/apps/todo/app.js ./     # pull one file down
# …edit ./app.js with any tool…
capora cp ./app.js remote://<you>/apps/todo/     # push it back → a new save point

That first line isn't decoration: every write needs an open session — see Sessions. Reads don't. Omit the space (remote:/apps) to use your default Space from ~/.capora/config. Directory copies are rsync-style: cp apps/todo remote://…/apps keeps the todo name; a trailing slash on the source (cp apps/todo/ …) copies its contents. cp only adds/overwrites — it never deletes remote files.

Every command

Account
capora login [--token <t>]sign in (saves a token to ~/.capora/config)
capora logoutremove saved credentials
capora whoamicurrent user + current Space + server URL
capora space listlist the Spaces you can reach
capora updateupgrade this binary in place (alias upgrade)
Sessions — required before any write
capora session start [<id>]open a work thread (new cs_…), or resume one by id (prints its context) · --message "<intent>"
capora session message <id> "<md>"append a checkpoint note (also refreshes the lease) · alias msg
capora session list [--active]every session + who holds what + its latest note · alias ls
capora session show <id>full journal of any session (read-only)
Files (netdisk)
capora cp <src> <dst> [-m <msg>] [--mirror]copy files/folders up, down, or remote→remote (direction set by which side is remote://). --mirror makes dest match src (deletes dest extras) for dir copies into a Space.
capora ls [remote://…]list one directory level
capora tree [remote://…]list all files under a path
capora cat remote://…print a file to stdout · --at <save> for an old version
capora stat remote://…one file's hash + size
capora find <glob>find paths by glob (e.g. "src/**")
capora mkdir remote://… [-m]create an empty directory
capora rm remote://… [-m]delete file(s) or a folder (recursive)
capora mv <a> <b> [-m]move/rename (zero-byte, content-addressed)
History
capora log [remote://…]save-point history (newest first)
capora show <save>files changed in a save
capora diff [a] [b]changes between two saves
capora restore <save> [path]roll back to a save point
Workflows
capora workflowslist workflows + their trigger
capora runsrecent run history — check here after a save to see what fired
capora secret set <NAME> [value]set a Space secret (injected into runs) · secret list / secret rm

Global: --space <space> to target a Space from anywhere. Env: CAPORA_URL, CAPORA_TOKEN, CAPORA_PROJECT, CAPORA_SESSION. Run capora help for the built-in cheat sheet.

Sessions — a Space is an OS, a session is your shell

A capora session is a work thread you open before you change anything. It exists because a Space is shared ground: you, your teammates, and several agents all write to the same filesystem, so every write is attributed to a thread with a stated intent — and anyone can see what the others are in the middle of. It's separate from an agent's own runtime session; the record is just a file, at .capora/sessions/<id>.json.

Writes require a session. cp / rm / mv / mkdir refuse without one — session start first, or pass --session-id <id> / set CAPORA_SESSION. Reads never need one. This holds inside workflow runs too, and the server enforces it there (a run token that writes with no live session is rejected), so an automation must capora session start before saving anything back.
# open a thread (prints a new id), or resume one — resuming prints its intent + notes + actions
capora session start --message "refresh the pricing page"     # → cs_k7m2p9qx
capora session start cs_k7m2p9qx

# the id is remembered, so later writes are attributed automatically
capora cp ./site remote://<you>/site
capora cp ./site remote://<you>/site --session-id cs_k7m2p9qx   # …or be explicit

# checkpoint: a short note. Put long output in files and link them from the text
capora session message cs_k7m2p9qx "rewrote the tiers; numbers in remote://<you>/notes/pricing.md"

capora session list --active                                    # who is working on what, right now
capora session show cs_k7m2p9qx                                # read anyone's journal

How it behaves

Workflows — saving a file is the trigger

A workflow is a file at .capora/workflows/<name>.json: a trigger plus one entry script. You publish it by copying it up like any other file — there is no separate deploy step.

# .capora/workflows/transform.json
{
  "on": { "change": "data/raw/**" },   // …or { "schedule": "0 3 * * *" }
  "run": "scripts/transform.sh"        // a script in your Space
}

The two triggers

There are two triggers, and that's on purpose:

Always declare a trigger. A workflow with no "on" never runs on its own — there is no "run it now" button or command, by design. Deliberate, reproducible triggering means every run ties to a save point you can point at. Fire a job on demand by saving the input it watches; check capora runs to see what happened.
# create the pipeline (both files live in the Space)
capora cp scripts/  remote://<you>/scripts  -m "transform script"
capora cp .capora/  remote://<you>/.capora  -m "add transform workflow"
capora workflows                    # → transform  [change data/raw/**]

# fire it — by saving a file it watches
capora cp ./batch.csv remote://<you>/data/raw/  -m "new batch"
capora runs                         # confirm it ran, and how it ended

Inside a run

The run script is read from the pinned save point and executed in a container honoring its shebang (bash / node / python3). The Space's secrets are injected as env vars, along with a per-run CAPORA_URL / CAPORA_PROJECT / CAPORA_TOKEN so the script can copy files down and write results back. Jobs run asynchronously, so long work is fine.

The runner ships node/python/git, the capora CLI, and Claude Code (claude) — pre-configured — so a workflow can do AI steps (edit files, review a diff, gather data, generate content) then capora cp the result back. No key setup: runs route through Capora's AI gateway on a per-Space key, all permissions are bypassed by default, and a built-in capora skill lets claude read/write your Space. Just call it headless: claude -p "…".

Agent automations

Keep the task's intent as a plain-language brief at .capora/automations/<name>.md and make the workflow's script a one-liner — claude -p "capora session start, then read .capora/automations/<name>.md and do exactly what it says, saving output back with the capora CLI". The agent logs in with a session (required before any write), then does the fetching, generation, error-handling and write-back; since the brief is a Space file, it can even refine it across runs.