Skip to content

c3-oss/codexcw

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

151 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

codexcw

CI License: CC0 1.0

Run Codex or Claude Code non-interactively: spawn the selected agent, decode its JSONL event stream, and expose each run as streams, callbacks, results, and typed errors.

codexcw ships as five idiomatic packages for the same contract. Three are FFI-free native implementations (Go, Rust, .NET); the npm and PyPI packages are thin, idiomatic bindings over the Rust core (napi-rs / PyO3):

Language Package Install
Go github.com/c3-oss/codexcw go get github.com/c3-oss/codexcw
Rust codexcw (crates.io) cargo add codexcw
TypeScript @c3-oss/codexcw (npm) npm install @c3-oss/codexcw
Python codexcw (PyPI) pip install codexcw
C# / .NET C3OSS.Codexcw (NuGet) dotnet add package C3OSS.Codexcw

The Go library lives at the repo root; the Rust core is in crates/codexcw; the npm + PyPI bindings (backed by that Rust core) are in bindings/; and the .NET port is in dotnet/. Each registry is fed by its own release train (v*, rust-v*, node-v*, py-v*, dotnet-v*); a package version exists on its registry once the matching tag has been released — until then, build from the repository (for .NET, a project reference to dotnet/Codexcw/Codexcw.csproj).

Two agents share the same event model:

  • Codex (the default) spawns codex exec --json. Defaults are automation-friendly: JSONL streaming, ephemeral sessions, read-only sandbox, approval policy never, color disabled, and the Git repository check skipped.
  • Claude Code — the claude agent — spawns claude -p --output-format stream-json and normalizes its events into the same event model, with model selection between the haiku, sonnet, and opus aliases and Claude permission modes on the request.

The selected agent's executable must be on PATH and authenticated: codex new enough to support codex exec --json, claude new enough to support --output-format stream-json. See the per-language examples in docs/examples/.

Account usage is available through agent-specific helpers. The Codex helpers (GetAccountUsage, get_account_usage, getAccountUsage) call codex app-server --stdio and return limits, credits, and token usage. The Claude helpers (GetClaudeAccountUsage, get_claude_account_usage, getClaudeAccountUsage) call Claude Code's /usage command and return its report, parsed percentage windows, and raw JSON. Both accept a custom executable, environment, and timeout.

Go

package main

import (
	"context"
	"fmt"
	"log"

	"github.com/c3-oss/codexcw"
)

func main() {
	runner := codexcw.New()
	result, err := runner.Run(context.Background(), codexcw.Request{Prompt: "diga oi"})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(result.FinalMessage)
}

More examples (resume, sandbox/approval, bypass, batches, …): docs/examples/go.md.

Rust

use codexcw::{Request, Runner};

#[tokio::main]
async fn main() -> Result<(), codexcw::Error> {
    let runner = Runner::new();
    let result = runner.run(Request::new("diga oi")).await?;
    println!("{}", result.final_message);
    Ok(())
}

More examples (async + blocking): docs/examples/rust.md.

TypeScript / Node.js

import { Runner } from '@c3-oss/codexcw'

const runner = new Runner()
const result = await runner.run({ prompt: 'diga oi' })
console.log(result.finalMessage)

// Streaming
const session = await runner.start({ prompt: 'resuma este repo' })
for await (const event of session.events()) {
  if (event.type === 'item.completed' && event.item?.type === 'agent_message') {
    console.log(event.item.text)
  }
}
await session.wait()

More examples: docs/examples/typescript.md.

Python

from codexcw import Runner, Request

runner = Runner()
result = runner.run(Request(prompt="diga oi"))
print(result.final_message)

An async API mirrors the sync one under codexcw.aio. More examples (sync + async): docs/examples/python.md.

C# / .NET

using C3OSS.Codexcw;

var runner = new Runner();
var result = await runner.RunAsync(new Request { Prompt = "diga oi" });
Console.WriteLine(result.FinalMessage);

// Streaming
using var session = runner.Start(new Request { Prompt = "resuma este repo" });
await foreach (var evt in session.Events())
{
    if (evt.ItemCompleted?.Item is { Kind: ItemKind.AgentMessage } item)
    {
        Console.WriteLine(item.Text);
    }
}
await session.WaitAsync();

More examples: docs/examples/csharp.md.

Development

devbox shell       # enter the pinned toolchain (Go + Rust + Node + Python + .NET), wire hooks
just ci            # local mirror of the PR pipeline (all five languages)

Recipes are language-namespaced:

Target Purpose
just go-build / go-test / go-lint Go library
just rust-build / rust-test / rust-lint Rust core
just node-build / node-test npm package
just py-build / py-test PyPI package
just dotnet-build / dotnet-test NuGet package
just quality markdown lint, link check, secret scan
just ci the full local lane

Complete per-language usage recipes (sync and async) live in docs/examples/. See AGENTS.md for the canonical project guide.

License

To the extent possible under law, Caian Ertl has waived all copyright and related or neighboring rights to this work. In the spirit of freedom of information, I encourage you to fork, modify, change, share, or do whatever you like with this project! ^C ^V

License