CLI

Manage issues, comments, labels, and projects from the terminal. Device-flow auth — no passwords in the shell.

Installation

npm install -g @xpntl/cli

Or with your preferred package manager:

# pnpm
pnpm add -g @xpntl/cli

# yarn
yarn global add @xpntl/cli

Verify the installation:

xpntl --version

Authentication

The CLI uses a device authorization flow. No passwords are ever entered in the terminal.

Interactive login

xpntl auth login

This generates a one-time code, opens your browser, and waits for you to approve. Once approved, the session token is saved locally for future commands.

  1. CLI requests a device code from the API
  2. Your browser opens to app.xpntl.dev/device?code=XXXX-XXXX
  3. Sign in (if needed) and approve the code
  4. CLI detects approval and saves the token

Harness key login

For CI/CD pipelines or agent harnesses, authenticate directly with a harness key:

xpntl auth login --key xpntl_hk_...

This saves the key locally without opening a browser.

Check status

xpntl auth whoami

Prints the signed-in user and active workspace. Add the global --json flag for machine-readable output.

Logout

xpntl auth logout
Running xpntl with no arguments shows the animated logo and, if you're not signed in, offers to start the device login right there.

Commands

Issues

# List issues (with optional filters)
xpntl issues list
xpntl issues list --state started --priority 1

# Get issue details
xpntl issues get ACME-42

# Create an issue
xpntl issues create --title "Fix login bug" --priority 2

# Update an issue
xpntl issues update ACME-42 --title "New title" --priority 1

# Delete (soft-delete) an issue
xpntl issues delete ACME-42

# Assign / unassign, move, duplicate, relate
xpntl issues assign ACME-42 <userId>
xpntl issues unassign ACME-42 <userId>
xpntl issues move ACME-42 "Frontend"
xpntl issues duplicate ACME-42
xpntl issues relate ACME-42 ACME-7 --type blocks

# Update many at once
xpntl issues bulk-update ACME-1 ACME-2 ACME-3 --state done

List filters: --state, --priority, --assignee, --query.

Comments

# List comments on an issue (shows each comment id)
xpntl comments list ACME-42

# Add a comment
xpntl comments add ACME-42 --body "Fix verified — deploying."

# Delete a comment by id (no edit — delete & repost to fix)
xpntl comments delete <commentId>

Labels

# List labels
xpntl labels list

# Create a label
xpntl labels create --name "bug" --color "#ff0000"

# Update or delete a label (admins only)
xpntl labels update <labelId> --name "defect" --color "#e11d48"
xpntl labels delete <labelId>

# Attach / detach a label on an issue
xpntl labels add ACME-42 <labelId>
xpntl labels remove ACME-42 <labelId>

Projects

# List projects
xpntl projects list

# Create a project
xpntl projects create --name "Frontend" --key FE

# Rename / update a project (status: planned|started|paused|completed|canceled)
xpntl projects update <projectId> --name "Web Client" --status started

# Delete a project and everything in it (admins only)
xpntl projects delete <projectId>

Workflow States

# List workflow states (use these IDs for issue transitions)
xpntl states list

# Create / update / delete (admins only)
xpntl states create --name "In Review" --type review
xpntl states update <id> --name "QA" --wip-limit 3
xpntl states delete <id>          # must be empty

# Reorder the board — pass every state id in the new order
xpntl states reorder <id1> <id2> <id3> ...

Teams

xpntl teams list
xpntl teams create --name "Platform" --key PLAT     # admins only
xpntl teams update <id> --name "Core Platform"
xpntl teams delete <id>
xpntl teams members <id>
xpntl teams add-member <id> <userId> --role Lead
xpntl teams remove-member <id> <userId>

Cycles

xpntl cycles list <projectId>
xpntl cycles active <projectId>
xpntl cycles create --project <id> --starts 2026-07-01 --ends 2026-07-14 --name "Cycle 7"
xpntl cycles close <id>
xpntl cycles assign <issueId> <cycleId>   # omit cycleId to unschedule

Docs

xpntl docs list
xpntl docs get <id>
xpntl docs create --title "Runbook" --content "## Steps"
xpntl docs update <id> --content "..."
xpntl docs delete <id>

Notifications

xpntl notifications list --unread
xpntl notifications read <id>
xpntl notifications mark-all-read

Import

# Track import jobs
xpntl import status
xpntl import status <jobId>

# CSV — preview headers, then import with a column mapping (title required)
xpntl import csv-preview issues.csv
xpntl import csv issues.csv --project <id> \
  --map title=Summary --map description=Body --map priority=Priority

# ClickUp — browse spaces, then import one (becomes a project)
xpntl import clickup-tree --token pk_...
xpntl import clickup --token pk_... --space <spaceId> --name "Imported"

# Jira
xpntl import jira-projects --url https://acme.atlassian.net --email me@acme.com --token <t>
xpntl import jira --url https://acme.atlassian.net --email me@acme.com --token <t> \
  --jira-project ENG --project <id>

# GitHub
xpntl import github-repo --repo acme/app --token <t>
xpntl import github --repo acme/app --token <t> --project <id>

Agent Loops

# Loop definitions (admins)
xpntl loops list
xpntl loops create --name "Triage" --cadence 60 --project <id> --agents 2
xpntl loops update <id> --enabled false
xpntl loops delete <id>
xpntl loops fire <id>

# Managed runs
xpntl loops run-now --project <id>
xpntl loops runs --limit 20
xpntl loops kill <runId>
xpntl loops status --project <id>

# Review gate (grooming proposals)
xpntl loops review-queue
xpntl loops review-apply --approve id1,id2 --veto id3

# Per-project guardrails & BYOK credentials (admins)
xpntl loops set-policy --project <id> --max-claims 25 --spend-ceiling 10
xpntl loops set-credential --kind anthropic_api_key --value sk-ant-...
xpntl loops credentials
xpntl loops validate-credential

Users

# List workspace members
xpntl users list

Configuration

Credentials are stored at ~/.xpntl/config.json. The CLI resolves the API base URL in this order: the XPNTL_API_URL environment variable, then an apiUrl in the config file, then the default https://api.xpntl.dev.

# Point to a self-hosted instance
export XPNTL_API_URL=https://xpntl.example.com