Thank you for your interest in contributing to ADO (Agentic Development Orchestrator)! This document provides guidelines and instructions for contributing.
- Code of Conduct
- Getting Started
- Development Setup
- Project Structure
- Coding Standards
- Testing
- Submitting Changes
- Documentation
- Release Process
This project adheres to the Code of Conduct. By participating, you are expected to uphold this code.
- Node.js 22+
- pnpm 9+ (required, not npm or yarn)
- Git
- Familiarity with TypeScript, Node.js, and CLI development
- Browse open issues
- Look for issues labeled
good first issueorhelp wanted - Comment on the issue to claim it
- Wait for maintainer approval before starting work
- GitHub Discussions for questions
- Discord Server for real-time chat
- Tag maintainers in issues for clarification
# Fork the repository on GitHub, then:
git clone https://github.com/YOUR_USERNAME/ado.git
cd ado
# Add upstream remote
git remote add upstream https://github.com/dxheroes/ado.git# Install pnpm if not already installed
npm install -g pnpm
# Install project dependencies
pnpm install# Build all packages
pnpm build
# Build in watch mode during development
pnpm dev# Run all tests
pnpm test
# Run tests in watch mode
pnpm test:watch
# Run tests with coverage
pnpm test:coverage# Type check
pnpm typecheck
# Lint
pnpm lint
# Format code
pnpm formatADO is a pnpm monorepo with 7 packages:
ado/
├── packages/
│ ├── core/ # Orchestration engine (~21K LoC)
│ ├── cli/ # CLI application
│ ├── adapters/ # Agent adapters (Claude, Gemini, etc.)
│ ├── shared/ # Shared types and utilities
│ ├── dashboard/ # React web dashboard
│ ├── api/ # tRPC API server
│ └── mcp-server/ # MCP server
├── deploy/ # K8s manifests, Helm charts
├── spec/ # Technical specification (67 docs)
├── docs/ # User documentation
├── .github/ # GitHub workflows, templates
└── [config files]
shared ← core ← cli
shared ← adapters ← cli
shared ← api
shared ← dashboard
shared ← mcp-server
Rule: Never create circular dependencies between packages.
- Strict mode enabled (
exactOptionalPropertyTypes: true) - No
anytypes unless absolutely necessary - Explicit types for function parameters and return values
- Use
| undefinedfor optional properties (not just?)
// ❌ Wrong
interface Config {
timeout?: number; // Implicit undefined
}
// ✅ Correct
interface Config {
timeout: number | undefined; // Explicit undefined
}We use Biome for linting and formatting (not ESLint or Prettier).
# Lint code
pnpm lint
# Fix linting issues
pnpm lint:fix
# Format code
pnpm formatConfiguration: biome.json
- Files:
kebab-case.ts - Functions:
camelCase() - Classes:
PascalCase - Constants:
SCREAMING_SNAKE_CASE - Unused parameters: Prefix with
_(e.g.,_unusedParam)
- Use
.jsextensions for relative imports (required for ESM) - Never use barrel exports that could cause circular dependencies
- Group imports: external → internal → relative
// External dependencies
import { z } from "zod";
import type { Express } from "express";
// Internal packages
import { type Task } from "@dxheroes/ado-shared";
// Relative imports (with .js extension)
import { executeTask } from "./executor.js";
import type { Config } from "../types.js";- Use
Result<T, E>types or explicit error returns - Never throw errors in async functions without try/catch
- Provide meaningful error messages with context
// ✅ Good
async function loadConfig(): Promise<Result<Config, ConfigError>> {
try {
const data = await fs.readFile("config.yaml", "utf-8");
const config = parseYaml(data);
return { success: true, value: config };
} catch (error) {
return {
success: false,
error: new ConfigError("Failed to load config", { cause: error }),
};
}
}
// ❌ Bad
async function loadConfig(): Promise<Config> {
const data = await fs.readFile("config.yaml", "utf-8"); // Can throw!
return parseYaml(data);
}- JSDoc for all public APIs
- Code comments for complex logic only
- README.md in each package
/**
* Executes a task using the specified provider.
*
* @param task - Task to execute
* @param provider - Provider adapter to use
* @returns Task execution result with status and output
*
* @example
* ```typescript
* const result = await executeTask(task, claudeAdapter);
* if (result.status === "completed") {
* console.log(result.output);
* }
* ```
*/
export async function executeTask(
task: Task,
provider: AgentAdapter,
): Promise<TaskResult> {
// Implementation
}We use Vitest for all tests.
packages/core/src/
├── provider/
│ ├── registry.ts
│ └── __tests__/
│ ├── registry.test.ts
│ └── router.test.ts
import { describe, it, expect, beforeEach } from "vitest";
import { ProviderRegistry } from "../registry.js";
describe("ProviderRegistry", () => {
let registry: ProviderRegistry;
beforeEach(() => {
registry = new ProviderRegistry();
});
it("should register a provider", () => {
registry.register({
id: "claude-code",
adapter: claudeAdapter,
});
expect(registry.has("claude-code")).toBe(true);
});
it("should throw error for duplicate provider", () => {
registry.register({ id: "claude-code", adapter: claudeAdapter });
expect(() => {
registry.register({ id: "claude-code", adapter: anotherAdapter });
}).toThrow("Provider already registered: claude-code");
});
});- Minimum coverage: 80% for new code
- Focus areas: Core business logic, API endpoints, adapters
- Integration tests: For complex workflows
# Run tests with coverage
pnpm test:coverage
# View coverage report
open coverage/index.html# Update main
git checkout main
git pull upstream main
# Create feature branch
git checkout -b feature/your-feature-name
# Or for bug fixes
git checkout -b fix/issue-123- Write code following coding standards
- Add tests for new functionality
- Update documentation as needed
- Run
pnpm buildto verify no type errors
We use Conventional Commits:
# Format: <type>(<scope>): <description>
#
# Types: feat, fix, docs, style, refactor, test, chore
# Scope: package name (core, cli, adapters, etc.)
git commit -m "feat(core): add support for custom provider adapters"
git commit -m "fix(cli): resolve config validation error"
git commit -m "docs(adapters): add Gemini CLI setup guide"# Push to your fork
git push origin feature/your-feature-name
# Create Pull Request on GitHub
# Fill out the PR template completely- All tests pass (
pnpm test) - No type errors (
pnpm typecheck) - No linting errors (
pnpm lint) - Code coverage ≥80% for new code
- Documentation updated
- Conventional commit messages
- PR description explains changes and motivation
- Related issues linked (e.g., "Closes #123")
- Respond to review comments promptly
- Make requested changes in new commits (don't force push)
- Mark conversations as resolved after addressing
- Request re-review when ready
Once approved:
- Maintainer will squash and merge your PR
- Your contribution will be included in the next release
- You'll be added to contributors list
Located in /docs:
- Installation:
docs/installation.md - Configuration:
docs/configuration.md - Troubleshooting:
docs/TROUBLESHOOTING.md
Located in /spec:
- Architecture:
spec/03-architecture/ - API Reference:
spec/05-api/ - Design Docs:
spec/04-design/
Each package has a README.md with:
- Package purpose and features
- Installation instructions
- API reference
- Usage examples
- Use Markdown for all documentation
- Include code examples for complex features
- Keep line length ≤100 characters
- Use relative links for cross-references
- Test all code examples
Releases are managed by maintainers using Changesets.
When making a significant change, create a changeset:
# Create changeset
pnpm changeset
# Select packages affected
# Choose version bump type (major, minor, patch)
# Write changelog entryThis creates .changeset/random-name.md:
---
"@dxheroes/ado-core": minor
"@dxheroes/ado-cli": minor
---
Add support for custom provider adapters. Users can now create their own adapters by implementing the AgentAdapter interface.Maintainers will:
# Update versions
pnpm changeset version
# Commit
git commit -am "chore: version packages"
# Publish
pnpm changeset publish# 1. Start fresh
git checkout main
git pull upstream main
# 2. Create branch
git checkout -b feature/my-feature
# 3. Develop in watch mode
pnpm dev
# 4. Run tests
pnpm test:watch
# 5. Commit and push
git add .
git commit -m "feat(core): add feature X"
git push origin feature/my-feature
# 6. Create PR# Build specific package
pnpm --filter @dxheroes/ado-core build
# Run tests for specific package
pnpm --filter @dxheroes/ado-cli test
# Dev mode for specific package
pnpm --filter @dxheroes/ado-core dev# Debug CLI
node --inspect-brk packages/cli/dist/index.js run "test"
# Debug tests
pnpm test --inspect-brk --no-coverage
# Enable debug logs
DEBUG=ado:* pnpm dev- GitHub Discussions
- Discord Server
- Tag
@dxheroes/maintainersin issues
- Check Development Setup
- Review Coding Standards
- Look at existing code for examples
- Ask in Discussions or Discord
Contributors are recognized in:
- README.md
- Release notes
- CHANGELOG.md
Thank you for contributing to ADO! 🎉