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 - Run
npx tsc --noEmitto 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 or join our Discord.
By contributing, you agree that your contributions will be licensed under MIT.