Skip to main content

Agent and CLI for controlling SO-ARM101 robotic arm grippers

Project description

arm101-cli

Agent and CLI for controlling SO-ARM101 robotic arm grippers

What you get

  • An agent-first CLI cited from teken (afi-cli) — the runtime package has no third-party dependencies.
  • A mesh identityculture.yaml (suffix + backend) and the matching prompt file (AGENTS.colleague.md for this agent's backend: colleague).
  • The canonical guildmaster skill kit (11 skills) under .claude/skills/, vendored cite-don't-import. See docs/skill-sources.md.
  • A build + deploy baseline — pytest, lint, the agent-first rubric gate, and PyPI Trusted Publishing wired into GitHub Actions.

Installation

Base install (zero third-party runtime dependencies — introspection only):

uv sync          # or: pip install arm101-cli

For real Feetech STS3215 motor I/O on the Seeed Studio SO-101 kit, add the [seeed] extra (named by the kit provider; the CLI verifies each connected motor really is a Feetech STS3215 at runtime):

uv sync --extra seeed          # or: pip install 'arm101-cli[seeed]'

This pulls in feetech-servo-sdk (import module scservo_sdk), which the bus adapter lazy-imports. The base install stays zero-dep so the CLI and agent introspection work on any machine without hardware attached.

Quickstart

uv sync
uv run pytest -n auto                 # run the test suite
uv run arm101 whoami                 # identity from culture.yaml (console script is 'arm101')
uv run arm101 learn                  # self-teaching prompt (add --json)
uv run teken cli doctor . --strict    # the agent-first rubric gate CI runs

CLI

Verb What it does
whoami Report this agent's nick, version, backend, and model from culture.yaml.
learn Print a structured self-teaching prompt.
explain <path> Markdown docs for any noun/verb path.
overview Read-only descriptive snapshot of the agent.
doctor Check the agent-identity invariants (prompt-file-present, backend-consistency).
cli overview Describe the CLI surface itself.
arm overview / arm read / arm flex / arm explore / arm setup <role> Arm-level operations on the SO-101 — see below.

Every command supports --json. Results go to stdout, errors/diagnostics to stderr (never mixed). Exit codes: 0 success, 1 user error, 2 environment error, 3+ reserved.

Arm verbs

The arm noun group carries the SO-101 hardware surface: arm overview (read-only spec snapshot), arm read (read-only live joint state), arm flex (gated single-joint/demo motion), arm explore (gated reachability mapping — documented below), and arm setup <role> (gated per-role motor bring-up). arm flex/arm explore/arm setup are gated motion: a TTY prompts for confirmation, a non-TTY run without --apply prints a dry-run plan (zero motion, zero bus access), and non-TTY with --apply proceeds (agent mode).

Torque safety: hold on success, release on abnormal

Every gated motion verb owns the motors it energizes and releases them on any abnormal exit — an unhandled exception, a bus fault, or Ctrl-C. The arm is never walked away from hot. The release attempts each motor independently and survives its own failure, because the bus that just threw is the same bus the release has to talk to.

A clean exit is different: torque is left exactly as the verb left it, so a successful gentle_move's deliberate stop-and-hold survives and a gripper that has closed on an object does not drop it when the command returns. A powered arm at process exit is therefore always a deliberate state, never an accident.

Known limit. This protects every failure where the process still has a bus. It cannot protect against physical loss of the bus: the servos are powered from the 12 V supply while USB carries only data, so unplugging the cable removes the host's only channel to the arm — every release write fails and the motors hold their last commanded goal. No software can release torque over a bus that no longer exists. Whether the servo can safe itself on comms loss is tracked in #37.

arm explore — map the arm's reachable joint-space

Before this verb, nothing persisted where the arm can safely move: limits were found by manually flexing one joint at a time and eyeballing contacts, and that knowledge was lost the moment the session ended. arm explore autonomously flood-fills the follower's (or leader's) joint-space at safe speed — via the same overload-safe gentle_move primitive arm flex --gentle uses — detects every self/environment contact from real load, and writes a resumable, overridable reachability map.

uv run arm101 arm explore --apply                       # follower, defaults
uv run arm101 arm explore --role leader --map ./bench-a.map.json --apply
uv run arm101 arm explore --threshold 300 --max-moves 500 --apply

Flags: --role {follower,leader} (default follower), --port (default auto-detect), --map PATH (resume input if it exists, and the write target; default ./arm-explore-<role>.map.json), --threshold (contact-load threshold, default 250), --max-moves (move/probe budget cap, default 2000 — hardware-tuned open question), --resolution (per-joint grid bucket size in encoder ticks, default 512 — hardware-tuned open question), --apply, --json.

Every run writes two artifacts: an append-only JSONL event log (the resumable source of truth — a killed run resumes instead of re-probing already-mapped cells) and a derived, compact reachability map (per-joint reachable ranges plus a sparse list of blocked joint-combinations). When a joint is blocked, a bounded multi-joint escape search perturbs other joints to find combinations that unblock it, rather than stopping at the first single-joint contact. A bundled self-collision default map ships and loads automatically when no user --map is present.

v1 scope: arm explore produces and stores the reachability map, and the map is queryable offline straight from the file — but v1 does not change arm flex's behavior. Consuming the map to gate arm flex targets (refuse/warn on a request outside the discovered envelope) is a documented follow-up, not part of this verb.

Make it your own

  1. Rename the package arm101/ and the arm101-cli CLI/dist name throughout pyproject.toml, the package, tests/, sonar-project.properties, and this README.md. The name is hard-coded in ~100 places, so list every occurrence first — see the git grep discovery command in CLAUDE.md, the authoritative rename procedure.
  2. Edit culture.yaml with your suffix and backend.
  3. Rewrite CLAUDE.md for your agent and run /init.
  4. Re-vendor only the skills you need from guildmaster (see docs/skill-sources.md).

See CLAUDE.md for the full conventions (version-bump-every-PR, the cicd PR lane, deploy setup).

License

Apache 2.0 — see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

arm101_cli-0.22.1.tar.gz (749.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

arm101_cli-0.22.1-py3-none-any.whl (262.4 kB view details)

Uploaded Python 3

File details

Details for the file arm101_cli-0.22.1.tar.gz.

File metadata

  • Download URL: arm101_cli-0.22.1.tar.gz
  • Upload date:
  • Size: 749.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for arm101_cli-0.22.1.tar.gz
Algorithm Hash digest
SHA256 a7aea31ab97411262f5689dc5ed7a39418574a9b13a62e0401257b4dbd77567f
MD5 fe93082795f9cc1a9279eea14fc5fe96
BLAKE2b-256 19250d40981c035d264cef6195fa5e8a829f92c3896cfd4ac82f7d30033ea169

See more details on using hashes here.

File details

Details for the file arm101_cli-0.22.1-py3-none-any.whl.

File metadata

  • Download URL: arm101_cli-0.22.1-py3-none-any.whl
  • Upload date:
  • Size: 262.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for arm101_cli-0.22.1-py3-none-any.whl
Algorithm Hash digest
SHA256 1ef615974e805ef8f0aee4df307b7c8249c8544ed243049457e029789b6f8d7d
MD5 967915b8f112dffc4f6cf6f6cf7a6735
BLAKE2b-256 5a443d915f360c34e81fb309069fcdc4b06be9e029afd0b3efec9eace98974eb

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page