包详细信息

@dddappp/ao-cli

dddappp581ISC1.4.26

Universal AO CLI tool for testing and automating AO dApps (replaces AOS REPL)

ao, cli, blockchain, arweave

自述文件

AO CLI

中文版本 | English Version

Universal AO CLI tool for testing and automating any AO dApp (replaces AOS REPL)

⚠️ Important Notice: This tool has not been sufficiently adapted and tested for mainnet environments. Please use it on legacy networks for development and testing purposes. Mainnet support is currently experimental and may not function as expected.

Overview

This is a non-interactive command-line interface for the AO (Arweave Offchain) ecosystem. Unlike the official aos REPL tool, this CLI exits after each command completes, making it perfect for automation, testing, and CI/CD pipelines.

This repository is a standalone, self-contained implementation of the AO CLI with its own comprehensive test suite.

Features

  • Non-REPL Design: Each command executes and exits immediately
  • Full AO Compatibility: Works with all AO processes and dApps
  • Mainnet & Testnet Support: Seamlessly switch between AO networks
  • Automatic Module Loading: Resolves and bundles Lua dependencies (equivalent to .load in AOS)
  • Rich Output Formatting: Clean JSON parsing and readable results
  • Structured JSON Output: --json option for automation and scripting
  • Proxy Support: Automatic proxy detection and configuration
  • Comprehensive Commands: spawn, eval, load, message, inbox operations
  • Self-Contained Testing: Complete test suite included

Installation

Prerequisites

  • Node.js 18+
  • npm
  • AO wallet file (~/.aos.json)

Setup

git clone https://github.com/dddappp/ao-cli.git
cd ao-cli
npm install
npm link  # Makes 'ao-cli' available locally for development/testing

Verify Installation

ao-cli --version
ao-cli --help

Publishing to npm

This package is published as a scoped package for security and professionalism.

For Maintainers

# 1. Run complete test suite
npm link  # Make ao-cli available locally
npm test  # Run all tests to ensure functionality

# 2. Login to npm
npm login

# 3. Test package
npm run prepublishOnly

# 4. Publish (scoped package requires --access public)
npm publish --access public
# View the package
# npm view @dddappp/ao-cli

# 5. Update version for new releases
npm version patch  # or minor/major
npm publish --access public

For Users

# Install globally
npm install -g @dddappp/ao-cli

# Or use with npx
npx @dddappp/ao-cli --help

Security Note: Always verify package downloads and check the official npm page at https://www.npmjs.com/package/@dddappp/ao-cli

Usage

Basic Commands

Spawn a Process

# Spawn with default module (testnet)
ao-cli spawn default --name "my-process-$(date +%s)"

# Spawn with custom module
ao-cli spawn <module-id> --name "my-process"

# Spawn on mainnet with default URL (https://forward.computer)
ao-cli spawn default --mainnet --name "mainnet-process"

# Spawn on mainnet with custom URL
ao-cli spawn default --mainnet https://your-mainnet-node.com --name "mainnet-process"

Load Lua Code with Dependencies

# Load a Lua file (equivalent to '.load' in AOS REPL)
ao-cli load <process-id> tests/test-app.lua --wait

Note: If the process ID starts with -, you can use either of the following methods:

  • Use -- separator: ao-cli load -- <process-id> tests/test-app.lua --wait
  • Or wrap with quotes: ao-cli load "<process-id>" tests/test-app.lua --wait

Send Messages

# Send a message and wait for result
ao-cli message <process-id> TestMessage --data '{"key": "value"}' --wait

# Send without waiting
ao-cli message <process-id> TestMessage --data "hello"

# Send token transfer with direct properties (for contracts that read msg.Recipient, msg.Quantity)
ao-cli message <token-process-id> Transfer --prop Recipient=<target-address> --prop Quantity=100 --wait

Note: If the process ID starts with -, you can use either of the following methods:

  • Use -- separator: ao-cli message -- <process-id> TestMessage ...
  • Or wrap with quotes: ao-cli message "<process-id>" TestMessage ...

Evaluate Lua Code

# Evaluate code from file
ao-cli eval <process-id> --file script.lua --wait

# Evaluate code string
ao-cli eval <process-id> --data 'return "hello"' --wait

Note: If the process ID starts with -, you can use either of the following methods:

  • Use -- separator: ao-cli eval -- <process-id> --file script.lua --wait
  • Or wrap with quotes: ao-cli eval "<process-id>" --file script.lua --wait

Check Inbox

# Get latest message
ao-cli inbox <process-id> --latest

# Get all messages
ao-cli inbox <process-id> --all

# Wait for new messages
ao-cli inbox <process-id> --wait --timeout 30

📋 Inbox Mechanism Explanation: Inbox is a global variable inside a process that records all received messages that have no handlers to process them. Handlers in the receiving process often reply to the sender; if the sender process wants the reply message to enter its own Inbox, it needs to execute a Send operation within that process (using ao-cli eval). Using ao-cli message to send messages directly will not cause reply messages to enter the process's Inbox.

🔍 --trace Feature Explanation: eval --trace queries the target process's result history and attempts to precisely associate handler execution results through message References. If an exact match is found, it displays the print output from the handler triggered by that message; if an exact association cannot be made, it displays the most recent handler activity as a reference. Note: This feature only applies to the eval command and is currently only effective in legacy mode (the tool has not been sufficiently adapted and tested for mainnet, and does not support result history queries).

Note: If the process ID starts with -, you can use either of the following methods:

  • Use -- separator: ao-cli inbox -- <process-id> --latest
  • Or wrap with quotes: ao-cli inbox "<process-id>" --latest

Advanced Usage

Environment Variables

# Mainnet mode and URL (automatically enables mainnet when set)
export AO_URL=https://forward.computer

# Proxy settings (auto-detected if not set)
export HTTPS_PROXY=http://proxy:port
export HTTP_PROXY=http://proxy:port

# Gateway and scheduler
export GATEWAY_URL=https://arweave.net
export SCHEDULER=http://scheduler.url

# Wallet location
export WALLET_PATH=/path/to/wallet.json

# Test wait time
export AO_WAIT_TIME=3  # seconds to wait between operations

📋 Environment Variable Details:

  • AO_URL: When set, automatically enables mainnet mode and uses the specified URL as the AO node endpoint. No need to combine with --mainnet flag.
    • Example: export AO_URL=https://forward.computer enables mainnet with Forward Computer node
    • The CLI parameter --mainnet takes priority over AO_URL if both are provided

Network Configuration

AO CLI supports both AO testnet and mainnet. By default, all commands use testnet.

Testnet (Default)
# All commands default to testnet
ao-cli spawn default --name "testnet-process"
Mainnet
# Use --mainnet flag (uses https://forward.computer as default)
ao-cli spawn default --mainnet --name "mainnet-process"

# Specify custom mainnet URL with --mainnet flag
ao-cli spawn default --mainnet https://your-mainnet-node.com --name "mainnet-process"

# Use AO_URL environment variable (automatically enables mainnet)
export AO_URL=https://forward.computer
ao-cli spawn default --name "mainnet-process"

# Environment variable + custom URL
export AO_URL=https://your-custom-node.com
ao-cli spawn default --name "mainnet-process"
Network Endpoints
  • Testnet: https://cu.ao-testnet.xyz, https://mu.ao-testnet.xyz
  • Mainnet: https://forward.computer (default), or any AO mainnet node
Configuration Priority
  1. CLI parameters take highest priority (e.g., --mainnet https://custom-node.com)
  2. Environment variables are used when CLI parameters are not provided (e.g., AO_URL=https://custom-node.com)
  3. Defaults are used when neither CLI nor environment variables are set

💡 Important:

  • Setting AO_URL environment variable automatically enables mainnet mode. You don't need to combine it with --mainnet flag.
  • Mainnet operations require payment: Unlike testnet, mainnet processes charge fees for computation. Ensure your wallet has sufficient AO tokens.

Custom Wallet

ao-cli spawn default --name test --wallet /path/to/custom/wallet.json

Examples

Complete Test Suite Run

#!/bin/bash

# Run the complete test suite
./tests/run-tests.sh

Manual Testing

# 1. Spawn process (using JSON mode for reliable parsing)
PROCESS_ID=$(ao-cli spawn default --name "test-$(date +%s)" --json | jq -r '.data.processId')

# 2. Load test application
ao-cli load "$PROCESS_ID" tests/test-app.lua --wait

# 3. Test basic messaging
ao-cli message "$PROCESS_ID" TestMessage --data "Hello AO CLI!" --wait

# 4. Test data operations
ao-cli message "$PROCESS_ID" SetData --data '{"key": "test", "value": "value"}' --wait
ao-cli message "$PROCESS_ID" GetData --data "test" --wait

# 5. Test eval functionality
ao-cli eval "$PROCESS_ID" --data "return {counter = State.counter}" --wait

# 6. Check inbox
ao-cli inbox "$PROCESS_ID" --latest

💡 Tip: If you prefer not to use JSON mode, you can also use the traditional parsing method: PROCESS_ID=$(ao-cli spawn default --name "test-$(date +%s)" | grep "Process ID:" | awk '{print $4}')

Structured JSON Output for Automation

AO CLI supports structured JSON output for automation, testing, and scripting. Use the --json flag to enable machine-readable output.

JSON Output Format

All commands return JSON with a consistent structure:

{
  "command": "spawn|load|message|eval|inbox|address",
  "success": true|false,
  "timestamp": "2025-10-22T01:54:52.958Z",
  "version": "1.4.21",
  "data": {
    // Command-specific data (when successful)
    "processId": "...",
    "messageId": "...",
    "result": {...}
  },
  "error": "error message", // Only present when success is false
  "gasUsed": 123, // Optional, present when applicable
  "extra_fields": {...} // Command-specific additional data
}

Examples

# Get wallet address in JSON format
ao-cli address --json

# Spawn process and parse the result
PROCESS_ID=$(ao-cli spawn default --name "test" --json | jq -r '.data.processId')

# Send message and check success
ao-cli message "$PROCESS_ID" TestAction --data "test" --wait --json | jq '.success'

# Error handling - errors go to stderr as JSON
ao-cli address --wallet nonexistent.json --json 2>&1 | jq '.error'

Lua Print Output in JSON Mode

When using --json output, all print() statements from your Lua code are captured in the response:

{
  "data": {
    "result": {
      "Output": {
        "data": "🔍 Processing message...\n📊 Counter: 1\n✅ Done",
        "print": true
      }
    }
  }
}

Key Points:

  • All print() output is collected in Output.data field
  • Original formatting is preserved (newlines, emojis, etc.)
  • Output.print is just a boolean flag indicating print output exists
  • Print statements are ordered chronologically as they execute

Automation Benefits

  • Reliable Parsing: No more fragile text parsing with grep and awk
  • Structured Data: Easy access to process IDs, message IDs, and results
  • Error Handling: Consistent error reporting in JSON format
  • CI/CD Ready: Perfect for automated testing and deployment pipelines
  • Language Agnostic: JSON can be parsed by any programming language

Command Reference

Global Options

These options work with all commands:

  • --json: Output results in JSON format for automation and scripting
  • --mainnet [url]: Enable mainnet mode (uses https://forward.computer if no URL provided)
  • --wallet <path>: Custom wallet file path (default: ~/.aos.json)
  • --gateway-url <url>: Arweave gateway URL
  • --cu-url <url>: Compute Unit URL (testnet only)
  • --mu-url <url>: Messenger Unit URL (testnet only)
  • --scheduler <id>: Scheduler ID
  • --proxy <url>: Proxy URL for HTTPS/HTTP/ALL_PROXY

Environment Variables (Global):

  • AO_URL: Set mainnet URL and automatically enable mainnet mode (e.g., AO_URL=https://forward.computer)

Hidden Parameters (for AOS compatibility):

  • --url <url>: Set AO URL directly (equivalent to AOS hidden parameter)

address

Get the wallet address from the current wallet.

Usage:

ao-cli address

Alternative Method (if address command is not available): Send a message to any process and check the receiving process's inbox - the From field will contain your wallet address.

# Send a test message to any process (use an action that won't be handled)
ao-cli message <process-id> UnknownAction --data "test" --wait

# Check the RECEIVING process's inbox to see your address in the From field
ao-cli inbox <process-id> --latest

Test Results:

  • ✅ Direct address command: Shows wallet address HrhlqAg1Tz3VfrFPozfcb2MV8uGfYlOSYO4qraRqKl4
  • ✅ Alternative method: Theoretically verified - When sending unhandled messages to a process, the From field in the receiving process's inbox contains the sender's wallet address
  • 📝 Test Limitation: Due to current network connectivity issues, the inbox method cannot be practically tested, but the implementation follows AO protocol correctly

spawn <moduleId> [options]

Spawn a new AO process.

Options:

  • --name <name>: Process name

load <processId> <file> [options]

Load Lua file with automatic dependency resolution.

Options:

  • --wait: Wait for evaluation result (default: true)

eval <processId> [options]

Evaluate Lua code.

Options:

  • --file <path>: Lua file to evaluate
  • --data <string>: Lua code string
  • --wait: Wait for result
  • --trace: Trace sent messages for cross-process debugging (legacy network only)

message <processId> <action> [options]

Send a message to a process.

Options:

  • --data <data>: Message data (JSON string or plain text)
  • --tag <tags...>: Additional tags in format name=value
  • --prop <props...>: Message properties (direct attributes) in format name=value
  • --wait: Wait for result

inbox <processId> [options]

Check process inbox.

Options:

  • --latest: Get latest message
  • --all: Get all messages
  • --wait: Wait for new messages
  • --timeout <seconds>: Wait timeout (default: 30)

Output Format

All commands provide clean, readable output:

📋 MESSAGE #1 RESULT:
⛽ Gas Used: 0
📨 Messages: 1 item(s)
   1. From: Process123
      Target: Process456
      Data: {
        "result": {
          "success": true,
          "counter": 1
        }
      }

Comparison with AOS REPL

Operation AOS REPL AO CLI
Spawn aos my-process ao-cli spawn default --name my-process
Spawn (Mainnet) aos my-process --mainnet <url> ao-cli spawn default --mainnet <url> --name my-process
Spawn (AOS Style) aos my-process --url <url> ao-cli spawn default --url <url> --name my-process
Load Code .load app.lua ao-cli load <pid> app.lua --wait
Send Message Send({Action="Test"}) ao-cli message <pid> Test --wait
Send Message (Inbox Test) Send({Action="Test"}) ao-cli eval <pid> --data "Send({Action='Test'})" --wait
Check Inbox Inbox[#Inbox] ao-cli inbox <pid> --latest
Eval Code eval code ao-cli eval <pid> --data "code" --wait

💡 Important Notes:

  • To test Inbox functionality, you need to use ao-cli eval to execute Send operations within the process; do not use ao-cli message to send messages directly.
  • If the process ID starts with -, you can use -- separator or wrap with quotes, for example: ao-cli load -- <pid> tests/test-app.lua --wait or ao-cli load "<pid>" tests/test-app.lua --wait.

Project Structure

ao-cli/
├── ao-cli.js          # Main CLI implementation
├── package.json       # Dependencies and scripts
├── tests/             # Self-contained test suite
│   ├── test-app.lua   # Test AO application
│   └── run-tests.sh   # Complete test automation
└── README.md          # This file

Testing

The repository includes a comprehensive self-contained test suite that verifies all CLI functionality.

Running Tests

# Run all tests
./tests/run-tests.sh

# Custom wait time between operations
AO_WAIT_TIME=5 ./tests/run-tests.sh

Test Coverage

The test suite covers:

  • ✅ Process spawning (spawn command)
  • ✅ Lua code loading (load command)
  • ✅ Message sending and responses (message command)
  • ✅ Code evaluation (eval command)
  • ✅ Inbox checking (inbox command)
  • ✅ Error handling and validation
  • ✅ State management and data persistence
  • AOS Compatibility: Complete workflow testing (spawn → load handler → send message)
  • Mainnet Support: Free spawning and message sending to mainnet nodes
  • Full AOS Compatibility: --url parameter, ANS-104 signing, free mainnet spawning
  • Complete Token Workflow: Spawn → Load → Mint → Balance checking with real contracts

AOS Compatibility Testing

AO CLI supports AOS-style mainnet operations using the --url parameter:

# Test complete AOS workflow: spawn → load handler → send message → response
./tests/test-mainnet-free-spawn.sh

# Manual test - spawn process
ao-cli spawn default --url http://node.arweaveoasis.com:8734 --name "test-process"

# Manual test - load handler (like AOS .editor)
ao-cli message <process-id> Eval --data 'Handlers.add("ping", "ping", function(msg) print("pong from " .. msg.From) end)' --url http://node.arweaveoasis.com:8734

# Manual test - send message (like AOS send())
ao-cli message <process-id> ping --data "ping" --url http://node.arweaveoasis.com:8734

Key Achievement: AO CLI is fully compatible with AOS --url parameter functionality!

✅ Complete AOS Compatibility:

  • ✅ Spawn processes without account balance (like aos process --url <node>)
  • ✅ Use correct hyper module for lua@5.3a execution (wal-fUK-YnB9Kp5mN8dgMsSqPSqiGx-0SvwFUSwpDBI)
  • ✅ Set proper device configuration (device: 'process@1.0') for mainnet connections
  • ✅ Load handlers using ao-cli message <id> Eval (equivalent to AOS .editor)
  • ✅ Send messages to trigger handlers (equivalent to AOS send() function)
  • ✅ Load contracts using ao-cli load (equivalent to AOS .load-blueprint)
  • ✅ Send signed ANS-104 messages to mainnet nodes
  • ✅ Use identical signing and request formats as AOS
  • ✅ Work with Arweave Oasis nodes: http://node.arweaveoasis.com:8734
  • ✅ Complete workflow: spawn → load handler → send message → response

Current Status:

  • Process spawning: Works reliably on mainnet nodes (AOS compatibility achieved)
  • Contract loading: Initiates successfully (like AOS .load-blueprint)
  • Message sending: Requests sent successfully with ANS-104 signing
  • Handler execution: Fully working! Can load handlers and see immediate execution results (like AOS send())

🎯 Mission Accomplished: AO CLI now fully supports AOS-style --url parameter for free mainnet operations!

📋 Complete Workflow Tests:

# Test the complete AOS-compatible workflow: spawn + load + mint + balance
./tests/test-ao-token.sh

# Demo: AO CLI vs AOS side-by-side comparison
./tests/demo-aos-compatibility.sh

# Note: If your network requires a proxy to access AO nodes, set these environment variables:
# export HTTPS_PROXY=http://127.0.0.1:1235
# export HTTP_PROXY=http://127.0.0.1:1235
# export ALL_PROXY=socks5://127.0.0.1:1234

Test Application

The tests/test-app.lua provides handlers for:

  • TestMessage: Basic message testing with counter and detailed logging output
  • SetData/GetData: Key-value data operations
  • TestInbox: Inbox functionality testing (sends internal messages to demonstrate inbox behavior)
  • TestError: Error handling testing (available for manual testing of error conditions)
  • InboxTestReply: Processes inbox test replies
  • TestReceiverPrint: Cross-process print testing for advanced debugging scenarios

Future Improvements (TODOs)

🔄 Planned Enhancements

  1. Dependency Updates

    • Regularly update @permaweb/aoconnect and other dependencies to latest versions
    • Add automated dependency vulnerability scanning
  2. Enhanced Error Handling

    • Add more granular error messages for different failure scenarios
    • Implement retry logic for network timeouts
    • Add better validation for process IDs and message formats
  3. Performance Optimizations

    • Add module caching to speed up repeated code loading
    • Implement parallel processing for batch operations
    • Add connection pooling for multiple AO operations
  4. Testing Improvements

    • Add unit tests for individual CLI commands
    • Implement integration tests with different AO dApps
    • Add performance benchmarking tests
  5. Developer Experience

    • Add shell completion scripts (bash/zsh/fish)
    • Create VS Code extension for AO development
    • Add interactive mode option alongside non-REPL design
  6. Documentation

    • Add video tutorials for common use cases
    • Create cookbook with real-world AO dApp examples
    • Add API reference documentation
  7. CI/CD Integration

    • Add GitHub Actions workflows for automated testing
    • Create Docker images for easy deployment
    • Add pre-built binaries for multiple platforms
  8. Monitoring & Observability

    • Add metrics collection for operation performance
    • Implement structured logging with log levels
    • Add health check endpoints for monitoring

🤝 Contributing

We welcome contributions! Please see our contribution guidelines and feel free to submit issues or pull requests.

Troubleshooting

Common Issues

  1. "fetch failed"

    • Check proxy settings
    • Verify network connectivity
  2. "Wallet file not found"

    # Ensure wallet exists
    ls -la ~/.aos.json
  3. "Module not found" errors

    • Check Lua file paths
    • Ensure dependencies are in the same directory
  4. Empty inbox results

    • Use --wait option
    • Increase timeout with --timeout

Debug Mode

Enable verbose logging:

export DEBUG=ao-cli:*

Development

Adding New Commands

  1. Add command definition in ao-cli.js
  2. Implement handler function
  3. Update this README

Running Tests During Development

./tests/run-tests.sh

License

ISC