Catalog PyPI
Back to packageRELEASE DETAILS

0.1.4

PyPI

agent-tool-shared-cli

Shared chassis for agent-ready CLIs: the exit-code contract, JSON/table/markdown/CSV output with field projection, and keyring-backed credentials.

agent-readyai-agentautomationclicommand-lineexit-codesjson-outputkeyringllm
Published20 Jul 2026
Direct dependencies4
Transitive dependenciesNot calculated

README

Version 0.1.4 documentation

agent-tool-shared-cli

The shared chassis for the agent-tool-<x>-cli family — agent-ready command-line tools that an LLM can drive with no prior knowledge of them.

PyPI CI Python License: MIT

pip install agent-tool-shared-cli

The tools built on it — each learns the same contract, so an agent that knows one knows them all:

ToolInstallFor
drone-clipipx install agent-tool-drone-cliDrone CI — builds, failing-step logs, promotions
grafana-clipipx install agent-tool-grafana-cliGrafana — log discovery, health scan, alert routing
openprojectpipx install agent-tool-openproject-cliOpenProject — work packages, time, invoicing
lexware-officepipx install agent-tool-lexware-office-cliLexware Office — invoices, contacts, AR-aging

This repo also holds the family's engineering docs — read these first if you are standing up a new tool:

Keywords: agent CLI chassis, LLM tool contract, exit-code taxonomy, JSON output CLI, keyring credentials, Python CLI library, AI agent tooling, Claude.

What's in it

This package is deliberately small. It holds the agent contract and the pure utilities that implement it — the things that must be identical across every tool, because an agent learns the contract once and applies it everywhere.

ModuleWhat
agentcli.errorsThe exit-code taxonomy (0/1/3/4/5/6/7/130) + DryRun
agentcli.outputEmitter: json/table/markdown/csv, --fields projection, NDJSON streaming
agentcli.credentialsKeyring storage with a 0600 fallback and an env override
agentcli.appspecAppSpec — the two strings that make all of the above tool-specific
from agentcli import AppSpec, Credentials, Emitter, OutputFormat, NotFoundError

SPEC = AppSpec(name="drone-cli", env_prefix="DRONECLI")

SPEC.config_dir()            # ~/.config/drone-cli  (or $DRONECLI_CONFIG_DIR)
SPEC.env("TOKEN")            # "DRONECLI_TOKEN"

Credentials(SPEC).get_token("default")     # env > keyring > 0600 file
Emitter(OutputFormat.json, fields=["id", "status"]).emit(rows)
raise NotFoundError("no such build")       # -> exit 5, JSON on stderr

The exit-code contract

Published API. You may leave a code unallocated, or repurpose one deliberately. You may never renumber one — agents branch on these, and they are documented in three places per tool (README, the in-binary guide, and the Claude skill).

CodeMeaning
0success (including a successful --dry-run)
1generic error
2reserved for Click/Typer usage errors — never allocate
3config error
4auth error (401/403)
5not found (404)
6conflict (409 / optimistic locking)
7validation error (422) — see fieldErrors
8+per-tool, and only for a condition you have observed
130SIGINT

What is deliberately NOT here

client.py, serialize.py, resolve.py and the domain commands stay in each tool. They look shareable and are not:

OpenProject stops paginating on an authoritative total — "never stop on a short page". Drone has no total, and a short page is the terminator. The rule that inverts between tool #1 and tool #2 is exactly the rule you must not hoist.

Auth schemes, retry matrices and error-body shapes are the same story. Pulling them in would make this a framework with a config object per tool, which is how shared-code projects die.

Share the contract, not the transport.

Contributing

You need nothing but Python:

pip install -e '.[test]'
pytest                       # 74 tests, no network, no services

Changes here affect every downstream CLI. Two rules:

  1. Never renumber an exit code, and never change an output shape without treating it as a breaking change — downstream agents depend on both.
  2. Don't add a module because two tools happen to share it today. Wait until a third does, and until you can state the rule it obeys. tests/test_contract.py is the tripwire: if a change makes you edit it, stop and think.

License

MIT — see LICENSE.

Downloads & popularity

Awaiting observations

No metric observations yet

Download counts and popularity will appear here as the collector receives them.

Declared dependencies 4

Native requirements
4 direct targetsNot calculated transitive count
Package / targetRequirementRelationship
keyring
Environment
{
  "extras": "",
  "marker": null,
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
keyring>=25runtime
rich
Environment
{
  "extras": "",
  "marker": null,
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
rich>=13runtime
pytest
Environment
{
  "extras": "",
  "marker": "extra == \"test\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
pytest>=8; extra == "test"runtime
pytest-timeout
Environment
{
  "extras": "",
  "marker": "extra == \"test\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
pytest-timeout>=2.3; extra == "test"runtime

Distribution files

2 collected
agent_tool_shared_cli-0.1.4-py3-none-any.whl

bdist_wheel · 17.72 KB · Python py3

Source file
agent_tool_shared_cli-0.1.4.tar.gz

sdist · 22.45 KB · Python source

Source file

Repository

PENDING
alexander-zierhut/agent-tool-shared-cli

Shared repository data · GitHub

License detected in repository
Not collected

Metadata history

Meaningful changes
Current collected state Current

Observed since 20 Oct, 23:34 UTC

No superseded metadata states collected. Unchanged observations do not create new revisions.

Record identity

package_version:3dcf3063c4fc1cdab8695e1eeed18882d211ff31048e4f03fa9fbbe16717b88b

Other collected versions

View all collected versions →