页面可视化编辑器
基于浏览器的 HTML 页面可视编辑器。用户在浏览器中完成样式/内容编辑,保存后输出结构化 JSON,供 Agent 回写到源码。
快速开始(双进程模型)
本工具采用 双进程架构,必须严格按以下顺序启动:
# ===== 第 0 步:安装依赖(仅需首次,后续跳过)=====
SKILL_DIR="{skill-base-dir}/assets/page-editor"
if [ ! -d "$SKILL_DIR/node_modules" ]; then
cd "$SKILL_DIR" && npm install --prefer-offline --no-audit --no-fund
fi
# ===== 第 1 步:启动服务进程(后台常驻,只启动一次!)=====
# 日志写入临时文件以便排障;服务就绪后会自动打开浏览器(延迟 4s,页面显示加载遮罩直到 JS 就绪)
LOGFILE="/tmp/page-editor-$(date +%s).log"
nohup node {skill-base-dir}/assets/page-editor/bin/page-editor.js --file <目标HTML路径> > "$LOGFILE" 2>&1 &
SERVICE_PID=$!
# ===== 第 1.5 步:等待服务就绪(重要!不要跳过)=====
for i in $(seq 1 30); do
if [ -f ".page-editor.port" ]; then break; fi
sleep 0.5
done
if [ ! -f ".page-editor.port" ]; then
echo "⚠️ 服务未能在 15 秒内启动,请检查日志: cat $LOGFILE"
fi
# ===== 第 2 步:启动监听进程(前台阻塞,10 分钟超时)=====
# 阻塞等待用户保存或关闭编辑器。10 分钟内无操作会超时退出。
node {skill-base-dir}/assets/page-editor/bin/page-editor.js --monitor
双进程说明:
| | 服务进程(第 1 步) | 监听进程(第 2 步) |
|---|---|---|
| 命令 | nohup ... --file xxx & | node ... --monitor |
| 运行方式 | 后台 & | 前台阻塞 |
| 生命周期 | 启动后持续运行,30 分钟无活动自动退出 | 每次保存/关闭后自动退出 |
| 可重复启动? | 不需要重复! 只启动一次 | 每轮保存后需重新启动一个新的 |
⚠️ Agent 绝对不能犯的错误:
- ❌ 忘记启动服务进程就直接启动监听 → 监听会报错连不上
- ❌ 每次保存后重新启动服务进程 → 浏览器会刷新/断开,用户体验断裂
- ❌ 把两个命令写成一行或颠倒顺序 → 监听找不到服务
- ❌ 用普通
&而非nohup→ Agent 会话结束时服务被杀掉 - ❌ 收到
page-editor:closed信号后重启服务 → 这是用户主动关闭,必须停止循环! - ❌ 跳过第 1.5 步(等待服务就绪)直接启动 --monitor → 可能连接失败
- ❌ 使用
preview_url在 IDE 内置浏览器中打开编辑器 → 编辑器 Shell 层会丢失。服务启动后自动打开外部浏览器
Agent 工作流程
触发判断
主动触发(任一条件即启动):
- 用户明确说 "启动设计模式"、"进入编辑模式"、"可视化编辑"等
AI 预判触发(以下情况应主动建议启用设计模式):
- 用户对同一页面连续提出视觉类修改超过 2 轮仍未满意
- 用户用"再...一点"、"还不行"、"不是这个感觉"等反复迭代
- Agent 判断继续用语言/代码来回修改效率低
完整执行流程
═══ 阶段 A:首次启动 ═══
Step 1. Agent 安装依赖(如未安装),然后启动【服务进程】(后台,只此一次):
nohup node {skill-base-dir}/assets/page-editor/bin/page-editor.js --file <目标路径> > /tmp/page-editor.log 2>&1 &
服务启动后会自动打开浏览器编辑器,Agent 不需要手动打开。
Step 2. Agent **等待服务就绪**(检查 .page-editor.port 文件出现,最多等 15 秒)
Step 3. Agent 告知用户:
"✅ 设计模式已开启,浏览器会自动打开编辑器。
我会持续监听你的保存操作。调整完后点「保存」我会自动处理。
如果你想先做别的事,可以点暂停按钮,保存完跟我说一句「我保存好了」即可。"
Step 4. Agent 立即启动【监听进程】(10 分钟超时,无需传 timeout 参数):
node {skill-base-dir}/assets/page-editor/bin/page-editor.js --monitor
Step 5. 浏览器自动打开 → 用户在编辑器中自由调整样式/内容
Step 6. 用户点击「保存」→ --monitor 进程输出 JSON 到 stdout → 监听进程自动退出
═══ 阶段 B:处理保存结果(自动执行,无需用户确认)═══
**用户视角的交互流程(保存→看到最新效果):**
1. 用户点击「保存」→ 全屏等待遮罩出现 → "正在等待 AI 修改代码..."
→ 编辑器自动退出编辑模式(防止用户操作过期内容)
2. AI 读取 JSON → 将改动写入源码磁盘 → **调用 `/api/reload` 通知浏览器**
3. SSE 推送刷新信号到浏览器
4. 遮罩文字变为 "样式已更新" → "正在加载最新预览…"
5. iframe 强制重载 → 显示 AI 改写后的最新页面
6. 遮罩淡出消失 → 编辑器重新初始化 → **自动进入编辑模式** → 用户可继续编辑
Step 7. Agent 从 stdout 读取 JSON,**自动将改动应用到源码文件**(无需询问用户)
Step 7.5. ⚡ **源码全部写入磁盘后,Agent 必须通知浏览器刷新:**
```bash
node {skill-base-dir}/assets/page-editor/bin/page-editor.js --reload
```
⚠️ **这一步必须执行!不调用则浏览器的等待遮罩永远不会消失。**
调用后 → SSE 推送 → iframe 强制刷新 → 遮罩消失 → 编辑器自动恢复编辑模式。
Step 8. Agent 调用 reload 后,**立即启动新的【监听进程】进入下一轮等待**:
node {skill-base-dir}/assets/page-editor/bin/page-editor.js --monitor
⚠️ 【服务进程】一直在运行,不需要重启!
Step 9. Agent 回复用户(**在启动 monitor 之后回复**,因为 --monitor 是阻塞的):
"✅ 修改已生效,页面已自动更新!继续调整随时点「保存」,我在这里。"
═══ 阶段 C:持续编辑循环(无感刷新)═══
(此阶段完全由 Agent 自动维持,用户无需说任何话即可持续编辑)
Step 9. 用户在浏览器中继续编辑 → 点击「保存」
→ 监听进程收到 JSON → 输出到 stdout → **监听进程自动退出**
Step 10. Agent 读取 stdout 输出,**根据返回类型判断下一步**:
⚠️ **关键:必须先检查返回的 JSON type 字段!**
▸ type = "page-editor:changes" → **正常保存**,执行 Step 10a
▸ type = "page-editor:closed" → **用户关闭了编辑器**,直接跳转 阶段 D
▸ type = "timeout" → **10 分钟内无操作**,执行 Step 10b
Step 10a. Agent 自动将改动应用到源码
⚡ 源码全部写入磁盘后,**必须通知浏览器刷新**:
```bash
node {skill-base-dir}/assets/page-editor/bin/page-editor.js --reload
```
→ 浏览器 iframe 自动刷新 + 自动恢复编辑模式
Step 10b. Agent 收到 timeout(10 分钟无操作):
告知用户:"⏰ 监听已超时(10 分钟无操作)。如果你保存了改动,跟我说一句「我保存好了」,
我会读取修改文件并处理。或者跟我说「继续监听」,我会重新启动监听。"
⚠️ **不要自动重启 monitor!** 超时说明用户可能不在了。等用户回来再处理。
Step 11. Agent **再次启动新的【监听进程】**:
node {skill-base-dir}/assets/page-editor/bin/page-editor.js --monitor
Step 12. Agent 回复用户:
"✅ 已更新!继续调整随时点「保存」。"
Step 13. 循环 Step 9 ~ 12,直到用户主动结束或收到 closed 信号
═══ 阶段 D:结束编辑(仅用户主动触发)═══
以下任一情况发生时,Agent 才终止服务:
① 用户在对话中说:「好了」「不用了」「改完了」「关闭设计模式」「退出编辑器」等
② 用户在编辑器界面点击「关闭」按钮 → --monitor 输出 `{"type":"page-editor:closed"}` 后退出
③ --monitor 的 stdout 输出中包含 `"type":"page-editor:closed"`
**⚠️ 识别 closed 信号的方法:**
- 输出中出现 `PAGE EDITOR CLOSED` 或 `"type":"page-editor:closed"`
- 这是**正常关闭**,**不是异常**,**绝对不要重启服务进程**!
Agent 操作:
- 终止后台【服务进程】:pkill -f "page-editor.js.*--file"
- 如有未应用的改动,先应用再关闭
- 回复:"✅ 设计模式已关闭,所有改动已保存。"
⚠️ **绝对不要做的事:**
- ❌ 不要在每轮保存后问"是否执行"——默认直接执行
- ❌ 不要等用户说"继续"才启动下一次 monitor——保存后立刻重启
- ❌ 不要让用户觉得需要说话才能继续编辑——整个循环应该是静默自动的
- ❌ **不要让用户手动刷新浏览器**——改完源码后调用 `/api/reload`,浏览器会自动刷新
- ❌ **收到 `page-editor:closed` 后不要重启服务!** 必须结束循环
- ❌ **收到 timeout 后不要自动重启 monitor!** 等用户回来再处理
- ❌ **不要使用 `preview_url`!** 服务启动后会自动打开外部浏览器
- ❌ **改完源码后不要忘记调用 `--reload`!** 不调用则浏览器等待遮罩不会消失
### 暂停降级路径
如果用户暂停了当前命令(点击暂停按钮或中断 --monitor 进程),或者 --monitor 超时了:
1. Agent 告诉用户:"监听已暂停。你可以继续在浏览器中编辑。保存后跟我说一句「我保存好了」即可。"
2. 用户说"我保存好了" → Agent 读取 `page-edits.json` 文件:
```bash
cat page-edits.json
- Agent 根据文件内容应用改动到源码
- 改完后通知浏览器刷新:
node {skill-base-dir}/assets/page-editor/bin/page-editor.js --reload - 然后重新启动
--monitor进入下一轮
异常处理清单
| 异常现象 | 原因 | Agent 应该怎么做 |
|---------|------|----------------|
| --monitor 输出 page-editor:closed | 不是异常! 用户点了「关闭」按钮 | 不要重启! 执行阶段 D |
| --monitor 报错连不上 | 服务进程超时退出或崩溃 | 重启服务进程(Step 1)→ 重启 monitor |
| 浏览器打不开/空白 | 端口被占用 | 换 -p 指定其他端口重试 |
| 保存后浏览器不刷新 | AI 没有调用 --reload | 必须调用 node {skill-base-dir}/assets/page-editor/bin/page-editor.js --reload |
| 用户说"浏览器编辑不了了" | 服务进程终止 | 重新执行 Step 1 + monitor |
| 用户在对话中插话 | 用户想在编辑器之外加需求 | 记录需求,等当前保存循环完成后一并处理 |
编辑能力
样式编辑
- 背景色 / 渐变色(Figma 风格的颜色选择器,支持光谱、色相、透明度)
- 文字颜色
- 字号、字重
- 圆角、内边距、外边距、间距
- 宽度、高度
- 边框(颜色、宽度、样式)
- 阴影、透明度
- Flex 布局属性(方向、主轴对齐、交叉轴对齐、换行、间距)
内容编辑
- 双击行内编辑文字内容
- 图片 URL 替换(background-image 或 img src)
- 图片适配模式(cover / contain / original)
高级功能
- 配色方案库 — 自动从目标页面提取 CSS 自定义属性(变量/Token)
- 伪状态编辑 — 通过属性面板切换元素状态来编辑 :hover、:focus、:active 样式
- 一致性检测 — 保存时自动检测跨元素模式,建议批量修改 CSS 规则
- 元素删除 — 从 DOM 中删除元素(可撤销,记录在输出中)
- 多选对齐 — 选中多个元素并进行对齐操作
- 完整撤销/重做 — 支持最多 200 步操作,Cmd/Ctrl+Z / Cmd/Ctrl+Shift+Z
变更管理
- 变更计数器显示 "N 个元素 + M 个变量 已修改"
- 点击计数器打开所有已修改元素的浮出列表
- 悬停列表项可在页面中高亮对应元素并滚动到可视区域
- 点击 ✕ 可撤销某个元素的修改(可撤销)
AI 输出增强 (v3.3)
- CSS 规则上下文 — 每项变更包含
matchedRule.fullRuleText - 逐元素 CSS 差异 —
cssDiff视图展示逐属性的 action - 伪状态感知 — 明确标记
pseudoState和匹配的伪状态 CSS 规则 - CSS 变量追踪 — Token 编辑包含变量名、定义位置和文件
- 跨元素模式检测 — 多个元素共享相同变更时建议修改公共规则
- 修改策略 —
strategy字段给出最佳应用方式 - 内置指令 —
instructions字段提供分步指导
输出格式(摘要)
保存后生成 page-edits.json(v4.0)。顶层结构:
{
"version": "4.0",
"savedAt": "2026-04-14T10:30:00.000Z",
"targetFile": "./dist/index.html",
"targetAnalysis": { "type": "multi-file", "cssFramework": "tailwind" },
"summary": { "totalChanges": 12, "elementsModified": 5 },
"patterns": [ { "type": "batch-same-change", "suggestion": "..." } ],
"byElement": [ { "selector": "...", "tag": "div", "intent": "调整配色", "strategy": "..." } ]
}
变更类型
| type | 含义 | 应用方式 |
|------|---------|-------------|
| style | CSS 属性变更 | 更新 CSS 规则或行内样式 |
| text | 文字内容变更 | 更新模板/HTML 中的文字 |
| attribute | HTML 属性变更 | 更新 HTML 中的属性 |
| cssVariable | CSS 自定义属性变更 | 更新 CSS 中的变量定义 |
| delete | 元素被删除 | 从模板/HTML 中移除元素 |
| reorder | 子元素顺序调整 | 调整模板中的子元素排列顺序 |
完整字段说明见 references/output-format.md。
命令行选项
选项:
-u, --url <url> 目标编辑 URL(如 http://localhost:3000)
-f, --file <path> 目标 HTML 文件路径(绝对路径或相对路径)
-p, --port <number> 编辑器服务端口(默认:7788)
-o, --output <path> page-edits.json 的输出路径(默认:./page-edits.json)
-m, --monitor 监听模式:连接已运行的编辑器,阻塞直到保存/关闭(10 分钟超时)
-w, --wait --monitor 的别名(向后兼容)
-r, --reload 通知浏览器刷新(替代 curl 调用 /api/reload,无需确认)
-t, --timeout <sec> 覆盖默认超时(秒),0 = 使用默认 10 分钟
-h, --help 显示帮助信息
-V, --version 显示版本号
注意事项
- 禁止使用
preview_url! 服务启动后会自动在外部浏览器打开 - 编辑器服务在保存后持续运行——用户无需重启即可多次保存
- 使用
--monitor监听保存事件(10 分钟超时);超时后等用户回来再处理 - 服务启动后自动打开浏览器(延迟 4s),页面显示加载遮罩直到 JS 就绪
- 启动服务后必须等待 .page-editor.port 文件出现再启动 --monitor
- 改完源码后必须调用
node {skill-base-dir}/assets/page-editor/bin/page-editor.js --reload! 这是通知浏览器刷新的唯一方式,不调用则等待遮罩永远不会消失 - 所有编辑均在内存中进行;仅在点击保存时写入磁盘
- 编辑器服务空闲 30 分钟 后自动退出
Scan to contact