Skip to content

Commit 697d22c

Browse files
Rlin1027claude
andcommitted
docs: rewrite README with Mermaid pipeline diagram, troubleshooting, and roadmap
Replace ASCII art flow chart with Mermaid graph LR for native GitHub rendering. Add Requirements, Troubleshooting, Project Structure, and Roadmap sections. Update CHANGELOG with R-12 and README rewrite entries. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 6550f7c commit 697d22c

2 files changed

Lines changed: 205 additions & 43 deletions

File tree

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1616
- Confidence scoring in CLI output
1717
- Pre-migration confirmation prompt (`--yes` to skip)
1818
- Bridge/fallback guidance for untranslatable packages
19+
- CI/CD integration templates for GitHub Actions and GitLab CI (`ci-templates/`)
20+
- GitHub Actions CI pipeline (lint, type-check, test on Python 3.10–3.13)
21+
- Automated PyPI release via GitHub Release + trusted publishing
22+
- README rewrite with pipeline diagram, prerequisites, troubleshooting, and roadmap
1923

2024
### Changed
2125
- Updated CLI help text for analyze and status commands
2226
- Improved launch rule conversion for `<machine>` and `<test>` tags
2327
- Updated PromptBuilder to support custom rule merging
2428

29+
### Fixed
30+
- Release workflow missing `environment: pypi` for PyPI trusted publishing
31+
2532
## [0.1.0] - 2026-02-24
2633

2734
### Added

README.md

Lines changed: 198 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@
22

33
**AI-driven ROS1 to ROS2 migration CLI tool.**
44

5-
[![CI](https://img.shields.io/github/actions/workflow/status/Rlin1027/ROSForge/ci.yml?branch=main&label=CI)](https://github.com/Rlin1027/ROSForge/actions) [![PyPI](https://img.shields.io/pypi/v/rosforge)](https://pypi.org/project/rosforge/) [![License](https://img.shields.io/badge/license-Apache%202.0-blue)](LICENSE)
5+
[![CI](https://img.shields.io/github/actions/workflow/status/Rlin1027/ROSForge/ci.yml?branch=main&label=CI)](https://github.com/Rlin1027/ROSForge/actions) [![PyPI](https://img.shields.io/pypi/v/rosforge)](https://pypi.org/project/rosforge/) [![Python](https://img.shields.io/pypi/pyversions/rosforge)](https://pypi.org/project/rosforge/) [![License](https://img.shields.io/badge/license-Apache%202.0-blue)](LICENSE)
66

77
## Why ROSForge?
88

9-
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 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.
9+
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.
10+
11+
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.
1012

1113
## Features
1214

@@ -19,45 +21,110 @@ ROS1 reached end-of-life in May 2025. Migrating a production codebase to ROS2 by
1921
- **Static knowledge base** — built-in C++/Python API mappings, CMake rules, and launch conversion patterns
2022
- **Cost estimation** — token and USD estimates shown before any API calls are made
2123
- **Confidence scoring** — every output file is rated HIGH / MEDIUM / LOW; low-confidence files are flagged for manual review
24+
- **CI/CD templates** — ready-made GitHub Actions and GitLab CI integration
25+
26+
## Requirements
27+
28+
- **Python 3.10+**
29+
- **pip** (or [uv](https://docs.astral.sh/uv/))
30+
- One of the following AI backends:
31+
- [Claude CLI](https://docs.anthropic.com/en/docs/claude-code) or an Anthropic API key
32+
- [Gemini CLI](https://github.com/google-gemini/gemini-cli) or a Google API key
33+
- An OpenAI API key
34+
- (Optional) `colcon` — required only if you use the auto-fix loop (`--max-fix-attempts`)
2235

2336
## Quick Start
2437

2538
```bash
26-
# Install
39+
# 1. Install
2740
pip install rosforge
2841

29-
# Set your preferred AI backend (stored in ~/.config/rosforge/config.toml)
30-
rosforge config set engine.name gemini
42+
# 2. Configure your AI backend
43+
rosforge config set engine.name claude
3144
rosforge config set engine.mode cli
3245

33-
# Migrate a single ROS1 package
46+
# 3. Analyze a package first (no code changes, no AI calls)
47+
rosforge analyze ./my_ros1_package
48+
49+
# 4. Run the migration
3450
rosforge migrate ./my_ros1_package -o ./my_ros1_package_ros2
3551
```
3652

53+
**Expected output:**
54+
55+
```
56+
╭─ ROSForge ─────────────────────────────────────╮
57+
│ AI-driven ROS1 → ROS2 Migration │
58+
╰─────────────────────────────────────────────────╯
59+
Engine: claude-cli
60+
Source: /home/user/catkin_ws/src/my_ros1_package
61+
Output: /home/user/catkin_ws/src/my_ros1_package_ros2
62+
Target distro: humble
63+
64+
[1/6] Ingest .............. done
65+
[2/6] Analyze ............. done
66+
[3/6] Transform ........... done
67+
[4/6] Report .............. done
68+
69+
Migration complete. Report: /home/user/.../migration_report.md
70+
Files transformed: 12 (8 rule-based, 4 AI-driven)
71+
Average confidence: 87%
72+
Confidence breakdown: 9 HIGH, 2 MEDIUM, 1 LOW
73+
74+
Low-confidence files (manual review recommended):
75+
• src/legacy_driver.cpp
76+
```
77+
3778
The migrated package and a `migration_report.md` are written to the output directory.
3879

80+
## How It Works
81+
82+
ROSForge runs a multi-stage pipeline on your ROS1 package:
83+
84+
```mermaid
85+
graph LR
86+
A[Ingest] --> B[Analyze]
87+
B --> C[Transform]
88+
C --> D{Interactive?}
89+
D -->|Yes| E[Review]
90+
D -->|No| F{Auto-fix?}
91+
E --> F
92+
F -->|Yes| G[Validate + Fix Loop]
93+
F -->|No| H[Report]
94+
G --> H
95+
```
96+
97+
1. **Ingest** — parses `package.xml`, `CMakeLists.txt`, C++/Python sources, launch files, and msg/srv/action definitions
98+
2. **Analyze** — resolves dependencies, scores risk, estimates cost, and decides per-file strategy (rule-based vs. AI-driven)
99+
3. **Transform** — applies static knowledge base mappings first, then sends remaining files to the AI engine
100+
4. **Review** *(optional, `--interactive`)* — shows a diff for each file; press `a` to accept, `s` to skip, `q` to quit
101+
5. **Validate** *(optional, `--max-fix-attempts N`)* — runs `colcon build`; if it fails, feeds errors to the AI for auto-fix, up to N retries
102+
6. **Report** — generates `migration_report.md` with a full changelog, warnings, and manual intervention suggestions
103+
39104
## Commands
40105

41106
| Command | Description |
42107
|---|---|
43108
| `rosforge migrate <path>` | Migrate a single ROS1 package to ROS2 |
44109
| `rosforge migrate-workspace <path>` | Migrate all packages in a catkin workspace |
45-
| `rosforge analyze <path>` | Analyze a package and report migration complexity without transforming |
46-
| `rosforge config set <key> <value>` | Set a configuration value and persist it |
110+
| `rosforge analyze <path>` | Analyze and report migration complexity (no code changes) |
111+
| `rosforge config set <key> <value>` | Set a configuration value |
47112
| `rosforge config get <key>` | Get a single configuration value |
48-
| `rosforge config list` | Print all current configuration values as JSON |
113+
| `rosforge config list` | Print all current settings as JSON |
49114
| `rosforge config reset` | Reset configuration to defaults |
50-
| `rosforge config path` | Show the path to the configuration file |
51-
| `rosforge status` | Show the status of an in-progress or completed migration |
115+
| `rosforge config path` | Show the config file path |
116+
| `rosforge status` | Show the status of a completed migration |
117+
118+
Configuration is stored at `~/.rosforge/config.toml`.
52119

53120
## AI Engine Configuration
54121

55-
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 directly, requires an API key).
122+
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).
56123

57-
### Claude
124+
### Claude (Anthropic)
58125

59126
```bash
60-
# CLI mode — requires the Anthropic Claude CLI installed and authenticated
127+
# CLI mode — requires Claude CLI installed and authenticated
61128
rosforge config set engine.name claude
62129
rosforge config set engine.mode cli
63130

@@ -68,10 +135,10 @@ rosforge config set engine.mode api
68135
export ANTHROPIC_API_KEY=sk-ant-...
69136
```
70137

71-
### Gemini
138+
### Gemini (Google)
72139

73140
```bash
74-
# CLI mode — requires the Google Gemini CLI installed and authenticated
141+
# CLI mode — requires Gemini CLI installed and authenticated
75142
rosforge config set engine.name gemini
76143
rosforge config set engine.mode cli
77144

@@ -118,17 +185,44 @@ Build the output with `colcon build` after migration, feed any errors back to th
118185
rosforge migrate ./my_package --max-fix-attempts 3
119186
```
120187

121-
### Custom rules
188+
### Custom transformation rules
122189

123-
Supply additional or overriding transformation mappings:
190+
Supply additional or overriding transformation mappings via a YAML file:
124191

125192
```bash
126193
rosforge migrate ./my_package --rules custom_rules.yaml
127194
```
128195

196+
<details>
197+
<summary><strong>Example custom_rules.yaml</strong></summary>
198+
199+
```yaml
200+
# custom_rules.yaml
201+
version: 1
202+
203+
api_mappings:
204+
cpp:
205+
"ros::NodeHandle": "rclcpp::Node"
206+
"ros::Publisher": "rclcpp::Publisher"
207+
python:
208+
"rospy.init_node": "rclpy.init"
209+
"rospy.Publisher": "rclpy.create_publisher"
210+
211+
package_mappings:
212+
"roscpp": "rclcpp"
213+
"rospy": "rclpy"
214+
215+
cmake_mappings:
216+
"find_package(catkin REQUIRED": "find_package(ament_cmake REQUIRED"
217+
```
218+
219+
</details>
220+
221+
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`.
222+
129223
### Skip confirmation
130224

131-
Skip the cost-estimate confirmation prompt (useful in CI):
225+
Skip the cost-estimate confirmation prompt (useful in CI or scripted runs):
132226

133227
```bash
134228
rosforge migrate ./my_package --yes
@@ -144,6 +238,8 @@ rosforge migrate ./my_package --distro jazzy
144238

145239
### Workspace migration
146240

241+
Migrate all packages in a catkin workspace at once:
242+
147243
```bash
148244
rosforge migrate-workspace ./catkin_ws -o ./ros2_ws --engine gemini --yes
149245
```
@@ -154,7 +250,7 @@ rosforge migrate-workspace ./catkin_ws -o ./ros2_ws --engine gemini --yes
154250
# Rich table output in the terminal
155251
rosforge analyze ./my_package
156252
157-
# Machine-readable JSON
253+
# Machine-readable JSON (ideal for CI)
158254
rosforge analyze ./my_package --json
159255
160256
# Save JSON report to file
@@ -234,51 +330,110 @@ rosforge-migrate:
234330
| 1 | Failure |
235331
| 2 | Completed with warnings (set `fail-on-warnings` to treat as failure) |
236332

237-
## Custom Rules
333+
## Troubleshooting
238334

239-
Create a YAML file to add or override transformation mappings:
335+
### "Engine not available" error
240336

241-
```yaml
242-
# custom_rules.yaml
243-
version: 1
337+
Make sure the engine CLI is installed and on your `PATH`:
244338

245-
api_mappings:
246-
cpp:
247-
"ros::NodeHandle": "rclcpp::Node"
248-
"ros::Publisher": "rclcpp::Publisher"
249-
python:
250-
"rospy.init_node": "rclpy.init"
251-
"rospy.Publisher": "rclpy.create_publisher"
339+
```bash
340+
# For Claude
341+
claude --version
252342
253-
package_mappings:
254-
"roscpp": "rclcpp"
255-
"rospy": "rclpy"
343+
# For Gemini
344+
gemini --version
345+
```
256346

257-
cmake_mappings:
258-
"find_package(catkin REQUIRED": "find_package(ament_cmake REQUIRED"
347+
If using API mode, verify the API key is set:
348+
349+
```bash
350+
echo $ANTHROPIC_API_KEY # Should not be empty
351+
```
352+
353+
### "Command timed out" during migration
354+
355+
Large packages may exceed the default 300-second timeout. Set a longer timeout in the config:
356+
357+
```bash
358+
rosforge config set engine.timeout_seconds 600
359+
```
360+
361+
### Auto-fix loop fails immediately
362+
363+
The auto-fix loop requires `colcon` to be installed and on your `PATH`. On Ubuntu:
364+
365+
```bash
366+
sudo apt install python3-colcon-common-extensions
259367
```
260368

261-
Pass the file with `--rules custom_rules.yaml`. Custom mappings take precedence over the built-in knowledge base.
369+
### "Could not parse JSON from stdout"
370+
371+
This usually means the AI engine returned unexpected output. Try:
372+
373+
1. Run with `--verbose` to see the raw AI response
374+
2. Switch to a different engine (some models are more reliable for structured output)
375+
3. Retry — AI responses can vary between runs
376+
377+
### Config file location
378+
379+
ROSForge stores its configuration at `~/.rosforge/config.toml`. To find or reset it:
380+
381+
```bash
382+
rosforge config path # Show the file path
383+
rosforge config reset # Reset to defaults
384+
```
262385

263386
## Development
264387

265388
```bash
389+
# Clone and install in development mode
266390
git clone https://github.com/Rlin1027/ROSForge.git
267391
cd ROSForge
268392
pip install -e ".[dev,all]"
269-
pytest tests/
270-
```
271393
272-
Lint and type-check:
394+
# Run the test suite (700+ tests)
395+
pytest tests/
273396
274-
```bash
397+
# Lint and type-check
275398
ruff check src/
399+
ruff format --check src/
276400
mypy src/
277401
```
278402

403+
### Project structure
404+
405+
```
406+
src/rosforge/
407+
cli/ # Typer CLI commands (migrate, analyze, config, status)
408+
config/ # ConfigManager — loads/saves ~/.rosforge/config.toml
409+
engine/ # BYOM engine backends (claude, gemini, openai × cli, api)
410+
knowledge/ # Static API mapping tables + custom rules loader
411+
models/ # Pydantic data models (config, result, report, source)
412+
parsers/ # File parsers (Python, C++, CMake, launch XML, msg/srv)
413+
pipeline/ # Pipeline stages (ingest, analyze, transform, review, validate, fix, report)
414+
templates/ # Jinja2 report templates
415+
utils/ # Subprocess helpers, JSON extraction
416+
tests/
417+
unit/ # Unit tests for individual modules
418+
integration/ # Integration tests for cross-module workflows
419+
e2e/ # End-to-end CLI tests
420+
fixtures/ # Sample ROS1 packages for testing
421+
```
422+
423+
## Roadmap
424+
425+
- [x] R-01~R-05: Core migration pipeline (v0.1.0)
426+
- [x] R-06: Auto build verification & fix loop (v0.2.0)
427+
- [x] R-07: Interactive migration mode (v0.2.0)
428+
- [x] R-08: Batch workspace migration (v0.2.0)
429+
- [x] R-09: Custom transformation rules (v0.2.0)
430+
- [x] R-12: CI/CD integration templates (v0.2.0)
431+
- [ ] R-10: Plugin API — community-contributed domain-specific strategies
432+
- [ ] R-11: Web Dashboard — visual migration progress and diff viewer
433+
279434
## Contributing
280435
281-
Contributions are welcome. Please open an issue before submitting a pull request for significant changes. See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
436+
Contributions are welcome! Please open an issue before submitting a pull request for significant changes. See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
282437
283438
## License
284439

0 commit comments

Comments
 (0)