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