@koreanhole/opencodex 2.99.0 → 3.1.0

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/AGENTS_INSTALL.md CHANGED
@@ -1,4 +1,4 @@
1
- # Installing and Operating the Cline + Gemini CLI Proxy
1
+ # Installing and Operating the OpenCodex ACP Distribution
2
2
 
3
3
  This file is for an agent that is installing or operating this package, not for
4
4
  an agent changing its source code.
@@ -6,11 +6,14 @@ an agent changing its source code.
6
6
  ## Install
7
7
 
8
8
  ```bash
9
- curl -fsSL https://bun.sh/install | bash
10
- export PATH="$HOME/.bun/bin:$PATH"
11
- bun install
9
+ npm install -g @koreanhole/opencodex
12
10
  ```
13
11
 
12
+ The package installs the pinned original opencodex runtime automatically. Do not
13
+ install or clone the original project separately. The original dashboard,
14
+ clients, providers, lifecycle, service, and update commands remain available
15
+ through the same command.
16
+
14
17
  Use the package CLI rather than invoking internal modules directly:
15
18
 
16
19
  ```bash
@@ -66,15 +69,20 @@ ocx restore back [--json]
66
69
  ocx eject
67
70
  ```
68
71
 
69
- The default listener is loopback-only. A non-loopback bind is refused unless a
70
- token is configured. There is no dashboard and no management GUI; if a command
71
- or URL for one is suggested, it is stale and must not be used.
72
+ The adapter gateway is loopback-only and uses a per-run bearer token. The
73
+ original opencodex listener and management surface follow upstream policy,
74
+ including the dashboard and non-loopback authentication rule.
75
+
76
+ `ocx update` is managed by this distribution. Install the package update with
77
+ `npm install -g @koreanhole/opencodex@latest`; never let the upstream updater
78
+ target `@bitkyc08/opencodex`.
72
79
 
73
80
  ## Verification
74
81
 
75
82
  Before claiming the proxy works, run:
76
83
 
77
84
  ```bash
85
+ bun run verify:upstream
78
86
  bun run typecheck
79
87
  bun test tests/e2e/cline-only.test.ts
80
88
  bun run test:e2e:gemini
package/README.md CHANGED
@@ -1,263 +1,146 @@
1
- # opencodex: Cline + Gemini CLI proxy
1
+ # opencodex: full upstream runtime + Cline JSON and Gemini CLI ACP adapters
2
2
 
3
- `ocx` is a small local proxy that lets OpenAI Codex and Claude Code use a locally
4
- installed Cline CLI or Gemini CLI as their model transport.
3
+ This distribution keeps the complete original
4
+ [`@bitkyc08/opencodex`](https://github.com/lidge-jun/opencodex) runtime and adds
5
+ locally installed Cline CLI and Gemini CLI as model providers. Cline turns use
6
+ the CLI's one-shot `--json` mode after a runtime `--help` capability check;
7
+ Gemini uses ACP.
5
8
 
6
- This fork contains only those two local CLI paths. There is no dashboard, desktop
7
- app, macOS widget, client-config integration writer, account pool, docs site, or
8
- GitHub Actions workflow.
9
+ The original package is an exact npm dependency. This repository does not copy,
10
+ patch, delete, or rewrite upstream source files. The `ocx` entrypoint loads the
11
+ original CLI in-process and attaches the two CLI adapters through a loopback
12
+ Responses gateway.
9
13
 
10
- ## Requirements
14
+ ## Install
15
+
16
+ ```bash
17
+ npm install -g @koreanhole/opencodex
18
+ ```
11
19
 
12
- - Bun 1.4.4 (the npm launcher installs the pinned runtime)
13
- - A locally installed and authenticated Cline CLI, Gemini CLI, or both
20
+ That single package installs the pinned upstream runtime as a normal dependency.
21
+ Do not install the original package separately and do not clone either project
22
+ just to run this distribution.
23
+
24
+ Vendor prerequisites remain separate:
14
25
 
15
26
  ```bash
16
27
  npm install -g cline
17
28
  cline auth
18
29
 
19
30
  npm install -g @google/gemini-cli
20
- gemini # configure GEMINI_API_KEY before using it through opencodex
31
+ gemini
21
32
  ```
22
33
 
23
- Cline must advertise ACP (`cline --help` includes `--acp`). opencodex uses ACP
24
- only and fails closed with `cline_acp_unsupported` for older one-shot-only
25
- builds.
26
-
27
- Gemini authentication remains in Gemini CLI's own home/settings. The proxy never
28
- copies, logs, or stores an API key, OAuth token, bearer token, or full request
29
- body.
30
-
31
- For third-party clients such as opencodex, use a Gemini Developer API key
32
- (Google AI Studio) or a Vertex AI GenAI API key. Do not use Gemini CLI's
33
- personal Google OAuth flow: Gemini CLI's official FAQ identifies third-party
34
- software piggybacking on its OAuth authentication as a terms violation and says
35
- the supported third-party method is an API key.
34
+ For third-party clients, use a Gemini Developer API key or Vertex AI GenAI API
35
+ key. Do not use personal Google OAuth for third-party software.
36
36
 
37
- ## Install
37
+ ## Start
38
38
 
39
39
  ```bash
40
- bun install
41
- bun run src/cli/index.ts provider add cline-cli --set-default
42
- bun run src/cli/index.ts start
40
+ ocx provider add gemini-cli --set-default
41
+ ocx provider add cline-cli
42
+ ocx start
43
43
  ```
44
44
 
45
- Select the Gemini transport instead with:
45
+ The original opencodex commands, dashboard, client integrations, account and
46
+ model management, service lifecycle, and restore behavior remain available
47
+ through the same `ocx` command.
46
48
 
47
- ```bash
48
- bun run src/cli/index.ts provider add gemini-cli --set-default
49
- bun run src/cli/index.ts start
50
- ```
49
+ The managed provider rows appear as `gemini-cli/...` and `cline-cli/...`.
50
+ Cline model discovery and explicit login use ACP, while Cline model turns use
51
+ the installed CLI's JSON transport. Gemini discovery, reasoning metadata, session
52
+ continuation, and tool intent come from this distribution's ACP implementation.
51
53
 
52
- The default config is `~/.opencodex/config.json`; set `OPENCODEX_HOME` to isolate
53
- it. The proxy listens on `http://127.0.0.1:10100/v1` by default. Existing
54
- Cline-only configs load unchanged and keep Cline as the default.
55
-
56
- ## Codex
54
+ ## Commands
57
55
 
58
- `ocx start` now records a mode-0600 pre-image under `$OPENCODEX_HOME/codex/`,
59
- injects the loopback Responses provider, and points Codex at the live model
60
- catalog. The managed block is marked and is the only block opencodex will touch.
56
+ Adapter-specific compatibility commands:
61
57
 
62
58
  ```bash
63
- ocx start
59
+ ocx login cline-cli [--json] [--no-wait]
60
+ ocx provider add <cline-cli|gemini-cli> [--set-default]
61
+ ocx provider use <cline-cli|gemini-cli>
62
+ ocx provider list [--json]
63
+ ocx adapter detach
64
64
  ```
65
65
 
66
- The resulting Codex config is equivalent to:
67
-
68
- ```toml
69
- model = "gemini-cli/gemini-3.5-flash-lite"
70
- model_provider = "opencodex"
71
-
72
- [model_providers.opencodex]
73
- name = "opencodex (Cline or Gemini CLI)"
74
- base_url = "http://127.0.0.1:10100/v1"
75
- wire_api = "responses"
76
- requires_openai_auth = false
77
- model_catalog_url = "http://127.0.0.1:10100/v1/model-catalog"
78
- ```
79
-
80
- Switch back to native Codex without stopping the proxy:
66
+ All other commands are delegated to the immutable upstream CLI. Examples:
81
67
 
82
68
  ```bash
83
- ocx restore # alias: ocx eject
84
- ocx restore back # re-point Codex at the running proxy
69
+ ocx start
70
+ ocx status
71
+ ocx stop
72
+ ocx restore
73
+ ocx sync
74
+ ocx service install
75
+ ocx gui
76
+ ocx doctor
85
77
  ```
86
78
 
87
- `ocx stop`, Ctrl-C/SIGTERM, and SIGHUP also restore native Codex. The restore
88
- covers Codex config and the opencodex catalog only; resume-history metadata is
89
- not changed. A pre-existing unmarked `[model_providers.opencodex]` block is
90
- treated as user-owned and refused. Remove a stale manual block first with
91
- `ocx restore --remove-codex-provider-table` if needed.
79
+ `ocx adapter detach` removes only the two managed provider rows or restores
80
+ their previous values from the mode-0600 journal.
92
81
 
93
- The model list is live. Cline ACP models are exposed as `cline-cli/<encoded-id>`;
94
- Gemini ACP models are exposed as `gemini-cli/<encoded-id>`. Each provider keeps a
95
- `default` selector. A provider prefix routes only to that vendor; unprefixed
96
- `default` uses the configured default provider.
82
+ ## Upstream updates
97
83
 
98
- Gemini model IDs and reasoning ladders are discovered from the installed Gemini
99
- CLI. Thinking-capable models expose the locally supported levels; non-thinking
100
- models do not get an invented ladder. For a running Codex app, refresh the active
101
- catalog and reload the app/app-server:
84
+ The dependency is pinned exactly:
102
85
 
103
- ```bash
104
- bun run src/cli/index.ts codex sync
86
+ ```json
87
+ {
88
+ "@bitkyc08/opencodex": "2.94.0"
89
+ }
105
90
  ```
106
91
 
107
- The command updates the root `model_catalog_json` target when it names an
108
- opencodex catalog, otherwise it writes `$CODEX_HOME/opencodex-catalog.json` and
109
- prints the activation setting. `model_catalog_url` avoids the file when the app
110
- catalog is fetched dynamically.
92
+ To adopt an upstream release:
111
93
 
112
- Codex 0.165.0 can use the Responses WebSocket transport when the provider sets
113
- `supports_websockets = true` and the process is started with
114
- `--enable responses_websockets`. opencodex accepts the WebSocket on
115
- `/v1/responses`, handles the `generate=false` warmup, and maps the following
116
- `previous_response_id` onto the stored Gemini session. HTTP remains the fallback.
94
+ 1. Change only the exact dependency version and refresh the lockfile.
95
+ 2. Run `bun run verify:upstream`.
96
+ 3. Run `bun run typecheck`, `bun test tests`, `bun run test:e2e`, and
97
+ `bun run test:e2e:gemini`.
98
+ 4. Accept the update only when every gate passes.
117
99
 
118
- Gemini context capacity, prompt modalities, and session-load support are
119
- discovered from the installed ACP agent at runtime; the proxy does not hardcode a
120
- model context window. A reusable Codex conversation uses
121
- `previous_response_id`, `prompt_cache_key`, or a documented conversation header
122
- to load the vendor session and send only the new input. Tool-use turns fall back
123
- to bounded replay because the vendor session is cancelled when a tool intent is
124
- captured.
100
+ No patch series or upstream source tree is maintained in this repository.
125
101
 
126
- ## Claude Code
102
+ `ocx update` and `ocx system update` are intercepted because the upstream
103
+ updater is hardcoded to the original package name. Update this distribution with:
127
104
 
128
105
  ```bash
129
- ANTHROPIC_BASE_URL=http://127.0.0.1:10100 \
130
- ANTHROPIC_AUTH_TOKEN=local \
131
- ANTHROPIC_MODEL=gemini-cli/gemini-3.5-flash-lite \
132
- claude
106
+ npm install -g @koreanhole/opencodex@latest
133
107
  ```
134
108
 
135
- Use a `cline-cli/...` model to route the same Messages surface to Cline.
109
+ Automatic upstream update checks are disabled for the delegated runtime.
136
110
 
137
111
  ## Security boundary
138
112
 
139
- - Neither Cline nor Gemini receives filesystem or terminal capability from the proxy.
140
- - Cline turns use a request-scoped Cline home with built-in/plugin tools, hooks,
141
- telemetry, updates, and automatic approval disabled. The real vendor provider
142
- store is immutable; a mode-0600 copy inside the staged home lets the vendor CLI
143
- refresh auth state and is removed after the turn.
144
- - Codex restore uses a mode-0600 journal under `$OPENCODEX_HOME/codex/`. The
145
- journal contains the pre-image needed to reverse only opencodex-managed config
146
- and catalog changes; it is never logged and is removed after a successful restore.
147
- - Gemini native tools are removed by a per-turn deny policy; permission requests
148
- are cancelled, and no ACP filesystem/terminal client capabilities are advertised.
149
- User MCP servers, extensions, skills, and hooks are disabled for the session; only
150
- the isolated `opencodex` MCP catalog can receive a client tool call.
151
- - Gemini runs with a staged `GEMINI_CLI_HOME` under opencodex control; only the
152
- minimum vendor auth files are linked from the real home, and staged session
153
- state is bounded and reclaimed.
154
- - Declared client tools are exposed only through a request-scoped MCP process that
155
- records bounded intent and never executes; Codex owns approval and execution.
156
- - Vendor credentials remain in the vendor's real home or authenticated
157
- environment. Cline's request-scoped copy is never logged or persisted beyond
158
- the turn. The proxy stores no vendor token.
159
- - Request-path traffic never starts an interactive login.
160
- - The listener is loopback-only by default; a non-loopback listener requires an
161
- explicit API token.
162
- - Image input is forwarded only when the selected Gemini model and ACP agent
163
- advertise image capability; video and audio input are rejected before a vendor
164
- process starts.
165
-
166
- ## Commands
167
-
168
- ```bash
169
- bun run src/cli/index.ts login cline-cli [--json] [--no-wait]
170
- bun run src/cli/index.ts provider add <cline-cli|gemini-cli> [--set-default]
171
- bun run src/cli/index.ts provider use <cline-cli|gemini-cli>
172
- bun run src/cli/index.ts provider list [--json]
173
- bun run src/cli/index.ts start [--port 10100] [--host 127.0.0.1]
174
- bun run src/cli/index.ts status [--json]
175
- bun run src/cli/index.ts stop [--json]
176
- bun run src/cli/index.ts restore [--json] [--remove-codex-provider-table]
177
- bun run src/cli/index.ts restore back [--json]
178
- bun run src/cli/index.ts eject
179
- ```
180
-
181
- Gemini has no proxy login command. Authenticate it through the official CLI
182
- (`gemini` or its API-key configuration); `ocx login gemini-cli` returns that
183
- guidance without prompting for or accepting a credential.
113
+ - Neither Cline nor Gemini receives filesystem or terminal capability from the
114
+ proxy.
115
+ - Cline runs with request-scoped, mode-0600 settings. Its built-in tools, user
116
+ MCP servers, hooks, plugins, telemetry, updates, and self-approval are disabled.
117
+ Its turn options are used only after the installed binary's `--help` output
118
+ advertises them.
119
+ - Gemini native tools are denied, user extensions/MCP/skills/hooks are disabled,
120
+ and only the isolated request-scoped MCP catalog can receive tool intent.
121
+ - Tool intent is returned to Codex for approval and execution.
122
+ - Vendor credentials stay in vendor homes or authenticated environments. The
123
+ proxy does not store or log vendor tokens.
124
+ - The adapter gateway binds `127.0.0.1` only and uses a per-run bearer token.
125
+ - Request bodies, API keys, bearer tokens, and full vendor diagnostics are never
126
+ logged.
184
127
 
185
128
  ## Tests
186
129
 
187
130
  ```bash
131
+ bun run verify:upstream
188
132
  bun run typecheck
189
133
  bun test tests
190
134
  bun run test:e2e
191
135
  bun run test:e2e:gemini
192
- bun run test:e2e:gemini-tool
193
- bun run test:e2e:gemini-multiturn
194
- bun run test:e2e:gemini-previous-response
195
- bun run test:e2e:gemini-websocket
196
- bun run test:e2e:gemini-websocket-tool
197
- bun run test:e2e:gemini-reasoning
198
- bun run test:e2e:codex-restore
199
136
  bun run privacy:scan
200
137
  bun run structure:check
201
138
  ```
202
139
 
203
- The deterministic suite uses ACP fixtures for both providers and fails rather than
204
- skipping missing fixture/process behavior. `test:e2e` covers Cline HTTP behavior.
205
-
206
- `test:e2e:gemini` is the one-completion text gate. It starts an isolated
207
- opencodex listener, discovers the real authenticated Gemini roster, chooses an
208
- advertised Flash Lite model, writes an isolated `CODEX_HOME`, runs one real Codex
209
- prompt, and asserts the response marker, observed model, and child cleanup.
210
-
211
- `test:e2e:gemini-tool` exercises the two-completion tool loop: Gemini requests
212
- Codex's `exec_command`, Codex executes a fixed read-only `printf`, and Gemini
213
- returns the final answer. Both commands use no retries. Missing binaries,
214
- authentication, or a Flash Lite model cause a hard failure.
215
-
216
- `test:e2e:gemini-multiturn` starts a persisted real Codex session, resumes it with
217
- `codex exec resume`, and asserts that the proxy loads the Gemini session and
218
- sends only the new turn. Codex 0.165.0 sends `prompt_cache_key` for this path.
219
-
220
- `test:e2e:gemini-previous-response` sends a direct Responses continuation with
221
- `previous_response_id` and verifies that the proxy loads the stored Gemini
222
- session and sends only the new input.
223
-
224
- `test:e2e:gemini-websocket` and `test:e2e:gemini-websocket-tool` enable Codex's
225
- actual WebSocket transport with `supports_websockets = true` and
226
- `--enable responses_websockets`. They verify the `generate=false` warmup, the
227
- real request's non-empty `previous_response_id`, and the WebSocket tool loop.
228
-
229
- `test:e2e:gemini-reasoning` discovers a thinking-capable model and level from the
230
- local Gemini CLI, validates the refreshed Codex catalog, and runs one minimal
231
- reasoning-enabled turn. It fails when the authenticated account cannot execute
232
- the discovered model.
233
-
234
- Optional overrides are `CLINE_BIN_PATH`, `GEMINI_BIN_PATH`, and `CODEX_BIN_PATH`.
235
-
236
- ## Troubleshooting
237
-
238
- - **Cline not found**: install `cline` and verify `cline --help` works.
239
- - **Cline authentication required**: run `ocx login cline-cli`, then retry.
240
- - **Cline ACP unavailable**: opencodex no longer falls back to the one-shot JSON
241
- path. Upgrade Cline so `cline --help` advertises `--acp`, or set
242
- `OPENCODEX_CLINE_ACP=1`; otherwise requests fail with
243
- `cline_acp_unsupported`.
244
- - **Gemini not found**: install it and verify `gemini --help` works, or set
245
- `GEMINI_BIN_PATH`.
246
- - **Gemini authentication required**: configure a Gemini Developer API key or
247
- Vertex AI API key for Gemini CLI; do not use personal Google OAuth with this
248
- third-party proxy and do not pass the key to opencodex.
249
- - **Gemini ACP unavailable**: upgrade Gemini CLI to a version advertising `--acp`.
250
- - **Gemini Pro quota exhausted**: reasoning-capable models may require paid Pro
251
- quota; the catalog stays accurate but that model cannot complete a live turn.
252
- - **Codex model picker is stale**: run `ocx codex sync`, then restart the Codex
253
- app/app-server.
254
- - **Codex provider conflict**: an existing unmarked
255
- `[model_providers.opencodex]` was preserved. Reconcile it manually or use
256
- `ocx restore --remove-codex-provider-table`, then start again.
257
- - **Port in use**: choose another port with `ocx start --port <port>`.
258
- - **Stale runtime state**: run `ocx stop`; it removes stale state only when the
259
- recorded process and health endpoint cannot be verified.
260
-
261
- ## License
262
-
263
- MIT. See [LICENSE](LICENSE).
140
+ `test:e2e:gemini` starts the original runtime and the adapter gateway, then uses
141
+ a real Codex client and a real authenticated Gemini CLI. It fails, not skips, on
142
+ a missing binary, authentication, Flash Lite model, response marker, or child
143
+ cleanup assertion.
144
+
145
+ Optional overrides are `CLINE_BIN_PATH`, `GEMINI_BIN_PATH`, and
146
+ `CODEX_BIN_PATH`.
package/bin/ocx.mjs CHANGED
@@ -7,7 +7,7 @@ import { fileURLToPath } from "node:url";
7
7
 
8
8
  const require = createRequire(import.meta.url);
9
9
  const here = dirname(fileURLToPath(import.meta.url));
10
- const cli = join(here, "..", "src", "cli", "index.ts");
10
+ const cli = join(here, "..", "src", "cli", "entry.ts");
11
11
 
12
12
  function bundledBun() {
13
13
  try {
@@ -1,3 +1,7 @@
1
+ import { createRequire } from "node:module";
2
+ import { dirname, join } from "node:path";
3
+ import { pathToFileURL } from "node:url";
4
+
1
5
  export const packageName = "@koreanhole/opencodex";
2
6
  export const cliCommand = "ocx";
3
7
 
@@ -5,5 +9,11 @@ export async function loadBunApi() {
5
9
  if (typeof Bun === "undefined") {
6
10
  throw new Error("The opencodex programmatic API requires Bun. Use `ocx` for the CLI.");
7
11
  }
8
- return import("../src/index.ts");
12
+ const require = createRequire(import.meta.url);
13
+ const upstreamPackage = require.resolve("@bitkyc08/opencodex/package.json");
14
+ const upstream = await import(
15
+ pathToFileURL(join(dirname(upstreamPackage), "src", "index.ts")).href
16
+ );
17
+ const local = await import("../src/index.ts");
18
+ return { ...upstream, ...local, upstream, local };
9
19
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@koreanhole/opencodex",
3
- "version": "2.99.0",
4
- "description": "Cline and Gemini CLI provider proxy for OpenAI Codex and Claude Code",
3
+ "version": "3.1.0",
4
+ "description": "Full opencodex runtime with Cline JSON and Gemini CLI ACP provider adapters",
5
5
  "type": "module",
6
6
  "main": "./bin/package-main.mjs",
7
7
  "exports": {
@@ -26,8 +26,8 @@
26
26
  "node": ">=18"
27
27
  },
28
28
  "scripts": {
29
- "dev": "bun run src/cli/index.ts start",
30
- "start": "bun run src/cli/index.ts start",
29
+ "dev": "bun run src/cli/entry.ts start",
30
+ "start": "bun run src/cli/entry.ts start",
31
31
  "test": "bun test tests",
32
32
  "test:e2e": "bun test tests/e2e/cline-only.test.ts",
33
33
  "test:e2e:gemini": "bun test ./tests/e2e/gemini-codex.live.ts -t \"one minimal Flash Lite completion\"",
@@ -41,11 +41,13 @@
41
41
  "typecheck": "bun check --no-script --noEmit",
42
42
  "privacy:scan": "bun scripts/privacy-scan.ts",
43
43
  "structure:check": "bun scripts/structure-check.ts",
44
- "prepush": "bun run typecheck && bun run test && bun run privacy:scan && bun run structure:check",
45
- "prepublishOnly": "bun run typecheck && bun run test"
44
+ "verify:upstream": "bun scripts/verify-upstream.ts",
45
+ "prepush": "bun run verify:upstream && bun run typecheck && bun run test && bun run privacy:scan && bun run structure:check",
46
+ "prepublishOnly": "bun run verify:upstream && bun run typecheck && bun run test"
46
47
  },
47
48
  "dependencies": {
48
49
  "@agentclientprotocol/sdk": "1.9.0",
50
+ "@bitkyc08/opencodex": "2.94.0",
49
51
  "@modelcontextprotocol/sdk": "^1.32.1",
50
52
  "bun": "1.4.4"
51
53
  },