|
| 1 | +# codex-java-sdk |
| 2 | + |
| 3 | +[] [](https://www.apache.org/licenses/LICENSE-2.0.txt) |
| 4 | + |
| 5 | +> Java SDK for the [Codex CLI](https://github.com/openai/codex): subprocess |
| 6 | +> integration that drives the local `codex` agent (exec, interactive sessions, |
| 7 | +> session resume / fork / archive, doctor, review) from Java. |
| 8 | +
|
| 9 | +## Table of Contents |
| 10 | + |
| 11 | +- [1. Project Overview](#1-project-overview) |
| 12 | +- [2. Features & Status](#2-features--status) |
| 13 | +- [3. Requirements & Compatibility](#3-requirements--compatibility) |
| 14 | +- [4. Architecture & Modules](#4-architecture--modules) |
| 15 | +- [5. Installation](#5-installation) |
| 16 | +- [6. Quick Start](#6-quick-start) |
| 17 | +- [7. Configuration](#7-configuration) |
| 18 | +- [8. Core Usage / API](#8-core-usage--api) |
| 19 | +- [9. Testing & Build](#9-testing--build) |
| 20 | +- [10. Versioning & Branches](#10-versioning--branches) |
| 21 | +- [11. Contributing & License](#11-contributing--license) |
| 22 | + |
| 23 | +## 1. Project Overview |
| 24 | + |
| 25 | +`codex-java-sdk` lets Java applications run the |
| 26 | +[Codex CLI](https://github.com/openai/codex) agent (`codex`) as a local subprocess. |
| 27 | +It is a **CLI wrapper**, not a direct OpenAI API client — every call maps to a real |
| 28 | +`codex` command line invocation. |
| 29 | + |
| 30 | +The SDK covers: |
| 31 | + |
| 32 | +- **Exec mode** — `codex exec <prompt>` with model, sandbox, JSONL output, web |
| 33 | + search, output files, output schema, images, config overrides and ephemeral runs. |
| 34 | +- **Interactive sessions** — `codex [prompt]` and full session lifecycle: |
| 35 | + `resume` / `resumeLast` / `fork` / `archive` / `unarchive`. |
| 36 | +- **Parsed models** — `CodexEvent` (JSONL events), `CodexSession`, `CodexDoctorReport`. |
| 37 | +- **Utilities** — `doctor`, `review`, `login` / `logout`, MCP management, `update`, |
| 38 | + `features`, shell `completion`. |
| 39 | + |
| 40 | +What it is **not**: |
| 41 | + |
| 42 | +- Not an OpenAI API client (no direct HTTP calls to the OpenAI API). |
| 43 | +- Not a replacement for the `codex` binary — the CLI must be installed and runnable. |
| 44 | + |
| 45 | +Typical scenarios: |
| 46 | + |
| 47 | +| Scenario | What you use | |
| 48 | +| :--- | :--- | |
| 49 | +| One-shot coding task | `CodexClient.exec(prompt)` | |
| 50 | +| Machine-readable event stream | `execAndParse(prompt)` → `List<CodexEvent>` | |
| 51 | +| Long-running interactive agent | `startSession(prompt)` / `resumeSession(sessionId)` | |
| 52 | +| Reproduce a session in a sandbox | `forkSession(sessionId)` / `execResume(sessionId, prompt)` | |
| 53 | +| Environment diagnostics | `doctorSummary()` / `doctorJson()` | |
| 54 | + |
| 55 | +## 2. Features & Status |
| 56 | + |
| 57 | +| Capability | Status | Notes | |
| 58 | +| :--- | :--- | :--- | |
| 59 | +| `codex exec` non-interactive mode | Active development | `exec`, `exec(model)`, `exec(ExecOptions)` | |
| 60 | +| Exec variants | Active development | `execInDir`, `execEphemeral`, `execWithSearch`, `execToFile`, `execWithSchema`, `execWithImage`, `execWithConfigOverrides`, `execDangerously`, `execBypassHookTrust`, `execWithEnable` / `execWithDisable` | |
| 61 | +| JSONL event parsing | Active development | `execAndParse(prompt)` → `List<CodexEvent>` | |
| 62 | +| Interactive sessions | Active development | `startSession()`, `startSession(prompt)`, `startSession(GlobalOptions, prompt)` | |
| 63 | +| Session lifecycle | Active development | `resumeSession`, `resumeLastSession`, `forkSession`, `forkLastSession`, `archiveSession`, `unarchiveSession`, `execResume` | |
| 64 | +| Doctor & review | Active development | `doctor`, `doctorJson`, `doctorSummary`, `review`, `reviewCommit`, `reviewBase` | |
| 65 | +| Auth / MCP / misc | Active development | `login`, `logout`, `mcpList` / `mcpAdd` / `mcpGet` / `mcpRemove`, `update`, `features`, `completion`, `app` | |
| 66 | +| Config model | Active development | `CodexClientConfig` POJO (plain, Spring-bindable) | |
| 67 | + |
| 68 | +> **Assumption**: the capability statuses above reflect the current state of the |
| 69 | +> 1.0.x branch; the module is under active development. |
| 70 | +
|
| 71 | +## 3. Requirements & Compatibility |
| 72 | + |
| 73 | +| Requirement | Version / Notes | |
| 74 | +| :--- | :--- | |
| 75 | +| JDK | 8+ | |
| 76 | +| Maven | 3.0+ (enforced; Maven Wrapper `./mvnw` included) | |
| 77 | +| Codex CLI | `codex` must be installed and available (`localExecutable` configures the path) | |
| 78 | + |
| 79 | +Version lines: |
| 80 | + |
| 81 | +| Branch | JDK | Version | |
| 82 | +| :--- | :--- | :--- | |
| 83 | +| `feature/1.0.x` | 8 | `1.0.x.*` | |
| 84 | +| `feature/2.0.x` | 17 | `2.0.x.*` | |
| 85 | +| `feature/3.0.x` | 21 | `3.0.x.*` | |
| 86 | + |
| 87 | +## 4. Architecture & Modules |
| 88 | + |
| 89 | +```text |
| 90 | ++------------------+ +------------------------------------------+ |
| 91 | +| Java application | | codex-java-sdk | |
| 92 | +| |-->| CodexClient (facade) | |
| 93 | +| prompt / options | | | CodexCli (command mapping) | |
| 94 | +| | | | | CodexCliExecutor | |
| 95 | +| | | | | `codex` child process | |
| 96 | +| | | | CodexCliResult | |
| 97 | ++------------------+ | | CodexEvent/CodexSession/DoctorReport| |
| 98 | + +-------------------+----------------------+ |
| 99 | + | |
| 100 | + v |
| 101 | + +-------------------------------------------+ |
| 102 | + | Local `codex` CLI (exec, session, doctor, | |
| 103 | + | review, login, ...) | |
| 104 | + +-------------------------------------------+ |
| 105 | +``` |
| 106 | + |
| 107 | +Single-module Maven project (`packaging: jar`). No child modules. |
| 108 | + |
| 109 | +| Artifact | Responsibility | |
| 110 | +| :--- | :--- | |
| 111 | +| `io.github.easy4j:codex-java-sdk` | CLI facade, command mapping, subprocess executor, result & parsed models | |
| 112 | + |
| 113 | +Key packages: |
| 114 | + |
| 115 | +| Package | Content | |
| 116 | +| :--- | :--- | |
| 117 | +| `io.github.easy4j.codex` | `CodexClient`, `CodexClientConfig` | |
| 118 | +| `io.github.easy4j.codex.cli` | `CodexCli`, `CodexCliExecutor`, `CodexCliResult` | |
| 119 | +| `io.github.easy4j.codex.model` | `CodexEvent`, `CodexSession`, `CodexDoctorReport` | |
| 120 | + |
| 121 | +## 5. Installation |
| 122 | + |
| 123 | +The project is **not yet published to Maven Central**. Snapshots/releases are |
| 124 | +distributed through the Aliyun Maven repository and GitHub Releases. |
| 125 | + |
| 126 | +Maven: |
| 127 | + |
| 128 | +```xml |
| 129 | +<dependency> |
| 130 | + <groupId>io.github.easy4j</groupId> |
| 131 | + <artifactId>codex-java-sdk</artifactId> |
| 132 | + <version>1.0.x.20260630-SNAPSHOT</version> |
| 133 | +</dependency> |
| 134 | +``` |
| 135 | + |
| 136 | +Gradle: |
| 137 | + |
| 138 | +```groovy |
| 139 | +implementation 'io.github.easy4j:codex-java-sdk:1.0.x.20260630-SNAPSHOT' |
| 140 | +``` |
| 141 | + |
| 142 | +## 6. Quick Start |
| 143 | + |
| 144 | +```java |
| 145 | +import io.github.easy4j.codex.CodexClient; |
| 146 | +import io.github.easy4j.codex.CodexClientConfig; |
| 147 | +import io.github.easy4j.codex.cli.CodexCliResult; |
| 148 | + |
| 149 | +public class CodexDemo { |
| 150 | + |
| 151 | + public static void main(String[] args) { |
| 152 | + CodexClientConfig config = new CodexClientConfig(); |
| 153 | + config.setLocalExecutable("codex"); // or an absolute path |
| 154 | + config.setLocalTimeoutSeconds(600); |
| 155 | + |
| 156 | + try (CodexClient client = new CodexClient(config)) { |
| 157 | + CodexCliResult result = client.exec("Write a Java hello world"); |
| 158 | + System.out.println("exit=" + result.getExitCode()); |
| 159 | + System.out.println(result.getStdout()); |
| 160 | + } |
| 161 | + } |
| 162 | +} |
| 163 | +``` |
| 164 | + |
| 165 | +Expected result: `codex exec "Write a Java hello world"` runs locally; |
| 166 | +`result.getExitCode()` is `0` on success and `result.getStdout()` contains the |
| 167 | +agent's answer. |
| 168 | + |
| 169 | +## 7. Configuration |
| 170 | + |
| 171 | +`CodexClientConfig` is a plain POJO (Spring `@ConfigurationProperties`-bindable). |
| 172 | +There is no configuration file of its own. Key fields: |
| 173 | + |
| 174 | +| Field | Type | Default | Description | |
| 175 | +| :--- | :--- | :--- | :--- | |
| 176 | +| `localExecutable` | String | `codex` | CLI executable name or absolute path | |
| 177 | +| `localTimeoutSeconds` | int | `600` | Command execution timeout (seconds) | |
| 178 | +| `localProbeTimeoutSeconds` | int | `5` | Timeout for the CLI availability probe | |
| 179 | +| `defaultModel` | String | - | Default model | |
| 180 | +| `defaultSandbox` | String | - | Sandbox mode (`read-only`, `workspace-write`, `danger-full-access`) | |
| 181 | +| `defaultApprovalPolicy` | String | - | Approval policy (`untrusted`, `on-request`, `never`) | |
| 182 | +| `defaultProfile` | String | - | Default config profile | |
| 183 | +| `ossProvider` / `localProvider` | boolean / String | - | OSS provider / local provider (`lmstudio`, `ollama`) | |
| 184 | +| `skipGitRepoCheck` | boolean | `false` | Skip git repo checks | |
| 185 | +| `ephemeral` | boolean | `false` | Ephemeral session (no persistence) | |
| 186 | +| `jsonOutput` | boolean | `true` | JSONL output | |
| 187 | +| `outputSchema` | String | - | Output schema file path | |
| 188 | +| `search` | boolean | `false` | Enable web search | |
| 189 | +| `image` | String | - | Image file path | |
| 190 | +| `configOverrides` | String[] | - | Config overrides (`-c key=value`) | |
| 191 | +| `outputFile` | String | - | Output file path (`output-last-message`) | |
| 192 | +| `workingDir` | String | - | Working directory | |
| 193 | +| `dangerouslyBypassApprovalsAndSandbox` | boolean | `false` | Skip all approvals and sandbox (dangerous) | |
| 194 | +| `dangerouslyBypassHookTrust` | boolean | `false` | Skip hook trust checks | |
| 195 | +| `strictConfig` | boolean | `false` | Fail on unknown config fields | |
| 196 | +| `enable` / `disable` | String[] | - | Features to enable / disable | |
| 197 | + |
| 198 | +## 8. Core Usage / API |
| 199 | + |
| 200 | +### 8.1 JSONL events |
| 201 | + |
| 202 | +```java |
| 203 | +try (CodexClient client = new CodexClient(config)) { |
| 204 | + // codex exec --json <prompt>, parsed into typed events |
| 205 | + List<CodexEvent> events = client.execAndParse("Fix the failing test"); |
| 206 | + events.forEach(event -> System.out.println(event.getType() + " -> " + event.getMessage())); |
| 207 | +} |
| 208 | +``` |
| 209 | + |
| 210 | +### 8.2 Session lifecycle |
| 211 | + |
| 212 | +```java |
| 213 | +try (CodexClient client = new CodexClient(config)) { |
| 214 | + client.exec("first task"); // creates a persisted session |
| 215 | + client.resumeSession("session-id"); // resume an interactive session |
| 216 | + client.forkSession("session-id"); // fork into a new session |
| 217 | + client.archiveSession("session-id"); // archive a session |
| 218 | + client.execResume("session-id", "continue");// non-interactive resume |
| 219 | + client.doctorSummary(); // environment diagnostics |
| 220 | +} |
| 221 | +``` |
| 222 | + |
| 223 | +## 9. Testing & Build |
| 224 | + |
| 225 | +```bash |
| 226 | +./mvnw clean verify |
| 227 | +``` |
| 228 | + |
| 229 | +- The build is configured with the JaCoCo Maven plugin (report + `check` goal with a |
| 230 | + 90% line-coverage rule bound to the `verify` phase; `haltOnFailure=false`). |
| 231 | +- **Assumption**: the 1.0.x branch currently checks in no test sources under |
| 232 | + `src/test`; coverage thresholds are therefore enforced only when tests exist. |
| 233 | +- No CI workflow files are present under `.github/` in this worktree. |
| 234 | + |
| 235 | +## 10. Versioning & Branches |
| 236 | + |
| 237 | +| Branch | JDK | Version | Notes | |
| 238 | +| :--- | :--- | :--- | :--- | |
| 239 | +| `feature/1.0.x` | 8 | `1.0.x.*` | Current branch, JDK 8 baseline, active development | |
| 240 | +| `feature/2.0.x` | 17 | `2.0.x.*` | JDK 17 line | |
| 241 | +| `feature/3.0.x` | 21 | `3.0.x.*` | JDK 21 line | |
| 242 | + |
| 243 | +Maintenance policy: the `1.0.x` line receives bug fixes and compatibility updates |
| 244 | +for the JDK 8 baseline. New features targeting newer JDKs land on the `2.0.x` / |
| 245 | +`3.0.x` lines. Releases are published to the Aliyun Maven repository and as |
| 246 | +GitHub Releases; the project is not yet published to Maven Central. |
| 247 | + |
| 248 | +## 11. Contributing & License |
| 249 | + |
| 250 | +Contributions are welcome — please open issues or pull requests on GitHub. |
| 251 | + |
| 252 | +Licensed under the [Apache License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0.txt). |
0 commit comments