Thanks for your interest in OmniCommand! This document covers everything you need to contribute.
- Node.js ≥ 20.3.0 (use
nvm install 22 && nvm use 22) - Git
git clone https://github.com/Rishet11/OmniCommand.git
cd OmniCommand/cli
npm install
npm run build
node dist/index.js doctorThe doctor command will tell you which optional dependencies are missing. Pandoc is optional for non-PDF document conversion; Gemini OCR and MCP SDK support are optional/lazy-loaded.
cd cli
# Run once
npm test
# Watch mode (re-runs on file change)
npm run test:watchAll tests should pass. If any fail before your change, that's a bug — please open an issue.
OmniCommand/
├── cli/ # npm package (omx-cmd)
│ ├── src/
│ │ ├── index.ts # CLI entry point (Commander.js commands)
│ │ ├── lib.ts # Public TypeScript exports
│ │ ├── types.ts # Shared engine and batch interfaces
│ │ ├── mcp.ts # MCP server for agentic integration
│ │ ├── engines/
│ │ │ ├── image.ts # Sharp image processing
│ │ │ ├── video.ts # FFmpeg video/audio
│ │ │ └── document.ts # PDF + Pandoc + Gemini
│ │ ├── utils/
│ │ │ └── config.ts # ~/.config/omx/config.json storage
│ │ └── __tests__/ # Vitest test suite
│ └── package.json
└── src/ # Landing page (React/Vite)
- Create a branch:
git checkout -b feat/my-feature - Make changes in
cli/src/ - Build:
npm run build(runs TypeScript compiler) - Test:
npm test - Submit a PR — include a description of what changed and why
- TypeScript strict mode (
"strict": true) — no type suppressions without justification - ESM (
"type": "module") — useimport/export, notrequire() - No
anywithout comment — prefer typed interfaces - Error messages must be actionable — include both "what went wrong" and "what to do next"
// Bad
throw new Error('Something went wrong');
// Good
throw new Error(
`PDF conversion to ${format} requires Pandoc.\n` +
`Install it: brew install pandoc (macOS) | apt install pandoc (Linux)`
);The CLI follows a strict exit code contract. Do not break these:
| Code | Meaning |
|---|---|
0 |
Success |
1 |
Runtime error (file corrupt, dependency missing, network failure) |
2 |
User input error (bad syntax, missing argument, unsupported format) |
- Create
cli/src/engines/myformat.ts - Export a
processMyFormat(inputFile, targetFormat, options)function - Route it in
executeEngine()incli/src/index.ts - Add file extensions to the relevant ext list (
imageExts,videoExts,documentExts) - Write at least 3 tests in
cli/src/__tests__/myformat.test.ts
Open an issue at github.com/Rishet11/OmniCommand/issues.
Include:
- OS and Node.js version (
node --version) - Exact command that failed
- Full error output (run without
--quiet) - Input file format and approximate size