Skip to main content
This page takes you from a folder of session files on your machine to those sessions stored in your org, with nothing but the litmus-ai command and an org token. No console, and no help from us. It takes four steps, and the same command runs them again if one is interrupted.

Words this page uses

  • Org token: the secret that proves a call is from your org. A push token can store evidence; read cannot. Get a token says who mints one.
  • Evidence: anything you store in your org for Litmus to read: session transcripts, traces, documents. A push stores evidence.
  • Session: one conversation between a user and your agent, with the tool calls it made. A transcript file holds one or many.
  • Request: one HTTP call the command makes. A folder is sent in requests of up to 8 MB each, so a large export is several requests.
  • Job: work the workspace does in the background after it has answered you. A large request is stored at once and read by a job; you follow the job until it is done. Its id starts with job_.
  • Already in: a file the org already holds exactly as sent. It is counted and never stored twice, so running the same push again is safe.
  • Data access: what the push shares with Litmus, declared on every push. The four levels are on the CLI page.

1. Install

The second line prints the client’s version and its digest, offline. The same file is served by your workspace at GET /litmus.py, so you can check one against the other.

2. Say which workspace and which org

Either pin them once:
or set the two environment variables and pass nothing: LITMUS_TOKEN (your org token) and LITMUS_ORG (your org’s tag). LITMUS_URL is the workspace, and defaults to the hosted one. The variables win over the pinned values when both are set. Nothing on this page prints a token; the command masks it in everything it says.

3. Push the folder

  • ./sessions is a folder (or a .zip, .tar, .tar.gz). Every file in it is read: session transcripts and trace files as sessions, .md, .txt, .pdf, .pptx and .docx as documents. A file of a kind Litmus does not read is listed as refused, by name; hidden files and a Mac folder’s metadata are skipped.
  • --surface names the system your agent drives. With it, the push starts the pipeline on that system once, after the last request.
  • --data-access says what the push shares. Leave it off on a terminal and the command asks, with the four levels numbered; in CI or a script a push without it is refused before anything is read or sent.
  • --request-bytes <n> changes how much one request holds (default 8 MB). You will not normally need it; the command comes down on its own when a request does not get through.

What the lines mean

The command says what it is doing before each request, not after:
  • request k of n · files · size → sending is one request leaving your machine. A small push is one request and is answered in it.
  • A line starting job_ means the workspace stored that request whole and is reading it in the background. planned is how many of the request’s files it has read so far, stored how many it has kept (new, or replacing an earlier version of the same session), and the last number is how long you have waited. The line is printed each time the numbers move, every two seconds at most, until done.
  • If a request does not get through (the gateway answers 502 or 504, or the connection drops), the command says so and sends the same files again in two requests of half the size. It never sends a file the job had already stored. If the smaller request fails too, the push stops and prints the request it stopped at and the line that resumes it:
Run the same command again. Files already in are counted as such and skipped by the workspace, and the push carries on from where it stopped.

The summary

After the last request, one line per outcome and reason — its count and up to three example paths — and then the totals, in the workspace’s own words:
  • accepted / replaced / already in / refused / skipped are the workspace’s outcomes for each file. Replaced means the org held an earlier version of that session and now holds this one; the earlier one is kept, not counted. Files that met the same outcome for the same reason share one line, so a reason thousands of files share is read once, not thousands of times; pass --verbose to print every file’s outcome on its own line (<path>: refused — <reason>) when you need to find one file.
  • formats counts the sessions by the format each file was read as. Only the formats that arrived are named.
  • tool map appears when the push held session transcripts and a toolmap.json: how many of the recorded tool calls map onto the system you named, and the tool names left unmapped (no counterpart on it) or undecided (no rule names them). Those two lists are what to settle next; they hold tool names only, never a line of a transcript.
  • pipeline is the job the push started on your system, when it started one.

4. Follow a job from Claude

Every job_ id above is a job you can read from anywhere a tool reaches the workspace. From Claude, attached as Attach Claude shows, ask:
Where is job job_3f9c2a1b7d04?
Claude calls job_status with {"job_id": "job_3f9c2a1b7d04"} and reads the same record the command was printing from. While the job runs, tally holds files_done of files, what is accepted, replaced, already in, refused and skipped so far, and each landed file’s name and outcome; step says which of its three steps (open, ingest, finish) it is on. Once it is done, result holds the whole answer the summary above was printed from. Over HTTP the same record is GET /v0/jobs/{job_id} on the Runs page.

If something is refused

  • A whole folder is refused before anything is sent when one of its files holds something shaped like a secret. The message names the file and the count. Re-run with --allow-secrets if they are not secrets.
  • One file is refused when it is larger than one request holds, or of a kind Litmus does not read; the summary names it with the reason, and the rest of the push is unaffected.
  • A whole request is refused (the answer is 422) when an archive holds a path that leaves it, a link, or more than 2,000 entries. Nothing of it is stored; fix the archive and push again.