# ZeroClaw Rust SDK And Customer CLI

ZeroClaw is the first SysRelay Claw-family plugin being pushed to customer-delivery level. This crate now ships both a Rust SDK and a profile-driven CLI that customers can initialize, onboard, refresh, and use for signed relay sends.

Current scope:

- Blocking HTTP client via `reqwest::blocking` for onboarding, route, relay, inbox poll, ACK, and capability validation.
- Async HTTP client via `reqwest::Client` for the same API surface.
- Async WebSocket inbox receive plus batch ACK helpers for worker-style receive loops.
- Built-in P-521 key generation and challenge signing.
- Profile-based customer CLI with persisted identity assets and token storage.

## Customer quickstart

Initialize a customer profile directory. This creates `zeroclaw-profile.json`, `identity-private.pem`, and `identity-public.pem`.

```powershell
cargo run -- init C:\ZeroClaw\customer @acme/zero https://sysrelay.com
$env:ZEROCLAW_PROFILE_PATH = "C:\ZeroClaw\customer\zeroclaw-profile.json"
cargo run -- whoami
```

Onboard the profile and persist the issued access token back into the profile.

```powershell
$env:ZEROCLAW_PROFILE_PATH = "C:\ZeroClaw\customer\zeroclaw-profile.json"
cargo run -- onboard
```

Refresh the token later without manually copying challenges or signatures.

```powershell
$env:ZEROCLAW_PROFILE_PATH = "C:\ZeroClaw\customer\zeroclaw-profile.json"
cargo run -- refresh-token
```

Issue a short-lived cross-namespace capability token explicitly when you want to debug or inspect the bound token before sending.

```powershell
$env:ZEROCLAW_PROFILE_PATH = "C:\ZeroClaw\customer\zeroclaw-profile.json"
cargo run -- issue-capability @partner/worker task.execute 300
```

Send a signed JSON relay envelope using the stored identity.

```powershell
$env:ZEROCLAW_PROFILE_PATH = "C:\ZeroClaw\customer\zeroclaw-profile.json"
cargo run -- send @partner/worker '{"task":"ping","priority":"normal"}' global
```

For cross-namespace sends, ZeroClaw now auto-requests a short-lived capability token from SysRelay and injects it into `sr_payload.capability_token` before signing and sending. The payload must be a JSON object for this automatic injection to work.

Check inbox and ACK delivery once the profile has a token.

```powershell
$env:ZEROCLAW_PROFILE_PATH = "C:\ZeroClaw\customer\zeroclaw-profile.json"
cargo run -- poll 15
cargo run -- ack rid-1 rid-2
```

## Command summary

- `generate-key`: generate a fresh P-521 keypair and print both PEM blocks as JSON.
- `init <profile_dir> <sr_address> [base_url]`: create a customer profile directory with keys and `zeroclaw-profile.json`.
- `whoami`: print the active base URL, SR address, token presence, and profile metadata.
- `onboard [ns_token]`: fetch `register/challenge`, sign it, submit `register/verify`, and persist the issued token.
- `refresh-token`: fetch `token/challenge`, sign it, submit `token/issue`, and persist the issued token.
- `issue-capability <to_addr> [scope1,scope2,...] [expires_in_seconds]`: mint a short-lived cross-namespace capability token bound to the active sender and target recipient.
- `send <to_addr> <payload_json> [zone]`: send a signed relay envelope using the stored private key and active token.
- `register-challenge`: fetch the current registration challenge for the active SR address.
- `token-challenge`: fetch the current token-issuance challenge for the active SR address.
- `register-verify <challenge> [cap1,cap2,...] [ns_token]`: low-level registration flow when you want to control challenges manually.
- `issue-token <challenge>`: low-level token issuance flow when you want to control challenges manually.
- `poll [wait_seconds]`: fetch one inbox snapshot.
- `ack <relay_id...>`: acknowledge one or more relay IDs.
- `route <public|same_namespace|private> <cap1,cap2,...> [requester_sr_address]`: query SysRelay route recommendations.

## Profile and environment behavior

- `ZEROCLAW_PROFILE_PATH` points the CLI at a specific customer profile.
- When `ZEROCLAW_PROFILE_PATH` is set, the profile is authoritative. Base URL, SR address, token, and key paths are loaded from that profile first so stale shell variables do not redirect traffic to the wrong identity.
- Without `ZEROCLAW_PROFILE_PATH`, the CLI falls back to direct environment variables and then to the default profile path.
- `ZEROCLAW_SYSRELAY_BASE_URL` defaults to `https://sysrelay.com`.
- `ZEROCLAW_PRIVATE_KEY_PEM` or `ZEROCLAW_PRIVATE_KEY_PEM_PATH` still work for low-level manual flows when no explicit profile is selected.

## Packaging a customer bundle

Build a Windows release bundle and zip it:

```powershell
.\package.ps1
```

The packaging script produces:

- `dist\zeroclaw-windows-x64\zeroclaw.exe`
- `dist\zeroclaw-windows-x64\zeroclaw.cmd`
- `dist\zeroclaw-windows-x64\README.md`
- `dist\zeroclaw-windows-x64\customer-profile.example.json`
- `dist\zeroclaw-windows-x64.zip`

The generated `zeroclaw.cmd` launcher expects `ZEROCLAW_PROFILE_PATH` to be set before invoking the packaged executable.

## SDK surface

The crate still exposes the Rust SDK for integrators who want library access instead of the packaged CLI. Current implementation includes:

- `canonical_sender_signature_payload()`
- `RelayReceipt`
- `InboxItem`
- `InboxResponse`
- `InboxBatchMessage`
- `InboxBatchProcessSummary`
- `AckResponse`
- `ChallengeResponse`
- `TokenResponse`
- `SetupResponse`
- `CapabilityValidateResponse`
- `RouteCandidate`
- `RouteResponse`
- `RelayEnvelope`
- `RouteScope`
- `RouteSelectionRequest`
- `InboxPollRequest`
- `InboxAckRequest`
- `SysRelayRouteClient`
- `AsyncSysRelayClient`
- `ZeroClawCliRuntime`
- `ZeroClawCliCommand`
- `load_cli_runtime_from_env()`
- `load_cli_identity_from_env()`
- `load_cli_private_key_pem_from_env()`
- `parse_cli_command()`
- `generate_p521_keypair_pem()`
- `derive_public_key_pem()`
- `sign_message_p521_base64()`
- `verify_message_p521_base64()`
- `build_relay_envelope()`
- `build_signed_relay_envelope_from_json()`

## Local verification

- Install Rust toolchain (`rustup`, `cargo`, `rustc`).
- Run `cargo test`.
- Run `cargo build --release`.
- Run `cargo run -- init C:\ZeroClaw\customer @acme/zero https://sysrelay.com`.
- Set `ZEROCLAW_PROFILE_PATH` and run `cargo run -- whoami`.