This is the uniswap-ai monorepo providing Uniswap-specific AI tools (skills, plugins, agents) for developers and AI agents integrating the Uniswap ecosystem.
- REQUIREMENT: Use Nx for ALL packages and tooling in this monorepo
- Every package must be an Nx project with proper configuration
- Use Nx generators, executors, and workspace features wherever possible
- Leverage Nx's dependency graph and caching capabilities
- All packages must be properly configured Nx libraries or applications
- Use Nx's project.json for configuration
- Follow Nx best practices for monorepo organization
- Use Nx commands for all operations (build, test, lint, etc.)
- Maintain proper inter-package dependencies through Nx
- Ensure all packages are part of the Nx workspace graph
After making any code changes, Claude Code MUST:
- Format the code: Run
npx nx format:write --uncommittedto format all uncommitted files - Lint the code: Run
npx nx affected --target=lint --base=HEAD~1to check for linting errors - Typecheck the code: Run
npx nx affected --target=typecheck --base=HEAD~1to typecheck affected projects - Lint markdown files: Run
npm exec markdownlint-cli2 -- --fix "**/*.md" - Lint documentation prose: Run
npm run docs:lintto check documentation quality with Vale
| Type | Scope | npm | Marketplace |
|---|---|---|---|
| Plugins | @uniswap |
No | Yes (Claude Code Marketplace) |
uniswap-ai/
├── .github/
│ ├── workflows/ # CI/CD workflows
│ ├── actions/ # Reusable composite actions
│ └── scripts/ # CI scripts
├── .claude-plugin/
│ └── marketplace.json # Claude Code marketplace config
├── .claude/
│ └── rules/ # Agent rules (agnostic design)
├── docs/ # VitePress documentation
├── evals/ # AI tool evaluations (Promptfoo)
│ ├── rubrics/ # Shared evaluation rubrics
│ ├── scripts/ # Custom providers and utilities
│ ├── suites/ # Per-skill eval suites
│ └── templates/ # Templates for new suites
├── packages/
│ └── plugins/ # Claude Code plugins
│ ├── uniswap-cca/ # Continuous Clearing Auction (CCA) plugin
│ ├── uniswap-driver/ # Swap & liquidity deep link planning
│ ├── uniswap-hooks/ # Uniswap v4 hooks plugin
│ ├── uniswap-trading/ # Uniswap swap integration
│ └── uniswap-viem/ # EVM blockchain integration (viem/wagmi)
├── scripts/ # Build/validation scripts
├── nx.json
├── package.json
├── tsconfig.base.json
├── CLAUDE.md # This file
├── AGENTS.md -> CLAUDE.md # Symlink for agent-agnostic access
├── LICENSE # MIT
└── README.md
Plugins are stored in ./packages/plugins/<plugin-name>/:
- Each plugin is a self-contained Nx package with
package.json,project.json, and.claude-plugin/plugin.json - The
.claude-plugin/marketplace.jsonreferences plugins via relative paths - Plugin validation:
node scripts/validate-plugin.cjs packages/plugins/<plugin-name>
All plugins follow semantic versioning (semver):
- Patch (1.0.X): Bug fixes, minor documentation updates
- Minor (1.X.0): New skills, agents, or commands (backward compatible)
- Major (X.0.0): Breaking changes, significant restructuring
After making any changes to packages/plugins/, bump the plugin version in .claude-plugin/plugin.json.
All AI tools in this repo should be usable by ANY LLM coding agent, not just Claude Code:
- Documentation: Use AGENTS.md (symlink to CLAUDE.md) as standard
- Prompts: Write prompts that work across models (avoid Claude-specific features unless necessary)
- Skills: Structure skills as markdown that any agent can interpret
- No vendor lock-in: Prefer standards over proprietary features
- Testing: Evals should work with multiple LLM backends
Evals are to AI tools what tests are to traditional code. This project uses Promptfoo for declarative, CI-integrated evaluations.
evals/
├── promptfoo.yaml # Root config with default providers
├── rubrics/ # Shared evaluation rubrics (.txt files)
│ └── security-checklist.txt
├── scripts/
│ └── anthropic-provider.ts # Custom provider for OAuth support
├── suites/ # Per-skill eval suites
│ └── <skill-name>/
│ ├── promptfoo.yaml # Suite-specific config
│ ├── cases/ # Test case prompts (markdown)
│ └── rubrics/ # Skill-specific rubrics (.txt files)
└── templates/ # Templates for new suites
Note: Rubric files must use
.txtextension (not.md). Promptfoo's grader only supports.txt,.json, and.yamlforfile://references in assertions.
# Requires 1Password CLI (https://developer.1password.com/docs/cli/get-started)
eval $(op signin)
nx run evals:setupOr set environment variables directly:
export ANTHROPIC_API_KEY=sk-ant-... # CI, production
# OR
export CLAUDE_CODE_OAUTH_TOKEN=<token> # Local developmentnx run evals:eval --suite=v4-security-foundations # Run specific suite (no caching)
nx run evals:eval-suite:swap-planner # Run specific suite (with Nx caching)
nx run evals:eval:all # Run all suites
nx run evals:eval:view # Open results viewer
nx run evals:eval:cache-clear # Clear promptfoo cacheEach eval suite has a dedicated eval-suite:<name> Nx target with cache: true. Nx tracks the suite's inputs (promptfoo config, cases, rubrics, and the referenced skill files) and caches results.json. When inputs haven't changed, Nx restores the cached result without making LLM API calls.
To force a re-run (skip cache): nx run evals:eval-suite:swap-planner --skip-nx-cache
- Copy
evals/templates/suite/toevals/suites/<skill-name>/ - Rename
.templatefiles (remove.templateextension) - Replace
{{SKILL_NAME}}placeholders - Add test cases in
cases/directory - Define rubrics in
rubrics/directory - Update
promptfoo.yamlwith your prompts and assertions - Add an
eval-suite:<skill-name>target toevals/project.jsonwith properinputspointing to the skill directory
Evals run automatically on PRs that modify:
packages/plugins/**evals/**
Each suite runs through its Nx eval-suite:* target. The Nx cache is persisted between CI runs via GitHub Actions cache, so suites whose inputs haven't changed since the last run are served from cache (no LLM API calls). Pass rate must be ≥85% for PR to pass. Results include inference cost tracking.
- Focus on outputs, not prescribed paths
- Include edge cases and security probes for smart contract code
- Use deterministic checks (
contains,not-contains) for required patterns - Use LLM rubrics for qualitative assessment
- Never use
---in.txtprompt files. Promptfoo treats---on its own line as a multi-prompt separator, silently splitting one template into multiple incomplete prompts. Use***instead. - Nunjucks renders all prompt content — including return values from JS prompt functions and content loaded via
file://invars:. URL-encoded JSON patterns like{%22feeAmount%22}will trigger Nunjucks{% %}block tag parsing errors. - Use
{% raw %}...{% endraw %}to protect content containing{%patterns. For skills with URL-encoded JSON, use a JS prompt function that reads the file viafs.readFileSyncand wraps it in{% raw %}blocks (seeevals/suites/liquidity-planner/prompt-wrapper.js).
CRITICAL: This project requires npm >=11.7.0
npm install -g npm@latest
npm --version # Should output: 11.7.0 or higherAlways pin external actions to specific commit hashes with version comments:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0Never use ${{ }} expressions directly in bash scripts. Use environment variables instead:
- name: Process input
env:
INPUT_VALUE: ${{ github.event.inputs.value }}
run: |
echo "Processing: $INPUT_VALUE"Every job running on non-macOS runners MUST have bullfrogsec/bullfrog as the FIRST step.
When modifying plugins or skills, update the corresponding VitePress documentation pages:
- Plugin added/modified: Update or create
docs/plugins/{plugin-name}.md - Skill added/modified: Update or create
docs/skills/{skill-name}.md - Plugin/skill added or removed: Update index pages:
docs/plugins/index.md- table of all pluginsdocs/skills/index.md- table of all skills grouped by plugindocs/index.md- featured skills section (if applicable)
Run node scripts/validate-docs.cjs to verify all documentation pages exist. This check is enforced in CI.
After changes to files in this repository, update the relevant CLAUDE.md file to reflect the changes.
Check all README.md files in directories with changes and update if appropriate.
Skills are discoverable via the skills.sh CLI (npx skills add Uniswap/uniswap-ai).
- Create the skill directory in
packages/plugins/<plugin-name>/skills/<skill-name>/ - Add a
SKILL.mdfile with required frontmatter (name,description,license,metadata.author) - Add the skill to the plugin's
plugin.jsonskillsarray - Create a documentation page at
docs/skills/<skill-name>.md - Update
docs/skills/index.mdto include the new skill - CI
validate-skillsandvalidate-docsjobs will verify consistency
Merging to main = publishing to skills.sh. The CLI fetches directly from the repo's default branch. No separate publish step is required.
The validate-skills job in PR checks enforces:
- Required frontmatter fields (
name,description,license,metadata.author) - Name consistency (frontmatter name matches directory name)
- Consistency between
plugin.jsonskills array and skill directories - Prerequisite existence (referenced skills exist across plugins)
- When running tasks, always prefer running through
nx(i.e.,nx run,nx run-many,nx affected) - Use
nx_workspacetool to understand workspace architecture - Use
nx_project_detailsto analyze specific project structure - Use
nx_docsfor configuration questions and best practices