This document guides the conversion of OpenCode (TypeScript/Bun) to Orbit (Rust).
Convert crates in this order (dependency-based):
| Phase | Crate | Depends On | TypeScript Source |
|---|---|---|---|
| 1 | orbit-core |
(none) | src/util/*, src/id/*, src/global/* |
| 2 | orbit-bus |
core | src/bus/* |
| 2 | orbit-storage |
core | src/storage/* |
| 3 | orbit-project |
core, storage | src/project/* |
| 4 | orbit-config |
core, storage, project | src/config/* |
| 5 | orbit-permission |
core, bus, config | src/permission/* |
| 5 | orbit-provider |
core, bus, config | src/provider/* |
| 6 | orbit-lsp |
core, project, bus, config | src/lsp/* |
| 6 | orbit-mcp |
core, bus, config | src/mcp/* |
| 7 | orbit-session |
core, storage, bus, project, provider, permission, config | src/session/* |
| 7 | orbit-tools |
core, session, project, permission, bus, config | src/tool/* |
| 8 | orbit-server |
(all crates) | src/server/* |
Rule: Never start a crate until all its dependencies are 100% complete.
At the start of each crate, create a CONVERSION.md that maps all TypeScript files to Rust modules.
Work through each module in the CONVERSION.md, converting from simplest to most complex.
cargo build -p <crate-name>
cargo test -p <crate-name>
cargo clippy -p <crate-name>Update CONVERSION.md status and move to next crate.
Use this prompt when starting a NEW crate:
I am converting OpenCode (TypeScript) to Orbit (Rust).
Create a CONVERSION.md file for `crates/orbit-bus/` that:
1. Lists ALL Rust modules in `crates/orbit-bus/src/`
2. Maps each Rust module to its TypeScript source in `OpenCode-reference/packages/opencode/src/`
3. Counts lines in each TypeScript file
4. Orders modules from simplest to most complex
5. Includes a checklist for each module
6. Includes TypeScript → Rust pattern reference
Reference the existing `crates/orbit-core/CONVERSION.md` for format.
TypeScript source is in: `OpenCode-reference/packages/opencode/src/bus/`
Rust modules are in: `crates/orbit-bus/src/`
Use this prompt to convert ONE module:
Convert `crates/orbit-core/src/id.rs` to Rust.
TypeScript source: `OpenCode-reference/packages/opencode/src/id/id.ts`
Requirements:
1. Read the TypeScript file completely
2. Match the functionality exactly
3. Use idiomatic Rust (Result, Option, iterators)
4. No unwrap() or expect() - use ? operator
5. Add #[must_use] to functions returning values
6. Add doc comments with # Errors section for Result functions
7. Add unit tests
8. Run cargo clippy -p orbit-core and fix warnings
9. Update CONVERSION.md status to ✅
Show me the complete converted file.
Use this prompt to convert an ENTIRE crate:
Convert ALL modules in `crates/orbit-core/` to Rust.
Follow the CONVERSION.md in that crate:
- Read: `crates/orbit-core/CONVERSION.md`
- Convert each module in the listed order
- TypeScript sources are in `OpenCode-reference/packages/opencode/src/`
For each module:
1. Read TypeScript source
2. Convert to Rust
3. Add docs and tests
4. Run clippy and fix warnings
5. Mark as ✅ in CONVERSION.md
When done, run:
- cargo test -p orbit-core
- cargo clippy -p orbit-core
Report final status.
Use this prompt to verify a crate is 100% done:
Validate that `crates/orbit-core/` is 100% complete:
1. Read CONVERSION.md - all modules should be ✅
2. Run cargo build -p orbit-core
3. Run cargo test -p orbit-core
4. Run cargo clippy -p orbit-core (should have 0 errors)
5. Check all public functions have doc comments
6. Check all Result functions have # Errors docs
Report any issues found.
| TypeScript | Rust |
|---|---|
throw new Error(msg) |
return Err(Error::Other(msg.into())) |
async function foo() |
async fn foo() |
Promise<T> |
impl Future<Output = T> |
T | null |
Option<T> |
T | undefined |
Option<T> |
try { } catch { } |
result? or match result { } |
namespace Foo { } |
pub mod foo { } |
interface Foo { } |
pub struct Foo { } or pub trait Foo { } |
type Foo = A | B |
pub enum Foo { A, B } |
export function |
pub fn |
export const |
pub const or pub static |
Map<K, V> |
HashMap<K, V> |
Set<T> |
HashSet<T> |
Array<T> |
Vec<T> |
Buffer |
Vec<u8> or bytes::Bytes |
Date.now() |
SystemTime::now() or Instant::now() |
setTimeout |
tokio::time::sleep |
setInterval |
tokio::time::interval |
fs.readFile |
tokio::fs::read |
fs.writeFile |
tokio::fs::write |
path.join |
PathBuf::join or Path::join |
JSON.parse |
serde_json::from_str |
JSON.stringify |
serde_json::to_string |
console.log |
tracing::info! |
console.error |
tracing::error! |
TypeScript:
function foo(): string {
if (bad) throw new Error("something went wrong")
return "ok"
}Rust:
/// Does foo.
///
/// # Errors
///
/// Returns an error if something goes wrong.
pub fn foo() -> Result<String> {
if bad {
return Err(Error::Other("something went wrong".into()));
}
Ok("ok".into())
}TypeScript:
async function fetchData(): Promise<Data> {
const response = await fetch(url)
return response.json()
}Rust:
pub async fn fetch_data() -> Result<Data> {
let response = reqwest::get(url).await?;
let data = response.json().await?;
Ok(data)
}agentsdk/
├── Cargo.toml # Workspace manifest
├── Workflow.md # THIS FILE
├── clippy.toml # Clippy config
├── rustfmt.toml # Formatter config
├── deny.toml # Dependency audit
│
├── crates/
│ ├── orbit-core/
│ │ ├── Cargo.toml
│ │ ├── CONVERSION.md # ← Tracks conversion progress
│ │ └── src/
│ │ ├── lib.rs
│ │ ├── id.rs
│ │ └── ...
│ │
│ ├── orbit-bus/
│ │ ├── Cargo.toml
│ │ ├── CONVERSION.md # ← Create this when starting
│ │ └── src/
│ │
│ └── ... (other crates)
│
├── OpenCode-reference/ # TypeScript source (READ ONLY)
│ └── packages/
│ └── opencode/
│ └── src/
│ ├── id/
│ ├── bus/
│ ├── util/
│ └── ...
│
└── Conversion/ # Planning docs
└── CLAUDE.md
# Build single crate
cargo build -p orbit-core
# Test single crate
cargo test -p orbit-core
# Lint single crate
cargo clippy -p orbit-core
# Build entire workspace
cargo build --workspace
# Test entire workspace
cargo test --workspace
# Lint entire workspace
cargo clippy --workspace
# Format code
cargo fmt
# Check formatting
cargo fmt --check
# Generate docs
cargo doc -p orbit-core --open| Crate | Modules | Complete | Status |
|---|---|---|---|
| orbit-core | 10 | 0 | ⬜ Not Started |
| orbit-bus | ? | 0 | ⬜ Not Started |
| orbit-storage | ? | 0 | ⬜ Not Started |
| orbit-project | ? | 0 | ⬜ Not Started |
| orbit-config | ? | 0 | ⬜ Not Started |
| orbit-permission | ? | 0 | ⬜ Not Started |
| orbit-provider | ? | 0 | ⬜ Not Started |
| orbit-lsp | ? | 0 | ⬜ Not Started |
| orbit-mcp | ? | 0 | ⬜ Not Started |
| orbit-session | ? | 0 | ⬜ Not Started |
| orbit-tools | ? | 0 | ⬜ Not Started |
| orbit-server | ? | 0 | ⬜ Not Started |
Update this table as crates are completed.