Skip to content

Latest commit

 

History

History
1068 lines (806 loc) · 28.6 KB

File metadata and controls

1068 lines (806 loc) · 28.6 KB

Lucid Agents Monorepo - AI Coding Guide

This guide helps AI coding agents understand and work with the lucid-agents monorepo effectively.

Project Overview

This is a TypeScript/Bun monorepo for building, monetizing, and verifying AI agents. It provides:

  • @lucid-agents/core - Protocol-agnostic agent runtime with extension system
  • @lucid-agents/http - HTTP extension for request/response handling
  • @lucid-agents/identity - ERC-8004 identity and trust layer
  • @lucid-agents/payments - x402 payment utilities
  • @lucid-agents/wallet - Wallet SDK for agent and developer wallets
  • @lucid-agents/a2a - A2A Protocol client for agent-to-agent communication
  • @lucid-agents/ap2 - AP2 (Agent Payments Protocol) extension
  • @lucid-agents/hono - Hono HTTP server adapter
  • @lucid-agents/express - Express HTTP server adapter
  • @lucid-agents/tanstack - TanStack Start adapter
  • @lucid-agents/cli - CLI for scaffolding new agent projects

Tech Stack:

  • Runtime: Bun (Node.js 20+ compatible)
  • Language: TypeScript (ESM, strict mode)
  • Build: tsup
  • Package Manager: Bun workspaces
  • Versioning: Changesets

Architecture Overview

Package Dependencies

cli (scaffolding tool)
    ↓ scaffolds projects using
hono OR express OR tanstack (adapters)
    ↓ both use
core (protocol-agnostic runtime)
    ↓ uses extensions
http, identity, payments, wallet, a2a, ap2 (extensions)

Extension System

The framework uses an extension-based architecture where features are added via composable extensions:

  • http (@lucid-agents/http) - HTTP request/response handling, streaming, SSE
  • wallets (@lucid-agents/wallet) - Wallet management for agents
  • payments (@lucid-agents/payments) - x402 payment verification and pricing
  • identity (@lucid-agents/identity) - ERC-8004 on-chain identity and trust
  • a2a (@lucid-agents/a2a) - Agent-to-agent communication protocol
  • ap2 (@lucid-agents/ap2) - Agent Payments Protocol extension

Adapter System

The framework supports multiple runtime adapters:

  • Hono (@lucid-agents/hono) - Traditional HTTP server
  • Express (@lucid-agents/express) - Node.js/Express server with x402 middleware
  • TanStack Start (@lucid-agents/tanstack) - Full-stack React with dashboard (UI) or API-only (headless)

Templates are adapter-agnostic and work with any compatible adapter.

Data Flow

HTTP Request
    ↓
Adapter Router (Hono, Express, or TanStack)
    ↓
x402 Paywall Middleware (if configured)
    ↓
Runtime Handler (core)
    ↓
Entrypoint Handler
    ↓
Response (JSON or SSE stream)

Key Architectural Decisions

  1. Multi-adapter support - Same agent logic works with different frameworks
  2. Template-based scaffolding - Templates use .template extensions for clean code generation
  3. Zod for validation - Schema-first approach for input/output
  4. Server-Sent Events for streaming - Standard SSE for real-time responses
  5. ERC-8004 for identity - On-chain agent identity and reputation
  6. x402 for payments - HTTP-native payment protocol supporting both EVM and Solana networks

Supported Payment Networks

The framework supports payment receiving on multiple blockchain networks:

EVM Networks:

  • base - Base mainnet (L2, low cost)
  • base-sepolia - Base Sepolia testnet
  • ethereum - Ethereum mainnet
  • sepolia - Ethereum Sepolia testnet

Solana Networks:

  • solana - Solana mainnet (high throughput, low fees)
  • solana-devnet - Solana devnet

Key Differences:

  • EVM: EIP-712 signatures, ERC-20 tokens (USDC), 0x-prefixed addresses
  • Solana: Ed25519 signatures, SPL tokens (USDC), Base58 addresses
  • Transaction finality: Solana (~400ms) vs EVM (12s-12min)
  • Gas costs: Solana (~$0.0001) vs EVM ($0.01-$10)

Identity vs Payments:

  • Identity registration (ERC-8004): EVM-only (smart contract on Ethereum chains)
  • Payment receiving: Any supported network (EVM or Solana)
  • These are independent: register identity on Base, receive payments on Solana

Code Structure Principles

These principles guide how we organize and structure code across the monorepo. Follow them when writing new code or refactoring existing code.

1. Single Source of Truth

One type definition per concept. Avoid duplicate types like PaymentsRuntimeInternal vs PaymentsRuntime. If you need variations, use type composition or generics, not separate type definitions.

Bad:

// Internal type
type PaymentsRuntimeInternal = { config: PaymentsConfig | undefined; activate: ... };
// Public type
type PaymentsRuntime = { config: PaymentsConfig; requirements: ... };

Good:

// One type definition
type PaymentsRuntime = {
  config: PaymentsConfig;
  isActive: boolean;
  requirements: ...;
  activate: ...;
};

2. Encapsulation at the Right Level

Domain complexity belongs in the owning package. The payments package should handle all payments-related complexity. The core runtime should use it directly without transformation layers.

Bad:

// In core runtime - wrapping payments runtime
const paymentsRuntime = payments.config ? {
  get config() { return payments.config!; },
  get isActive() { return payments.isActive; },
  requirements(...) { return evaluatePaymentRequirement(...); }
} : undefined;

Good:

// In payments package - returns complete runtime
export function createPaymentsRuntime(...): PaymentsRuntime | undefined {
  return {
    config,
    isActive,
    requirements(...) { ... },
    activate(...) { ... }
  };
}

// In core runtime - use directly
const payments = createPaymentsRuntime(...);
return { payments };

3. Direct Exposure

Expose runtimes directly without unnecessary wrappers. If the type matches what's needed, pass it through. Don't create intermediate objects or getters unless there's a clear need.

Bad:

return {
  get payments() {
    return payments.config ? { ...wrappedObject } : undefined;
  },
};

Good:

return {
  wallets,
  payments,
};

4. Consistency

Similar concepts should follow the same pattern. If wallets is exposed directly, payments should be too. Consistency reduces cognitive load and makes the codebase easier to understand.

Example:

// Both follow the same pattern
const wallets = createWalletsRuntime(config);
const payments = createPaymentsRuntime(opts?.payments, config);

return {
  wallets, // Direct exposure
  payments, // Direct exposure
};

5. Public API Clarity

If something needs to be used by consumers, include it in the public type. Don't hide methods or use type casts. The public API should be complete and type-safe.

Bad:

// Internal method not in public type
payments.activate(def); // Type error or requires cast

Good:

// Public type includes all needed methods
type PaymentsRuntime = {
  config: PaymentsConfig;
  isActive: boolean;
  requirements: ...;
  activate: (entrypoint: EntrypointDef) => void; // Public method
};

6. Simplicity Over Indirection

Avoid unnecessary getters, wrappers, and intermediate objects. Prefer straightforward code. Add complexity only when there's a clear benefit.

Bad:

// Unnecessary wrapper
const paymentsRuntime = {
  get config() { return payments.config!; },
  get isActive() { return payments.isActive; },
  requirements(...) { return evaluate(...); }
};

Good:

// Direct use
payments.requirements(...);

7. Domain Ownership

Each package should own its complexity. The payments package creates and returns a complete PaymentsRuntime with all its methods. Consumers use it as-is without transformation.

Principle: Each package should return what consumers need, and consumers should use it directly without transformation layers.

8. No Premature Abstraction

Avoid layers like sync(), resolvedConfig vs activeConfig, etc. Keep it simple until you actually need the complexity. YAGNI (You Aren't Gonna Need It) applies.

Bad:

// Multiple config states
type PaymentsRuntime = {
  config: PaymentsConfig | undefined;
  resolvedConfig: PaymentsConfig | undefined;
  activeConfig: PaymentsConfig | undefined;
  sync: (agent: AgentCore) => void;
};

Good:

// Single config state
type PaymentsRuntime = {
  config: PaymentsConfig;
  isActive: boolean;
  activate: (entrypoint: EntrypointDef) => void;
};

Monorepo Structure

/
├── packages/
│   ├── core/               # Protocol-agnostic runtime
│   │   ├── src/
│   │   │   ├── core/            # AgentCore, entrypoint management
│   │   │   ├── extensions/      # AgentBuilder, extension system
│   │   │   ├── config/          # Config management
│   │   │   └── utils/           # Helper utilities
│   │   └── AGENTS.md            # Package-specific guide
│   │
│   ├── http/               # HTTP extension
│   │   ├── src/
│   │   │   ├── extension.ts     # HTTP extension definition
│   │   │   ├── invoke.ts        # HTTP invocation logic
│   │   │   ├── stream.ts        # HTTP streaming logic
│   │   │   └── sse.ts           # Server-Sent Events
│   │   └── examples/
│   │
│   ├── wallet/             # Wallet SDK
│   │   ├── src/
│   │   │   └── env.ts           # Wallet config from env
│   │   └── examples/
│   │
│   ├── payments/           # x402 payment utilities
│   │   ├── src/
│   │   │   └── extension.ts     # Payments extension
│   │   └── examples/
│   │
│   ├── identity/           # ERC-8004 identity
│   │   ├── src/
│   │   │   ├── init.ts          # createAgentIdentity()
│   │   │   ├── extension.ts     # Identity extension
│   │   │   ├── registries/      # Registry clients
│   │   │   └── utils/           # Identity utilities
│   │   └── examples/
│   │
│   ├── a2a/                # A2A Protocol client
│   │   ├── src/
│   │   │   ├── extension.ts     # A2A extension
│   │   │   └── client.ts        # A2A client
│   │   └── examples/
│   │
│   ├── ap2/                # AP2 extension
│   │   └── src/
│   │       └── extension.ts     # AP2 extension
│   │
│   ├── hono/               # Hono adapter
│   │   ├── src/
│   │   │   ├── app.ts           # createAgentApp() for Hono
│   │   │   └── paywall.ts       # x402 Hono middleware
│   │   └── examples/
│   │
│   ├── express/            # Express adapter
│   │   ├── src/
│   │   │   ├── app.ts           # createAgentApp() for Express
│   │   │   └── paywall.ts       # x402 Express middleware
│   │   └── __tests__/
│   │
│   ├── tanstack/           # TanStack adapter
│   │   ├── src/
│   │   │   ├── runtime.ts       # createTanStackRuntime()
│   │   │   └── paywall.ts       # x402 TanStack middleware
│   │   └── examples/
│   │
│   └── cli/                # CLI scaffolding tool
│       ├── src/
│       │   ├── index.ts         # CLI implementation
│       │   └── adapters.ts      # Adapter definitions
│       └── templates/           # Project templates
│           ├── blank/           # Minimal agent
│           ├── identity/        # Identity-enabled agent
│           ├── trading-data-agent/      # Trading data merchant
│           └── trading-recommendation-agent/  # Trading shopper
│
├── scripts/
│   ├── build-packages.ts   # Build script
│   └── changeset-publish.ts # Publish script
│
└── package.json            # Workspace config

Build & Development Commands

Workspace-Level Commands

# Install all dependencies
bun install

# Build all packages
bun run build
# or
bun run build:packages

# Version packages (for release)
bun run changeset
bun run release:version

# Publish packages
bun run release:publish

# Full release flow
bun run release

Package-Level Commands

# Work in a specific package
cd packages/core

# Build this package
bun run build

# Run tests
bun test

# Type check
bunx tsc --noEmit

# Watch mode (if configured)
bun run dev

API Quick Reference

Hono Adapter

createAgentApp(runtimeOrBuilder)

import { createAgent } from '@lucid-agents/core';
import { http } from '@lucid-agents/http';
import { payments } from '@lucid-agents/payments';
import { paymentsFromEnv } from '@lucid-agents/payments';
import { createAgentApp } from '@lucid-agents/hono';

const agent = await createAgent({
  name: 'my-agent',
  version: '0.1.0',
  description: 'Agent description',
})
  .use(http())
  .use(payments({ config: paymentsFromEnv() }))
  .build();

const { app, addEntrypoint } = await createAgentApp(agent);

Express Adapter

createAgentApp(runtimeOrBuilder)

import { createAgent } from '@lucid-agents/core';
import { http } from '@lucid-agents/http';
import { createAgentApp } from '@lucid-agents/express';

const agent = await createAgent({
  name: 'my-agent',
  version: '0.1.0',
  description: 'Agent description',
})
  .use(http())
  .build();

const { app, addEntrypoint } = await createAgentApp(agent);

// Express apps need to listen on a port
const server = app.listen(process.env.PORT ?? 3000);

TanStack Adapter

createTanStackRuntime(runtimeOrBuilder)

import { createAgent } from '@lucid-agents/core';
import { http } from '@lucid-agents/http';
import { createTanStackRuntime } from '@lucid-agents/tanstack';

const agent = await createAgent({
  name: 'my-agent',
  version: '0.1.0',
  description: 'Agent description',
})
  .use(http())
  .build();

const { runtime: tanStackRuntime, handlers } = await createTanStackRuntime(agent);

// Use runtime.addEntrypoint() instead of addEntrypoint()
tanStackRuntime.addEntrypoint({ ... });

// Export for TanStack routes
export { runtime: tanStackRuntime, handlers };

addEntrypoint(definition)

addEntrypoint({
  key: 'echo',
  description: 'Echo back input',
  input: z.object({ text: z.string() }),
  output: z.object({ text: z.string() }),
  price: '1000', // Optional x402 price
  handler: async ctx => {
    return {
      output: { text: ctx.input.text },
      usage: { total_tokens: 0 },
    };
  },
});

paymentsFromEnv()

import { paymentsFromEnv } from '@lucid-agents/payments';

const payments = paymentsFromEnv();
// Returns PaymentsConfig or undefined

Identity Functions

createAgentIdentity(options)

import { createAgent } from '@lucid-agents/core';
import { wallets } from '@lucid-agents/wallet';
import { walletsFromEnv } from '@lucid-agents/wallet';
import { createAgentIdentity } from '@lucid-agents/identity';

const agent = await createAgent({
  name: 'my-agent',
  version: '1.0.0',
})
  .use(wallets({ config: walletsFromEnv() }))
  .build();

const identity = await createAgentIdentity({
  runtime: agent,
  domain: 'agent.example.com',
  autoRegister: true, // Register if not exists
});

// Returns:
// - identity.record (if registered)
// - identity.clients (registry clients)
// - identity.trust (trust config)
// - identity.didRegister (whether just registered)

getTrustConfig(identity)

import { getTrustConfig } from '@lucid-agents/identity';

const trustConfig = getTrustConfig(identity);
// Returns TrustConfig for agent manifest

CLI

Interactive Mode

bunx @lucid-agents/cli my-agent

With Adapter Selection

# Hono adapter (traditional HTTP server)
bunx @lucid-agents/cli my-agent --adapter=hono

# Express adapter (Node-style HTTP server)
bunx @lucid-agents/cli my-agent --adapter=express

# TanStack UI (full dashboard)
bunx @lucid-agents/cli my-agent --adapter=tanstack-ui

# TanStack Headless (API only)
bunx @lucid-agents/cli my-agent --adapter=tanstack-headless

Non-Interactive Mode

bunx @lucid-agents/cli my-agent \
  --adapter=tanstack-ui \
  --template=identity \
  --non-interactive \
  --AGENT_DESCRIPTION="My custom agent" \
  --PAYMENTS_RECEIVABLE_ADDRESS="0x..."

How the Template System Works

Template Structure

Each template in packages/cli/templates/ contains:

template-name/
├── src/
│   ├── agent.ts         # Agent definition
│   └── index.ts         # Server setup
├── package.json         # Dependencies
├── tsconfig.json        # TypeScript config
├── template.json        # Wizard configuration
├── template.schema.json # JSON Schema for arguments
├── AGENTS.md            # Template-specific guide
└── README.md            # User-facing docs

Wizard Flow

  1. Parse CLI args - Extract flags like --template=identity --KEY=value
  2. Load templates - Scan templates/ directory
  3. Resolve template - Match --template flag or prompt user
  4. Collect wizard answers:
    • Use pre-supplied --KEY=value flags if present
    • Otherwise, prompt user (or use defaults in --non-interactive)
  5. Copy template - Copy entire template directory to target
  6. Transform files:
    • Update package.json with actual package name
    • Replace {{AGENT_NAME}} tokens in README
    • Generate .env with wizard answers
  7. Remove artifacts - Delete template.json
  8. Install dependencies - Run bun install if requested

How to Modify an Existing Template

  1. Edit files in packages/cli/templates/[template-name]/
  2. Update template.json if adding wizard prompts
  3. Update template.schema.json to document new arguments
  4. Update AGENTS.md with examples of new features
  5. Test:
    cd packages/cli
    bun run build
    cd ../..
    bunx ./packages/cli/dist/index.js test-agent --template=[template-name]

How to Create a New Template

  1. Create directory: packages/cli/templates/my-template/
  2. Add required files:
    mkdir -p src
    # Create src/agent.ts, src/index.ts
    # Copy package.json, tsconfig.json from blank template
  3. Create template.json:
    {
      "id": "my-template",
      "name": "My Template",
      "description": "Description here",
      "wizard": {
        "prompts": [
          {
            "key": "SOME_CONFIG",
            "type": "input",
            "message": "Enter config value:",
            "defaultValue": "default"
          }
        ]
      }
    }
  4. Create template.schema.json documenting all arguments
  5. Create AGENTS.md with comprehensive examples
  6. Test the template
  7. Add to help text in src/index.ts

Testing Conventions

Unit Tests

Located in src/__tests__/ within each package:

import { describe, expect, test } from 'bun:test';

describe('MyModule', () => {
  test('should do something', () => {
    expect(something()).toBe(expected);
  });
});

Run tests:

bun test                    # All tests
bun test src/__tests__/specific.test.ts  # Specific test

Integration Tests

Example-based testing in examples/ directories:

cd packages/core/examples
bun run client.ts           # Test against running agent

Testing cli

# Test template generation
cd /tmp
bunx /path/to/lucid-agents/packages/cli/dist/index.js test-agent --template=blank
cd test-agent
bun install
bun run dev

PR Completion Checklist

A pull request is not considered complete unless it includes:

  • E2E example smoke test - If the PR adds or modifies SDK surface area (new extensions, entrypoints, or config patterns), add a corresponding smoke test in packages/examples/src/__tests__/smoke.test.ts. Smoke tests verify that agents build, servers boot, agent cards are valid, and entrypoints respond correctly — all without external services. Run bun test packages/examples/src/__tests__/ to confirm.
  • Documentation - Update relevant documentation: AGENTS.md for architecture/patterns, package-level README.md files for usage, and inline JSDoc for public APIs. If you add a new package or extension, add it to the directory structure and dependency diagram sections.

Release Process with Changesets

Creating a Changeset

When you make changes:

bun run changeset

This prompts you for:

  1. Which packages changed?
  2. Semver bump type (major/minor/patch)
  3. Summary of changes

Creates a file in .changeset/ describing the change.

Versioning

bun run release:version

This:

  1. Reads all changeset files
  2. Updates package.json versions
  3. Updates CHANGELOG.md files
  4. Removes processed changeset files

Publishing

bun run release:publish

This:

  1. Builds all packages
  2. Publishes to npm

Full flow:

bun run release  # version + publish

Coding Standards

General

  • No emojis - Do not use emojis in code, comments, or commit messages unless explicitly requested by the user
  • Re-exports are banned - Do not re-export types or values from other packages. Define types in the appropriate shared types package (@lucid-agents/types) or in the package where they are used. Re-exports create unnecessary coupling and make it unclear where types are actually defined.

TypeScript

  • ESM only - Use import/export, not require()
  • Strict mode - All packages use strict: true
  • Explicit types - Avoid any, prefer explicit types or unknown
  • Type exports - Export types separately: export type { MyType }

File Naming

  • Source: kebab-case.ts
  • Types: types.ts or inline
  • Tests: *.test.ts in __tests__/
  • Examples: Descriptive names in examples/

Code Organization

Package structure:

src/
├── index.ts           # Main exports
├── types.ts           # Type definitions
├── feature1.ts        # Feature implementation
├── feature2.ts
├── utils/
│   └── helpers.ts     # Utility functions
└── __tests__/
    └── feature1.test.ts

Export patterns:

// index.ts
export { mainFunction } from './feature1';
export { helperFunction } from './utils/helpers';
export type { MyType } from './types';

Common Patterns

Error handling:

try {
  const result = await operation();
  return result;
} catch (error) {
  throw new Error(`Operation failed: ${(error as Error).message}`);
}

Environment variables:

const value = process.env.KEY;
if (!value) {
  throw new Error('KEY environment variable required');
}

Zod schemas:

import { z } from 'zod';

const schema = z.object({
  field: z.string().min(1),
  optional: z.number().optional(),
});

type Parsed = z.infer<typeof schema>;

How Packages Interact

core → identity

// core imports identity types
import type { TrustConfig } from '@lucid-agents/identity';

// core accepts trust config
createAgentApp(meta, {
  trust: trustConfig, // From identity
});

cli → core + identity

Templates reference both packages:

// In generated agent.ts
import { createAgentApp } from '@lucid-agents/core';
import { createAgentIdentity } from '@lucid-agents/identity';

The CLI doesn't directly import these; it scaffolds code that uses them.

Common Development Tasks

Testing Local Packages in External Projects

When developing changes to packages and testing them in external projects (e.g., your own agent), use bun's linking feature:

Workflow:

  1. Register packages globally - In the lucid-agents monorepo, register the packages you want to link:

    cd lucid-agents/packages/types
    bun link
    
    cd ../wallet
    bun link
    
    cd ../identity
    bun link
  2. Update your test project's package.json to use the link: protocol:

    {
      "dependencies": {
        "@lucid-agents/identity": "link:@lucid-agents/identity",
        "@lucid-agents/types": "link:@lucid-agents/types",
        "@lucid-agents/wallet": "link:@lucid-agents/wallet"
      }
    }
  3. Install dependencies in your test project:

    cd my-test-agent
    bun install
  4. Make changes in the linked package:

    cd lucid-agents/packages/identity
    # Make your changes to source code
    bun run build  # Build after changes
  5. Test immediately - Changes are reflected in your test project automatically

  6. Before committing, remember to change back to version references:

    {
      "dependencies": {
        "@lucid-agents/identity": "^1.12.0",
        "@lucid-agents/types": "^1.5.5",
        "@lucid-agents/wallet": "^0.5.5"
      }
    }

How it works:

  • bun link registers a package globally by name
  • The link:@package-name protocol in package.json references the globally registered package
  • Any changes you make and build in the linked package are immediately available
  • No need to publish to npm or reinstall dependencies
  • Perfect for rapid iteration and testing

Adding a New Feature to core

  1. Create implementation in packages/core/src/feature.ts
  2. Add types to types.ts or inline
  3. Export from index.ts
  4. Add tests in __tests__/feature.test.ts
  5. Update README.md with examples
  6. Update AGENTS.md with AI-focused guide
  7. Create changeset: bun run changeset

Adding a New Entrypoint Type

  1. Update EntrypointDef type in types.ts
  2. Update manifest generation in manifest.ts
  3. Update routing in app.ts
  4. Add examples showing the new type
  5. Update template files if relevant

Modifying the CLI

  1. Edit packages/cli/src/index.ts
  2. Build: cd packages/cli && bun run build
  3. Test locally: bunx ./dist/index.js test-agent
  4. Update help text and README
  5. Create changeset

Troubleshooting

"Module not found" errors

Ensure:

  1. All packages are built: bun run build:packages
  2. Dependencies are installed: bun install
  3. Using correct import paths (e.g., @lucid-agents/core/types)

TypeScript errors in templates

Templates use the built packages:

  1. Build packages first
  2. Check that template package.json references correct versions
  3. Run bunx tsc --noEmit in template directory

Changesets not working

Ensure:

  1. You're in the repo root
  2. Changes are committed to git
  3. .changeset directory exists
  4. Run bunx changeset not bun run changeset if workspace command fails

Build fails

Check:

  1. TypeScript version matches across packages
  2. All imports are resolvable
  3. No circular dependencies
  4. Run bun install again

Key Files and Their Purposes

packages/core/src/http/runtime.ts

Core HTTP runtime that adapters wrap. Handles manifest building, entrypoint registry, streaming helpers, and payment evaluation.

packages/hono/src/app.ts

Hono-specific createAgentApp() implementation. Wires Fetch handlers to Hono routes and installs the x402 middleware.

packages/express/src/app.ts

Express-specific createAgentApp() implementation. Bridges Node requests/responses to the Fetch-based runtime and installs the x402 Express middleware.

packages/core/src/manifest.ts

Generates AgentCard and manifest JSON. Includes A2A skills, payments metadata, trust registrations.

packages/core/src/paywall.ts

x402 payment middleware. Checks payment headers, validates with facilitator, enforces pricing.

packages/core/src/types.ts

Core type definitions: EntrypointDef, AgentContext, AgentMeta, PaymentsConfig, etc.

packages/identity/src/init.ts

Main createAgentIdentity() function. Bootstraps ERC-8004 identity, handles auto-registration.

packages/identity/src/registries/

Registry client implementations for Identity, Reputation, and Validation registries.

packages/cli/src/index.ts

CLI implementation. Handles argument parsing, wizard prompts, template copying, file transformation.

Additional Resources

Questions or Issues?

When working on this codebase:

  1. Check package READMEs - Each package has detailed documentation
  2. Check AGENTS.md files - Package-specific guides for AI agents
  3. Look at examples - All packages have examples/ directories
  4. Review tests - Tests show expected behavior
  5. Check changesets - Recent changes documented in .changeset/