内容
<div align="center">
<img src="icons/icon128.png" width="96" alt="Slop Off logo">
# Slop Off
**无缝衔接的体验。关闭 Slop Off。**
AI 快速构建页面,但生成的页面通常不完善 — 最后的 10% 是润色,而润色不应增加额外负担。Slop Off 让您可以像编辑文档一样直接修改实时页面:重写文本,修复措辞,调整您不满意的部分。每次更改都直接发送到您的编码代理,生成精确的、针对特定元素的变更前/后对比。只需一次技能调用,您的润色就能应用于源代码。



</div>
---
## 为什么?
您的代理在几秒钟内生成页面 — 然后真正的编辑工作才刚刚开始。文本平淡无奇,标题没有切中要点,按钮标签感觉不对劲。那最后的 10% 是润色,而润色在反复确认中会受到影响:描述 *哪里* 有文本,描述 *应该是什么*,等待,审查,发现更改错误,再重复。
Slop Off 让添加润色变得无缝。**您直接在页面上进行编辑**,根据润色的需求精确到特定元素,然后扩展程序将其转换为机器可用的变更日志,供您的代理或编码工具使用。只需调用一次 `/slop-off` 技能;代理将处理其余部分,而您继续浏览。
而且您无需离开页面。Slop 不会在差异视图中显示 — 它显示在渲染结果中,即用户实际看到的内容。代码并不凌乱;页面只是不 *完整*。所以请根据页面进行判断,而不是源代码:发现问题,立即修复,保持流程。您的代理处理代码 — 您无需查看。
## 功能
- ✏️ **一键编辑模式** — 整个页面通过 `designMode` 变得可编辑;金色轮廓显示编辑模式已启用
- ⌨️ **键盘快捷键** — 使用 `Cmd+Shift+E`(`Ctrl+Shift+E` 在 Windows/Linux 上)切换编辑模式
- 📋 **变更前/后报告** — 一个 URL 对应一个部分,一个变更元素对应一个变更前/后对比对,包裹在代码块中,发送给您的代理
- 🎯 **每个编辑的 CSS 选择器** — 每个编辑都包含一个选择器行,以便您的助手可以精确定位元素,即使相同的文本出现两次
- 🤖 **可配置的 AI 提示** — 在报告中添加提示前缀,以便您的助手可以直接应用它;编辑它(和 Webhook URL)在 ⚙ 叠加层的设置选项卡或设置页面中
- 🧭 **在导航和重新加载后仍然有效** — 编辑同步到后台工作线程;导航(完整加载 *和* SPA/pushState)或重新加载并继续编辑
- 📝 **表单字段也支持** — `<input>`、`<textarea>` 和 `<select>` 值更改会捕获并写入 HTML(包括复选框和单选按钮状态)
- 🖱 **表单也可编辑** — 按钮标签和 `<label>` 文本像任何文本一样编辑(⌘/Ctrl-click 按钮以实际按下它);在空字段中输入会编辑占位符本身;选择、复选框、详细信息和媒体控件保持交互(⌥-click `<summary>` 以编辑其文本)
- 🔁 **编辑在返回时重新应用** — 重新访问您在会话期间编辑的页面,您的更改将再次应用于它,并保持可编辑
- 🔗 **安全链接** — 编辑时链接点击不会导航;悬停链接显示内联 URL 编辑器和 ↗ 按钮(或 ⌘/Ctrl-click)以故意跟随链接,同时继续编辑会话
- ↩️ **每个编辑撤销** — 浮动芯片显示实时编辑计数;打开它以撤销此页面上的编辑(↩︎)或删除其他页面的编辑(✕)而不会丢失其余部分 — 结束编辑模式会立即发送报告
- 👁 **原始/差异/新视图** — 在页面的原始状态、页面内文字差异(红色删除线/绿色)和您的编辑版本之间切换;原始和差异表现像一个正常的只读页面,新版本返回到编辑
- 💬 **元素注释** — 按住 ⌃ 预览您要选择的元素,⌃-click 它并在终端式提示中输入指令(实时保存);一个小 💬 标记保留在元素上 — 悬停它以突出显示元素并读取提示,点击它以编辑,🗑 以删除;Tab 循环遍历您的注释(Shift+Tab 反向)而不是页面的选项卡顺序。注释作为元素 + 指令对进入报告,供您的代理使用
- 🗂 **报告历史** — 最近 20 条报告保存在历史选项卡中(⚙ 叠加层和设置页面中的相同面板):查看、复制、删除或重新应用一个以再次发送给代理
- 🧹 **放弃会话** — 编辑芯片旁边的 ✕(或快速双 Esc)恢复页面并丢弃会话,并有确认对话框,当有更改或注释时;报告仍保存在历史中,标记为已忽略
- ⚡ **即时或批量** — 编辑芯片旁边的 📦/⚡ 切换:批量(默认)在您结束会话时发送所有内容;即时在您暂停输入时将每个更改发送到 Webhook,因此您的代理立即开始工作 — 偏好被记住,如果 Webhook 宕机,更改将简单地批量处理
- 📤 **临时提交** — 有待处理的更改时,发送按钮出现在芯片旁边(或按 ⌘⏎):现在发送所有内容,会话继续以新的基线
- 🔔 **页面内 Toast** — 发送报告时出现确认信息
- 💾 **从不丢失报告** — 每个报告(已发送、失败或丢弃)都保留在历史中,准备重新应用或手动复制
- 🤝 **MCP 桥接** — 将报告发送到捆绑的 `mcp/server.js`,您的编码代理通过 `wait_for_report` 接收,排队并按顺序
- 🔁 **双向状态** — ⚙ 按钮上的圆点始终显示代理桥是否可达(绿色/红色/灰色);发送后,HUD 中的 ⏳ 标记和图标徽章显示仍有多少报告等待代理,并且当代理调用 `notify_browser` 时,页面上会出现 Toast,附有 1-2 行更改摘要;点击标记查看排队的报告或取消一个,然后代理接收到它,⚙ 叠加层有一个通知选项卡(也可以通过点击 Toast 访问)以阅读返回的最后 50 条代理通知
- ♻️ **自我更新桥接** — MCP 服务器在源代码更改时热加载自身(相同进程,相同管道),因此代码更新从不需要手动 `/mcp` 重新连接
- 🪶 **零依赖** — 小型 vanilla JS 文件,无需构建步骤
## 安装
此扩展程序尚未在 Chrome 应用商店上架。您可以从源代码安装:
1. 克隆此仓库,或从最新 [版本](../../releases) 下载 zip 文件并解压
2. 在 Chrome 中打开 `chrome://extensions`
3. 启用 **开发者模式**(右上角的切换按钮)
4. 点击 **加载解压的扩展程序** 并选择仓库文件夹
5. *可选:* 点击扩展程序的 **详细信息** 并启用 **允许访问文件 URL** 以在本地 `file://` 页面上使用它
## 使用
1. **点击扩展程序图标**(或按 `Cmd+Shift+E` / `Ctrl+Shift+E`)。页面出现金色轮廓,徽章显示 **REC**,现在所有文本都可直接编辑。
2. **编辑页面。** 修复文本,改写标题,纠正数字,更改表单字段值 — 任何操作。导航到其他页面或重新加载页面也没问题;编辑模式跟随您。
3. **再次点击图标。** 编辑模式关闭,报告发送到您的代理,Toast 确认并显示编辑计数。
4. **您的助手应用它。** 默认提示告诉它应用每个编辑到源文件,其摘要以 Toast 返回。
### 示例报告
```
将以下编辑应用于 URL 引用的源文件。
对于每个“变更前/后”对:找到文件中的变更前 HTML 并将其替换为变更后 HTML。
对于每个元素/指令对:找到源代码中的元素并执行指令。
选择器行描述了元素在渲染 DOM 中的位置,作为查找源代码的提示。
保持其他内容不变并保留原始格式和缩进。
---
url: file:///Users/you/project/index.html
selector: body > main > div:nth-of-type(1)
Before:
```
<div class='hero'>欢迎访问我们的网站</div>
```
After:
```
<div class='hero'>欢迎访问 WBSO.ai</div>
```
selector: body > main > h1
Element:
```
<h1>我们的功能</h1>
```
Instruction: 使此标题更具吸引力
```
### 设置
右键单击扩展程序图标 → **选项**(或前往 `chrome://extensions` → 详细信息 → 扩展程序选项)。在那里,您可以更改每个报告的前缀提示,或清除它以复制纯报告。**重置为默认** 恢复内置提示。
### 直接进入您的编码代理(MCP)
报告通过 `mcp/server.js` 中的捆绑桥接直接流入 Claude Code(或任何 MCP 客户端)— 一个单一的、依赖项少的 Node 脚本,它从扩展程序接收报告,通过 HTTP 提供给代理作为 MCP 工具。
#### 1. 注册 MCP 服务器
无需克隆 — 桥接已发布到 npm 并通过 `npx` 运行:
```sh
claude mcp add --scope user slop-off -- npx -y slop-off
```
`--scope user` 使工具在每个项目中都可用。验证使用 `claude mcp list`;再次删除使用 `claude mcp remove slop-off`。桥接监听端口 `8931`(使用环境变量 `SLOP_OFF_PORT` 覆盖 — 然后还要调整下面的 Webhook URL)。
> 喜欢从源代码运行?指向已检出的脚本:`claude mcp add --scope user slop-off -- node "$(pwd)/mcp/server.js"`。
#### 2. 将扩展程序指向它
无需操作 — 扩展程序默认将其 **Webhook URL** 设置为 `http://localhost:8931` ,正好是桥接监听的位置。每个报告都发送到那里,页面上的 Toast 确认: *"已发送给代理"*。当没有 Claude Code 会话(因此没有桥接)运行时,警告 Toast 告诉您,报告保留在历史中,准备稍后重新应用。清除设置中的字段以禁用发送,或更改它,如果您覆盖了 `SLOP_OFF_PORT`。
#### 3. 安装 `/slop-off` 技能
技能位于此仓库的 `.claude/skills/slop-off/`,因此在仓库内,斜杠命令直接有效。要从任何项目中使用它,请使用 [`skills`](https://skills.sh) CLI 安装:
```sh
npx skills add wbso-ai/slop-off
```
这会将技能直接从 GitHub 拉取并安装到 `~/.claude/skills/`(选择 **Claude Code** 和全局范围时提示;或非交互式:`npx skills add wbso-ai/slop-off -g -a claude-code -y`)。`skills` 支持 [70 多种其他代理](https://skills.sh) — 交换 `-a` 标志为 Cursor、Codex 等。
#### 4. 使用它
在项目中与 Claude Code 会话:
- `/slop-off` — 在主线程中循环:等待报告并直接应用它们,因此每个报告都会给出即时状态行(*✅ 3 个更改已应用 — 文件 · 2 仍在队列中*)。执行工作的模型只是您的会话模型 — 选择它。说 *停止* 以结束循环
- `/slop-off once` — 等待并应用单个报告
- `/slop-off latest` — 应用最近的报告,无需等待
- `/slop-off list` — 显示队列
- `/slop-off clear` — 删除队列中的所有待处理报告
报告按顺序排队(`~/.slop-off/queue.json`,最近 50 个),因此多个编辑会话连续传递 — `wait_for_report` 立即返回,而有积压时。没有技能,原始 MCP 工具(`wait_for_report`、`get_latest_report`、`list_reports`)也适用:*“等待我的编辑报告并应用它”*。
## 工作原理
| 文件 | 角色 |
|---|---|
| `background.js` | 服务工作线程:切换编辑模式,按选项卡存储每个选项卡的编辑记录 (`chrome.storage.session`),在导航后重新注入内容脚本,构建报告并将其发送到 Webhook |
| `content.js` | 注入时编辑模式激活:启用 `designMode`,在 `beforeinput` 事件发生前捕获每个元素的 `outerHTML`,处理注释/视图/面板 UI,并将编辑 + 注释同步到后台(防抖) |
| `panes.js` | 共享 UI 面板(快捷键/通知/历史/设置):一个实现适用于页面内的 ⚙ 叠加层和设置页面 |
| `options.html` / `options.js` | 设置页面:`panes.js` 的薄壳 — 存储在 `chrome.storage.sync` / `.local` |
| `mcp/server.js` | 可选的 MCP 桥接:Webhook 的 HTTP 端点(+ `GET /status` 用于待处理报告和代理通知,`POST /cancel` 用于丢弃一个)+ `wait_for_report` / `get_latest_report` / `list_reports` / `clear_reports` / `notify_browser` 工具通过 stdio;代码更改时热加载自身 |
| `.claude/skills/slop-off/` | Claude Code 技能:`/slop-off` 在循环中处理排队的报告 |
值得了解的细节:
- *变更前* 快照在 `beforeinput` 事件发生前拍摄,因此它捕获元素在您的第一个更改之前的状态。
- 如果父元素已跟踪,其子元素不会单独跟踪 — 这可以防止报告中出现嵌套的重复条目。
- 您关注但未实际更改的元素将被过滤掉。
- 报告部分按 URL 键入(忽略 `#hash`):每个页面一个部分,无论您访问多少次;重新访问会重新应用您的编辑。
### 权限
| 权限 | 为什么 |
|---|---|
| `scripting` + `<all_urls>` | 注入内容脚本,并在导航后重新注入(这让编辑模式在页面更改后仍然有效) |
| `storage` | 持久化您的提示(`sync`)和未完成的编辑(`session`) |
| `activeTab` | 您点击的选项卡的基本访问权限 |
扩展程序没有远程代码,也没有分析。 它做的唯一网络请求是报告 POST 到您自己的 Webhook URL — 默认情况下为 `http://localhost:8931`,即您自己的机器上的 MCP 桥接。清除设置中的字段,您的编辑不会离开扩展程序。
## 限制
- 在 `chrome://` 页面或 Chrome 应用商店上不起作用(徽章显示 ✗)。如果您在这样的页面上结束编辑模式,报告仍然会发送并保存在历史记录中 — 只有 Toast 无法在那里显示。
- 高动态页面(例如 React 应用重新渲染)可能会覆盖您的编辑或产生嘈杂的差异,因为框架拥有 DOM。SPA 导航本身正确处理。
## 开发
无需构建步骤。编辑文件,然后在 `chrome://extensions` 中点击扩展程序卡片上的重新加载图标。图标是编程生成的(纯 Python PNG 编写器,无依赖项) — 请参见 `icons/`。
欢迎贡献:打开问题或拉取请求。
## 许可证
[MIT](LICENSE) © 2026 Jankees van Woezik <jankees@wbso.ai> & Paul Tondeur <paul@wbso.ai>