DSH HUB
HomePlugin StorePlugin PacksCommunityRankingsResourcesPublish Guide
Plugin source
Back to catalog

Lumos-789 /

Lumos-789/demo-browser

Verified

This plugin has no description yet.

★ 0 Stars0 Forks0 IssuesN/A Community rating0 Confirmed installs
View on GitHub
READMESource: main@e0a25822

Demo Browser

演示用浏览器。基于 Electron + Chromium,把网页演示拆成 Stage(给观众看)和 Recorder(固定规格录制),不 fork 浏览器内核; 演示流程用场景脚本编排,配 Director 控制台与本地控制 API。

当前仓库只做技术验证:无头录制、CDP 物理交互、覆盖层、1080p30 出片、证据文件、 最小 .app。

快速开始

前提:Node ≥ 22.12(不含 23 行;本仓在 Node 24 上开发与测试)。 package.json 的 engines 已声明同一范围,版本不满足时包管理器在安装阶段就给出 明确提示(yarn 直接失败;npm / pnpm 默认打印 EBADENGINE 警告、engine-strict 下失败),不会拖到 vite / vitest 深处才炸出难懂的错误。

npm install
npm run build

# 起 fixture 静态服务(另开一个终端)
python3 -m http.server 4788 --bind 127.0.0.1 --directory out/fixture

# 默认:无头后台录制,10 秒
npx electron . --mode=record --seconds=10 --out=evidence --label=hidden

默认录制不显示窗口、不抢焦点、不占 Dock(macOS 下 setActivationPolicy('accessory')), 可以一边录一边继续用电脑。

命令

命令 作用
npm run build 编译主进程(tsc)和 fixture(vite)
npm start 打开 Director 控制台 + Stage(Stage 以 inactive 显示,不抢焦点)
npm run start:control 同上,并启动本地控制 API(http://127.0.0.1:7317)
npx electron . --mode=stage 可见 Stage,手动体验页面
npx electron . --mode=record --seconds=10 无头录制(默认)
npx electron . --mode=record --window-mode=inactive --seconds=10 可见但不抢焦点录制
npx electron . --mode=record --plain --seconds=10 不做交互,只录静态页(对照用)
npx electron . --mode=app --autorun=report-review --scenes=fixtures/scenes 无头跑完整场景并出片
npx electron . --mode=app --director-check --scenes=fixtures/scenes 隐形校验 Director 与 preload 桥接
npx electron . --mode=app --headless=true --control-api=true 全无窗口后台实例,只留控制 API 与录制
npm test 单元测试(Scene / Runner / Security / Timeline)
npm run package 打 dist/mac-arm64/Demo Browser.app
./scripts/run-phase0.sh 跑 Phase 0 主证据(hidden + inactive)

常用参数:--url、--width、--height、--out、--label、--keep-frames、 --window-mode=hidden|inactive|offscreen|ghost|focused、--focus-emulation=false、 --control-api=true、--control-port、--headless=true。

本地控制 API 只绑回环地址,启动时生成随机 token 并写到 <out>/control.json(0600), 接口与 curl 示例见 docs/control-api.md。

窗口模式(Phase 0 实测)

模式 行为 可录制 可交互
hidden(默认,带 focus emulation) 不显示窗口 是 是
hidden + --focus-emulation=false 不显示窗口 是 否,点击会被丢弃
inactive 显示窗口但不抢焦点 是 是
offscreen 显示到屏幕外 是 是
ghost 显示但透明度 0 是 是

无头模式必须配合 Emulation.setFocusEmulationEnabled,否则 CDP 物理点击不会生效。

输出

每次录制落两份文件:

evidence/
  hidden.mp4
  hidden.evidence.json     # 版本、视口、DPR、帧数、时长、SHA256、步骤、自检结果
  hidden.overlay-frame.png # 覆盖层校验帧(--plain 时不生成)

自检全过才返回 0:窗口无 Node、帧到达、时长误差 ≤0.5s、30fps、1920x1080、 黑帧占比 <50%、覆盖层真的进了视频。

结构

src/main/
  index.ts            # 启动、退出码、全局失败兜底
  cli.ts              # 参数
  app.ts              # app 模式装配:Scene 服务、Director、IPC
  app-controller.ts   # 状态快照、场景加载、运行、录制
  ipc.ts              # Director 通道与控制命令
  control-dispatch.ts # Director IPC 与本地 API 共用的命令分发
  control/            # 本地 HTTP 控制 API(回环 + token + SSE)
  stage-layout.ts     # 场景尺寸/安全策略/访问顺序的纯计算
  demo-protocol.ts    # demo:// 场景协议(按 session 注册)
  electron-page-driver.ts  # PageDriver 的 Electron 实现(CDP 物理事件)
  electron-overlay.ts      # OverlayPort:光标/高亮/聚光/标注/遮罩/黑屏
  scenes/             # Zod 校验、Scene 加载、变量插值、脚本 hash
  runner/             # 状态机、18 个动作、目标解析
  capture/            # screencast 抓帧、30fps 时间轴、ffmpeg、evidence
  security/           # 白名单、路径安全、权限与下载策略
  windows/            # Stage(BaseWindow+WebContentsView)、Director
  phase0.ts           # Phase 0 冒烟脚本(保留)
src/renderer/director # 讲解人控制台(React + lucide)
src/preload/          # Director 桥接(沙箱可用)
src/fixture/      # React fixture:计数按钮、搜索、风险行、动画
fixtures/scenes/  # 可直接加载的场景(report-review)
scripts/
  run-phase0.sh      # 主证据复现
  baseline_chrome.py # 无头 Chrome 对照(复用 recorder-pipe Recorder)
  compare.cjs        # SSIM 对比

场景(Phase 1)

fixtures/scenes/report-review/scene.yaml 是当前可用场景:7 步,包含 wait_for → highlight → click → fill → assert → spotlight → annotate。 本地页面通过 demo://scene/report-review/index.html 加载,只允许读写场景目录内的文件。

fixtures/scenes/multi-a → multi-b 验证多场景切换:1280×720 切到 1600×900, 同一路 screencast 不断流,evidence 里记 run.scene_ids。

Scene 层校验一次报全所有错误;未知字段、越界时间、缺目标都会在加载前失败。 录制产物落在 <out>/recordings/<时间戳>_<场景>/take-01.mp4 和同名 .evidence.json。 字段契约见 schemas/scene.schema.json。

目标解析(步骤怎么找到元素)

带目标的动作按固定顺序解析,先命中先用:

优先级 写法 解析为
1 data_demo_id: increment [data-demo-id="increment"]
2 selector: ".btn-primary" 原样 CSS 选择器
3 text: 金额异常 文本匹配(规则见下)
4 x: 640 + y: 360 视口坐标点(无选择器,兜底用)

文本匹配在页面内找可见(非隐藏且有尺寸)且文本包含目标串的最小元素, 命中后打上运行期属性供该步后续命令复用;找不到报 E_SELECTOR_NOT_FOUND, 四层都没写则报「步骤没有可解析的点击或视觉目标」。

两个特例里 text 不当目标用:

  • fill 的 text 是要输入的内容,目标另写 selector / data_demo_id / 坐标, 或用 target_text 指定要点的元素文本;
  • annotate 的 text 是标注文案,目标必须是 selector / data_demo_id / 坐标。

另外 wait_for 的 text 是等待条件(等文本出现),不是点击目标。

界面与主进程通过 director:get-snapshot / director:send / director:event 通信, 缺少桥接时 Director 会显示 MOCK 标记,不会把假数据当成真实会话。

失败行为

  • 找不到 ffmpeg、CDP 附加失败、选择器找不到、断言失败、没有帧、编码失败都非零退出。
  • 主进程未捕获异常直接打印并退出,不弹系统错误框(无头场景会静默阻塞)。
  • 录制失败保留失败 evidence;--keep-frames 额外保留原始帧。

退出码稳定,CI 可按码分支处理:

退出码 含义
0 成功:自检全过(autorun 成功时 stdout 另输出单行 JSON 快照)
2 参数错误,或通用失败(页面加载失败、E_SELECTOR_NOT_FOUND、断言失败、CDP 附加失败、场景校验失败、端口被占用等)
3 ffmpeg/ffprobe 缺失或执行失败(E_FFMPEG_MISSING / E_FFMPEG_FAILED,先安装 ffmpeg)
4 录制器失败(E_RECORDER_NO_FRAMES 等采帧/时间轴错误)

详细结论见 docs/phase0-report.md、docs/phase1.md、 docs/phase1b.md。

—/ 5

No ratings yet

Verified DSH bundle

Commit e0a25822271d

Community comments

No comments yet. Be the first to write one.

DSH HUB

A community index for DSH plugins. Not an official GitHub or DeepSeek AI product.

CommunityResourcesAPIAbout