Files
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

195 lines
8.7 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Harmness Browser — JetBrains 插件
在 JetBrains IDEIntelliJ IDEA / PyCharm / PhpStorm / WebStorm 等)的侧边栏内嵌一个
**可配置地址的浏览器窗口**。默认搭配本地 [Harness](https://harness.io/) 这类 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 时)
```bash
./scripts/setup-toolchain.sh
# 会下载 Temurin JDK 17 与 Gradle 8.11.1 到 .tools/
```
若本机已装 JDK 17+ 与 Gradle,可跳过,直接用系统的。
### 2. 构建插件 zip
```bash
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. 前端(可选)
```bash
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` 提供类型化封装:
```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. 申请插件仓库(只有一次)
1. 打开 <https://plugins.jetbrains.com/> 并登录。
2. 右上角头像 → **Developer Console**(或直接 <https://plugins.jetbrains.com/developer>)。
3. 点击 **Create New Plugin**(第一次需要填组织/开发者信息 + 同意
[Plugin Hosting Terms](https://plugins.jetbrains.com/docs/marketplace/plugin-hosting-terms.html))。
4. 创建后会得到一个 **Plugin ID**,把 `plugin.xml` 里的 `<id>`(当前为
`com.harmness.toolwindow`)改成该 ID(建议保持相同,便于后续关联)。
### 3. 构建并本地验证产物
```bash
./.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.kts``version` 一致(如 `0.1.0`
- **Since / Until build**:对应 `plugin.xml``242 / 243.*`
- **Changelog**:版本变更说明
- **Compatibility**:勾选目标 IDEIDEA Community/Ultimate 等)
4. 提交后,若勾选 **Publish**(或之后手动点 Publish),插件会进入审核,一般几分钟到数小时;
审核通过后即可在 Marketplace 搜索到。
> 之后每次发新版,重复第 3–4 步即可。也可用 CIGitHub Actions + JetBrains
> [publish plugin task](https://plugins.jetbrains.com/docs/intellij/publishing-plugin.html)
> `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 主题切换深/浅色、自动重连等。