Skip to main content
Glama
NealZhi
by NealZhi
README.md
<p align="center">
  <a href="./README.md"><img src="https://img.shields.io/badge/lang-中文-red.svg" alt="中文"></a>
  <a href="./README.en.md"><img src="https://img.shields.io/badge/lang-English-blue.svg" alt="English"></a>
</p>

# Codex JetBrains HUD + Hooks 接入说明

> 项目背景:这个适配方案是基于对 `Claude Code v2.1.88` 泄露源码的分析做出来的,目标是让 `Codex` 也具备类似 `Claude Code` 的能力,能够感知 JetBrains 系列 IDE 当前选中的文件、行号和代码范围。
>
> Author: `nealzhi`

本文档只保留一条接入路径:**HUD + hooks**。

本仓库已经移除了旧的“本地 MCP server + 全局提示词”方案,不再推荐也不再提供那套接法。

![成功截图](./screenshot.png)

## 1. 前提

先满足下面两个条件:

1. 你使用的是 JetBrains 系列 IDE  
   例如:`IntelliJ IDEA`、`PyCharm`、`WebStorm`、`GoLand`、`Android Studio`
2. 你的 IDE 已安装 **Claude Code 官方 JetBrains 插件**  
   这是联动前提。没有这个插件,就不会有本地 `~/.claude/ide/*.lock` 和对应的本地接口,Codex 也就无法读取当前选中的文件和代码范围。

## 2. 安装依赖

在仓库根目录执行:

```bash
cd codex-jetbrains-mcp
npm install
brew install tmux
```

说明:

- `npm install`:安装 HUD 和 hooks 依赖
- `tmux`:HUD 依赖

## 3. 接入 HUD

在仓库根目录执行:

```bash
chmod +x codex-jetbrains-mcp/bin/codex-jetbrains-hud
```

如果你希望以后直接运行 `codex` 就自动带 HUD,请把下面这一行加到 `~/.zshrc` 或 `~/.bashrc`:

```bash
alias codex='$(pwd)/codex-jetbrains-mcp/bin/codex-jetbrains-hud'
```

重新加载 shell:

```bash
source ~/.zshrc
```

如果你用的是 `bash`,就执行:

```bash
source ~/.bashrc
```

如果你在 macOS 自带终端或 Warp 终端里发现鼠标滚轮无法滚动 Codex 窗口,可以执行下面这条命令开启 `tmux` 鼠标支持:

```bash
tmux set -g mouse on
```

HUD 启动后会显示一行:

```text
JetBrains PyCharm 已连接 | test_main.py:2140-2147 (8 lines)
```

## 4. 配置 hooks

这套方案的核心就是:

1. 启动 `codex` 时同时启动 HUD
2. HUD 自动把 JetBrains 当前文件/行号写入 `.codex/jetbrains-selection-state.json`
3. `UserPromptSubmit` hook 在你发消息时读取这份状态
4. 有 JetBrains 上下文时,只注入“文件路径”或“文件路径 + 行号”
5. 不注入选中文本,让 Codex 自己按需读文件

### 4.1 推荐启动方式

在仓库根目录执行:

```bash
chmod +x codex-jetbrains-mcp/bin/codex-jetbrains-hud
alias codex='$(pwd)/codex-jetbrains-mcp/bin/codex-jetbrains-hud'
```

之后你正常执行 `codex` 即可。

现在 `codex-jetbrains-hud` 除了显示 HUD,还会自动同步 hook 所需状态。这是唯一推荐路径,不需要也不再提供单独的同步进程。

状态文件会写到:

```text
.codex/jetbrains-selection-state.json
```

### 4.2 配置 hooks

仓库里已经带了:

- `.codex/config.toml`
- `.codex/hooks/selection-state.mjs`
- `.codex/hooks.json`
- `.codex/hooks/user-prompt-submit-jetbrains-selection.mjs`

接入方式分两种:

1. 如果你在这个仓库目录里启动 `codex`
   Codex 会直接读取仓库里的 `.codex/config.toml` 和 `.codex/hooks.json`,不需要你再额外指定路径。
2. 如果你已经有自己的全局 `~/.codex/hooks.json`
   不要覆盖它,把仓库里这个 `UserPromptSubmit` 配置合并进去就行。
   如果你要复制到 `~/.codex/hooks/`,请把整个 `.codex/hooks/` 目录一起复制,不要只拷贝入口文件。

其中 `.codex/config.toml` 的作用是打开官方要求的 hooks 功能开关:

```toml
[features]
codex_hooks = true
```

按官方文档,hooks 默认是关闭的,必须在 `config.toml` 里开启,或者启动时传 `codex --enable codex_hooks`。另外,Codex 的配置层会从 `~/.codex/config.toml` 和仓库内 `.codex/config.toml` 一起读取;如果项目没有被标记为 trusted,仓库级 `.codex/config.toml` 不会生效。

仓库自带的配置内容就是:

```json
{
  "hooks": {
    "UserPromptSubmit": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "node \"$(git rev-parse --show-toplevel)/.codex/hooks/user-prompt-submit-jetbrains-selection.mjs\"",
            "statusMessage": "Loading JetBrains selection"
          }
        ]
      }
    ]
  }
}
```

这个 hook 会在每次 `UserPromptSubmit` 时读取本地状态文件:

- 如果当前只选中了文件,就给 Codex 注入“当前文件是哪个”
- 如果当前选中了代码范围,就给 Codex 注入“当前文件 + 行号”
- 如果当前没有 JetBrains 上下文,或者状态已经过期,就什么都不注入

它不会注入代码文本,只做位置指引。

### 4.3 清理旧配置

如果你以前接过旧版方案,请把下面两样删掉:

1. 删除本地 MCP 配置

```bash
codex mcp remove jetbrains-selection
```

2. 删除你自己的全局提示词里这类内容

```text
每次用户请求时,先调用 MCP 工具 jetbrains-selection.jetbrains_get_selection 获取 JetBrains 当前选区
```

这一步一定要做,不然模型还是可能沿着旧思路去调用一个已经不存在的 MCP 工具。

### 4.4 hook 实际注入的内容

只选中文件时,注入类似:

```text
JetBrains 当前选中文件:/path/to/file.ts
这只是文件指引,没有附带文件内容。
如果本轮问题和这个文件相关,请先自行读取该文件;如果无关,请忽略这条上下文。
```

选中了代码行号时,注入类似:

```text
JetBrains 当前选中位置:/path/to/file.ts:120-146
这只是位置指引,没有附带代码内容。
如果本轮问题和这个位置相关,请先自行读取对应文件和行号;如果无关,请忽略这条上下文。
```

默认状态有效期是 `20s`。HUD 运行期间会每 `5s` 刷新一次状态;如果 HUD 退出,hook 很快就会停止注入旧状态。你也可以通过环境变量 `CODEX_JB_HOOK_MAX_AGE_MS` 调整这个时间。

## 5. 为什么不再保留本地 MCP 方案

旧方案的问题主要有这几类:

- 需要额外执行 `codex mcp add`,多一层安装和维护成本
- 模型通常还要依赖全局提示词强制“每轮先调用一次 MCP”,即使这轮问题跟 JetBrains 选区无关,也会白走一步
- 选区是否相关,本来应该由当前提问来决定;放到全局提示词里会让行为过于机械
- 本地 MCP server 只是中转层,实际还是要连 Claude Code JetBrains 插件;这层单独保留,收益不高,复杂度更高
- 旧配置不容易清理干净,迁移后很容易残留无效工具名或旧提示词

改成 HUD + hooks 之后,收益会更直接:

- 只有在发消息时才读取本地状态,不再每轮多起一层 MCP 调用
- 注入内容只包含文件路径或行号,信息量更干净,模型再自己决定要不要去读文件
- 状态文件按项目根目录隔离,不同项目各写各的 `.codex/jetbrains-selection-state.json`
- HUD 存活时持续刷新心跳,HUD 停掉后旧状态会在超时后自动失效
- 接入路径更单一,用户只需要维护 HUD 和 hooks,不需要再维护 MCP 配置

## 6. 现在这套方案怎么工作

数据链路是这样的:

1. Claude Code 官方 JetBrains 插件暴露本地连接信息和选区事件
2. HUD 根据当前工作目录匹配正确的 JetBrains 项目窗口
3. HUD 收到选区变化后,把文件路径、行号和心跳时间写入当前项目的 `.codex/jetbrains-selection-state.json`
4. `UserPromptSubmit` hook 在你发消息时读取这份状态
5. 如果状态有效,就给 Codex 注入“当前文件”或“当前文件 + 行号”的轻量提示

这条链路里没有本地 MCP server,也不需要额外的全局提示词。

## 7. 验证

完成上面步骤后:

1. 打开 JetBrains IDE
2. 启动 `codex`
3. 如果你用了 HUD 包装启动,HUD 会自动同步 hook 状态
4. 回到安装了 Claude Code 官方插件的 JetBrains IDE 中选中文件或一段代码
5. 确认 HUD 已显示当前文件和行号
6. 在 Codex 中正常提问

如果 HUD 没刷新,最稳的做法是:

- 回到 IDE 里重新点一下文件
- 或重新拖一下选区

正常情况下:

- 只选中文件时,Codex 会拿到文件路径指引
- 选中代码范围时,Codex 会拿到文件路径和行号指引
- 没有 JetBrains 上下文时,不会注入任何 JetBrains 提示

TDQS

A3.7/5.0

Scored across 5 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: getting selection, listing instances, listing upstream tools, refreshing connection, and showing status. No two tools could be confused.

Naming Consistency5/5

All tools follow a consistent 'jetbrains_' prefix with verb_noun pattern (get_selection, list_instances, list_upstream_tools, refresh_connection, status). No mixing of conventions.

Tool Count5/5

With 5 tools, the set is well-scoped for a connection adapter that manages plugin instances and retrieves selections. Each tool earns its place without unnecessary bloat.

Completeness4/5

The tool surface covers the core operations: get current selection, list/manage instances, refresh connection, and check status. Minor gaps like setting selection or executing actions are absent, but the stated purpose is well-covered.

Maintenance

ActivityInactive
ResponsivenessNo issues