claude2codex 0.3.1 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +26 -5
- package/README.zh-CN.md +28 -7
- package/c2c.skill.md +58 -0
- package/dist/server.js +59 -0
- package/package.json +5 -4
package/README.md
CHANGED
|
@@ -12,14 +12,15 @@ One real contract round-trip, recorded live: Claude drafts the Goal Contract, `c
|
|
|
12
12
|
|
|
13
13
|
*Real Codex run (13k tokens, 50s), waits compressed. Replay in your terminal: `asciinema play demo/demo.cast`*
|
|
14
14
|
|
|
15
|
-
##
|
|
15
|
+
## Why
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
In 2025, AI-assisted coding meant writing detailed prompts that told the model *how* to implement things — which files to edit, what patterns to follow, sometimes nearly pseudocode. The engineer was a director; the AI was a typist that needed constant guidance.
|
|
18
18
|
|
|
19
|
-
-
|
|
20
|
-
- **OpenAI Codex** — the implementer. Receives specifications, writes code, runs tests, reports back.
|
|
19
|
+
That has changed. In 2026, models are [strong enough at implementation](https://www.anthropic.com/institute/recursive-self-improvement) that micromanaging the how is no longer the best use of a human's time. The bottleneck has shifted: when implementation is cheap, the expensive mistakes are **defining the wrong problem** and **failing to catch a bad result**. Getting the implementation steps right matters far less than getting the goal right.
|
|
21
20
|
|
|
22
|
-
|
|
21
|
+
This is why Goal Contracts are structured the way they are. They don't explain how to write the code — they define **what the code must do** (the Goal) and **how to prove it worked** (Success Conditions). The engineer's role becomes problem definition, context provision, and verification — the same things that make a good engineering manager effective at delegation.
|
|
22
|
+
|
|
23
|
+
This project is built on that premise: split planning and review (where human judgment still dominates) from implementation (where models now excel), and connect them with a contract format that forces clarity on the parts that matter most.
|
|
23
24
|
|
|
24
25
|
```mermaid
|
|
25
26
|
flowchart LR
|
|
@@ -30,6 +31,10 @@ flowchart LR
|
|
|
30
31
|
Claude -.->|Delta Contract if review fails| Codex
|
|
31
32
|
```
|
|
32
33
|
|
|
34
|
+
- **You** — decide what to build and give final approval.
|
|
35
|
+
- **Claude Code** — the architect and reviewer. Defines the problem, writes the contract, verifies the result.
|
|
36
|
+
- **OpenAI Codex** — the implementer. Receives the contract, writes code, runs tests, reports back.
|
|
37
|
+
|
|
33
38
|
## What is a Goal Contract?
|
|
34
39
|
|
|
35
40
|
A Goal Contract is a structured specification that tells Codex *exactly* what to build. It has three parts:
|
|
@@ -125,6 +130,22 @@ Add to your Claude Code MCP settings:
|
|
|
125
130
|
}
|
|
126
131
|
```
|
|
127
132
|
|
|
133
|
+
### Skill (optional)
|
|
134
|
+
|
|
135
|
+
The package includes a Claude Code Skill that teaches Claude the full contract workflow — drafting Goal Contracts, delegating to Codex, reviewing handoffs, and reworking failures. Install it to use `/c2c` from any project:
|
|
136
|
+
|
|
137
|
+
```sh
|
|
138
|
+
mkdir -p ~/.claude/skills
|
|
139
|
+
cp "$(npm root -g)/claude2codex/c2c.skill.md" ~/.claude/skills/c2c.md
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Or download directly:
|
|
143
|
+
|
|
144
|
+
```sh
|
|
145
|
+
mkdir -p ~/.claude/skills
|
|
146
|
+
curl -fsSL https://raw.githubusercontent.com/PrestoOverture/c2c/main/c2c.skill.md -o ~/.claude/skills/c2c.md
|
|
147
|
+
```
|
|
148
|
+
|
|
128
149
|
## Tools Provided
|
|
129
150
|
|
|
130
151
|
| Tool | Description |
|
package/README.zh-CN.md
CHANGED
|
@@ -6,20 +6,21 @@
|
|
|
6
6
|
|
|
7
7
|
## 演示
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
一次完整的workflow实践过程:Claude 起草 Goal Contract,`codex_estimate` 预估成本,Codex 在 goal loop 下自主实现(`codex_status` 实时流式进度),最后 Claude 独立复核 handoff。
|
|
10
10
|
|
|
11
11
|

|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
*Codex 运行(13k tokens,50 秒),等待时间已压缩。终端回放:`asciinema play demo/demo.cast`*
|
|
14
14
|
|
|
15
|
-
##
|
|
15
|
+
## 为什么做这个项目
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
2025 年,AI 辅助编程的主流方式是写详细的 prompt 告诉模型*怎么*实现——改哪些文件、用什么模式、有时候几乎是伪代码。工程师是导演,AI 是需要不断指导的执行者。
|
|
18
18
|
|
|
19
|
-
-
|
|
20
|
-
- **OpenAI Codex** — 实现者。接收规格说明,编写代码,运行测试,报告结果。
|
|
19
|
+
这已经变了。2026 年,模型的[实现能力已经足够强](https://www.anthropic.com/institute/recursive-self-improvement),事无巨细地指挥"怎么写"不再是人最好的时间投入方式。瓶颈转移了:当实现变得廉价,真正昂贵的错误是**定义了错误的问题**和**没有验收出坏的结果**。把实现步骤写对,远不如把目标定义对重要。
|
|
21
20
|
|
|
22
|
-
|
|
21
|
+
这就是为什么 Goal Contract 被设计成这样。它不解释怎么写代码——它定义**代码必须做到什么**(Goal)和**怎么证明做对了**(Success Conditions)。工程师的角色变成了问题定义、上下文补充和验收——和一个好的工程管理者委派任务时做的事情一样。
|
|
22
|
+
|
|
23
|
+
这个项目建立在这个前提上:把规划和审查(人的判断力仍然占主导)与实现(模型已经足够强)分开,用一种契约格式把它们连接起来,迫使工程师在最重要的部分(问题定义和验收标准)上做到清晰。
|
|
23
24
|
|
|
24
25
|
```mermaid
|
|
25
26
|
flowchart LR
|
|
@@ -30,6 +31,10 @@ flowchart LR
|
|
|
30
31
|
Claude -.->|Delta Contract 修正| Codex
|
|
31
32
|
```
|
|
32
33
|
|
|
34
|
+
- **你** — 决定做什么,给最终批准。
|
|
35
|
+
- **Claude Code** — 架构师和审查者。定义问题,撰写契约,验证结果。
|
|
36
|
+
- **OpenAI Codex** — 实现者。接收契约,编写代码,运行测试,报告结果。
|
|
37
|
+
|
|
33
38
|
## 什么是 Goal Contract(目标契约)?
|
|
34
39
|
|
|
35
40
|
Goal Contract 是一份结构化规格说明,精确告诉 Codex **要做什么**。它由三部分组成:
|
|
@@ -125,6 +130,22 @@ npx claude2codex
|
|
|
125
130
|
}
|
|
126
131
|
```
|
|
127
132
|
|
|
133
|
+
### Skill(可选)
|
|
134
|
+
|
|
135
|
+
包内附带一个 Claude Code Skill,教 Claude 完整的契约工作流——起草 Goal Contract、委派给 Codex、审查 handoff、失败时返工。安装后可在任何项目中使用 `/c2c`:
|
|
136
|
+
|
|
137
|
+
```sh
|
|
138
|
+
mkdir -p ~/.claude/skills
|
|
139
|
+
cp "$(npm root -g)/claude2codex/c2c.skill.md" ~/.claude/skills/c2c.md
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
或直接下载:
|
|
143
|
+
|
|
144
|
+
```sh
|
|
145
|
+
mkdir -p ~/.claude/skills
|
|
146
|
+
curl -fsSL https://raw.githubusercontent.com/PrestoOverture/c2c/main/c2c.skill.md -o ~/.claude/skills/c2c.md
|
|
147
|
+
```
|
|
148
|
+
|
|
128
149
|
## 提供的工具
|
|
129
150
|
|
|
130
151
|
| 工具 | 说明 |
|
package/c2c.skill.md
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: c2c
|
|
3
|
+
description: Delegate implementation to Codex via Goal Contracts. Draft, send, poll, review, rework.
|
|
4
|
+
trigger: When the user wants to delegate implementation work to Codex, or types /c2c.
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
You are the **architect and reviewer**. Codex is the **implementer**. You draft contracts, delegate via the `codex` MCP server, and review the output. You do not implement the task yourself.
|
|
8
|
+
|
|
9
|
+
If `codex_config` errors, tell the user to install the MCP server (npm: `claude2codex`).
|
|
10
|
+
|
|
11
|
+
## Workflow
|
|
12
|
+
|
|
13
|
+
1. **User decides** what to build or fix.
|
|
14
|
+
2. **You draft a Goal Contract** (format below). Show it to the user for approval.
|
|
15
|
+
3. **You send it** — `codex_estimate` to check budget, then `codex_implement`.
|
|
16
|
+
4. **You poll** — `codex_status` until terminal. Report progress to the user.
|
|
17
|
+
5. **You review** — `codex_result` for the handoff, then verify independently (see Review below).
|
|
18
|
+
6. **User approves** your findings.
|
|
19
|
+
|
|
20
|
+
If review fails → draft a **Delta Contract** → `codex_rework` (same `job_id`, thread resumes) → re-enter at step 4.
|
|
21
|
+
|
|
22
|
+
## Goal Contract
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
### Goal
|
|
26
|
+
What the code must do. First sentence = acceptance test in prose.
|
|
27
|
+
|
|
28
|
+
### Constraints
|
|
29
|
+
Only what Codex would get wrong without being told. One line of
|
|
30
|
+
"only modify files needed for this task" covers the rest.
|
|
31
|
+
|
|
32
|
+
### Success Conditions
|
|
33
|
+
- [ ] Assertions, not paragraphs. At least one is a command whose exit code decides.
|
|
34
|
+
- [ ] Handoff includes: Changed Files, Validation, Success Conditions, Risks & Deviations.
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
**Write lean contracts.** Goal and Success Conditions are what Codex acts on. Constraints are for genuine risks only — don't front-load your review checklist into the contract.
|
|
38
|
+
|
|
39
|
+
## Delta Contract
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
### Findings
|
|
43
|
+
- What is wrong, with file/line references.
|
|
44
|
+
|
|
45
|
+
### Failed Success Conditions
|
|
46
|
+
- [ ] The specific conditions that did not pass.
|
|
47
|
+
|
|
48
|
+
### Constraints
|
|
49
|
+
- Original constraints still apply. Fix only the findings; do not touch work that passed.
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Review
|
|
53
|
+
|
|
54
|
+
1. Handoff must be complete (all four sections). Missing handoff = review failure.
|
|
55
|
+
2. Re-run every verification command yourself — do not trust the handoff's claims.
|
|
56
|
+
3. Run the project's own typecheck/build/test/lint.
|
|
57
|
+
4. Flag security issues and constraint violations.
|
|
58
|
+
5. Report findings to the user. Fix small issues (typos, imports) directly; do not rewrite the implementation.
|
package/dist/server.js
CHANGED
|
@@ -137,6 +137,11 @@ var CodexAppServer = class {
|
|
|
137
137
|
stderrTail = [];
|
|
138
138
|
exitError;
|
|
139
139
|
exited = false;
|
|
140
|
+
/**
|
|
141
|
+
* Spawns a new Codex child process and sets up event listeners for stdout and stderr streams.
|
|
142
|
+
*
|
|
143
|
+
* @param opts - Configuration options specifying executable path, arguments, environment, and event callbacks
|
|
144
|
+
*/
|
|
140
145
|
constructor(opts) {
|
|
141
146
|
this.opts = opts;
|
|
142
147
|
this.proc = spawn(opts.bin, opts.args, {
|
|
@@ -158,6 +163,12 @@ var CodexAppServer = class {
|
|
|
158
163
|
this.handleExit(null, new Error(`failed to spawn ${opts.bin}: ${err.message}`));
|
|
159
164
|
});
|
|
160
165
|
}
|
|
166
|
+
/**
|
|
167
|
+
* Handles Codex child process termination or spawn failure, rejecting pending requests and notifying listeners.
|
|
168
|
+
*
|
|
169
|
+
* @param code - Exit code of the child process, or null if terminated abnormally
|
|
170
|
+
* @param error - Error instance causing process exit, if any (optional)
|
|
171
|
+
*/
|
|
161
172
|
handleExit(code, error) {
|
|
162
173
|
if (this.exited) return;
|
|
163
174
|
this.exited = true;
|
|
@@ -172,6 +183,11 @@ var CodexAppServer = class {
|
|
|
172
183
|
this.pending.clear();
|
|
173
184
|
this.opts.onExit?.(code, this.exitError);
|
|
174
185
|
}
|
|
186
|
+
/**
|
|
187
|
+
* Parses a single output line received from Codex stdout and dispatches it as a request response or notification.
|
|
188
|
+
*
|
|
189
|
+
* @param line - Raw text line emitted by the child process stdout
|
|
190
|
+
*/
|
|
175
191
|
handleLine(line) {
|
|
176
192
|
const trimmed = line.trim();
|
|
177
193
|
if (!trimmed) return;
|
|
@@ -199,10 +215,23 @@ var CodexAppServer = class {
|
|
|
199
215
|
this.opts.onNotification?.(msg.method, msg.params);
|
|
200
216
|
}
|
|
201
217
|
}
|
|
218
|
+
/**
|
|
219
|
+
* Serializes an object to JSON and writes it to the child process's standard input stream.
|
|
220
|
+
*
|
|
221
|
+
* @param obj - Object to send to the child process
|
|
222
|
+
*/
|
|
202
223
|
send(obj) {
|
|
203
224
|
if (this.exited) return;
|
|
204
225
|
this.proc.stdin.write(JSON.stringify(obj) + "\n");
|
|
205
226
|
}
|
|
227
|
+
/**
|
|
228
|
+
* Sends a correlated JSON-RPC request to Codex and returns a Promise that resolves with the response or times out.
|
|
229
|
+
*
|
|
230
|
+
* @param method - RPC method name to invoke
|
|
231
|
+
* @param params - Optional parameter object passed with the request
|
|
232
|
+
* @param timeoutMs - Maximum time to wait for a response in milliseconds, defaulting to 60,000ms
|
|
233
|
+
* @returns Promise resolving with the response result
|
|
234
|
+
*/
|
|
206
235
|
request(method, params, timeoutMs = 6e4) {
|
|
207
236
|
if (this.exited) {
|
|
208
237
|
return Promise.reject(this.exitError ?? new Error("codex app-server is not running"));
|
|
@@ -217,9 +246,20 @@ var CodexAppServer = class {
|
|
|
217
246
|
this.send({ id, method, ...params !== void 0 ? { params } : {} });
|
|
218
247
|
});
|
|
219
248
|
}
|
|
249
|
+
/**
|
|
250
|
+
* Sends a one-way notification message to Codex without waiting for a response.
|
|
251
|
+
*
|
|
252
|
+
* @param method - Notification method name
|
|
253
|
+
* @param params - Optional parameter object passed with the notification
|
|
254
|
+
*/
|
|
220
255
|
notify(method, params) {
|
|
221
256
|
this.send({ method, ...params !== void 0 ? { params } : {} });
|
|
222
257
|
}
|
|
258
|
+
/**
|
|
259
|
+
* Sends the initial handshake request to Codex and emits the initialized notification upon response.
|
|
260
|
+
*
|
|
261
|
+
* @returns Promise resolving with the server initialization response payload
|
|
262
|
+
*/
|
|
223
263
|
async initialize() {
|
|
224
264
|
const result = await this.request("initialize", {
|
|
225
265
|
clientInfo: { name: "claude2codex", title: "Claude\u2194Codex Contract Bridge", version: "0.3.1" },
|
|
@@ -228,6 +268,9 @@ var CodexAppServer = class {
|
|
|
228
268
|
this.notify("initialized", {});
|
|
229
269
|
return result;
|
|
230
270
|
}
|
|
271
|
+
/**
|
|
272
|
+
* Gracefully terminates the running Codex child process via SIGTERM signal.
|
|
273
|
+
*/
|
|
231
274
|
kill() {
|
|
232
275
|
if (!this.exited) this.proc.kill("SIGTERM");
|
|
233
276
|
}
|
|
@@ -291,8 +334,24 @@ function createJobStore(dir = defaultStateDir()) {
|
|
|
291
334
|
warnOnce(error);
|
|
292
335
|
}
|
|
293
336
|
return {
|
|
337
|
+
/**
|
|
338
|
+
* Retrieves a job from memory by its unique identifier.
|
|
339
|
+
*
|
|
340
|
+
* @param id - Unique job identifier to look up
|
|
341
|
+
* @returns The matching Job object, or undefined if not found
|
|
342
|
+
*/
|
|
294
343
|
getJob: (id) => records.get(id),
|
|
344
|
+
/**
|
|
345
|
+
* Returns a list of all currently cached jobs.
|
|
346
|
+
*
|
|
347
|
+
* @returns Array of cached Job objects
|
|
348
|
+
*/
|
|
295
349
|
listJobs: () => [...records.values()],
|
|
350
|
+
/**
|
|
351
|
+
* Persists job state and transcript history to memory cache and atomic disk storage.
|
|
352
|
+
*
|
|
353
|
+
* @param job - Job object to be saved
|
|
354
|
+
*/
|
|
296
355
|
save(job) {
|
|
297
356
|
const record = { ...job, transcript: job.transcript.slice(-200) };
|
|
298
357
|
records.set(job.id, record);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude2codex",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "MCP server bridging Claude (architect/reviewer) and Codex (implementer) via Goal/Delta Contracts and Codex's thread-goal loop.",
|
|
6
6
|
"bin": {
|
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
"files": [
|
|
10
10
|
"dist",
|
|
11
11
|
"PATTERNS.md",
|
|
12
|
-
"PATTERNS.zh-CN.md"
|
|
12
|
+
"PATTERNS.zh-CN.md",
|
|
13
|
+
"c2c.skill.md"
|
|
13
14
|
],
|
|
14
15
|
"keywords": [
|
|
15
16
|
"mcp",
|
|
@@ -30,8 +31,8 @@
|
|
|
30
31
|
"start": "bun src/server.ts",
|
|
31
32
|
"build": "tsup",
|
|
32
33
|
"test": "bun test",
|
|
33
|
-
"prepack": "cp ../README.md ../README.zh-CN.md ../PATTERNS.md ../PATTERNS.zh-CN.md .",
|
|
34
|
-
"postpack": "rm -f README.md README.zh-CN.md PATTERNS.md PATTERNS.zh-CN.md"
|
|
34
|
+
"prepack": "cp ../README.md ../README.zh-CN.md ../PATTERNS.md ../PATTERNS.zh-CN.md ../c2c.skill.md .",
|
|
35
|
+
"postpack": "rm -f README.md README.zh-CN.md PATTERNS.md PATTERNS.zh-CN.md c2c.skill.md"
|
|
35
36
|
},
|
|
36
37
|
"dependencies": {
|
|
37
38
|
"@modelcontextprotocol/sdk": "^1.29.0",
|