Skip to content

Latest commit

 

History

History
265 lines (200 loc) · 10.2 KB

File metadata and controls

265 lines (200 loc) · 10.2 KB

AWN (Agent World Network)

OpenClaw plugin for direct P2P communication between agent instances over plain HTTP/TCP and optional QUIC. Messages are Ed25519-signed at the application layer, and peers are only visible after joining a shared World.

Core Commands

  • Build: npm run build
  • Run tests: node --test test/*.test.mjs
  • Dev (watch mode): npm run dev
  • Add changeset: npx changeset add
  • Publish skill to ClawHub: npx clawhub@latest publish skills/awn

Always run build before tests — tests import from dist/.

Project Layout

├── src/                        → TypeScript plugin source
│   ├── index.ts                → Plugin entry: service lifecycle, world membership tracking, tools
│   ├── identity.ts             → Ed25519 keypair, agentId derivation, DID key
│   ├── address.ts              → Direct peer address parsing utilities
│   ├── transport.ts            → Transport interface + TransportManager
│   ├── transport-quic.ts       → UDPTransport with ADVERTISE_ADDRESS endpoint config
│   ├── peer-server.ts          → Fastify HTTP server: /peer/message, /peer/announce, /peer/ping
│   ├── peer-client.ts          → Outbound signed message + ping
│   ├── peer-db.ts              → JSON peer store with TOFU and debounced writes
│   ├── channel.ts              → OpenClaw channel registration (inbound/outbound wiring)
│   └── types.ts                → Shared interfaces
├── test/                       → Node.js built-in test runner (node:test)
├── skills/awn/              → ClawHub skill definition
│   ├── SKILL.md                → Skill frontmatter + tool docs
│   └── references/             → Supplementary docs (flows, discovery, install)
├── docs/                       → GitHub Pages docs for world discovery and architecture
├── openclaw.plugin.json        → Plugin manifest (channels, config schema, UI hints)
└── docker/                     → Docker Compose for local multi-node testing

Architecture Overview

Plugin registers a background service (awn-node) that:

  1. Loads/creates an Ed25519 identity (~/.openclaw/awn/identity.json)
  2. Starts a Fastify peer server on [::]:8099
  3. Registers tools (p2p_status, p2p_list_peers, p2p_send_message, list_worlds, join_world) and the AWN channel
  4. Discovers worlds via list_worlds() and joins them via join_world()
  5. World membership provides peer discovery — co-members' endpoints arrive from the world server on join
  6. Runs periodic member refresh (30s) to keep world membership current

Trust model (4-layer):

  1. Ed25519 signature over canonical JSON (application-layer)
  2. TOFU: first message caches public key; subsequent must match
  3. agentId derived from public key — unforgeable anchor identity
  4. World co-membership — transport rejects senders outside shared worlds

Development Patterns

TypeScript

  • Strict mode, ES2022 target, CommonJS output
  • No semicolons in source (match existing style)
  • Tests use node:test + node:assert/strict (no external test framework)
  • Tests import from dist/ — always npm run build first

Plugin Config

All runtime config is in openclaw.json under plugins.entries.awn.config:

{
  "peer_port": 8099,
  "quic_port": 8098,
  "advertise_address": "vpn.example.com",
  "advertise_port": 4433,
  "data_dir": "~/.openclaw/awn",
  "tofu_ttl_days": 7,
  "agent_name": "Alice's coder"
}

Gateway World Discovery

  • World Servers announce directly to the Gateway via GATEWAY_URL
  • The Gateway exposes GET /worlds for discovery and GET /world/<worldId> for endpoint/public-key lookup during join_world()
  • There is no standalone bootstrap/ deployment or published docs/bootstrap.json artifact in this branch
  • Agents still use list_worlds() for discovery and join_world() for direct membership

Peer DB

  • JSON file at $data_dir/peers.json
  • World membership / registry writes are debounced (1s); manual ops and TOFU writes are immediate
  • flushDb() called on service shutdown

Git Workflow

Branching Strategy

  • main — The only long-lived branch, always deployable
  • feature/<slug> — New features (branch from main)
  • fix/<slug> — Bug fixes (branch from main)

Workflow

# Start any change
git checkout main && git pull
git checkout -b feature/<slug>   # or fix/<slug>

# ... make changes ...
npx changeset add   # select patch/minor/major, write a description

# Push and open PR targeting main
git push -u origin feature/<slug>
gh pr create --base main

No develop branch. No git-flow. No backmerge.

Important: All Changes Via PR

main is branch-protected. No direct push allowed.

  1. Push feature/fix branch to origin
  2. Create PR targeting main
  3. CI must pass (test (20) + test (22))
  4. Squash merge only — one commit per PR
  5. Close the corresponding issue when merging (use Fixes #N or Closes #N in the PR description)
  6. Merged branches are auto-deleted

Commit Convention

  • feat: — New features
  • fix: — Bug fixes
  • perf: — Performance improvements
  • refactor: — Code refactoring
  • docs: — Documentation changes
  • test: — Test additions/changes
  • chore: — Maintenance tasks
  • Breaking changes: feat!: with BREAKING CHANGE: footer (0.x phase — breaking changes expected)

Do not add any watermark or AI-generated signatures to commit messages.

Issue Management

When creating new issues:

  1. Add type labels: bug, feature, enhancement, documentation, refactor, test, chore
  2. Add tag labels: priority:high / priority:medium / priority:low, good first issue, help wanted, area tags (bootstrap, p2p, identity, etc.)
  3. Write clear descriptions: bugs include reproduction steps + expected vs actual; features describe use case and desired outcome

PR Requirements

  1. All tests must pass: npm run build && node --test test/*.test.mjs
  2. TypeScript must compile: npm run build
  3. Feature/fix branches merge to main via PR
  4. Reference the issue number in the PR description (e.g., #123)
  5. Use closing keywords to auto-close issues on merge (e.g., Fixes #123, Closes #123)

Release Process

How Releases Work (Changesets)

AWN uses Changesets for automated versioning and publishing. The flow aligns with mastra, langchain, and other major TypeScript projects.

Step 1 — When opening a PR, add a changeset:

npx changeset add
# → select: patch / minor / major
# → write one line describing the change
# → commit the generated .changeset/xxx.md alongside your code

Step 2 — Merge PR to main.

CI (release.yml) detects the new changeset and automatically creates or updates a "Version Packages" PR that:

  • Bumps package.json, openclaw.plugin.json, skills/awn/SKILL.md
  • Updates CHANGELOG.md

Step 3 — Merge the "Version Packages" PR.

CI runs again and automatically:

  1. Publishes to npm (NPM_TOKEN)
  2. Creates GitHub Release + tag
  3. Publishes skill to ClawHub (CLAWHUB_TOKEN)

No manual version bumping, no release scripts, no backmerge.

CI Workflows

Workflow Trigger What it does
release.yml Push to main Changesets: create Version PR or publish npm + GH Release + ClawHub
publish.yml workflow_dispatch only Emergency manual npm publish
test.yml Push/PR to main Build + test (Node 20+22)
auto-close-issues.yml PR merged Close linked issues

Branch Strategy

main is the only long-lived branch. All feature/fix branches target main directly:

git checkout -b feature/<slug>     # or fix/<slug>
# ... make changes + npx changeset add ...
git push -u origin feature/<slug>
gh pr create --base main

No develop branch. No backmerge.

Branch Protection

main is protected:

  • No direct push — all changes via PR (squash merge only)
  • Required CI: test (20) + test (22) must pass
  • No force push or branch deletion
  • Enforced for admins — no bypass

Repo Security

  • Secret scanning + push protection: enabled (GitHub catches leaked tokens)
  • Squash merge only: one commit per PR, clean history
  • Auto-delete branches: merged PR branches are cleaned up automatically
  • Required secrets: NPM_TOKEN (npm), CLAWHUB_TOKEN (ClawHub)

Version-bearing Files

scripts/sync-version.mjs (run automatically by npm run version) keeps these in sync:

File Field
package.json "version" (canonical source — bumped by Changesets)
package-lock.json "version" (auto-updated)
openclaw.plugin.json "version"
skills/awn/SKILL.md version: in YAML frontmatter

Versioning

Semantic versioning: vMAJOR.MINOR.PATCH

  • MAJOR: Breaking changes (in 0.x phase, MINOR covers breaking changes)
  • MINOR: New features
  • PATCH: Bug fixes

When adding a changeset, choose accordingly.

Gateway Discovery Deployment

  • This branch no longer ships or deploys a standalone bootstrap/ service
  • If world discovery behavior changes, update the Gateway deployment that serves GATEWAY_URL
  • Verify discovery with curl -s "$GATEWAY_URL/worlds" and, for a specific world, curl -s "$GATEWAY_URL/world/<worldId>"
  • The published docs page documents those Gateway endpoints directly; there is no docs/bootstrap.json mirror to keep in sync

Version-bearing Files

These files must always have matching versions (synced automatically by scripts/sync-version.mjs during npm run version):

File Field
package.json "version" (canonical source)
package-lock.json "version" (auto-updated by npm version)
openclaw.plugin.json "version"
skills/awn/SKILL.md version: in YAML frontmatter

Versioning

Semantic versioning: vMAJOR.MINOR.PATCH

  • MAJOR: Breaking changes (in 0.x phase, MINOR covers breaking changes)
  • MINOR: New features
  • PATCH: Bug fixes

Security

  • Ed25519 private keys stored at ~/.openclaw/awn/identity.json — never log or expose
  • TOFU key mismatch returns 403 with explicit error (possible key rotation)
  • Trust is entirely application-layer: Ed25519 signature + agentId binding