AI-driven ROS1 to ROS2 migration CLI tool.
ROS1 reached end-of-life in May 2025. Migrating a production codebase to ROS2 by hand is tedious and error-prone: API namespaces changed, CMakeLists.txt rules are different, launch files moved from XML to Python, and hundreds of ros:: calls need one-by-one replacement.
ROSForge automates this work by combining a static knowledge base of known API mappings with an AI backend that handles the cases rules alone cannot cover. The result is a complete, confidence-scored migration in minutes rather than days.
- Full pipeline — analyze, transform, validate, and report in a single command
- BYOM (Bring Your Own Model) — Claude, Gemini, and OpenAI backends; CLI or API mode
- Auto-fix loop — runs
colcon build, feeds errors back to the AI, retries up to N times - Interactive mode — per-file diff review; accept or skip each transformed file
- Batch workspace migration — migrate an entire catkin workspace in one pass
- Custom transformation rules — override or extend mappings with a YAML file
- Static knowledge base — built-in C++/Python API mappings, CMake rules, and launch conversion patterns
- Cost estimation — token and USD estimates shown before any API calls are made
- Confidence scoring — every output file is rated HIGH / MEDIUM / LOW; low-confidence files are flagged for manual review
- CI/CD templates — ready-made GitHub Actions and GitLab CI integration
- Python 3.10+
- pip (or uv)
- One of the following AI backends:
- Claude CLI or an Anthropic API key
- Gemini CLI or a Google API key
- An OpenAI API key
- (Optional)
colcon— required only if you use the auto-fix loop (--max-fix-attempts)
# 1. Install
pip install rosforge
# 2. Configure your AI backend
rosforge config set engine.name claude
rosforge config set engine.mode cli
# 3. Analyze a package first (no code changes, no AI calls)
rosforge analyze ./my_ros1_package
# 4. Run the migration
rosforge migrate ./my_ros1_package -o ./my_ros1_package_ros2Expected output:
╭─ ROSForge ─────────────────────────────────────╮
│ AI-driven ROS1 → ROS2 Migration │
╰─────────────────────────────────────────────────╯
Engine: claude-cli
Source: /home/user/catkin_ws/src/my_ros1_package
Output: /home/user/catkin_ws/src/my_ros1_package_ros2
Target distro: humble
[1/6] Ingest .............. done
[2/6] Analyze ............. done
[3/6] Transform ........... done
[4/6] Report .............. done
Migration complete. Report: /home/user/.../migration_report.md
Files transformed: 12 (8 rule-based, 4 AI-driven)
Average confidence: 87%
Confidence breakdown: 9 HIGH, 2 MEDIUM, 1 LOW
Low-confidence files (manual review recommended):
• src/legacy_driver.cpp
The migrated package and a migration_report.md are written to the output directory.
ROSForge runs a multi-stage pipeline on your ROS1 package:
graph LR
A[Ingest] --> B[Analyze]
B --> C[Transform]
C --> D{Interactive?}
D -->|Yes| E[Review]
D -->|No| F{Auto-fix?}
E --> F
F -->|Yes| G[Validate + Fix Loop]
F -->|No| H[Report]
G --> H
- Ingest — parses
package.xml,CMakeLists.txt, C++/Python sources, launch files, and msg/srv/action definitions - Analyze — resolves dependencies, scores risk, estimates cost, and decides per-file strategy (rule-based vs. AI-driven)
- Transform — applies static knowledge base mappings first, then sends remaining files to the AI engine
- Review (optional,
--interactive) — shows a diff for each file; pressato accept,sto skip,qto quit - Validate (optional,
--max-fix-attempts N) — runscolcon build; if it fails, feeds errors to the AI for auto-fix, up to N retries - Report — generates
migration_report.mdwith a full changelog, warnings, and manual intervention suggestions
| Command | Description |
|---|---|
rosforge migrate <path> |
Migrate a single ROS1 package to ROS2 |
rosforge migrate-workspace <path> |
Migrate all packages in a catkin workspace |
rosforge analyze <path> |
Analyze and report migration complexity (no code changes) |
rosforge config set <key> <value> |
Set a configuration value |
rosforge config get <key> |
Get a single configuration value |
rosforge config list |
Print all current settings as JSON |
rosforge config reset |
Reset configuration to defaults |
rosforge config path |
Show the config file path |
rosforge status |
Show the status of a completed migration |
Configuration is stored at ~/.rosforge/config.toml.
ROSForge supports three AI backends. Each can run in CLI mode (calls a locally installed CLI tool, no API key required) or API mode (calls the provider's REST API, requires an API key).
# CLI mode — requires Claude CLI installed and authenticated
rosforge config set engine.name claude
rosforge config set engine.mode cli
# API mode — requires ANTHROPIC_API_KEY
pip install "rosforge[claude]"
rosforge config set engine.name claude
rosforge config set engine.mode api
export ANTHROPIC_API_KEY=sk-ant-...# CLI mode — requires Gemini CLI installed and authenticated
rosforge config set engine.name gemini
rosforge config set engine.mode cli
# API mode — requires GOOGLE_API_KEY
pip install "rosforge[gemini]"
rosforge config set engine.name gemini
rosforge config set engine.mode api
export GOOGLE_API_KEY=AIza...# API mode — requires OPENAI_API_KEY
pip install "rosforge[openai]"
rosforge config set engine.name openai
rosforge config set engine.mode api
export OPENAI_API_KEY=sk-...Install all backends at once:
pip install "rosforge[all]"Review each transformed file before it is written:
rosforge migrate ./my_package --interactivePress a to accept, s to skip, q to quit and accept all remaining files.
Build the output with colcon build after migration, feed any errors back to the AI, and retry:
rosforge migrate ./my_package --max-fix-attempts 3Supply additional or overriding transformation mappings via a YAML file:
rosforge migrate ./my_package --rules custom_rules.yamlExample custom_rules.yaml
# custom_rules.yaml
version: 1
api_mappings:
cpp:
"ros::NodeHandle": "rclcpp::Node"
"ros::Publisher": "rclcpp::Publisher"
python:
"rospy.init_node": "rclpy.init"
"rospy.Publisher": "rclpy.create_publisher"
package_mappings:
"roscpp": "rclcpp"
"rospy": "rclpy"
cmake_mappings:
"find_package(catkin REQUIRED": "find_package(ament_cmake REQUIRED"Custom mappings take precedence over the built-in knowledge base. See the version: 1 schema for supported keys: api_mappings.cpp, api_mappings.python, package_mappings, cmake_mappings.
Skip the cost-estimate confirmation prompt (useful in CI or scripted runs):
rosforge migrate ./my_package --yesThe default target is humble. To target a different distribution:
rosforge migrate ./my_package --distro jazzyMigrate all packages in a catkin workspace at once:
rosforge migrate-workspace ./catkin_ws -o ./ros2_ws --engine gemini --yes# Rich table output in the terminal
rosforge analyze ./my_package
# Machine-readable JSON (ideal for CI)
rosforge analyze ./my_package --json
# Save JSON report to file
rosforge analyze ./my_package -o analysis.jsonROSForge provides ready-made templates for GitHub Actions and GitLab CI so you can automatically verify ROS1→ROS2 migration in your pipeline.
Use the reusable composite action:
# .github/workflows/rosforge.yml
name: ROSForge Migration Check
on: [push, pull_request]
jobs:
analyze:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: Rlin1027/ROSForge/ci-templates/github@main
with:
source: ./src/my_ros1_package
mode: analyze # "analyze" or "migrate"For a full migration dry-run with auto-fix:
- uses: Rlin1027/ROSForge/ci-templates/github@main
with:
source: ./src/my_ros1_package
mode: migrate
engine: claude
engine-mode: api
max-fix-attempts: "2"
fail-on-warnings: "true"
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}See ci-templates/github/example-workflow.yml for a complete example.
Include the remote template and extend the hidden jobs:
# .gitlab-ci.yml
include:
- remote: "https://raw.githubusercontent.com/Rlin1027/ROSForge/main/ci-templates/gitlab/.gitlab-ci-rosforge.yml"
variables:
ROSFORGE_SOURCE: ./src/my_ros1_package
ROSFORGE_ENGINE: claude
ROSFORGE_TARGET_DISTRO: humble
rosforge-analyze:
extends: .rosforge-analyze
rosforge-migrate:
extends: .rosforge-migrate
variables:
ROSFORGE_ENGINE_MODE: api
ROSFORGE_MAX_FIX_ATTEMPTS: "2"| Code | Meaning |
|---|---|
| 0 | Success |
| 1 | Failure |
| 2 | Completed with warnings (set fail-on-warnings to treat as failure) |
Make sure the engine CLI is installed and on your PATH:
# For Claude
claude --version
# For Gemini
gemini --versionIf using API mode, verify the API key is set:
echo $ANTHROPIC_API_KEY # Should not be emptyLarge packages may exceed the default 300-second timeout. Set a longer timeout in the config:
rosforge config set engine.timeout_seconds 600The auto-fix loop requires colcon to be installed and on your PATH. On Ubuntu:
sudo apt install python3-colcon-common-extensionsThis usually means the AI engine returned unexpected output. Try:
- Run with
--verboseto see the raw AI response - Switch to a different engine (some models are more reliable for structured output)
- Retry — AI responses can vary between runs
ROSForge stores its configuration at ~/.rosforge/config.toml. To find or reset it:
rosforge config path # Show the file path
rosforge config reset # Reset to defaults# Clone and install in development mode
git clone https://github.com/Rlin1027/ROSForge.git
cd ROSForge
pip install -e ".[dev,all]"
# Run the test suite (700+ tests)
pytest tests/
# Lint and type-check
ruff check src/
ruff format --check src/
mypy src/src/rosforge/
cli/ # Typer CLI commands (migrate, analyze, config, status)
config/ # ConfigManager — loads/saves ~/.rosforge/config.toml
engine/ # BYOM engine backends (claude, gemini, openai × cli, api)
knowledge/ # Static API mapping tables + custom rules loader
models/ # Pydantic data models (config, result, report, source)
parsers/ # File parsers (Python, C++, CMake, launch XML, msg/srv)
pipeline/ # Pipeline stages (ingest, analyze, transform, review, validate, fix, report)
templates/ # Jinja2 report templates
utils/ # Subprocess helpers, JSON extraction
tests/
unit/ # Unit tests for individual modules
integration/ # Integration tests for cross-module workflows
e2e/ # End-to-end CLI tests
fixtures/ # Sample ROS1 packages for testing
- R-01~R-05: Core migration pipeline (v0.1.0)
- R-06: Auto build verification & fix loop (v0.2.0)
- R-07: Interactive migration mode (v0.2.0)
- R-08: Batch workspace migration (v0.2.0)
- R-09: Custom transformation rules (v0.2.0)
- R-12: CI/CD integration templates (v0.2.0)
- R-10: Plugin API — community-contributed domain-specific strategies
- R-11: Web Dashboard — visual migration progress and diff viewer
Contributions are welcome! Please open an issue before submitting a pull request for significant changes. See CONTRIBUTING.md for guidelines.
Apache 2.0 — see LICENSE for details.