- Gradle + Kotlin + IntelliJ Platform SDK build - JCEF embedded browser tool window with configurable start URL - Settings page (Tools > Harmness Browser) - JS<->Java bridge scaffold (window.harmnessBridge) - Vite + React + TypeScript web scaffold for embedded page - README: build, register, upload to Marketplace, install guide
8.7 KiB
Harmness Browser — JetBrains 插件
在 JetBrains IDE(IntelliJ IDEA / PyCharm / PhpStorm / WebStorm 等)的侧边栏内嵌一个 可配置地址的浏览器窗口。默认搭配本地 Harness 这类 AI 助手 Web 服务使用,让你不用切出 IDE 就能在代码区与 AI 界面之间来回操作。
本仓库已初始化:
- JetBrains 插件本体(Kotlin + Gradle + IntelliJ Platform SDK,
src/) - TypeScript Web 前端脚手架(Vite + React + TS,
web/,用于构建/调试将被嵌入的页面) - JS ↔ 插件双向桥 示例(页面上直接调用
window.harmnessBridge)
项目结构
.
├── build.gradle.kts # Gradle 构建(IntelliJ Platform plugin build)
├── settings.gradle.kts
├── gradle.properties
├── scripts/
│ └── setup-toolchain.sh # 一键下载 JDK17 + Gradle(无 root 环境)
├── src/main/
│ ├── kotlin/com/harmness/toolwindow/
│ │ ├── HarmnessBrowserPanel.kt # JCEF 内嵌浏览器 + JS↔Java 桥
│ │ ├── HarmnessToolWindowFactory.kt # 侧边栏工具窗口
│ │ ├── HarmnessSettingsConfigurable.kt # 设置页入口
│ │ ├── HarmnessBrowserConfigurablePanel.kt # 设置 UI(起始地址)
│ │ ├── SettingsState.kt # 持久化设置存储
│ │ └── WindowFocusService.kt # 工具窗口焦点广播(预留)
│ └── resources/
│ ├── META-INF/plugin.xml # 插件声明(扩展点注册)
│ └── icons/harmness.svg # 工具窗口图标
└── web/ # (可选)被嵌入页面的前端脚手架
├── package.json
├── vite.config.ts
└── src/{main.tsx, App.tsx, bridge.ts, ...}
本地构建
1. 准备工具链(本机没有 JDK/Gradle 时)
./scripts/setup-toolchain.sh
# 会下载 Temurin JDK 17 与 Gradle 8.11.1 到 .tools/
若本机已装 JDK 17+ 与 Gradle,可跳过,直接用系统的。
2. 构建插件 zip
export JAVA_HOME=/data/project/Plugin/harmness/.tools/jdk-17.0.12+7 # 若用脚本版
./.tools/gradle-8.11.1/bin/gradle buildPlugin -x test
产物:build/distributions/harmness-toolwindow-0.1.0.zip
首次构建会下载 IntelliJ Platform SDK(约 1–2GB),请保持网络畅通。
3. 在 IDE 里运行/调试
在 IDEA(Ultimate 或 Community 均可)中:
File → Open打开本仓库根目录(Gradle 项目会自动识别)。Gradle → Tasks → intellij → runIde,或运行主类com.intellij.idea.Main(由 Gradle 任务runIde提供)。- 等 IDE 启动后,右侧边栏会出现 Harmness Browser 工具窗口。
4. 前端(可选)
cd web
npm install
npm run dev # 起一个位于 http://127.0.0.1:8888 的页面
然后在插件设置里把「起始地址」填成 http://127.0.0.1:8888,即可在 IDE 侧边栏里看到该页面。
功能与使用
| 功能 | 说明 |
|---|---|
| 侧边栏浏览器 | 打开 IDE 后右侧出现可停靠/悬浮的工具窗口 |
| 配置起始地址 | Settings → Tools → Harmness Browser(或点工具栏 ⚙) |
| 地址栏 | 手动输入任意地址回车跳转 |
| 前进/后退/刷新 | 工具栏 ← → ⟳ |
| 外部浏览器打开 | 工具栏 ⧉ 把当前地址丢给系统浏览器 |
| JS↔Java 桥 | 页面加载后注入 window.harmnessBridge(payload),网页可调用插件能力(原型:ping / getUrl / openExternal:*) |
JS↔Java 桥(给 Harness 前端用)
web/src/bridge.ts 提供类型化封装:
import { callPlugin, openInExternalBrowser, initBridge } from './bridge'
initBridge(( ) => console.log('bridge ready'))
const pong = await callPlugin('ping') // -> "pong"
openInExternalBrowser('https://example.com') // 用系统浏览器打开
如果想要 Harness(或其前端)在收到网页请求时把代码插入编辑器、打开文件等,
需要在 HarmnessBrowserPanel.setupBridge() 的 handler 里扩展桥协议,
并通过 IntelliJ Platform API(FileDocumentManager、EditorFactory、CodeInsightUtil 等)
实现。IntelliJ 官方插件 SDK 不提供对 JCEF 页面 DOM 的直接访问,双向通信一律走
JBCefJSQuery(本插件已封装)。
发布到 JetBrains Marketplace
1. 注册 JetBrains 账号
访问 https://account.jetbrains.com/login 注册/登录(可用 Google / GitHub 账号)。
2. 申请插件仓库(只有一次)
- 打开 https://plugins.jetbrains.com/ 并登录。
- 右上角头像 → Developer Console(或直接 https://plugins.jetbrains.com/developer)。
- 点击 Create New Plugin(第一次需要填组织/开发者信息 + 同意 Plugin Hosting Terms)。
- 创建后会得到一个 Plugin ID,把
plugin.xml里的<id>(当前为com.harmness.toolwindow)改成该 ID(建议保持相同,便于后续关联)。
3. 构建并本地验证产物
./.tools/gradle-8.11.1/bin/gradle buildPlugin -x test
生成的 build/distributions/*.zip 即发布物。
可选(推荐):在 IDE 里用 Settings → Plugins → ⚙ → Install Plugin from Disk…
选这个 zip 验证一次,再上传。
4. 上传发布
- 进入 https://plugins.jetbrains.com/developer,选你的插件。
- Upload Plugin 上传 zip。
- 填写版本信息:
- Version:与
build.gradle.kts的version一致(如0.1.0) - Since / Until build:对应
plugin.xml的242 / 243.* - Changelog:版本变更说明
- Compatibility:勾选目标 IDE(IDEA Community/Ultimate 等)
- Version:与
- 提交后,若勾选 Publish(或之后手动点 Publish),插件会进入审核,一般几分钟到数小时; 审核通过后即可在 Marketplace 搜索到。
之后每次发新版,重复第 3–4 步即可。也可用 CI(GitHub Actions + JetBrains publish plugin task,
gradle publishPlugin)自动化。
5. 其他人安装使用
- IDE 内:
Settings → Plugins → Marketplace,搜索Harmness Browser安装。 - 手动:
Settings → Plugins → ⚙ → Install Plugin from Disk…选 zip。 - 下载:https://plugins.jetbrains.com/plugin/xxxx(你的插件主页)。
安装后在右侧栏点开 Harmness Browser,到
Settings → Tools → Harmness Browser 把地址配置成你的 Harness 实例即可。
与 Harness 的适配注意点(重要)
- 嵌入限制:目标 Web 应用(Harness)必须允许被嵌入渲染:
- 不能返回
X-Frame-Options: DENY/SAMEORIGIN, - CSP 里不能有
frame-ancestors 'none'。 若 Harness 有这些限制,需要在其反向代理/HTTP 头里放行,或使用 Harness 专门的无 frame 限制入口。
- 不能返回
- 登录态:cookie 与本地存储默认按 JCEF 的浏览器实例隔离,登录 Harness 后一般会保留 (IDE 重启后缓存仍有效,除非换 IDE/机器)。
- 性能与授权:JCEF 每次都会初始化一个 Chromium 实例,多个 IDE 窗口会占用较多内存; 老机器上建议只保留最需要的 IDE 窗口。
- 桥接协议:要把「网页请求 → 编辑代码/打开文件」打通,需按前面「JS↔Java 桥」一节扩展插件。
关于「把 Harness 塞进侧边栏」的可行性评估(给决策用)
你的想法是合理的,也是目前社区常见的做法(例如在 IDE 里嵌入 ChatGPT / Copilot 网页版)。 优点:
- 不用在两个窗口之间来回切换,交互摩擦小;
- 利用 IDE 自带的 JCEF,不需要额外浏览器进程;
- 可以做双向桥,网页 → 编辑器有原生 IPC 通路。
局限(需要接受或规避):
- JCEF = 内置 Chromium,内存占用明显(每个 IDE 窗口一份);
- 官方 SDK 不给页面 DOM 权限,需求超过「纯网页浏览 + 简单桥」就要自己维护桥协议 (本插件已铺好骨架);
- 第三方网页的嵌入限制(X-Frame-Options / CSP)可能直接挡掉,需要 Harness 侧配合。
结论:方向可行。建议先把 web/ 里替换成 Harness 实际前端,跑通「配置地址 → 侧边栏显示 →
桥接 ping」这条链路,再决定扩展哪些 IDE 能力。
License / 后续
- 当前版本为原型骨架(0.1.0),默认
sinceBuild=242, untilBuild=243.*,只覆盖 2024.2–2024.3。 - 后续可加:多地址书签、地址访问白名单(安全)、按 IDE 主题切换深/浅色、自动重连等。