From 0c2161cbd40b43afdbc697df28dd0d5c31ad5c6c Mon Sep 17 00:00:00 2001 From: Nando Vieira Date: Thu, 17 Sep 2026 09:56:05 -0700 Subject: [PATCH 1/3] Add stellar skill command for AI agents. --- FULL_HELP_DOCS.md | 9 +++ cmd/crates/soroban-test/tests/it/main.rs | 1 + cmd/crates/soroban-test/tests/it/skill.rs | 13 ++++ cmd/soroban-cli/src/commands/mod.rs | 6 ++ cmd/soroban-cli/src/commands/skill/SKILL.md | 77 +++++++++++++++++++++ cmd/soroban-cli/src/commands/skill/mod.rs | 22 ++++++ 6 files changed, 128 insertions(+) create mode 100644 cmd/crates/soroban-test/tests/it/skill.rs create mode 100644 cmd/soroban-cli/src/commands/skill/SKILL.md create mode 100644 cmd/soroban-cli/src/commands/skill/mod.rs diff --git a/FULL_HELP_DOCS.md b/FULL_HELP_DOCS.md index 6a15af08c8..22a60bb73f 100644 --- a/FULL_HELP_DOCS.md +++ b/FULL_HELP_DOCS.md @@ -58,6 +58,7 @@ Anything after the `--` double dash (the "slop") is parsed as arguments to the c - `completion` — Print shell completion code for the specified shell - `cache` — Cache for transactions and contract specs - `version` — Print version information +- `skill` — Print an AI-agent skill guide for using the Stellar CLI - `plugin` — The subcommand for CLI plugins - `ledger` — Fetch ledger information - `message` — Sign and verify arbitrary messages using SEP-53 @@ -4860,6 +4861,14 @@ Print version information - `--only-version-major` — Print only the major version - `--only-commit` — Print only the commit sha +## `stellar skill` + +Print an AI-agent skill guide for using the Stellar CLI + +Outputs a Markdown document describing how to use the Stellar CLI idiomatically. It is meant to be read by AI coding agents (or pasted into their instructions) so they follow the CLI's conventions: using named networks, identities, and contract aliases instead of raw RPC URLs, secret keys, and hard-coded contract ids. + +**Usage:** `stellar skill` + ## `stellar plugin` The subcommand for CLI plugins diff --git a/cmd/crates/soroban-test/tests/it/main.rs b/cmd/crates/soroban-test/tests/it/main.rs index 61b62b6b6b..3495e2ac2c 100644 --- a/cmd/crates/soroban-test/tests/it/main.rs +++ b/cmd/crates/soroban-test/tests/it/main.rs @@ -12,6 +12,7 @@ mod log; mod message; mod plugin; mod rpc_provider; +mod skill; mod strkey; mod tx; mod util; diff --git a/cmd/crates/soroban-test/tests/it/skill.rs b/cmd/crates/soroban-test/tests/it/skill.rs new file mode 100644 index 0000000000..dc13a9e777 --- /dev/null +++ b/cmd/crates/soroban-test/tests/it/skill.rs @@ -0,0 +1,13 @@ +use soroban_test::TestEnv; + +#[test] +fn skill_prints_agent_guide() { + let sandbox = TestEnv::default(); + sandbox + .new_assert_cmd("skill") + .assert() + .success() + .stdout(predicates::str::contains("network use")) + .stdout(predicates::str::contains("--alias")) + .stdout(predicates::str::contains("--id")); +} diff --git a/cmd/soroban-cli/src/commands/mod.rs b/cmd/soroban-cli/src/commands/mod.rs index 4d82ce0890..178580b81b 100644 --- a/cmd/soroban-cli/src/commands/mod.rs +++ b/cmd/soroban-cli/src/commands/mod.rs @@ -20,6 +20,7 @@ pub mod ledger; pub mod message; pub mod network; pub mod plugin; +pub mod skill; pub mod snapshot; pub mod token; pub mod tx; @@ -121,6 +122,7 @@ impl Root { Cmd::Container(container) => container.run(&self.global_args).await?, Cmd::Snapshot(snapshot) => snapshot.run(&self.global_args).await?, Cmd::Version(version) => version.run(), + Cmd::Skill(skill) => skill.run(), Cmd::Keys(id) => id.run(&self.global_args).await?, Cmd::Token(token) => token.run(&self.global_args).await?, Cmd::Tx(tx) => tx.run(&self.global_args).await?, @@ -214,6 +216,10 @@ pub enum Cmd { /// Print version information Version(version::Cmd), + /// Print an AI-agent skill guide for using the Stellar CLI + #[command(long_about = skill::LONG_ABOUT)] + Skill(skill::Cmd), + /// The subcommand for CLI plugins #[command(subcommand)] Plugin(plugin::Cmd), diff --git a/cmd/soroban-cli/src/commands/skill/SKILL.md b/cmd/soroban-cli/src/commands/skill/SKILL.md new file mode 100644 index 0000000000..330c50f220 --- /dev/null +++ b/cmd/soroban-cli/src/commands/skill/SKILL.md @@ -0,0 +1,77 @@ +# Stellar CLI skill + +A guide for AI agents driving the `stellar` CLI. Follow these conventions so commands stay short, reproducible, and free of hard-coded secrets and ids. + +## Overview + +The Stellar CLI (`stellar`) manages keys and accounts, builds and deploys smart contracts, deploys asset contracts, streams events, and encodes/decodes XDR. + +- Every command has help: `stellar --help`. +- List a contract's functions and their arguments on the fly: + + stellar contract invoke --id -- --help + + Anything after `--` is parsed against the contract's own schema. + +## Networks: prefer `stellar network use` + +Set a default network once instead of repeating `--network`, `--rpc-url`, and `--network-passphrase` on every command: + + stellar network use testnet + +After this, other commands use that network by default and you can omit the network flags entirely. + +- List configured networks: `stellar network ls` +- Add a custom network: `stellar network add --rpc-url --network-passphrase ` +- Clear the default: `stellar network unset` + +Only pass `--network ` explicitly when a single command needs to target a different network than the default. + +## Identities: prefer `stellar keys use`, never raw secret keys + +Create named identities and select a default with `stellar keys use`, just like networks. Do not paste raw `S...` secret seeds on the command line. + + stellar keys generate alice --fund # generates and funds on testnet + stellar keys use alice # sign and pay as alice by default + +After `stellar keys use`, other commands sign and pay with that identity, so you can omit the source flag entirely. + +- List identities: `stellar keys ls` +- Show an address: `stellar keys address alice` +- Clear the default: `stellar keys unset` + +Only pass `--source ` when a single command needs to override the default identity. + +## Contracts: use aliases, don't stash contract ids in env vars + +When deploying, assign an alias with `--alias` so the CLI persists the contract id for you: + + stellar contract deploy \ + --wasm target/wasm32v1-none/release/hello.wasm \ + --alias hello + +Then reference the contract by its alias with `--id` — the CLI resolves the alias to the real contract id automatically: + + stellar contract invoke --id hello -- hello --to world + +Do **not** capture the deployed contract id into a shell variable or `.env` file and thread it through later commands. Aliases are stored per-network, survive across sessions, and keep commands readable. + +- Manage aliases: `stellar contract alias ls`, `stellar contract alias add`, `stellar contract alias rm` +- Asset contracts accept `--alias` too: `stellar contract asset deploy --asset --alias ` + +## Inspecting configuration + +Use these to see the current state instead of guessing: + +- `stellar env` — effective environment variables and config in use +- `stellar network ls` — configured networks and the default +- `stellar keys ls` — configured identities +- `stellar contract alias ls` — contract aliases for the current network + +## Putting it together + + stellar network use testnet + stellar keys generate alice --fund + stellar keys use alice + stellar contract deploy --wasm hello.wasm --alias hello + stellar contract invoke --id hello -- hello --to world diff --git a/cmd/soroban-cli/src/commands/skill/mod.rs b/cmd/soroban-cli/src/commands/skill/mod.rs new file mode 100644 index 0000000000..7639621ba3 --- /dev/null +++ b/cmd/soroban-cli/src/commands/skill/mod.rs @@ -0,0 +1,22 @@ +use clap::Parser; + +pub const LONG_ABOUT: &str = "\ +Print an AI-agent skill guide for using the Stellar CLI + +Outputs a Markdown document describing how to use the Stellar CLI idiomatically. +It is meant to be read by AI coding agents (or pasted into their instructions) +so they follow the CLI's conventions: using named networks, identities, and +contract aliases instead of raw RPC URLs, secret keys, and hard-coded contract +ids. +"; + +#[derive(Parser, Debug, Clone)] +#[group(skip)] +pub struct Cmd {} + +impl Cmd { + #[allow(clippy::unused_self)] + pub fn run(&self) { + print!("{}", include_str!("SKILL.md")); + } +} From eae3a4d6b62260166dd86a6c9a5d100607c19f72 Mon Sep 17 00:00:00 2001 From: Nando Vieira Date: Thu, 17 Sep 2026 10:17:40 -0700 Subject: [PATCH 2/3] Expand skill guide with build and deploy workflow. --- cmd/crates/soroban-test/tests/it/skill.rs | 5 ++- cmd/soroban-cli/src/commands/skill/SKILL.md | 49 +++++++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/cmd/crates/soroban-test/tests/it/skill.rs b/cmd/crates/soroban-test/tests/it/skill.rs index dc13a9e777..e831986e0a 100644 --- a/cmd/crates/soroban-test/tests/it/skill.rs +++ b/cmd/crates/soroban-test/tests/it/skill.rs @@ -9,5 +9,8 @@ fn skill_prints_agent_guide() { .success() .stdout(predicates::str::contains("network use")) .stdout(predicates::str::contains("--alias")) - .stdout(predicates::str::contains("--id")); + .stdout(predicates::str::contains("--id")) + .stdout(predicates::str::contains("contract build")) + .stdout(predicates::str::contains("--send=no")) + .stdout(predicates::str::contains("container use")); } diff --git a/cmd/soroban-cli/src/commands/skill/SKILL.md b/cmd/soroban-cli/src/commands/skill/SKILL.md index 330c50f220..6773a1f900 100644 --- a/cmd/soroban-cli/src/commands/skill/SKILL.md +++ b/cmd/soroban-cli/src/commands/skill/SKILL.md @@ -59,6 +59,55 @@ Do **not** capture the deployed contract id into a shell variable or `.env` file - Manage aliases: `stellar contract alias ls`, `stellar contract alias add`, `stellar contract alias rm` - Asset contracts accept `--alias` too: `stellar contract asset deploy --asset --alias ` +## Building and deploying from source + +Scaffold, build, and deploy a contract project: + + stellar contract init my-project # scaffold a Cargo workspace + stellar contract build # compile to target/wasm32v1-none/release/.wasm + +Inside a contract project you can deploy without pointing at a `.wasm` — the CLI builds it for you: + + stellar contract deploy --alias counter -- --admin alice + +Constructor arguments go after the `--`, passed as `--arg-name value`; they are forwarded to the contract's `__constructor`. + +- Deploy a prebuilt file: `stellar contract deploy --wasm --alias ` +- Upload Wasm without instantiating a contract (e.g. for factories or upgrades): `stellar contract upload` (the older `install` is a deprecated alias). + +## Discovering a contract's interface + +Besides `stellar contract invoke --id -- --help`, you can inspect a deployed contract's functions and types without invoking it: + + stellar contract info interface --id + +`--id` accepts a contract id or an alias and works across contract commands (it's the short form of `--contract-id`) — prefer it everywhere. + +## Reading data and parsing output + +- For view/query calls, use `--send=no` to simulate without submitting a transaction or paying fees: + + stellar contract invoke --id counter --send=no -- get_count + +- A function's return value is printed to **stdout** as JSON; logs and diagnostics go to **stderr**. When capturing output for parsing, add `-q`/`--quiet` to silence logs and keep stdout clean. + +## Data lifecycle and TTL (archival) + +Ledger entries are rented and expire over time; expired entries are archived and must be restored before use. + +- `stellar contract read` — inspect a contract's storage entries +- `stellar contract extend` — bump an entry's time-to-live before it expires +- `stellar contract restore` — revive archived state + +## Running a local network + +For fast, offline iteration, run a self-contained network (node + RPC + faucet) in a container: + + stellar container start local + +- Container engine: defaults to Docker (or any Docker-compatible CLI such as Podman). On Apple silicon (macOS 26+) you can use Apple's `container` CLI. Set the default once with `stellar container use ` (engines: `docker`, `apple-container`); override a single command with `--engine`, or set `STELLAR_CONTAINER_ENGINE`. +- On testnet, fund an account through friendbot: `stellar keys fund alice`. + ## Inspecting configuration Use these to see the current state instead of guessing: From 6898336a358c3cea7c3754444cf27203cc8a2d29 Mon Sep 17 00:00:00 2001 From: Nando Vieira Date: Thu, 17 Sep 2026 10:56:42 -0700 Subject: [PATCH 3/3] Fix skill guide storage TTL and alias listing docs. --- cmd/soroban-cli/src/commands/skill/SKILL.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cmd/soroban-cli/src/commands/skill/SKILL.md b/cmd/soroban-cli/src/commands/skill/SKILL.md index 6773a1f900..d09a2687ea 100644 --- a/cmd/soroban-cli/src/commands/skill/SKILL.md +++ b/cmd/soroban-cli/src/commands/skill/SKILL.md @@ -93,11 +93,11 @@ Besides `stellar contract invoke --id -- --help`, you can inspect a deployed ## Data lifecycle and TTL (archival) -Ledger entries are rented and expire over time; expired entries are archived and must be restored before use. +Contract storage is rented and each entry has a time-to-live (TTL). Behavior on expiry depends on the storage type: contract code, instance, and persistent entries are **archived** when their TTL runs out and must be restored before use, whereas **temporary** entries are deleted permanently and cannot be restored. - `stellar contract read` — inspect a contract's storage entries -- `stellar contract extend` — bump an entry's time-to-live before it expires -- `stellar contract restore` — revive archived state +- `stellar contract extend` — bump an entry's TTL before it expires +- `stellar contract restore` — restore an archived persistent or instance entry (temporary data can't be restored) ## Running a local network @@ -115,7 +115,7 @@ Use these to see the current state instead of guessing: - `stellar env` — effective environment variables and config in use - `stellar network ls` — configured networks and the default - `stellar keys ls` — configured identities -- `stellar contract alias ls` — contract aliases for the current network +- `stellar contract alias ls` — stored contract aliases, grouped by network ## Putting it together