- Fork the repository on GitHub
- Clone your fork locally:
git clone https://github.com/<your_gh_username>/omni.git cd omni
- Add upstream remote:
git remote add upstream https://github.com/getomnico/omni.git
- Docker and Docker Compose (primary requirement — all services run in containers)
- Rust 1.75+ (install via rustup) — only needed for development outside containers
- Node.js 22+ — only needed for frontend development outside containers
- Python 3.12+ and uv — only needed for AI service development outside containers
-
Configure environment:
[ -f .env ] || cp .env.example .env keystore="${OMNI_DEV_KEYSTORE:-$HOME/.config/omni/dev-encryption.env}" mkdir -p "$(dirname "$keystore")" [ -f "$keystore" ] || { umask 077; printf 'ENCRYPTION_KEY=%s\nENCRYPTION_SALT=%s\n' "$(openssl rand -base64 48)" "$(openssl rand -hex 16)" > "$keystore"; } sed -i '/^ENCRYPTION_KEY=/d; /^ENCRYPTION_SALT=/d' .env cat "$keystore" >> .env
-
Start the development environment:
docker compose -f docker/docker-compose.yml -f docker/docker-compose.dev.yml --env-file .env up -d --build
-
Access the web UI at http://localhost:3000
omni-web(SvelteKit) andomni-ai(Python/FastAPI) hot-reload when you edit source files- To point the stack at another worktree, plain
up -dfrom there is enough; rebuild only services your branch changed (includemigratorif it adds migrations) - Rust services need to be rebuilt after changes:
docker compose -f docker/docker-compose.yml -f docker/docker-compose.dev.yml --env-file .env up -d --build searcher
If you prefer developing outside containers:
# Rust services
cargo build --workspace
# Frontend
cd web && npm install
# AI service
cd services/ai && uv syncomni/
├── services/
│ ├── searcher/ # Search engine (Rust)
│ ├── indexer/ # Document indexing (Rust)
│ ├── ai/ # LLM orchestration, agent (Python)
│ ├── connector-manager/ # Connector orchestration (Rust)
│ ├── sandbox/ # Code execution sandbox (Rust)
│ └── migrations/ # SQL migrations
├── connectors/ # One container per data source
│ ├── google/ # Google Drive & Gmail (Rust)
│ ├── slack/ # Slack (Rust)
│ ├── atlassian/ # Confluence & Jira (Rust)
│ └── ...
├── web/ # SvelteKit frontend
├── sdk/ # Connector SDKs (Python, TypeScript)
├── shared/ # Shared Rust libraries
└── docker/ # Compose files
Rust:
cargo test --workspace
# Specific service
cargo test -p indexer
# With logs
RUST_LOG=debug cargo test --workspacePython (AI service):
cd services/ai
uv run pytest- Prefer integration tests over unit tests. We use testcontainers to bring up real Postgres (ParadeDB) and Redis instances — the existing test harnesses in most services already do this.
- For Python connector tests, there's a testing harness at
sdk/python/omni_connector/testing. - Avoid unit tests just for coverage. If the behavior is better tested against a real database instance, do that instead.
- Create a feature branch:
git checkout -b feature/your-feature-name
- Make your changes and test against the local dev deployment
- Update your fork and push:
git fetch upstream git rebase upstream/main git push origin feature/your-feature-name
- Create a Pull Request on GitHub
If you're building a new connector, we have a Claude Code skill that covers the entire process — SDK usage, manifest structure, content storage, testing, frontend integration, Docker/Terraform setup, and more.
Just invoke /build-connector <service name> in Claude Code — e.g., /build-connector Asana. The skill is auto-discovered from .claude/skills/ in the repo.
- GitHub Issues: Bug reports and feature requests
- GitHub Discussions: Questions and ideas