Skip to content

feat: add standalone Rust CLI binary (awn) for agent-native AWN interface#158

Merged
Jing-yilin merged 11 commits into
mainfrom
feat/awn-rust-cli
Mar 24, 2026
Merged

feat: add standalone Rust CLI binary (awn) for agent-native AWN interface#158
Jing-yilin merged 11 commits into
mainfrom
feat/awn-rust-cli

Conversation

@Jing-yilin
Copy link
Copy Markdown
Contributor

Summary

Adds a standalone Rust CLI binary (awn) under packages/awn-cli/ that provides an agent-native interface to the Agent World Network. Following the CLI-Anything philosophy: CLI is the most universal entry point for AI agents.

Why

  • Current AWN is deeply coupled to OpenClaw's plugin API — only OpenClaw users can use it
  • CLI is universally accessible: any agent framework (Claude Code, Codex, Droid, opencode) can call it via shell exec
  • Single binary, zero runtime dependencies (no Node.js required)
  • --json flag for structured output makes it agent-native

What's included

Modules (all with full test coverage)

  • crypto.rs (18 tests) — Ed25519 signing, agentId derivation, canonicalize, domain-separated signatures. Byte-for-byte compatible with TS SDK (4 cross-language compatibility tests with identical seed/output).
  • identity.rs (7 tests) — Load/create Ed25519 keypair, persist to disk. File format compatible with TS identity.json.
  • peer_db.rs (14 tests) — JSON peer store with TOFU trust model, capability search, camelCase field names matching TS format.
  • daemon.rs (5 tests) — Axum IPC server on localhost with /ipc/status, /ipc/peers, /ipc/worlds, /ipc/ping endpoints.

CLI Commands

awn daemon start [--data-dir ~/.awn] [--gateway-url ...] [--port 8099]
awn daemon stop
awn status                          # agent ID, transport, joined worlds
awn peers [--capability world:]     # list known peers
awn worlds                          # list from Gateway + local cache

All commands support --json for structured output.

Version sync

  • Cargo.toml version synced from root package.json via sync-version.mjs
  • PROTOCOL_VERSION derived from Cargo.toml at compile time (major.minor)
  • AGENTS.md updated to document Cargo.toml as version-bearing file

SKILL.md

CLI-Anything format skill definition for agent discovery.

Test Results

test result: ok. 44 passed; 0 failed; 0 ignored

Atomic Commits

  1. feat: add Rust awn CLI skeleton with wire-compatible crypto module
  2. feat(awn): add identity module with TS-compatible key persistence
  3. feat(awn): add peer DB with TOFU, capability search, and TS-compatible persistence
  4. feat(awn): add daemon with IPC + clap CLI (status, peers, worlds)
  5. docs(awn): add CLI-Anything style SKILL.md for agent discovery
  6. chore: add changeset for Rust awn CLI

Jing-yilin and others added 7 commits March 24, 2026 16:45
- packages/awn-cli: Cargo project (name=awn, version synced to 1.3.1)
- crypto.rs: Ed25519 signing, agentId derivation, canonicalize, domain
  separators — all byte-for-byte compatible with TS agent-world-sdk
- PROTOCOL_VERSION derived from Cargo.toml at compile time (major.minor)
- 18 tests including 4 cross-language compatibility tests verified against
  TS output (same seed → same agentId, canonical JSON, signature, digest)
- sync-version.mjs: now syncs Cargo.toml version alongside other files
- AGENTS.md: document Cargo.toml as version-bearing file

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
- load_or_create_identity: load seed from JSON or generate new keypair
- File format matches TS identity.json (seed + publicKey fields)
- Can load TS-generated identity files and derive same agentId
- 7 tests: create, reload, cross-name isolation, TS compat, nested dirs,
  corrupt file handling

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
…e persistence

- PeerDb: JSON peer store at $data_dir/peers.json
- upsert, remove, list (sorted by lastSeen), get, find_by_capability
- TOFU trust model: first-use caching, TTL-based key refresh, mismatch rejection
- camelCase JSON field names matching TS peers.json format
- 14 tests: CRUD, persistence, TOFU logic, capability prefix/exact search,
  corrupt file recovery, TS format compatibility

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
- daemon.rs: axum HTTP server on localhost for IPC, with /ipc/status,
  /ipc/peers, /ipc/worlds, /ipc/ping endpoints
- main.rs: clap CLI with subcommands: daemon start/stop, status, peers,
  worlds — all with --json dual output for agent consumption
- daemon fetches worlds from gateway + merges with local peer DB cache
- 5 daemon integration tests (start, ping, status, peers, identity reuse)
- Binary name: awn (not awn-cli)

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
- Follows CLI-Anything SKILL.md format (name/description table, command
  groups, installation, JSON output docs, agent usage guide)
- Documents daemon start, status, peers, worlds commands
- Explains --json flag for machine-readable output

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
- test.yml: new test-rust job runs cargo test on PRs (with rust-cache)
- release-cli.yml: triggered by GitHub Release publish, cross-compiles
  awn binary for linux-x64, darwin-x64, darwin-arm64, uploads tar.gz
  archives to the release
- AGENTS.md: update CI workflows table

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

@Jing-yilin Jing-yilin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Codex Review

[Medium] CLI commands cannot reach daemons started on a non-default IPC port

daemon start accepts --ipc-port, but status, peers, and worlds always resolve the daemon address from AWN_IPC_PORT or the hard-coded default 8199. If the daemon is started on any other port, the follow-up commands still call 127.0.0.1:8199 and report that the daemon is not running unless the caller also exports AWN_IPC_PORT out of band. I reproduced this with cargo run -- --json daemon start --ipc-port 8207 followed by cargo run -- --json status, which failed until AWN_IPC_PORT=8207 was set. That makes the advertised --ipc-port flag effectively unusable across normal CLI invocations.
Refs: packages/awn-cli/src/main.rs:52, packages/awn-cli/src/main.rs:74, packages/awn-cli/src/main.rs:119, packages/awn-cli/src/main.rs:148, packages/awn-cli/src/main.rs:190, packages/awn-cli/src/daemon.rs:222

[Medium] awn daemon stop reports an error but still exits 0

The stop subcommand currently prints daemon stop not yet implemented and then returns success. That is particularly risky here because the bundled skill explicitly tells agents to treat exit code 0 as success and non-zero as failure, so scripts will happily continue under the false assumption that the daemon has been stopped. Until the stop path is implemented, this branch should return a non-zero exit code.
Refs: packages/awn-cli/src/main.rs:110, packages/awn-cli/src/main.rs:112, packages/awn-cli/src/main.rs:113, packages/awn-cli/skills/SKILL.md:73

Validation: cd packages/awn-cli && cargo test

Jing-yilin and others added 4 commits March 24, 2026 17:03
- Cargo.toml: add cargo-deb metadata for .deb package building
- release-cli.yml: build .deb on Linux, auto-generate Homebrew formula
  on release, upload .deb + tar.gz archives to GitHub Releases
- install.sh: universal installer (detects OS/arch, downloads binary)
- SKILL.md: document all installation methods (brew, apt, curl, cargo)

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Fixes two issues from Codex review:

1. CLI commands now discover daemon IPC port via:
   --ipc-port flag > AWN_IPC_PORT env > ~/.awn/daemon.port file > default
   The daemon writes its bound port to daemon.port on start and removes
   it on shutdown, so 'awn status' works after 'awn daemon start --ipc-port N'
   without needing out-of-band env setup.

2. 'awn daemon stop' now exits with code 1 (was 0) since it is not yet
   implemented. Agents relying on exit codes will correctly detect failure.

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
## Summary
- rename peer-facing TypeScript modules and APIs to agent/world
terminology
- add dedicated world db/registry storage in the plugin, SDK, and
gateway
- update gateway world discovery, heartbeats, and tests for
worldId-as-identity plus slug support

## Validation
- npm run build
- npm --prefix packages/agent-world-sdk run build
- node --test test/*.test.mjs

---------

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
- peer_db.rs → agent_db.rs (PeerRecord → AgentRecord, PeerDb → AgentDb)
- peers.json → agents.json (store version bumped to 3)
- CLI command: awn peers → awn agents
- IPC endpoint: /ipc/peers → /ipc/agents
- Status output: Known peers → Known agents, Peer port → Listen port
- PeersResponse → AgentsResponse, PeersQuery → AgentsQuery
- SKILL.md updated to match new terminology

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
@Jing-yilin Jing-yilin merged commit 27834f5 into main Mar 24, 2026
4 checks passed
@Jing-yilin Jing-yilin deleted the feat/awn-rust-cli branch March 24, 2026 10:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant