Files
harmness-browser/README.md
T
harmness cbe41e4f4f Initialize Harmness Browser JetBrains plugin skeleton
- 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
2026-09-10 13:27:43 +08:00

8.7 KiB
Raw Blame History

Harmness Browser — JetBrains 插件

在 JetBrains IDEIntelliJ IDEA / PyCharm / PhpStorm / WebStorm 等)的侧边栏内嵌一个 可配置地址的浏览器窗口。默认搭配本地 Harness 这类 AI 助手 Web 服务使用,让你不用切出 IDE 就能在代码区与 AI 界面之间来回操作。

本仓库已初始化:

  • JetBrains 插件本体Kotlin + Gradle + IntelliJ Platform SDKsrc/
  • TypeScript Web 前端脚手架Vite + React + TSweb/,用于构建/调试将被嵌入的页面)
  • 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(约 12GB),请保持网络畅通。

3. 在 IDE 里运行/调试

在 IDEAUltimate 或 Community 均可)中:

  1. File → Open 打开本仓库根目录(Gradle 项目会自动识别)。
  2. Gradle → Tasks → intellij → runIde,或运行主类 com.intellij.idea.Main(由 Gradle 任务 runIde 提供)。
  3. 等 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 APIFileDocumentManagerEditorFactoryCodeInsightUtil 等) 实现。IntelliJ 官方插件 SDK 不提供对 JCEF 页面 DOM 的直接访问,双向通信一律走 JBCefJSQuery(本插件已封装)。

发布到 JetBrains Marketplace

1. 注册 JetBrains 账号

访问 https://account.jetbrains.com/login 注册/登录(可用 Google / GitHub 账号)。

2. 申请插件仓库(只有一次)

  1. 打开 https://plugins.jetbrains.com/ 并登录。
  2. 右上角头像 → Developer Console(或直接 https://plugins.jetbrains.com/developer)。
  3. 点击 Create New Plugin(第一次需要填组织/开发者信息 + 同意 Plugin Hosting Terms)。
  4. 创建后会得到一个 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. 上传发布

  1. 进入 https://plugins.jetbrains.com/developer,选你的插件。
  2. Upload Plugin 上传 zip。
  3. 填写版本信息:
    • Version:与 build.gradle.ktsversion 一致(如 0.1.0
    • Since / Until build:对应 plugin.xml242 / 243.*
    • Changelog:版本变更说明
    • Compatibility:勾选目标 IDEIDEA Community/Ultimate 等)
  4. 提交后,若勾选 Publish(或之后手动点 Publish),插件会进入审核,一般几分钟到数小时; 审核通过后即可在 Marketplace 搜索到。

之后每次发新版,重复第 3–4 步即可。也可用 CIGitHub 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 的适配注意点(重要)

  1. 嵌入限制:目标 Web 应用(Harness)必须允许被嵌入渲染:
    • 不能返回 X-Frame-Options: DENY/SAMEORIGIN,
    • CSP 里不能有 frame-ancestors 'none'。 若 Harness 有这些限制,需要在其反向代理/HTTP 头里放行,或使用 Harness 专门的无 frame 限制入口。
  2. 登录态:cookie 与本地存储默认按 JCEF 的浏览器实例隔离,登录 Harness 后一般会保留 (IDE 重启后缓存仍有效,除非换 IDE/机器)。
  3. 性能与授权:JCEF 每次都会初始化一个 Chromium 实例,多个 IDE 窗口会占用较多内存; 老机器上建议只保留最需要的 IDE 窗口。
  4. 桥接协议:要把「网页请求 → 编辑代码/打开文件」打通,需按前面「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.22024.3。
  • 后续可加:多地址书签、地址访问白名单(安全)、按 IDE 主题切换深/浅色、自动重连等。