Skip to content

Command line interface

lithora puts your workspace — and the confirmation-gated agent — in your terminal and your CI pipeline. Built on the same Python SDK, so there is one HTTP core and one set of semantics.

Install

Install lithora-cli
pipx install lithora-cli    # recommended — isolated environment
# or
pip install lithora-cli

Installs the lithora command. Requires Python 3.9 or newer. The package is lithora-cli; the command is lithora. Shell completion is available via lithora --install-completion.

Authenticate

For scripts, CI and anything unattended, use a personal access token. Mint one at Settings → API Tokens — see Authentication for the scope list.

Token auth (recommended)
# Mint a token at dashboard.lithora.app/settings -> API Tokens
export LITHORA_TOKEN=lth_pat_your_token_here

lithora whoami
lithora doctor          # checks config, connectivity and auth in one shot

For day-to-day interactive use on your own machine you can log in instead:

Interactive login
lithora login --email you@example.com
# Password is prompted; it is never accepted as a flag value.
# The token goes to your OS keychain, or a 600-mode file if no keychain is available.

Interactive login cannot complete a 2FA or new-device challenge

lithora login fails with exit code 3 if the account has 2FA enabled or the request comes from an unrecognised device, because neither challenge can be answered from a terminal. That is not a bug to work around — it is the reason to use a token. Set LITHORA_TOKEN and every command works regardless.

Resolution order for every setting is flag → environment variable → profile on disk → default. The relevant variables are LITHORA_TOKEN, LITHORA_BASE_URL, LITHORA_PROFILE and LITHORA_OUTPUT. The base URL defaults to https://api.lithora.app, and the CLI prints a loud warning if you point it at a plaintext non-localhost host.

Everyday commands

Projects and work items
# Find the team, then create a project inside it
lithora teams list
lithora projects create --name "Q3 Launch" --team <team_id>

# Work items
lithora tasks create --title "Wire up billing" --project <project_id> --priority high
lithora tasks list --project <project_id> --status todo
lithora tasks show <task_id>
lithora tasks status <task_id> in_progress
lithora tasks assign <task_id> --user <user_id>
lithora tasks my                            # everything assigned to you
lithora tasks delete <task_id>              # prompts unless you pass --yes

Ids are printed by the corresponding list command — run lithora teams list first and copy the team_id. Every group supports --help.

The agent, and the gate

lithora ai "<prompt>" is shorthand for lithora ai chat. If the agent proposes changes it prints the plan and stops — nothing is written until you say yes.

Ask the agent
lithora ai "break the autosave issue into a parent task and subtasks"
What you see before anything is written
ACTION PLAN  (requires confirmation)
  Action: 5e2a91c7-…   Status: waiting_confirmation
  1. + task: Add autosave to the editor   [acme/web#418]
       - subtask: Persist drafts to localStorage
       - subtask: Debounced autosave on change
  Summary: Agent will create 1 task + 2 subtasks

Approve? [y]es / [n]o [n]:

In CI there is no one to answer the prompt, so the CLI refuses rather than guessing:

Non-interactive approval
# Non-interactive: approve up front, or the run exits 2 rather than hanging.
lithora ai chat "triage last night's CI failures" --yes

# Or review staged plans (overnight triage, CI-failure triage) and approve by id.
lithora ai pending
lithora ai confirm <action_id> --session <session_id>
lithora ai confirm <action_id> --session <session_id> --reject

--yes is a standing approval

--yes approves whatever the agent proposes, sight unseen. Use it only where the prompt is narrow and the blast radius is bounded. The safer CI shape is to let autonomous runs stage plans and approve them with lithora ai pending / confirm after a human has read them.

Scripting

-o json emits the exact API payload, unmodified. That is the contract to script against — the table renderer is for humans and its columns may change.

JSON output
lithora tasks list --project <project_id> -o json | jq '.[] | select(.priority=="urgent")'

# -o accepts table (default on a TTY), json, or yaml.
# LITHORA_OUTPUT=json makes it the default for a whole CI job.

Exit codes

Exit codes follow Unix conventions so a pipeline can branch on the failure mode rather than grepping stderr.

CodeMeaning
0Success.
1Generic failure — including a 5xx or a connectivity problem.
2Bad usage, or a plan needed confirmation with no TTY and no --yes.
3Not authenticated (401) or forbidden (403).
4Not found (404).
5Conflict (409).
7Rate limited (429) — the SDK already retried. Wait, then re-run.
22Invalid input (400 or 422).
130Interrupted with Ctrl-C.

In GitHub Actions

.github/workflows/lithora.yml
name: Sync release tasks
on:
  release:
    types: [published]

jobs:
  sync:
    runs-on: ubuntu-latest
    steps:
      - run: pipx install lithora-cli
      - name: Create the release checklist
        env:
          LITHORA_TOKEN: ${{ secrets.LITHORA_TOKEN }}
          LITHORA_OUTPUT: json
        run: |
          lithora tasks create \
            --title "Post-release checks for ${{ github.event.release.tag_name }}" \
            --project "${{ vars.LITHORA_PROJECT_ID }}" \
            --priority high

Profiles

Profiles work like kubectl contexts: one per account, org or environment. Non-secret state lives in ~/.lithora/config.json (directory 700, file 600); the token itself goes to the OS keychain when one is available.

Switching contexts
lithora profile list
lithora profile use staging
lithora profile show

# Per-invocation overrides beat everything:
lithora --profile staging --base-url http://localhost:8000 teams list

Managing tokens from the CLI

lithora token
lithora token list
lithora token create --name ci-release-bot --scope tasks:write --scope projects:read
lithora token revoke <token_id>

These need a login session, not a token

A token can never manage tokens — the API returns 403 for a PAT-authenticated caller on create and revoke. Run lithora login first, or manage tokens in the web app.

Command groups

GroupSubcommands
lithora login / logout / whoami / doctorAuthenticate, sign out, identify yourself, diagnose.
lithora teamslist, show, members, create
lithora projectslist, show, create, update, delete
lithora taskslist, my, show, create, status, update, assign, delete
lithora work-itemslist, graph, cycle-time, pr-status, resolve
lithora automationslist, show, create, toggle, execute, history, run-status, export, versions, rollback, templates
lithora runnerslist, register, manifest, dispatch, jobs, audit, revoke
lithora sprintslist, show, create, plan, update, close, summary, velocity
lithora webhookslist, events, show, create, update, delete, logs, clear-logs, stats, rotate-secret, test
lithora datafields, export, import
lithora githubstatus, repos, connect
lithora searchquery, recent
lithora aichat (the default), pending, confirm, sessions
lithora tokencreate, list, revoke
lithora profilelist, use, show

Troubleshooting

  • Everything exits 3. Run lithora doctor. It prints the resolved profile, base URL and whether a token was found at all — usually the answer is that LITHORA_TOKEN was not exported into the shell the command actually ran in.
  • Requests hit the wrong host. lithora profile show prints the effective base URL. A stale LITHORA_BASE_URL beats the profile on disk.
  • A CI job hangs or exits 2 on an agent command. The plan needed confirmation and there was no TTY. Add --yes, or split it into ai pending plus a reviewed ai confirm.
  • Debugging a request. --debug turns on verbose, credential-redacted request logging.