Thanks for your interest in contributing! Clodds is open-source and welcomes contributions.
- Fork the repository
- Clone your fork:
git clone https://github.com/YOUR_USERNAME/clodds cd clodds - Install dependencies:
npm install
- Create a branch:
git checkout -b feature/my-feature
# Run in dev mode (hot reload)
npm run dev
# Type check
npm run typecheck
# Build
npm run buildsrc/
├── index.ts # Entry point
├── types.ts # TypeScript types
├── gateway/ # WebSocket server
├── channels/ # Telegram, Discord adapters
├── feeds/ # Market data (Polymarket, Kalshi, etc.)
├── agents/ # Claude AI integration
├── skills/ # Agent skills (SKILL.md)
├── sessions/ # Per-user state
├── cron/ # Scheduled tasks
├── db/ # SQLite persistence
└── cli/ # CLI commands
- Create
src/feeds/your-platform/index.ts - Implement the feed interface:
export interface YourPlatformFeed extends EventEmitter { start(): Promise<void>; stop(): void; searchMarkets(query: string): Promise<Market[]>; getMarket(id: string): Promise<Market | null>; }
- Register in
src/feeds/index.ts - Add to types in
src/types.ts
- Create
src/channels/your-channel/index.ts - Implement message handling and sending
- Register in
src/channels/index.ts
- Create
src/skills/bundled/your-skill/index.tswith a default export:export default { name: 'your-skill', description: 'What this skill does', commands: ['/your-skill'], // Optional: declare env vars needed before handler runs requires: { env: ['API_KEY'] }, handle: async (args: string): Promise<string> => { // ... }, };
- Add the directory name to
SKILL_MANIFESTinsrc/skills/executor.ts(alphabetical order) - Add the skill name to
COMMAND_CATEGORIESinsrc/commands/registry.tswith its category (e.g.'your-skill': 'Tools') - Run
npm run typecheckto verify
Skills are lazy-loaded via await import() on first use. Each skill loads in its own try/catch, so a missing dependency only disables that one skill. If requires.env is set, the executor checks those vars before calling the handler and returns a clear message if any are missing.
To also give the AI agent context about your skill, create src/skills/bundled/your-skill/SKILL.md with YAML frontmatter:
---
name: your-skill
description: "What this skill does"
---
# Your Skill
Instructions for the AI...- Keep changes focused and atomic
- Update types when needed
- Add comments for complex logic
- Test manually before submitting
- Describe what changed and why
- Use TypeScript strict mode
- Prefer
async/awaitover callbacks - Use descriptive variable names
- Keep functions small and focused
When contributing code that involves command execution:
-
Never use string interpolation with
execSync():// BAD - vulnerable to command injection execSync(`which ${cmd}`); // GOOD - safe with array arguments execFileSync('which', [cmd]);
-
Use
execFileSyncwith array arguments for all shell commands -
Validate and sanitize user-provided paths and inputs
-
Report vulnerabilities via GitHub Security Advisories, not public issues
-
Run security checks before submitting:
npm audit npm run typecheck
See docs/SECURITY_AUDIT.md for our security practices.
Please include:
- Node.js version
- Steps to reproduce
- Expected vs actual behavior
- Error messages/logs
Open an issue, join our Discord, or visit the Agent Forum where AI agents discuss strategies and features.
By contributing, you agree that your contributions will be licensed under MIT.