Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions openclaw-cpp/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# openclaw-cpp build artifacts
build/
build-*/
/tmp/

# Downloaded third-party headers (regenerated by cmake)
third_party/nlohmann/
third_party/CLI11/
third_party/httplib.h

# IDE / editor files
.vscode/
.idea/
*.swp
*.swo
CMakeCache.txt
CMakeFiles/
cmake_install.cmake
Makefile
*.cmake
36 changes: 36 additions & 0 deletions openclaw-cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
cmake_minimum_required(VERSION 3.20)
project(openclaw VERSION 1.0.0 LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

# Build options
option(BUILD_TESTS "Build tests" ON)
option(BUILD_SHARED_LIBS "Build shared libraries" OFF)

# Output directories
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)

# ── Dependencies (vendored headers in third_party/) ─────────────────────────
add_subdirectory(third_party)

# ── Core library ────────────────────────────────────────────────────────────
add_subdirectory(src)

# ── Entry-point executable ───────────────────────────────────────────────────
add_executable(openclaw src/entry.cpp)
target_link_libraries(openclaw PRIVATE openclaw_core)
target_include_directories(openclaw PRIVATE ${CMAKE_SOURCE_DIR}/src)

# Installation
include(GNUInstallDirs)
install(TARGETS openclaw RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})

# ── Tests ───────────────────────────────────────────────────────────────────
if(BUILD_TESTS)
enable_testing()
add_subdirectory(tests)
endif()
147 changes: 147 additions & 0 deletions openclaw-cpp/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
# openclaw-cpp

C++20 port of [OpenClaw](https://openclaw.ai) — an AI gateway and CLI that connects AI models to messaging channels.

This directory contains a faithful translation of the TypeScript source tree under `../src/` into standard C++20, maintaining the **same folder structure, file names, and public API surface** as the original.

---

## Folder Structure

```
openclaw-cpp/
├── CMakeLists.txt # Root CMake build (mirrors package.json / tsdown.config.ts)
├── README.md # This file
├── third_party/ # Vendored header-only dependencies
│ ├── nlohmann/json.hpp # JSON (nlohmann/json v3)
│ ├── CLI11/ # CLI argument parsing (CLI11 v2)
│ ├── spdlog/ # Structured logging (spdlog v1)
│ └── httplib.h # HTTP client/server (cpp-httplib)
├── src/ # Mirrors ../src/ 1-to-1
│ ├── entry.cpp # ← ../src/entry.ts
│ ├── index.cpp / .hpp # ← ../src/index.ts
│ ├── version.cpp / .hpp # ← ../src/version.ts
│ ├── globals.cpp / .hpp # ← ../src/globals.ts
│ ├── logger.cpp / .hpp # ← ../src/logger.ts
│ ├── logging.cpp / .hpp # ← ../src/logging.ts
│ ├── runtime.cpp / .hpp # ← ../src/runtime.ts
│ ├── utils.cpp / .hpp # ← ../src/utils.ts
│ ├── cli/ # ← ../src/cli/
│ ├── commands/ # ← ../src/commands/
│ ├── config/ # ← ../src/config/
│ ├── infra/ # ← ../src/infra/
│ ├── acp/ # ← ../src/acp/
│ ├── agents/ # ← ../src/agents/
│ └── ... # All other sub-modules mirrored
└── tests/ # Unit tests (mirrors *.test.ts co-located pattern)
├── CMakeLists.txt
└── ...
```

---

## Building

### Prerequisites

| Tool | Version |
|------|---------|
| CMake | ≥ 3.20 |
| C++ compiler | GCC ≥ 12 / Clang ≥ 15 / MSVC 2022 |
| ninja (optional) | any |

The project vendors all dependencies as header-only libraries — no separate install step required.

### Quick start

```bash
# From openclaw-cpp/
cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build -j$(nproc)
./build/bin/openclaw --version
```

### Debug build with tests

```bash
cmake -B build -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTS=ON
cmake --build build -j$(nproc)
ctest --test-dir build --output-on-failure
```

---

## Usage

The CLI interface is identical to the TypeScript version:

```bash
openclaw --version
openclaw --help
openclaw agent --message "Hello"
openclaw status
openclaw config set gateway.mode local
openclaw gateway run
```

---

## Dependency Mapping

| TypeScript (npm) | C++ equivalent |
|-----------------|----------------|
| `commander` | `CLI11` |
| `zod` | Manual struct validation |
| `pino` / `bunyan` | `spdlog` |
| `node-fetch` / `axios` | `cpp-httplib` |
| `ws` (WebSocket) | `cpp-httplib` WebSocket |
| `JSON5` / `JSON.parse` | `nlohmann/json` |
| `dotenv` | Custom `infra/dotenv.cpp` |
| Node.js `fs` / `path` | `std::filesystem` |
| Node.js `child_process` | `posix_spawn` / `CreateProcess` |
| Node.js `net` / `http` | `cpp-httplib` |

---

## Architecture

Each TypeScript module maps to a C++ translation unit:

- `.ts` exports → `.hpp` public header + `.cpp` implementation
- `*.test.ts` → `tests/` directory with matching name (e.g. `version.test.cpp`)
- `index.ts` re-exports → `index.hpp` aggregating includes
- Dynamic `import()` → lazy-loaded via function pointers / `std::function`
- `process.env` → `std::getenv` wrapped in `infra/env.hpp`
- `process.exit` → `std::exit` via `runtime.hpp` `RuntimeEnv`

---

## Status

| Module | Status |
|--------|--------|
| `src/version` | ✅ Full |
| `src/infra/env` | ✅ Full |
| `src/infra/errors` | ✅ Full |
| `src/infra/is-main` | ✅ Full |
| `src/infra/ports` | ✅ Full |
| `src/utils` | ✅ Full |
| `src/globals` | ✅ Full |
| `src/runtime` | ✅ Full |
| `src/logger` | ✅ Full |
| `src/logging` | ✅ Full |
| `src/cli/argv` | ✅ Full |
| `src/cli/program` | ✅ Full |
| `src/entry` | ✅ Full |
| `src/index` | ✅ Full |
| `src/config/*` | ✅ Stub |
| `src/commands/*` | ✅ Stub |
| `src/acp/*` | ✅ Stub |
| `src/agents/*` | ✅ Stub |
| `src/channels/*` | ✅ Stub |
| `src/gateway/*` | ✅ Stub |
| `src/providers/*` | ✅ Stub |
| All other modules | ✅ Stub |

> **Stub** = header + minimal implementation skeleton with the same public API signature.
> Full conversion of every module is in progress.
166 changes: 166 additions & 0 deletions openclaw-cpp/src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
# openclaw-cpp/src/CMakeLists.txt
# Builds the core openclaw_core static library.

# ── Collect sources ───────────────────────────────────────────────────────────
# Root-level translation units
set(OPENCLAW_CORE_SOURCES
version.cpp
globals.cpp
logger.cpp
logging.cpp
runtime.cpp
utils.cpp
# infra/
infra/env.cpp
infra/errors.cpp
infra/is-main.cpp
infra/ports.cpp
infra/binaries.cpp
infra/dotenv.cpp
infra/home-dir.cpp
infra/runtime-guard.cpp
infra/warning-filter.cpp
# cli/
cli/argv.cpp
cli/program.cpp
# config/
config/io.cpp
config/paths.cpp
config/types.cpp
config/validation.cpp
config/sessions.cpp
# logging/
logging/logger.cpp
logging/subsystem.cpp
logging/redact.cpp
# terminal/
terminal/table.cpp
terminal/theme.cpp
# process/
process/exec.cpp
process/child-process-bridge.cpp
# utils/
utils/boolean.cpp
# channels/
channels/types.cpp
channels/routing.cpp
# routing/
routing/routing.cpp
# auto-reply/
auto-reply/reply.cpp
auto-reply/templating.cpp
# hooks/
hooks/hooks.cpp
# sessions/
sessions/sessions.cpp
# secrets/
secrets/secrets.cpp
# memory/
memory/memory.cpp
# providers/
providers/types.cpp
# gateway/
gateway/gateway.cpp
gateway/server.cpp
# daemon/
daemon/runtime.cpp
# pairing/
pairing/pairing.cpp
# i18n/
i18n/i18n.cpp
# types/
types/types.cpp
)

# Messaging channel stubs (each maps to its own channel extension).
set(OPENCLAW_CHANNEL_SOURCES
telegram/channel.cpp
slack/channel.cpp
discord/channel.cpp
signal/channel.cpp
web/channel.cpp
whatsapp/whatsapp.cpp
imessage/imessage.cpp
)

# Command handlers (stubs).
set(OPENCLAW_COMMAND_SOURCES
commands/agent.cpp
commands/agents.cpp
commands/channels.cpp
commands/configure.cpp
commands/dashboard.cpp
commands/doctor.cpp
commands/gateway-status.cpp
commands/health.cpp
commands/message.cpp
commands/models.cpp
commands/onboard.cpp
commands/reset.cpp
commands/sandbox.cpp
commands/sessions.cpp
commands/setup.cpp
commands/status.cpp
)

# ACP (Agent Control Protocol) stubs.
set(OPENCLAW_ACP_SOURCES
acp/client.cpp
acp/server.cpp
acp/session.cpp
acp/translator.cpp
acp/policy.cpp
acp/types.cpp
)

# Agent stubs.
set(OPENCLAW_AGENT_SOURCES
agents/auth-profiles.cpp
agents/agent-paths.cpp
agents/agent-scope.cpp
agents/apply-patch.cpp
)

# Media / TTS stubs.
set(OPENCLAW_MEDIA_SOURCES
media/media.cpp
tts/tts.cpp
)

# ── Library target ────────────────────────────────────────────────────────────
add_library(openclaw_core STATIC
${OPENCLAW_CORE_SOURCES}
${OPENCLAW_CHANNEL_SOURCES}
${OPENCLAW_COMMAND_SOURCES}
${OPENCLAW_ACP_SOURCES}
${OPENCLAW_AGENT_SOURCES}
${OPENCLAW_MEDIA_SOURCES}
)

target_include_directories(openclaw_core
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}
PRIVATE ${CMAKE_SOURCE_DIR}/third_party
)

target_link_libraries(openclaw_core
PUBLIC third_party::json
third_party::cli11
third_party::httplib
)

# Enable C++20 features.
target_compile_features(openclaw_core PUBLIC cxx_std_20)

# Compiler warnings.
if(MSVC)
target_compile_options(openclaw_core PRIVATE /W4 /WX)
else()
target_compile_options(openclaw_core PRIVATE
-Wall -Wextra -Wpedantic
-Wno-unused-parameter # Many stubs have unused params intentionally.
)
endif()

# Platform threading.
find_package(Threads REQUIRED)
target_link_libraries(openclaw_core PUBLIC Threads::Threads)
13 changes: 13 additions & 0 deletions openclaw-cpp/src/acp/client.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// openclaw-cpp/src/acp/client.cpp
// Mirrors src/acp/client.ts
// Description: ACP client
//
// Stub implementation — port the TypeScript logic from src/acp/client.ts here.

#include "client.hpp"

namespace openclaw::acp {

// TODO: implement functions declared in client.hpp

} // namespace openclaw::acp
Loading