This guide covers day-to-day development on CleverCon: setup, common tasks, testing, linting, CI, deployment, and debugging. For a high-level tour of the system, see architecture.md. For the contribution workflow (branches, commit style, PR process), see CONTRIBUTING.md.
clevercon/
├── contracts/agent-vault/ CleverVault Soroban contract (Rust)
├── contracts/budget-guardian/ legacy contract, not used by the orchestrator
├── packages/common/ shared types, constants, wallet helpers
├── packages/registry/ agent discovery + reputation API
├── packages/orchestrator/ planner, executor, vault client, WS hub
├── packages/dashboard/ React frontend (not a priority for backend work)
├── packages/agents/*/ five specialist agents
├── scripts/ setup, lifecycle, and seeding scripts
└── docs/ this guide + architecture.md
-
Install Node.js 20 (see
.nvmrc) and runnpm installfrom the repo root — this installs all workspace packages. -
Copy
.env.exampleto.envand setANTHROPIC_API_KEY. Most other variables are filled in by the scripts below. -
Generate Stellar testnet wallets:
npx tsx scripts/setup-wallets.ts
This creates
wallets.json(gitignored) and prints the secret keys to stdout. Copy the printed*_SECRET_KEY=S...lines into your.envfile before continuing — the services refuse to start without them. -
Add USDC trustlines to every wallet:
npx tsx scripts/add-usdc-trustlines.ts
-
Fund the orchestrator with testnet USDC (swap XLM → USDC via testnet DEX):
npx tsx scripts/fund-testnet-usdc.ts
The orchestrator receives 9999 XLM from Stellar friendbot during wallet setup; this script swaps ~15 XLM → 15 USDC via the testnet DEX. No browser required. If the DEX has no liquidity (rare), fall back to https://faucet.circle.com (Stellar Testnet, paste orchestrator address).
-
Distribute USDC from the orchestrator to each agent wallet:
npx tsx scripts/distribute-usdc.ts
-
(Optional) Deploy CleverVault to your own testnet contract:
cd contracts/agent-vault && ./deploy.sh
This writes
AGENT_VAULT_CONTRACT_IDto.env. If unset, the orchestrator's vault client (agent-vault-client.ts) detects that the vault is inactive (VAULT_ACTIVE = false) and all vault calls become safe no-ops — useful for working on non-vault code without a deployed contract.
./scripts/start.sh # build dashboard, start registry + 5 agents + orchestrator
./scripts/stop.sh # stop everything start.sh startedstart.sh writes each service's stdout/stderr to logs/<service>.log and its
PID to logs/<service>.pid (both gitignored). Tail a log while debugging:
tail -f logs/orchestrator.logFor tighter iteration on a single service, run it directly:
npm run dev:registry
npm run dev:orchestrator
npm run dev:oracle # stellar-oracle agent
npm run dev:webintel # web-intel agent
npm run dev:webintel2 # web-intel-v2 agent
npm run dev:analysis
npm run dev:reporterOr all of them concurrently with npm run dev.
npx tsx scripts/bootstrap.ts --auto-approveRuns ~25 varied tasks through the orchestrator so agents accumulate reputation history — useful when working on the selector or dashboard.
npm run build # build all backend services (esbuild) + dashboard
npm run typecheck # tsc --noEmit across every workspace package
npm run lint # ESLint over all TypeScript sources
npm run format # Prettier --write
npm run format:check # Prettier --check (used in CI)
npm test # Vitest unit testsBuild a single service with npm run build:<name> (e.g. build:orchestrator,
build:oracle) — see package.json for the full list. Each maps to an
esbuild invocation that bundles the service into packages/<pkg>/dist/.
Returns the execution plan for a task without creating a task or touching the vault. Useful for showing users what agents will be selected and the estimated cost before they commit USDC.
Request body
{ "prompt": "summarise yesterday's Stellar DEX volume", "budget": 1.0 }prompt and task are interchangeable. budget defaults to DEFAULT_BUDGET
(1.0 USDC) if omitted.
Success response (200)
{
"feasible": true,
"total_estimated_cost": 0.02,
"budget": 1.0,
"over_budget": false,
"reasoning": "Use stellar-oracle to fetch DEX stats.",
"steps": [
{
"agent_id": "stellar-oracle-v1",
"agent_name": "Stellar Oracle",
"action": "Fetch yesterday's DEX volume from Stellar Horizon",
"estimated_cost": 0.02,
"payment_method": "x402",
"endpoint": "https://stellar-oracle.example.com"
}
]
}Error responses
| Status | error field |
Meaning |
|---|---|---|
| 400 | task is required |
Body missing both task and prompt |
| 422 | feasible: false |
No registered agent covers the required capabilities |
| 503 | no_agents |
Registry has no active agents |
| 503 | registry_unavailable |
Cannot reach the registry service |
Example curl
curl -s -X POST http://localhost:3000/api/tasks/preview \
-H 'Content-Type: application/json' \
-d '{"prompt": "summarise yesterday Stellar DEX volume", "budget": 1.0}' | jq .Unit tests use Vitest and are colocated with the code
they test as *.test.ts. Current coverage focuses on pure logic that's easy
to verify in isolation:
packages/registry/src/reputation.test.ts— reputation score calculation and rolling-average updates.packages/registry/src/search.test.ts— capability matching.packages/orchestrator/src/selector.test.ts— agent scoring/selection.packages/orchestrator/src/validator.test.ts— execution plan validation.packages/orchestrator/src/server.preview.test.ts—/api/tasks/previewendpoint (happy path, no-agents 503, infeasible 422).
Run the full suite with npm test, or scope to a package with
npm test -w packages/registry.
cd contracts/agent-vault
cargo test # uses soroban-sdk testutils
cargo fmt
cargo clippy -- -D warningsESLint (TypeScript) and Prettier are configured at the repo root and apply to
every workspace package except packages/dashboard (which has its own
frontend tooling and is out of scope for backend hardening). Run
npm run lint and npm run format:check before opening a PR — CI runs both.
Two workflows run on pull requests and pushes to main:
.github/workflows/ci.yml— a TypeScript job (npm ci,typecheck,lint,format:check,build,test) and a Rust job (cargo fmt --check,cargo clippy,cargo testfor each contract)..github/workflows/dependency-review.yml— flags newly introduced dependencies with known vulnerabilities on pull requests.
render.yaml defines all 7 services (registry, orchestrator+dashboard, and
the 5 agents) as a Render Blueprint. To deploy:
- Push to GitHub and create a Blueprint from this repo in Render.
- Set the
sync: falsesecrets (*_SECRET_KEY,ANTHROPIC_API_KEY,AGENT_VAULT_CONTRACT_ID) in the Render dashboard for each service. - After the first deploy, update
REGISTRY_URLand each*_SELF_URLenv var to the assigned*.onrender.comURLs, then redeploy — agents re-register themselves with the registry on startup.
Render's free tier cold-starts services after inactivity; the orchestrator's
executor (checkHealth in executor.ts) retries health checks for up to ~90
seconds to accommodate this.
- Agents can't reach the registry on startup. Each agent's
register.tsself-registers once at boot with no retry — if the registry isn't up yet, the agent won't appear until it's restarted or re-registers via its heartbeat.start.shstarts the registry first and waits for its health check for this reason. - Stellar sequence number errors during execution.
release_paymentcalls for a task must be submitted in order —executor.ts'sreleaseSequentialserializes them. If you're callingagent-vault-client.tsfunctions directly (e.g. from a script), don't fire multiple orchestrator-signed transactions concurrently. - Vault calls silently no-op. If
AGENT_VAULT_CONTRACT_IDis unset or looks like a placeholder,VAULT_ACTIVEisfalseandagent-vault-client.tsreturns safe defaults instead of calling the contract. Useful for local dev, but confusing if you're expecting on-chain state to change. data/andlogs/are gitignored and created at runtime. If yourm -rf data/, the registry, vault ledger, activity log, and task history all reset. Don't commit anything fromdata/— it includes orchestrator wallet secret keys (see SECURITY.md).tsc -bproject references. Each workspace package has its owntsconfig.jsonextending the root config;npm run typecheckrunstsc --noEmitper package rather than relying on a single project-reference build.
The agent interface is service-agnostic. Your specialist can be anything that fulfills three requirements:
- An HTTP endpoint that responds to the
POST /querypattern (x402) or an MPP session endpoint. - A Stellar wallet with a USDC trustline, used to receive payments.
- A
/healthand/manifestendpoint so the registry and orchestrator can identify capabilities, pricing, and liveness.
The existing agents in packages/agents/ all happen to be LLM-powered because
that was the initial focus, but the protocol does not require it. Your
specialist could be:
- A traditional API wrapper (weather data, FX rates, on-chain analytics)
- A computation service (financial modeling, image processing, data transforms)
- A verification service (notarization, credential checks)
- A human-in-the-loop service (tasks fulfilled by a human for USDC payment)
- Any other service that can accept a task query and return a structured result
Use one of the existing agents (e.g. packages/agents/stellar-oracle) as a
reference for the manifest schema, payment middleware wiring, and
self-registration pattern. The @clevercon/agent-sdk package (Phase 3 on the
roadmap) will eventually package this scaffolding so you don't have to copy it.
- Service logs:
logs/<service>.logwhen started viastart.sh. - On-chain state: use the read-only helpers in
packages/orchestrator/src/agent-vault-client.ts(getBalance,getAvailable,getAccount,get_taskviagetTask-style calls) or query directly with the Stellar CLI /stellar.experttestnet explorer using the contract ID and account addresses from.env. - WebSocket events: the orchestrator emits a typed event stream
(
task_started,step_started,step_complete,step_failed,budget_released,task_complete) over/ws— connect withwscator the dashboard's network tab to watch a task execute in real time. - Vault ledger / activity log / task results: inspect
data/vault-ledger.json,data/activity-log.json, anddata/task-results.jsondirectly for a record of what the orchestrator has done.
Open an issue (use the bug report or contributor issue template), or email the maintainer at joshuaibitoye111@gmail.com for anything sensitive — see SECURITY.md for vulnerability reports specifically.