shapes CLI
@openape/shapes
Shapes is the execution layer for agents. It wraps existing CLI tools and ensures every command runs within the boundaries set by grants. Instead of giving agents blanket access to kubectl or aws, Shapes maps each command to a structured permission and checks it against the agent's approved grants.
How It Works
Agent: "gh repo delete myorg/old-repo"
β
Shapes: Load adapter for "gh"
β
Parser: Match operation "repo.delete"
β
Resolver: Build permission "gh:repo.delete(owner=myorg,name=old-repo)"
β
Grant check: Does a valid grant cover this?
β Yes β Execute command
β No β Request grant, wait for human approval
Installation
npm install -g @openape/shapes
Quick Start
# See what permissions a command requires (without executing)
shapes explain -- gh repo list myorg
# β gh:repo.list (risk: low) β List repositories for owner myorg
# Request a grant and execute
shapes request --idp https://id.example.com --approval once -- gh issue create --repo myorg/app --title "Bug"
# β Requests grant... waiting for approval... approved! Executing.
# Execute with a pre-approved grant token
shapes --grant <jwt> -- kubectl get pods -n production
The Shapes Registry
The Shapes Registry is the catalog of available adapters. It defines which CLI tools can be wrapped and how their commands map to permissions.
Registry Structure
The registry is a GitHub repository with TOML adapter definitions:
shapes-registry/
βββ registry.json # Generated index (auto-built)
βββ adapters/
β βββ gh/
β β βββ adapter.toml # Operation definitions
β β βββ meta.json # Metadata
β β βββ README.md
β βββ kubectl/
β βββ az/
β βββ exo/
β βββ o365mail/ # 20 operations for Outlook mail
β βββ ls/
β βββ cat/
β βββ chmod/
β βββ ...
Discovering and Installing Adapters
# Search the registry
shapes adapter search github
# β gh β GitHub CLI (devtools)
# Install an adapter
shapes adapter install gh
# List installed adapters
shapes adapter list
# Update all adapters
shapes adapter update
# Verify adapter integrity (SHA-256 digest)
shapes adapter verify gh
Adapters are cached locally at ~/.openape/shapes/adapters/. The registry is fetched from GitHub and cached for 1 hour.
Adapter Resolution Order
When Shapes loads an adapter, it searches in this order:
- Project-local:
.openape/shapes/adapters/{id}.toml - User home:
~/.openape/shapes/adapters/{id}.toml - System:
/etc/openape/shapes/adapters/ - Bundled:
node_modules/@openape/shapes/adapters/ - Fallback: scan all directories for matching executable name
Adapter Format
Each adapter is a TOML file that maps CLI commands to operations:
schema = "openape-shapes/v1"
[cli]
id = "gh"
executable = "gh"
version = "1"
[[operation]]
id = "repo.list"
command = ["repo", "list"]
positionals = ["owner"]
display = "List repositories for owner {owner}"
action = "list"
risk = "low"
resource_chain = ["owner:login={owner}", "repo:*"]
[[operation]]
id = "issue.create"
command = ["issue", "create"]
required_options = ["repo", "title"]
display = "Create issue in {repo}: {title}"
action = "create"
risk = "medium"
resource_chain = ["repo:owner={repo|owner},name={repo|name}", "issue:*"]
[[operation]]
id = "repo.delete"
command = ["repo", "delete"]
positionals = ["repo"]
display = "Delete repository {repo}"
action = "delete"
risk = "critical"
exact_command = true
resource_chain = ["repo:owner={repo|owner},name={repo|name}"]
Operation Fields
| Field | Required | Description |
|---|---|---|
id | Yes | Unique operation ID (e.g., repo.list) |
command | Yes | Command prefix to match (e.g., ["repo", "list"]) |
positionals | No | Positional argument names |
required_options | No | Required --option names |
display | Yes | Human-readable description with {binding} templates |
action | Yes | Action type: read, list, create, edit, delete, send, draft |
risk | Yes | Risk level: low, medium, high, critical |
resource_chain | Yes | Hierarchical resource selectors |
exact_command | No | If true, only exact argv match is allowed (for destructive operations) |
Resource Chains
Resource chains describe what is being accessed, hierarchically:
owner:login=myorg β repo:name=myapp β issue:id=42
Format: resource[:selector1=value1,selector2=value2]
Bindings use {name} templates resolved from parsed arguments:
{owner}β from positional argument{repo|owner}β extract owner part fromowner/nameformat{repo|name}β extract name part*β wildcard (matches any)
Risk Levels
| Level | When to use | Approval behavior |
|---|---|---|
low | Read-only, listing operations | May auto-approve with always grants |
medium | Create, edit operations | Typically once or timed grants |
high | Delete, modify permissions | Requires explicit once grant |
critical | Destructive, irreversible | Requires once grant + exact_command = true |
Integration with grapes
grapes uses Shapes for structured capability requests:
# Command-based (parses the actual CLI command)
grapes request "gh issue create --repo myorg/app --title Bug" --audience shapes --wait
# Capability-based (specify resources and actions directly)
grapes request-capability gh \
--resource repo \
--action list \
--selector owner.login=myorg \
--approval timed --duration 1h
Digest Verification
Security is enforced through SHA-256 digest verification at multiple points:
- Installation: Downloaded adapter TOML must match the registry digest
- Grant request: The adapter digest is included in the grant request
- Execution: The runtime adapter digest must match the grant's digest
This ensures that an adapter cannot be tampered with between grant approval and command execution.
Writing a Custom Adapter
- Create a directory in the shapes-registry:
adapters/my-tool/
βββ adapter.toml # Operation definitions
βββ meta.json # Metadata for the registry
βββ README.md # Documentation
- Define metadata in
meta.json:
{
"id": "my-tool",
"name": "My Tool",
"description": "Grant-aware wrapper for my-tool CLI",
"author": "your-org",
"category": "devtools",
"tags": ["ci", "deployment"],
"executable": "my-tool",
"min_shapes_version": "0.3.0"
}
- Define operations in
adapter.tomlfollowing the TOML format above - Submit a PR to the shapes-registry β the CI will validate the adapter format and compute the digest
CLI Reference
# Adapter management
shapes adapter search <query> # Search registry
shapes adapter install <id> # Install adapter
shapes adapter remove <id> # Remove adapter
shapes adapter list [--remote] # List adapters
shapes adapter info <id> # Show adapter details
shapes adapter update [<id>] # Update adapters
shapes adapter verify <id> # Verify digest
# Execution
shapes explain -- <cli> [args...] # Explain required permissions
shapes request -- <cli> [args...] # Request grant + execute
shapes --grant <jwt> -- <cli> [args...] # Execute with pre-approved grant