Skip to content

CLI for AI agents

The plm CLI is designed for AI agents as a first-class user. Every command has stable JSON output, predictable exit codes, and idempotent semantics. This page covers the patterns that make agent-written automation reliable.

Discovery

Three discovery surfaces, in increasing detail:

  1. /llms.txt — a curated index of every docs page, one bullet per page. Good for “what is this product?”
  2. /llms-full.txt — the entire docs corpus concatenated in markdown. Stream once at the start of a session and you have everything.
  3. Per-page markdown — every /docs/<slug>/ has a .md alternate at /docs/<slug>.md and a <link rel="alternate" type="text/markdown"> in the <head>.

For per-command machine-readable structure, each CLI reference page has an <details>Agent-readable summary</details> block containing JSON with arguments, options, defaults, and subcommands.

plm <noun> --help works too, but tends to be terser than the docs.

Output

Terminal window
plm parts list --format json

--format json is the agent default. Schemas are stable per command and versioned in the per-command reference page. --format table and --format yaml are also supported.

Exit codes

CodeMeaning
0Success.
1User error (bad flag, validation failure, missing argument).
2Network or auth failure. The credential at ~/.config/plm/credentials may need refresh — try plm login again.
3Conflict — a write-time collision in plm-data/. Retry after pulling the latest state.

Agents should distinguish exit 1 (don’t retry, fix the call) from 2/3 (transient, retry with backoff).

Idempotency

Writes are addressed by deterministic IDs (part numbers, BOM revision hashes, ECO IDs). Re-running the same plm parts create --file foo.yaml is a no-op if the existing part already matches the input bit-for-bit. If it differs, you get exit 3 unless you pass --update.

This means an agent can safely retry a failed write without worrying about creating duplicates.

Authentication for headless agents

For non-interactive contexts (CI, scheduled tasks, agent runners):

Terminal window
plm login --token <PAT>

PATs are generated in the dashboard at Settings → API tokens. Set the PLM_TOKEN env var to pre-populate, then plm login --token "$PLM_TOKEN". Tokens are scoped to one org by default; pass --org at command time to operate on others if your PAT has cross-org permission.

Where the data lives

plm-data/ in a Git repo, one repo per org. Branch + commit semantics are standard Git. Agents that want raw read access can clone the org’s plm-data repo directly — the CLI exists for write paths and for surface area that’s expensive to reimplement (validation, indexes, ECO state).

A sample agent loop

import subprocess, json
# 1) Discover the surface.
corpus = subprocess.check_output(["curl", "-fsSL", "https://simple-plm.com/llms-full.txt"]).decode()
# 2) Read a per-command JSON summary from the reference page.
ref = subprocess.check_output(["curl", "-fsSL", "https://simple-plm.com/docs/cli/parts.md"]).decode()
# 3) Execute. JSON output, retry on exit 2/3.
def call(args, retries=3):
for _ in range(retries):
r = subprocess.run(["plm", *args, "--format", "json"], capture_output=True, text=True)
if r.returncode == 0:
return json.loads(r.stdout)
if r.returncode in (2, 3):
continue
raise RuntimeError(f"plm {args} → exit {r.returncode}: {r.stderr}")
raise RuntimeError("retries exhausted")
print(call(["parts", "list"]))