Developing COSMOS
So you want to help develop COSMOS? All of our COSMOS Core code is on Github so the first thing to do is get an account. Next clone the COSMOS repository. We accept contributions from others as Pull Requests.
Development Tools
The OpenC3 team develops with the Visual Studio Code editor and we highly recommend it. We also utilize a number of extensions including openc3-vscode (search in the Markplace for 'OpenC3'), docker, kubernetes, gitlens, prettier, eslint, python, vetur, and ruby. We commit our openc3.code-workspace configuration for VSCode to help configure these plugins. You also need Docker Desktop which you should already have as it is a requirement to run COSMOS. You'll also need NodeJS and pnpm installed.
Building COSMOS
Note: We primarily develop COSMOS in MacOS so the commands here will reference bash scripts but the same files exist in Windows as batch scripts.
Build COSMOS using the openc3.sh script:
% ./openc3.sh build
This will pull all the COSMOS container dependencies and build our local containers. Note: This can take a long time especially for your first build!
Once the build completes you can see the built images with the following command:
% docker image ls | grep "openc3"
openc3inc/openc3-cosmos-init latest 4cac7a3ea9d3 29 hours ago 446MB
openc3inc/openc3-cosmos-script-runner-api latest 4aacbaf49f7a 29 hours ago 431MB
openc3inc/openc3-cosmos-cmd-tlm-api latest 9a8806bd4be3 3 days ago 432MB
openc3inc/openc3-operator latest 223e98129fe9 3 days ago 405MB
openc3inc/openc3-base latest 98df5c0378c2 3 days ago 405MB
openc3inc/openc3-redis latest 5a3003a49199 8 days ago 111MB
openc3inc/openc3-traefik latest ec13a8d16a2f 8 days ago 104MB
openc3inc/openc3-buckets latest 787f6e3fc0be 8 days ago 238MB
openc3inc/openc3-node latest b3ee86d3620a 8 days ago 372MB
openc3inc/openc3-ruby latest aa158bbb9539 8 days ago 326MB
If you're building in a offline environment or want to use a private Rubygems, NPM or APK server (e.g. Nexus), you can update the following environment variables: RUBYGEMS_URL, NPM_URL, APK_URL, and more in the .env file. Example values:
ALPINE_VERSION=3.22
ALPINE_BUILD=3
RUBYGEMS_URL=https://rubygems.org
NPM_URL=https://registry.npmjs.org
APK_URL=http://dl-cdn.alpinelinux.org
Running COSMOS
Running COSMOS in development mode enables localhost access to internal API ports as well as sets RAILS_ENV=development in the cmd-tlm-api and script-runner-api Rails servers. To run in development mode:
% ./openc3.sh run
You can now see the running containers (I removed CONTAINER ID, CREATED and STATUS to save space):
% docker ps
IMAGE COMMAND PORTS NAMES
openc3/openc3-cmd-tlm-api:latest "/sbin/tini -- rails…" 127.0.0.1:2901->2901/tcp cosmos-openc3-cmd-tlm-api-1
openc3/openc3-script-runner-api:latest "/sbin/tini -- rails…" 127.0.0.1:2902->2902/tcp cosmos-openc3-script-runner-api-1
openc3/openc3-traefik:latest "/entrypoint.sh trae…" 0.0.0.0:2900->80/tcp cosmos-openc3-traefik-1
openc3/openc3-operator:latest "/sbin/tini -- ruby …" cosmos-openc3-operator-1
openc3/openc3-buckets:latest "/usr/bin/docker-ent…" 127.0.0.1:9000->9000/tcp cosmos-openc3-buckets-1
openc3/openc3-redis:latest "docker-entrypoint.s…" 127.0.0.1:6379->6379/tcp cosmos-openc3-redis-1
If you go to localhost:2900 you should see COSMOS up and running!
Running a Frontend Application
So now that you have COSMOS up and running how do you develop an individual COSMOS application?
- Bootstrap the frontend with pnpm
openc3-init/plugins % pnpm install --frozen-lockfile --ignore-scripts
openc3-init/plugins % pnpm build:common
- Serve a local COSMOS application (CmdTlmServer, ScriptRunner, etc)
openc3-init % cd plugins/packages/openc3-tool-scriptrunner
openc3-tool-scriptrunner % pnpm serve
built in 128722ms
-
Set the single SPA override for the application
Visit localhost:2900 and Right-click 'Inspect'
In the console paste:
localStorage.setItem("devtools", true);
Refresh and you should see {...} in the bottom right
Click the Default button next to the application (@openc3/tool-scriptrunner)
Paste in the development path which is dependent on the port returned by the local pnpm serve and the tool name (scriptrunner)
http://localhost:2914/tools/scriptrunner/main.js
- Refresh the page and you should see your local copy of the application (Script Runner in this example). If you dynamically add code (like
console.log) the pnpm window should re-compile and the browser should refresh displaying your new code. It is highly recommended to get familiar with your browser's development tools if you plan to do frontend development.
Running a Backend Server
If the code you want to develop is the cmd-tlm-api or script-runner-api backend servers there are several steps to enable access to a development copy.
- Run a development version of traefik. COSMOS uses traefik to direct API requests to the correct locations.
% cd openc3-traefik
openc3-traefik % docker ps
# Look for the container with name including traefik
openc3-traefik % docker stop cosmos-openc3-traefik-1
openc3-traefik % docker build --build-arg TRAEFIK_CONFIG=traefik-dev.yaml -t openc3-traefik-dev .
openc3-traefik % docker run --network=openc3-cosmos-network -p 2900:2900 -it --rm openc3-traefik-dev
- Run a local copy of the cmd-tlm-api or script-runner-api
% cd openc3-cosmos-cmd-tlm-api
openc3-cosmos-cmd-tlm-api % docker ps
# Look for the container with name including cmd-tlm-api
openc3-cosmos-cmd-tlm-api % docker stop cosmos-openc3-cosmos-cmd-tlm-api-1
# Run the following on Windows:
openc3-cosmos-cmd-tlm-api> dev_server.bat
# In Linux, set all the environment variables in the .env file, but override REDIS to be local
openc3-cosmos-cmd-tlm-api % set -a; source ../.env; set +a
openc3-cosmos-cmd-tlm-api % export OPENC3_REDIS_HOSTNAME=127.0.0.1
openc3-cosmos-cmd-tlm-api % export OPENC3_REDIS_EPHEMERAL_HOSTNAME=127.0.0.1
openc3-cosmos-cmd-tlm-api % bundle install
openc3-cosmos-cmd-tlm-api % bundle exec rails s
- Once the
bundle exec rails scommand returns you should see API requests coming from interactions in the frontend code. If you add code (like Ruby debugging statements) to the cmd-tlm-api code you need to stop the server (CTRL-C) and restart it to see the effect.
Python Development
COSMOS uses Python for scripting and provides a Python library (openc3) that mirrors the Ruby API. The Python library uses modern tooling for fast, reliable dependency management and code quality.
Development Tools
- UV - Fast Python package manager (replaces pip/poetry)
- Ruff - Fast Python linter and formatter (replaces flake8/black/isort)
- Just - Command runner for development tasks
Installing Tools
macOS:
brew install uv ruff just
Linux/WSL:
# Install UV
curl -LsSf https://astral.sh/uv/install.sh | sh
# Install Ruff and Just (via cargo or package manager)
cargo install ruff just
Quick Start
- Install Python and dependencies:
cosmos/openc3/python % uv python install # Install Python from .python-version
cosmos/openc3/python % uv sync # Create venv and install dependencies
- View all available commands:
cosmos/openc3/python % just
Common Commands
# Code Quality
just format # Format all code with Ruff
just format-changed # Format only changed files (fast!)
just lint # Check code quality
just lint-changed # Lint only changed files (fast!)
just lint-fix # Auto-fix linting issues
just lint-stats # Show detailed linting statistics
# Testing
just test # Run all tests
just test-cov # Run tests with coverage
just test-cov-html # Generate HTML coverage report
just test-fast # Run fast tests only (skip slow tests)
just test-file test/path/to/test.py # Run specific test
# Pre-commit Check
just verify-changed # Quick check of only changed files (recommended!)
just verify # Full verification: format, lint, and test
just check # CI-friendly check without modifications
# Dependencies
just add package-name # Add a new dependency
just update # Update all dependencies
just deps # Show dependency tree
# Cleanup
just clean # Remove build artifacts and caches
Development Workflow
- Make your changes to the Python code
- Quick check before committing:
just verify-changed(fast!) - Or full verification:
just verify(formats, lints, tests everything) - Commit your changes
Tip: Use verify-changed for quick iterations - it only checks files you've modified!
Manual Commands
If you prefer not to use Just, you can run commands directly with UV:
# Setup
uv python install # Install Python from .python-version
uv sync # Create venv and install dependencies
# Run tests
uv run pytest
# Lint and format
uv run ruff check openc3
uv run ruff format openc3
# Run with coverage
uv run coverage run -m pytest
uv run coverage report