Metadata-Version: 2.4
Name: codex2opencode
Version: 0.1.0
Summary: Local Codex-to-Opencode bridge CLI
Author: OpenAI Codex
License-Expression: MIT
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: license-file

# codex2opencode

`codex2opencode` is a local one-way bridge from Codex to Opencode.

It provides:

- a reusable Python CLI bridge
- Opencode session persistence via native `sessionID`
- deterministic per-thread locking
- export-backed session verification
- a thin Codex skill wrapper surface
- no non-stdlib Python runtime dependency inside the bridge

Current implementation target:

- macOS / POSIX environments with Python 3 and local Opencode CLI access
- not designed for Windows in its current `fcntl`-based form

## Current Status

Implemented and locally verified in this repository:

- `ask`
- `status`
- `forget`
- `gc`
- `doctor`
- automatic resume via stored Opencode `sessionID`
- Opencode-native `--fork`
- Opencode-native `--title`
- same-thread lock conflict handling

Primary verification commands:

- `PYTHONPATH=bridge python3 -m unittest discover -s tests -p 'test_*.py' -v`
- direct `codex2opencode ask ...` smoke
- direct `codex2opencode doctor ...` smoke
- opt-in real Opencode smoke when local auth is available

## Install

```bash
python3 -m venv .venv
source .venv/bin/activate
python3 -m pip install -e .
```

When a PyPI release is available:

```bash
python3 -m pip install codex2opencode
```

You can also run it directly without installing:

```bash
PYTHONPATH=bridge python3 -m codex2opencode ask --prompt "Reply with ok only" --workspace "$PWD"
```

After editable install, both of these work:

```bash
python -m codex2opencode --help
codex2opencode --help
```

## Usage

Ask Opencode in the current workspace thread:

```bash
codex2opencode ask --prompt "Review this design" --workspace "$PWD"
```

Successful `ask` output begins with a one-line metadata header before the reply body, for example:

```text
[oc provider=opencode model=mimo-v2-omni-free session=ses_...]
```

If session verification fails after a successful run, the bridge still prints the reply plus a minimal header with the session id, then exits non-zero.

Use a named thread:

```bash
codex2opencode ask --prompt "Continue the review" --workspace "$PWD" --thread review
```

Force a fresh session:

```bash
codex2opencode ask --prompt "Start over" --workspace "$PWD" --new
```

Fork the current mapped Opencode session:

```bash
codex2opencode ask --prompt "Take this in a different direction" --workspace "$PWD" --fork
```

Set an Opencode title on creation or fork:

```bash
codex2opencode ask --prompt "Review the release checklist" --workspace "$PWD" --new --title "release-review"
```

Inspect stored thread state:

```bash
codex2opencode status --workspace "$PWD"
```

Run diagnostics:

```bash
codex2opencode doctor --workspace "$PWD"
```

Forget the current thread and delete the mapped Opencode session:

```bash
codex2opencode forget --workspace "$PWD"
```

Remove stale bridge-owned files:

```bash
codex2opencode gc --max-age-days 7
```

## Threading Model

By default, one workspace maps to one Opencode thread.

Use `--thread <name>` to split conversations inside the same repo:

```bash
codex2opencode ask --prompt "Review API design" --workspace "$PWD" --thread api
codex2opencode ask --prompt "Review docs tone" --workspace "$PWD" --thread docs
```

Use `--new` when you want a fresh Opencode session for the selected thread key.

Use `--fork` when you want Opencode to branch from the current mapped session instead of starting unrelated context. `--new` and `--fork` are intentionally mutually exclusive.

## Codex Skill

The Codex-facing wrapper lives at:

```text
skills/codex-to-opencode/SKILL.md
```

The skill should stay thin. It should only:

- collect the user prompt
- choose default thread, named thread, `--new`, or `--fork`
- invoke `codex2opencode`
- return stdout or surface stderr

It must not own JSONL parsing, session storage, retries, export verification, or custom lock handling.

Recommended high-signal trigger phrases:

- `Use the codex-to-opencode skill`
- `ask Opencode about this`
- `ask oc about this`
- `send this to Opencode`
- `send this to oc`
- `let Opencode review this`
- `let oc review this`
- `give this to Opencode`
- `给 Opencode 看看`
- `给oc看看`
- `让 Opencode review 一下`
- `让oc review一下`
- `问问 Opencode`
- `问问oc`

Treat `oc` as a supported short alias for `Opencode` when it appears with a clear action.
Avoid relying on bare `opencode` by itself.
Avoid relying on bare `oc` by itself.
Trigger phrases should include a clear action like ask, review, check, continue, send, or look.

Practical everyday examples:

- `问问oc这个方案哪里最危险`
- `给oc看看这个 diff`
- `让oc review一下发布流程`
- `发给oc继续聊这个线程`
- `ask oc to review this design`

## Activation Scope

These paths are expected to work:

- new Codex sessions started after the skill was installed
- `codex exec` runs started after the skill was installed
- direct `codex2opencode` CLI usage

Do not assume already-open Codex sessions will hot-reload newly installed or updated skills.

If you changed trigger phrases or installed the skill during an existing session, restart Codex or open a fresh session before testing.

## Troubleshooting

If a trigger phrase does not route to Opencode:

1. Start a new Codex session.
2. Test with a high-signal phrase such as `Use the codex-to-opencode skill. Ask Opencode: reply with ok only.`
3. Verify the bridge directly with `codex2opencode ask --prompt "Reply with ok only" --workspace "$PWD"`.
4. Run `codex2opencode doctor --workspace "$PWD"` to confirm Opencode availability, debug-path output, and thread-state diagnostics.

If direct CLI usage works but a natural-language trigger does not, the issue is skill discovery in that session, not the bridge itself.

If `doctor` reports an `orphaned` thread state, the local mapping points at an Opencode session that no longer exports successfully. `forget` will remove that mapping and attempt remote deletion again.

## Environment

- `CODEX2OPENCODE_OPENCODE_BIN`: override the Opencode executable path
- `CODEX2OPENCODE_HOME`: override the bridge state root without changing your real shell `HOME`
- `CODEX2OPENCODE_RUN_REAL=1`: enable opt-in real Opencode integration tests

## Doctor Output

`codex2opencode doctor --workspace "$PWD"` prints JSON and checks:

- the resolved bridge root and key paths
- whether `opencode --version` is readable
- whether `opencode debug paths` is readable
- whether `opencode debug config` is parseable
- whether the selected thread state is `missing`, `ok`, `error`, or `orphaned`
- whether the mapped session can still be verified through `opencode export`
- whether the selected lock path is healthy or currently locked

It returns `0` when required checks are healthy and non-zero when Opencode availability checks fail, the state file is corrupted, or the mapped session is orphaned.

## State Layout

Default bridge state root:

```text
~/.codex/codex2opencode/
  threads/
  runs/
  logs/
```

Key files:

- `threads/<thread_key>.json`: current thread state
- `threads/<thread_key>.lock`: per-thread lock file
- `runs/<thread_key>/*.json`: per-run artifacts
- `logs/bridge.log`: append-only JSONL bridge events

## Boundaries

This repository is intentionally narrow:

- one-way Codex-to-Opencode only
- no Claude orchestration here
- no roundtable or multi-model discussion system
- no bridge-owned retry orchestration
- no over-generalized multi-backend framework

For design rationale and internals, see [ARCHITECTURE.md](./ARCHITECTURE.md).
For developer workflow, see [DEVELOPMENT.md](./DEVELOPMENT.md).
For contribution and release details, see [CONTRIBUTING.md](./CONTRIBUTING.md).
