Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 45 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ Steer, Mic, Submit, and Latest Task & Scroll Encoder actions.
| Local-only transport | Bind CDP and the Bridge API to loopback addresses only |

This Ulanzi-maintained project is an unofficial integration with Codex Desktop
for **macOS, Ulanzi Studio, and Ulanzi D200 Series**. It is not affiliated with or
endorsed by OpenAI. The entire project was vibe-coded with Codex.
for **Windows or macOS, Ulanzi Studio, and Ulanzi D200 Series**. It is not
affiliated with or endorsed by OpenAI.

Ulanzi's implementation and maintenance scope is limited to
`integration/com.ulanzi.codexmicro.ulanziPlugin/`. The plugin only consumes
Expand All @@ -38,8 +38,8 @@ responsibility boundary.

### Installation environment

- macOS 13 or later;
- Codex Desktop;
- Windows 10 or later, or macOS 13 or later;
- Codex Desktop Stable or Beta;
- Ulanzi Studio 3.0.1 or later;
- Ulanzi D200 Series connected to Ulanzi Studio;
- Node.js 20 or newer only for repository-based manual installation.
Expand All @@ -49,15 +49,16 @@ responsibility boundary.
An LLM or coding agent must follow these steps:

1. Read [AGENTS.md](AGENTS.md) and inspect the installed Ulanzi Studio plugin
manifests under `~/Library/Application Support/Ulanzi/UlanziDeck/Plugins/`.
manifests under `%APPDATA%\Ulanzi\UlanziDeck\Plugins` on Windows or
`~/Library/Application Support/Ulanzi/UlanziDeck/Plugins` on macOS.
2. Treat Codex Micro as installed only when manifest UUID
`com.ulanzi.ulanzistudio.codexmicro` is present and its `CodePath` exists.
3. If it is missing or invalid, load
[`$install-ulanzi-studio-plugin`](skills/install-ulanzi-studio-plugin/SKILL.md),
install the plugin, and verify its manifest and entry point.
4. After the plugin is verified, load
[`$setup-codex-bridge`](skills/setup-codex-bridge/SKILL.md), install or repair
`Codex Bridge.app` and its sidecar, and verify the local health endpoint.
Codex Bridge and its sidecar, and verify the local health endpoint.
5. Report plugin installation and Bridge connectivity separately. Do not
reinstall a valid plugin unless an update or repair was requested.

Expand All @@ -66,13 +67,17 @@ An LLM or coding agent must follow these steps:
After installing the Codex Micro plugin, drag any Codex Micro action onto a
key and select it. Its shared **Codex Bridge Setup** page can:

- show whether `Codex Bridge.app`, the Bridge service, and CDP are available;
- show whether Codex Bridge, its user-level service, and CDP are available;
- install or repair the bundled Bridge without a repository or npm directory;
- launch `~/Applications/Codex Bridge.app`; and
- launch Codex with loopback-only CDP arguments; and
- recheck the connection or open the full installation guide.

The installer writes only to the current user's Applications, Application
Support, and LaunchAgents directories and does not require `sudo`.
The installer uses `%LOCALAPPDATA%\OpenCodexMicro` for Windows user data and a
hash-verified protected runtime under `%PROGRAMDATA%\OpenCodexMicro\Bridge`.
Windows requests administrator approval for first installation and protected
Bridge code updates; normal starts remain silent. On macOS it uses the current
user's Applications, Application Support, and LaunchAgents directories without
administrator access.

### 3. Manual installation

Expand All @@ -85,13 +90,18 @@ npm run setup
```

Quit Ulanzi Studio before running `npm run install:plugin`. The command
validates and atomically installs the prebuilt plugin. `npm run setup` builds
the loopback Bridge sidecar, registers its user LaunchAgent, and installs
`Codex Bridge.app` in `~/Applications`.

Reopen Ulanzi Studio. Quit Codex Desktop, then open
`~/Applications/Codex Bridge.app`; the wrapper starts Codex with a
loopback-only CDP endpoint. Confirm the connection with:
validates and atomically installs the prebuilt plugin. If Bridge is already
installed, the command also verifies its version and runtime hash, then safely
updates and restarts it when needed. `npm run setup` performs the initial Bridge
installation or an explicit repair.

Reopen Ulanzi Studio. **Launch Codex Bridge** and `npm run bridge:start` remain
available for manual startup and diagnostics, but a configured Task key also
invokes the same launch path whenever ChatGPT/CDP is unavailable. On Windows the
launcher discovers the current Stable or Beta Appx package dynamically; it never
pins a versioned WindowsApps directory. A desktop shortcut whose target points
at a version-specific `WindowsApps` directory is neither required nor used.
Confirm the connection with:

```bash
curl http://127.0.0.1:17373/health
Expand All @@ -102,14 +112,12 @@ In Ulanzi Studio, drag the Codex Micro actions onto the desired keys. See
[Setup and operations](docs/setup-and-operations.md) for installed paths,
diagnostics, updates, and uninstall instructions.

> **Important:** When using Codex Micro, always launch Codex through
> `~/Applications/Codex Bridge.app`. Do not open Codex Desktop directly.
>
> Launch command:
>
> ```bash
> open ~/Applications/Codex\ Bridge.app
> ```
> **Important:** Codex must be started with the loopback CDP arguments shown in
> the setup page. If `9222` is already available, a Task key or Launch only
> focuses the current Codex instance. If it is unavailable, the first Task press
> may restart that channel's main ChatGPT process once with the required
> arguments, wait for Bridge state to become connected, and then continue the
> requested task activation.

## Configure

Expand All @@ -118,6 +126,17 @@ actions: Codex Task 1–5, Fast, Usage, Pin, New, Fork, Steer, Mic, Submit, and
Latest Task & Scroll for Encoder controls.
No separate device daemon or shortcut mapping is required.

On Windows, focus stays bound to the PID that owns the active CDP listener. The
adapter revalidates cached windows, prefers unowned displayed top-level windows,
and falls back to another displayed window from that same PID without relying on
window titles, versioned Appx paths, or a global keyboard hook.

A Task press is successful only after both the requested renderer task is
confirmed active and the matching ChatGPT window is confirmed in the foreground.
Native Micro navigation is attempted first; DOM activation is a bounded fallback,
and a focus or activation failure is reported instead of being logged as partial
success.

Select any configured action to open the shared **Codex Bridge Setup** page.
It shows Bridge installation, service, and CDP status and provides Install /
Repair and Launch controls.
Expand All @@ -132,7 +151,7 @@ The repository includes two reusable Codex skills:

| Skill | Purpose |
| --- | --- |
| [`setup-codex-bridge`](skills/setup-codex-bridge/SKILL.md) | Install, update, verify, or repair `Codex Bridge.app` and its sidecar |
| [`setup-codex-bridge`](skills/setup-codex-bridge/SKILL.md) | Install, update, verify, or repair Codex Bridge and its sidecar |
| [`install-ulanzi-studio-plugin`](skills/install-ulanzi-studio-plugin/SKILL.md) | Install the repository's prebuilt plugin directory into Ulanzi Studio |

## Documentation
Expand Down
45 changes: 22 additions & 23 deletions README_zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ Ulanzi 的实现与维护范围仅限

### 安装环境

- macOS 13 或更高版本;
- Codex Desktop;
- Windows 10 或更高版本,或 macOS 13 或更高版本;
- Codex Desktop Stable 或 Beta
- Ulanzi Studio 3.0.1 或更高版本;
- 已在 Ulanzi Studio 中连接 Ulanzi D200 Series;
- 仅使用仓库手动安装时需要 Node.js 20 或更高版本。
Expand All @@ -44,17 +44,17 @@ Ulanzi 的实现与维护范围仅限

LLM 或代码 Agent 必须按以下步骤执行:

1. 阅读 [AGENTS.md](AGENTS.md),检查
`~/Library/Application Support/Ulanzi/UlanziDeck/Plugins/` 下已经安装的插件
manifest。
1. 阅读 [AGENTS.md](AGENTS.md),检查 Windows 的
`%APPDATA%\Ulanzi\UlanziDeck\Plugins` 或 macOS 的
`~/Library/Application Support/Ulanzi/UlanziDeck/Plugins` 下已经安装的插件 manifest。
2. 仅当 manifest UUID 为 `com.ulanzi.ulanzistudio.codexmicro`,且其 `CodePath`
确实存在时,才判断 Codex Micro 已安装。
3. 如果插件缺失或无效,加载
[`$install-ulanzi-studio-plugin`](skills/install-ulanzi-studio-plugin/SKILL.md),
安装插件并验证 manifest 和入口文件。
4. 插件验证通过后,加载
[`$setup-codex-bridge`](skills/setup-codex-bridge/SKILL.md),安装或修复
`Codex Bridge.app` 与 sidecar,并验证本机 health 接口。
Codex Bridge 与 sidecar,并验证本机 health 接口。
5. 分别报告插件安装状态和 Bridge 连接状态。除非用户要求更新或修复,否则不要重复
安装有效插件。

Expand All @@ -63,13 +63,13 @@ LLM 或代码 Agent 必须按以下步骤执行:
安装 Codex Micro 插件后,把任意 Codex Micro Action 拖到按键并选中。所有 Action
共用的 **Codex Bridge 设置**页可以:

- 显示 `Codex Bridge.app`、Bridge 后台服务和 CDP 的状态;
- 显示 Codex Bridge、用户级后台进程和 CDP 的状态;
- 使用插件内置资源安装或修复 Bridge,不需要仓库目录或 npm 项目目录;
- 启动 `~/Applications/Codex Bridge.app`
- 使用仅限回环地址的 CDP 参数启动 Codex
- 重新检测连接或打开完整安装说明。

安装器只写入当前用户的 Applications、Application Support 和 LaunchAgents 目录,
不需要 `sudo`
Windows 安装器写入 `%LOCALAPPDATA%\OpenCodexMicro`;macOS 安装器写入当前用户的
Applications、Application Support 和 LaunchAgents 目录。两者都不需要管理员权限

### 3. 手动安装

Expand All @@ -82,11 +82,12 @@ npm run setup
```

运行 `npm run install:plugin` 前请退出 Ulanzi Studio。该命令会校验并原子安装仓库
中的预构建插件;`npm run setup` 会构建本机 Bridge sidecar、注册用户级
LaunchAgent,并把 `Codex Bridge.app` 安装到 `~/Applications`
中的预构建插件;若 Bridge 已安装,还会校验其版本与 runtime hash,并在需要时安全
更新和重启。`npm run setup` 用于首次安装 Bridge 或显式修复

重新打开 Ulanzi Studio。完全退出 Codex Desktop,再打开
`~/Applications/Codex Bridge.app`。可用以下命令确认连接:
重新打开 Ulanzi Studio,在任意 Action 设置页点击“启动 Codex Bridge”,或运行
`npm run bridge:start`。Windows 会从 Appx 包元数据动态发现 Stable 或 Beta,
不会固定带版本号的 WindowsApps 目录。可用以下命令确认连接:

```bash
curl http://127.0.0.1:17373/health
Expand All @@ -96,21 +97,19 @@ curl http://127.0.0.1:17373/state
最后在 Ulanzi Studio 中把 Codex Micro actions 拖到需要的按键。安装路径、诊断、
更新与卸载方法见 [安装与运行](docs/setup-and-operations.md)。

> **注意事项:** 使用 Codex Micro 时,必须通过
> `~/Applications/Codex Bridge.app` 启动 Codex,请勿直接打开 Codex Desktop。
>
> 启动命令:
>
> ```bash
> open ~/Applications/Codex\ Bridge.app
> ```
> **注意事项:** Codex 必须带设置页所示的本机回环 CDP 参数启动。如果 `9222`
> 已在线,“启动”只会聚焦当前 Codex;否则会启动所选 Stable 或 Beta 通道。

## 配置

实体布局完全由 Ulanzi Studio 管理。插件提供 Codex Task 1–5、Fast、Usage、Pin、
New、Fork、Steer、Mic、Submit 和 Latest Task & Scroll 旋钮 Action,不需要额外的
设备 daemon 或快捷键映射。

Windows 聚焦始终绑定当前 CDP listener 对应的 PID。adapter 会重新校验缓存窗口,
优先选择无 owner 的可见顶层主窗口,并只在同一 PID 内回退到其他可见窗口;不会依赖
窗口标题、带版本号的 Appx 路径或全局键盘钩子。

选中任意已配置的 Action,即可打开共用的 **Codex Bridge 设置**页。该页面显示
Bridge 安装、后台服务和 CDP 状态,并提供“安装 / 修复”和“启动”操作。

Expand All @@ -123,7 +122,7 @@ Action 行为和布局建议见[配置详解](docs/configuration.md)。

| Skill | 用途 |
| --- | --- |
| [`setup-codex-bridge`](skills/setup-codex-bridge/SKILL.md) | 安装、更新、验证或修复 `Codex Bridge.app` 与 sidecar |
| [`setup-codex-bridge`](skills/setup-codex-bridge/SKILL.md) | 安装、更新、验证或修复 Codex Bridge 与 sidecar |
| [`install-ulanzi-studio-plugin`](skills/install-ulanzi-studio-plugin/SKILL.md) | 把仓库中的预构建插件目录安装到 Ulanzi Studio |

## 文档
Expand Down
26 changes: 26 additions & 0 deletions THIRD_PARTY_NOTICES.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,32 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

## Koffi

- Project: https://koffi.dev/
- Use: Low-overhead in-process Win32 FFI for Codex Desktop window activation
- License: MIT

Copyright 2023 Niels Martignène <niels.martignene@protonmail.com>

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

## esbuild

- Project: https://github.com/evanw/esbuild
Expand Down
44 changes: 35 additions & 9 deletions docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,11 @@ Codex renderer Micro store

## Codex Bridge

`Codex Bridge.app` launches the real Codex executable with CDP restricted to
`127.0.0.1:9222`. The sidecar keeps a persistent renderer connection and
Codex Bridge launches the real Codex executable with CDP restricted to
`127.0.0.1:9222`. Windows discovers Stable or Beta through Appx metadata and the
Ulanzi plugin supervises a current-user, on-demand scheduled task running at
`HighestAvailable`; macOS retains the wrapper app and user LaunchAgent. The
sidecar keeps a persistent renderer connection and
refreshes an in-memory snapshot every 500 ms. `/state` reads that cache rather
than triggering a fresh renderer scan for every plugin poll.

Expand All @@ -29,19 +32,39 @@ context map, and usage query clients. Those references are cached for the
renderer lifecycle and rediscovered only when they become invalid.

Task activation and Fast, Fork, Submit, and Mic use Codex Micro events. Pin,
New, and Steer invoke the matching semantic renderer controls. An uncertain
HTTP failure is never replayed through another mechanism because the first
request may already have executed.
New, Steer, and the three model presets invoke semantic renderer controls. The
model adapter requires the visible intelligence trigger, validates the exact
model option and reasoning-effort ordering, and verifies the final selection.
An uncertain HTTP failure is never replayed through another mechanism because
the first request may already have executed.

## Ulanzi Studio plugin

The plugin is a Node.js JavaScript plugin using protocol V3.0.0. It polls the
Bridge state, keeps each Ulanzi action instance keyed by its context, updates
task icons and titles, and forwards keydown/keyup events to the Bridge.

The installed Bridge is identified by plugin version plus the SHA-256 of its
runtime. `/health` reports the running version and runtime hash. Plugin startup
reconciles an existing Bridge when metadata, the installed file, or the running
process differs from the bundled runtime; replacement uses a targeted Bridge-only
stop, a cross-process lifecycle lock, a recoverable runtime swap, restart
confirmation, and rollback on failure.
On Windows, task code and its Node runtime are copied to an
administrator-protected `%PROGRAMDATA%` root. The task has no automatic trigger
and contains no capability token. A hash-validating protected launcher selects
only previously approved, hash-addressed runtimes; this permits silent starts and
rollback without making `%LOCALAPPDATA%` executable as administrator. Installing,
updating, or removing protected code requires one UAC confirmation.
Interrupted transactions restore runtime and metadata together before retrying;
plugin startup also applies bounded backoff for transient reconciliation errors.

The distributed entry point is the committed CommonJS file `dist/app.js`.
Build and smoke checks happen during development; `scripts/install-plugin.mjs`
only validates and atomically copies the prebuilt `.ulanziPlugin` directory.
validates and atomically copies the prebuilt `.ulanziPlugin` directory, then
reconciles an already-installed Bridge before discarding the plugin backup.
Independent `install:plugin` processes share an owner-checked filesystem lock;
Bridge mutations use a separate owner-checked lifecycle lock.

Ulanzi's implementation and maintenance scope is limited to
`integration/com.ulanzi.codexmicro.ulanziPlugin/`. The plugin is only the
Expand All @@ -51,7 +74,10 @@ development, or maintenance of CDP or Codex's CDP implementation.

## Installation boundary

- `scripts/install.mjs` installs only the Bridge sidecar and
`~/Applications/Codex Bridge.app`.
- `scripts/install-plugin.mjs` installs only the Ulanzi Studio plugin directory.
- `scripts/install.mjs` installs only the Bridge sidecar and its
platform-specific launcher/lifecycle files. Windows additionally registers the
current-user highest-privilege scheduled task; macOS remains user-level.
- `scripts/install-plugin.mjs` atomically installs the Ulanzi Studio plugin
directory and reconciles an already-installed Bridge to the bundled runtime.
It does not perform the initial Bridge installation.
- `scripts/uninstall.mjs` removes those two installed components.
Loading