dsh-capyreporter 0.1.2 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # 🐾 CapyReporter — the capybara that reports for you
2
2
 
3
+ English | [简体中文](README.zh.md)
4
+
3
5
  **An always-on-top capybara task reporter for the DeepSeek Harness Web UI.**
4
6
 
5
7
  CapyReporter is a tiny transparent window that floats above **every** app and tab of your desktop — not just inside the page — and quietly narrates what your deepseek harness agent is doing, one step at a time, so you can focus on your other work and never miss the moment a task finishes.
package/README.zh.md CHANGED
@@ -1,60 +1,55 @@
1
- # 🐾 CapyReporter — 替你盯梢的水豚小报
1
+ # CapyReporter 🦫
2
2
 
3
- **一个永远置顶的 「水豚小报」:为 DeepSeek Harness Web UI 实时播报任务进度的桌面宠物。**
3
+ [English](README.md) | 简体中文
4
4
 
5
- CapyReporter 是一个小小的透明窗口,悬浮在**你桌面上的每一个应用与标签页之上**——不止于网页内部。它会在 agent 工作的每一个关键节点轻声播报,让你安心处理手头的事,绝不错过任务完成的瞬间。
5
+ 一只常驻桌面的水豚,替你盯着 DeepSeek Harness 里跑着的任务。
6
6
 
7
- ## 🦫 亮点
7
+ 它是个透明小窗口,永远浮在所有应用之上——切到浏览器也好、写代码也好、打游戏也好,它都在。Agent 每跑一步(调工具、写回复、进新阶段),气泡就更新一行;任务跑完了,"✅ 任务完成"会一直挂在屏幕上等你回来,点一下水豚就直接跳回 DSH。
8
8
 
9
- - **真正的全局置顶。** 透明、无边框、除水豚本体外点击穿透。用记事本、看视频、玩游戏、写代码——她就静静浮在那里,大小字都看得清。Windows 上由 Electron 桌面窗口实现,未安装 Electron 时自动回落到页面内悬浮。
10
- - **播报运行轨迹。** 每到一个检查点,气泡就更新一行:`🔧 工具调用`、`💭 思考中…`、`🧭 调度/干预`、`🚀 工作流阶段`、`⚠️ 报错与重试`——实时看着你的 agent「思考」。
11
- - **智能气泡,不挡视线。**
12
- - *紧凑模式*:标题 + 最新状态一行。
13
- - *单击展开*:滚动查看本次运行的步骤历史。
14
- - *双击隐藏*:水豚安静下来,直到下一条更新。
15
- - *右键 → 恢复气泡*:随时找回小报。
16
- - **认得到项目的名字。** 气泡直接显示运行所属的**工作区/项目名**(与左侧边栏一致)。多会话并行时,你一眼就知道是谁在汇报。
17
- - **离开时也不错过完成。** `✅ 任务完成 — <项目名>` 会一直留在置顶窗口上,点击水豚一键回到 DeepSeek Harness;还可选桌面通知。
18
- - **完全可自定义。** 在 **设置 → 🐾 CapyReporter** 上传任意透明 PNG 换掉形象;在水豚身上滚动鼠标滚轮即可调整大小。设置里也能一键开启/关闭、卸载插件。
19
- - **持久且本地优先。** 偏好(形象、大小、位置)存于 `$DSH_HOME/capyreporter.json`;无云、无账号、无遥测。
9
+ ## 能干什么
20
10
 
21
- ## 📦 安装
11
+ - **真的全局置顶**:基于 Electron 的透明窗口,浮在所有应用之上。透明部分点击穿透,不挡下面的操作;只有点在水豚身上才算点到它。没装 Electron 也不影响,会自动退回页面内悬浮,气泡功能一样不少。
12
+ - **逐步播报**:工具调用、模型输出、steering、workflow 阶段、报错重试——每到一个节点,气泡换一行,像看轨迹时间线一样看着 agent 干活。
13
+ - **气泡不吵**:默认只显示最新一条状态;单击展开完整的步骤历史(带滚动条,按时间排序);双击先藏起来,有新动静会自己冒出来;右键菜单里随时能找回。
14
+ - **认项目**:气泡标题直接用任务所属的工作区名字(和左侧边栏一致)。多会话并行的时候,一眼就知道是谁在汇报。
15
+ - **摸鱼友好**:切去干别的,任务完成了水豚会在置顶窗口上提醒你,桌面通知也可以开。
16
+ - **形象随你换**:设置里上传任意透明 PNG 就能换角色;在水豚身上滚动滚轮缩放;偏好本地保存在 `$DSH_HOME/capyreporter.json`,重启不丢。
22
17
 
23
- **插件市场**(上架后):*设置 → 插件市场 → 搜索「capy」→ 安装 → 刷新页面*。
18
+ ## 安装
24
19
 
25
- **命令行:**
20
+ 推荐先装 [dsh-market](https://github.com/dsh-market/dsh-market#readme),然后在 设置 → 插件市场 里搜 "capy" 一键安装。
21
+
22
+ 命令行也行:
26
23
 
27
24
  ```sh
28
25
  dsh plugin --profile web add dsh-capyreporter
29
26
  ```
30
27
 
31
- 然后重启 `dsh web`(或直接刷新页面)。需要 DSH web 0.1.0-rc.6 或更新版本。
28
+ 装完重启 `dsh web`(或者直接刷新页面)。需要 dsh web 0.1.0-rc.6 以上。
29
+
30
+ ## 关于置顶窗口
32
31
 
33
- **为置顶窗口准备的 Electron(可选,推荐):**
32
+ 页面内的水豚只有切回 DSH 才看得到,想要"切走也在",得靠一个真正的置顶窗口,这块用的是 Electron
34
33
 
35
- - 若 Electron 已存在于 `%USERPROFILE%\.dsh\electron\electron.exe`(或 `DSH_PET_ELECTRON_PATH` 指向的任意路径),桌面窗口开箱即用;
36
- - 没有的话,CapyReporter 仍会在 **页面内** 工作——一个悬浮在 DeepSeek Harness 页面上的透明水豚,气泡功能一个不少。
34
+ - `%USERPROFILE%\.dsh\electron\electron.exe` 已经存在的话(或者用 `DSH_PET_ELECTRON_PATH` 指定路径),重启后置顶窗口会自动出现;
35
+ - 没有也不影响,水豚会以页面内悬浮的形式工作,功能一个不少。
37
36
 
38
- ## 🎛 操作一览
37
+ ## 操作一览
39
38
 
40
39
  | 操作 | 效果 |
41
40
  | --- | --- |
42
- | 拖动水豚 | 移动(窗口跟随) |
41
+ | 拖动水豚 | 挪位置(窗口跟着走,甩多快都跟得上) |
43
42
  | 在水豚上滚轮 | 缩放 |
44
43
  | 单击气泡 | 展开 / 收起步骤日志 |
45
- | 双击气泡 | 隐藏,直到下一条更新 |
46
- | 左键点击水豚 | 回到 DeepSeek Harness |
47
- | 右键点击水豚 | 菜单:恢复气泡 · 打开 DSH · 隐藏桌面宠物 |
48
-
49
- ## 🎨 美术与许可
50
-
51
- - 内置默认水豚形象,可随时在设置中用你自己的透明 PNG 替换。
52
- - MIT 许可;默认水豚形象刻意设计为「可替换」,换图无任何限制。
44
+ | 双击气泡 | 先藏起来,有新动静再冒出来 |
45
+ | 左键点水豚 | 回到 DeepSeek Harness |
46
+ | 右键水豚 | 菜单:恢复气泡 · 打开 DSH · 隐藏桌面宠物 |
53
47
 
54
- ## 🌍 贡献与反馈
48
+ ## 已知限制
55
49
 
56
- 欢迎提 Issue 与 PR。*本插件为社区作品——请只安装你信任的来源。*
50
+ - 置顶窗口依赖本机已安装的 Electron,目前不会自动下载(后面版本打算支持)。
51
+ - 个别独占全屏的程序(比如某些游戏)会盖住置顶窗口,这是系统层面的限制,绕不过去。
57
52
 
58
- ---
53
+ ## License
59
54
 
60
- 为 DeepSeek Harness 社区而作 🧡
55
+ [MIT](LICENSE)
package/lib/index.js CHANGED
@@ -491,4 +491,5 @@ function apply(ctx) {
491
491
  if (state.enabled && state.desktopEnabled) startHelper()
492
492
  }
493
493
 
494
- export { apply, inject, name }
494
+ // Pure helpers are exported for unit tests (node --test test/).
495
+ export { apply, inject, name, asText, titleOf, extractEventText, tailPreview, stepLineOf }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-capyreporter",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "CapyReporter — an always-on-top capybara task reporter for the DeepSeek Harness Web UI. A transparent floating pet that narrates each trajectory step in a speech bubble, tells you which project is reporting, alerts you when a task completes while you are away, and lets you upload your own pet art.",
5
5
  "keywords": [
6
6
  "dsh",
@@ -43,6 +43,7 @@
43
43
  "LICENSE"
44
44
  ],
45
45
  "scripts": {
46
+ "test": "node --test \"test/*.test.mjs\"",
46
47
  "verify": "node scripts/verify.mjs",
47
48
  "prepack": "node scripts/check-bom.mjs"
48
49
  },
@@ -110,6 +110,10 @@ app.whenReady().then(() => {
110
110
  const ch = Math.round(Number(size && size.h) || 0);
111
111
  if (cw < 80 || ch < 80 || cw > 4000 || ch > 4000) return;
112
112
  const b = w.getBounds();
113
+ // Same size → nothing to do. Re-issuing setBounds with identical values is
114
+ // not a no-op under fractional display scaling: every DIP↔physical round
115
+ // trip can round the position a pixel further (the "pet sinks" bug).
116
+ if (b.width === cw && b.height === ch) return;
113
117
  const area = screen.getPrimaryDisplay().workArea;
114
118
  const width = Math.min(cw, area.width);
115
119
  const height = Math.min(ch, area.height);
@@ -57,6 +57,10 @@
57
57
  // can report a fuller status (expanded step log) without the window blowing up.
58
58
  const BASE_IMG_H = 182;
59
59
  let scale = 1;
60
+ // Only resize when the size actually changed: re-issuing an identical resize
61
+ // every tick makes Windows' fractional-DPI bounds round-trip walk the window
62
+ // down the screen a pixel at a time.
63
+ const lastFit = { w: 0, h: 0 };
60
64
  function refit() {
61
65
  const imgH = Math.round(BASE_IMG_H * scale);
62
66
  img.style.height = imgH + 'px';
@@ -71,7 +75,12 @@
71
75
  w = Math.max(w, bw);
72
76
  h = Math.max(h, imgH + 12 + bh);
73
77
  }
74
- window.petBridge.resize({ w: Math.round(w), h: Math.round(h) });
78
+ w = Math.round(w);
79
+ h = Math.round(h);
80
+ if (w === lastFit.w && h === lastFit.h) return;
81
+ lastFit.w = w;
82
+ lastFit.h = h;
83
+ window.petBridge.resize({ w: w, h: h });
75
84
  }
76
85
  img.addEventListener('load', () => refit());
77
86
  window.addEventListener('wheel', (e) => {