@wbline/pi-acp-jetbrain
v0.1.19
Published
ACP adapter for the pi coding agent (JetBrains IDEs primary host)
Downloads
1,532
Maintainers
Readme
pi-acp-jetbrain
一个为 pi coding agent(pi 编码代理) 编写的 Agent Client Protocol (ACP) 适配器。主要宿主为 JetBrains IntelliJ。其他 ACP 客户端也能使用,但覆盖不完整。
该适配器以 ACP 服务端的形式运行于标准输入/输出(stdio)上。每个 ACP 会话会启动一个 pi --mode rpc 子进程。适配器负责在客户端与 pi 之间翻译消息。
npm 包名:@wbline/pi-acp-jetbrain(当前版本见上方徽章)。GitHub Actions 通过 npm OIDC 为每个发布生成带签名来源(provenance),CI
上无需 npm token。
Fork 声明。 本包是上游 ryan-brosas/pi-acp-jetbrain 的 fork,采用 MIT 许可证,原版权归 Sergii Kozak(2025)所有。见 LICENSE。本 fork 的本地改动与维护由
@wbline以相同 MIT 条款发布。
覆盖范围
该适配器覆盖了会话面:session/new、session/prompt、session/cancel、session/list、session/load、session/fork、
session/resume、session/close、session/delete、session/mode。pi 会自行保存会话文件。适配器在
~/.pi/pi-acp/session-map.json 处维护一张小型映射表,以便 load 时重新挂载已保存的会话。
助手文本以 agent_message_chunk 流式输出。推理内容在提供端发送时以 agent_thought_chunk 流式输出。工具调用映射为 tool_call 与 tool_call_update 事件。
当 pi 上报文件位置时,编辑事件会携带文件位置。适配器依据会话工作目录解析相对路径。对于文本编辑,它会从唯一匹配处找出被修改的行,并上报结构化的 diff。
每个会话都以一段 pi 启动信息(startup block)开始。可在 pi 设置中设置 quietStartup: true 隐藏它。
每轮(turn)结束后,适配器会依据 pi 会话统计上报 token 用量与成本。它把这些数据放在不稳定的 usage 字段中发送。
当客户端具备时,文本输入请求使用不稳定的 ACP 引导(elicitation)API。符合权限要求的请求走 ACP 权限通道。编辑器请求会显示取消通知,因为引导表单只承载基础字段。
模型选择器通过将 pi 模型映射为 ACP 供应商信息来实现。pi 将供应商凭据保存在 RPC 面之外。
斜杠命令可加载 pi 基于文件提示词以及在 pi 中启用的工具。同样还有内建命令 /compact、/export、/session、/name、/queue、/changelog、/steering、/follow-up。当 pi 设置中启用 skills 时,它们会以 /skill:<名称> 的形式出现。
/reload 命令会重新加载 MCP bridge(IDE 工具)和 pi 组件(扩展、技能、提示词、主题、上下文文件)。
本机开发树承载了 pi 开发工具:9 条提示词命令、101 个 skill 文件(跨 10 个包,91 个叶子节点)以及 .pi/ 下 12 个格式模板。这些检查在开发树中运行,在干净的 CI checkout 上会跳过。
JetBrains IDE 桥接
IntelliJ 每次聊天都会发送其内置 MCP 服务端的描述信息。适配器将这些 IDE 工具作为 ide_<server>_<tool> 扩展工具暴露给 pi。
当描述信息携带端口时,桥接会针对 http://127.0.0.1:<IJ_MCP_SERVER_PORT>/sse 打开一个直接的 MCP-over-SSE 客户端。仅当该端点不可达时才会启动 stdio 子进程。
两道允许名单守护这些 IDE 工具。IDE 端从 ~/.jetbrains/acp.json 读取 idea_mcp_allowed_tools。在已安装的构建中,缺省该项意味着 AllowAll。适配器端会拒绝 execute_tool 以及所有 xdebug_* 名称。可设置 PI_ACP_IDE_EXTRA_TOOLS 为逗号分隔的远程名列表,以重新放行你审核过的工具。
会话目录从不改变。修改完 IntelliJ MCP 设置或允许名单后,请开启一个新聊天。
安装
Node.js 20 或更高版本。你的 PATH 上需要有 pi 可执行文件。
以 Pi 包的方式安装,以激活随附的桥接扩展:
pi install npm:@wbline/pi-acp-jetbrainpi 会在 ~/.pi/agent/settings.json 中记录该包,并自动启用其声明的扩展。仅用 npm install -g 安装只会提供可执行文件,不会激活 Pi 包资源。
当你希望直接在 PATH 上使用 pi-acp-jetbrain 命令时,可全局安装:
npm install -g @wbline/pi-acp-jetbrain包名是 @wbline/pi-acp-jetbrain。安装后的命令为 pi-acp-jetbrain。
在 ~/.jetbrains/acp.json 中注册该适配器:
{
"agent_servers": {
"pi-acp-jetbrain": {
"command": "pi-acp-jetbrain",
"args": [],
"env": {}
}
}
}npx 方式亦可。建议固定版本,以免后续启动拉到不同发布版:
将 <version> 替换为当前发布版本(见上方徽章):
{
"agent_servers": {
"pi-acp-jetbrain": {
"command": "npx",
"args": [
"-y",
"@wbline/pi-acp-jetbrain@<version>"
],
"env": {}
}
}
}从源码运行:
npm install
npm run build将入口指向 dist/index.js:
{
"agent_servers": {
"pi-acp-jetbrain": {
"command": "node",
"args": ["/path/to/pi-acp-jetbrain/dist/index.js"],
"env": {}
}
}
}一个使用精简工具子集的开发配置:
{
"agent_servers": {
"pi-acp-jetbrain": {
"command": "/path/to/pi-acp-jetbrain/dist/index.js",
"args": [],
"env": {
"PI_ACP_PI_COMMAND": "/path/to/pi",
"PI_ACP_DEBUG_BRIDGE": "1"
},
"idea_mcp_allowed_tools": [
"search_symbol",
"get_symbol_info",
"analyze_calls",
"search_text",
"search_regex",
"get_file_problems",
"lint_files",
"build_project",
"execute_run_configuration",
"git_status",
"get_repositories",
"get_project_modules",
"get_project_dependencies",
"list_directory_tree",
"read_file",
"search_file",
"open_file_in_editor",
"get_all_open_file_paths",
"skill_search"
]
}
}
}idea_mcp_allowed_tools 起到“除所列工具外一律拒绝”的作用。按需添加工具即可。
环境变量
| 变量 | 作用 |
| --------------------------------------- | ------------------------------------------------------------------------------------------------------- |
| PI_ACP_PI_COMMAND | pi 可执行文件的路径。默认:pi。 |
| PI_ACP_DEBUG_BRIDGE=1 | 将脱敏后的 session/new MCP 描述信息记录到 stderr。IntelliJ 会把这些 stderr 写入 idea.log。 |
| PI_ACP_ENABLE_EMBEDDED_CONTEXT=true | 声明支持 embeddedContext。 |
| PI_ACP_ENFORCE_IDE_INSPECT=0 | 关闭每轮结束后运行的代码检视门。 |
| PI_ACP_IDE_MODE=off\|prefer\|required | 会话的 IntelliJ 优先编码模式。默认:off。详见“IntelliJ 优先编码模式”一节。 |
| PI_ACP_IDE_INSPECT_DIR | 将检视报告移到项目树之外。 |
| PI_ACP_SESSION_MAP | 覆盖会话映射表路径。默认:~/.pi/pi-acp/session-map.json。 |
| PI_ACP_IDE_EXTRA_TOOLS | 重新放行进入拒绝名单的 IDE 工具。以逗号分隔的远程名。 |
Plan/Build 模式
要使用 session/mode 功能切换到 plan 或 build 模式,需要安装额外的 pi 插件:
pi install npm:@janvitos/pi-plan-build安装完成后,即可在 JetBrains IDE 中使用 plan/build 模式进行项目规划和构建。
IntelliJ 优先编码模式
设置 PI_ACP_IDE_MODE 以控制会话如何让 IntelliJ 承担常规编码工作。所有实现仍由 pi 生成;IntelliJ 负责打开、读取、搜索、应用变更、重命名、重新格式化并验证。
off(默认)保持当前行为:IDE 工具与原生工具并列暴露,不移除任何工具,不加额外提示引导。prefer在所需 IDE 能力注册后,从活动工具集中移除原生read、edit、write、grep、find与ls工具。若 IDE 桥接降级,这些工具会恢复,会话会收到明确的降级通知。required立即移除上述原生工具,并且在 IDE 桥接缺失或断开连接时保持移除。会话会报告任务被阻塞,直到新的健康聊天开始。
必需能力:read_file、open_file_in_editor、apply_patch、create_new_file、一个搜索工具、一个检视工具。工具名从实时目录中发现,从不猜测。
在活动模式下,变更操作经 IntelliJ 执行并打开受影响文件:已有文件在 apply_patch 之前打开,新建/移动文件在之后打开。补丁目标与路径参数被限定在 ACP 项目根目录内;范围外的路径会被拒绝,包括符号链接逃逸。搜索与检视结果中的结构化路径字段会对照项目根目录检查。在 prefer 模式下,指到根目录之外文件的结果会在结果上标注诊断;在 required 模式下则被拒绝。非结构化结果文本原样透传:通用文本扫描不是安全的判别依据,因此按工具区分的结构化适配器仍是边界(这是上游限制)。
在 prefer 模式下,bash 仍可用于 Git、测试、构建与诊断。不受限的 bash 仍可改动文件,因此该模式仅是对常规编码工具的策略约束,而非文件系统沙箱。请勿将其当作安全边界。
在 prefer 与 required 且目录激活时,直接在 fabric_exec 内对 Fabric/Schema 文件做修改(schema.commit、pi.write,pi.edit)会在执行前被一道 tool_call 闸门拦截。变更必须经由 IDE 工具(ide_idea_apply_patch、ide_idea_create_new_file、重命名、重新格式化)进行,这些工具会打开受影响文件并把补丁/路径参数限定在项目根目录内。只读的 Fabric 代码(pi.read、pi.grep、IDE 工具调用)不受影响。这封堵了扩展工具绕过活动集过滤的路径;bash 仍是刻意的、有文档说明的例外。
每轮之后还有第二道防线:扩展通过鉴权后的 IPC 上报成功的 IDE 变更工具所应用的路径(mutations_applied),适配器将这些路径与轮次中变更的文件(git status 与轮次触碰的工路径合并)进行比对。未伴随 IDE 变更事件而变化的文件会在聊天中作为 Mutation provenance(变更溯源)违规浮出,并记录在 PromptResponse._meta.piAcp.mutationViolations 下。可用 PI_ACP_ENFORCE_IDE_MUTATIONS=0 关闭。被删除的文件以及轮次中途被外部自动提交监听器提交的文件无法被这层检测到(与代码检视门使用相同的 git-status 语义)。
模式可能降级或失效的情形
该模式是由本适配器实现的按会话适应机制,而非 IDE 的持久设置。其强制逻辑由一个基于 IDE 桥的实时能力探测驱动,因此可能在以下情形中降级或失效:
- 桥缺失 / IPC 断开:强制逻辑是有状态(
active、native_fallback、required_unavailable)的。在prefer下,桥丢失或断开会使会话落入native_fallback,原生工具回归,并伴随明确的降级提示。在required下,会话变为required_unavailable,任务被视为受阻,直到新的健康会话启动。 - 能力探测未命中:活动模式依赖所有必需能力都成功注册(
read_file、open_file_in_editor、apply_patch、create_new_file、一个搜索工具和一个检视工具)。若任一必需能力缺失——例如 IDE 升级后重命名或移除了某个 MCP 工具——prefer会回退、required会不可用。工具名是从活目录发现的,从不猜测,因此 IDE 侧的重命名可能静默破坏探测。 - 配置变更需要新建对话:桥和能力探测在会话开始时建立。修改
idea_mcp_allowed_tools、PI_ACP_IDE_MODE值或 IDE MCP 设置后,请新建对话;已打开的会话不会重新连接或重新评估其模式。 - 非法值安全关闭到 required:任何不是
off/prefer/required的PI_ACP_IDE_MODE值(例如拼写错误)都会被当作required并安全关闭,可能阻塞任务,而非回到默认的off。 - 并非安全沙箱:模式强制仅覆盖常规编码工具。Bash 仍可用(
prefer下)且仍能改文件;溯源门禁只上报违规而不回滚。
为适配器进程设置该变量,例如在 ~/.jetbrains/acp.json 中:
{
"agent_servers": {
"pi-acp-jetbrain": {
"command": "/path/to/pi-acp-jetbrain/dist/index.js",
"env": { "PI_ACP_IDE_MODE": "prefer", "PI_ACP_PI_COMMAND": "/path/to/pi" }
}
}
}认证
适配器会声明终端认证元数据。如需交互式供应商登录,可运行:
pi-acp-jetbrain --terminal-loginACP 客户端可从其认证界面启动同一命令。
开发
npm install
npm run dev # 使用 tsx 从 src 运行
npm run build
npm run lint
npm run test
npm run typecheck
npm run format
npm run smoke # 核心 stdio 冒烟测试
npm run smoke:full # 完整矩阵;发布前请运行
node scripts/check.mjs代码布局:
src/acp/存放 ACP 服务端与翻译逻辑。src/pi-rpc/存放 pi 子进程包装。
CI:check.yml 在 Node 20 和 24 上运行规范检查、测试、lint、typecheck 与构建。qodana_code_quality.yml 运行 Qodana Cloud 扫描,需要 QODANA_TOKEN 仓库密钥。CI 运行在 Linux 上。代码中存在 Windows 路径,但未经过测试。
发布
每次发布都会通过 GitHub Actions 发布到 npm,并带签名来源。CI 上没有交互式 npm 双重认证(2FA)。
开始一次发布:
gh workflow run Release -f version=<next-version>工作流 Release(文件 release.yml)校验版本、更新包文件、运行门禁、提交、打标签、推送、发布并创建 GitHub 发布条目。
工作流 Publish Package(文件 npm-publish.yml)在推送 v* 标签时运行。它校验标签与包版本一致,且 npm 上尚无该版本,然后发布并创建 GitHub 发布条目。
包所有者的一次性设置:在 npmjs.com 打开包 Settings 与 GitHub Cloud CI/CD 表单。授权 wbline/pi-acp-jetbrain、分支 main
、工作流文件名 npm-publish.yml 与 release.yml。
限制
信任边界
适配器信任它的 ACP 宿主。宿主提供会话工作目录与客户端提供的 MCP 描述信息;描述信息中点名的 stdio MCP 服务端会以适配器进程的环境、在该工作目录中被启动。只与你控制的宿主和 MCP 配置一起运行该适配器。切勿将其作为服务暴露给不受信任的客户端,也不要在适配器环境中放置不必要的密钥。
PI_ACP_IDE_MODE=prefer|required 仅是对常规编码工具的策略约束,而非文件系统沙箱:不受限的 Bash 仍可用,轮后门禁只上报违规而不回滚变更。关于模式可能静默回退或阻塞会话的具体情形,见模式可能降级或失效的情形一节。
适配器不暴露 ACP 文件系统或终端委托能力。pi 在本地读取文件、运行命令。
providers/set 与 providers/disable 返回“找不到方法”(method-not-found)错误。pi 在 RPC 面之外配置供应商。
ACP 计划(plan)面保持未接线状态。所安装的 SDK 未定义计划方法。
调试器工具仅在 IDE 调试会话存活期间注册。启动一个调试会话并开启一个新聊天即可看到它们。
重建适配器后请开启一个新聊天。Node 会保留旧文件,而 IntelliJ 会复用正在运行的代理进程。
商标
JetBrains、IntelliJ IDEA 与 WebStorm 是 JetBrains s.r.o. 的商标。本项目是一个独立的社区维护适配器,与 JetBrains 没有关联、未获其背书或赞助。商标归各自权利人所有,此处仅用于描述本适配器所互操作的工具。
许可证
MIT。见 LICENSE。
