桌面置顶小条帮你拆解任务、跟踪进度并给出下一步建议
30.7/100
综合分
1
GitHub 星标
—
npm 周下载
—/5
用户评分
数据截至 2026/10/26 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add liyangyu001-hue/dsh-work该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:已验证
是什么
dsh 原生插件 · chat
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 9 天前
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码v2.7.0🔵 扫描:含敏感能力尚无人工评估展开查看扫描说明与证据 ↓
安全扫描自动 · 静态分析源码
v2.7.0静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。
可执行外部命令读写/删除本地文件发起外部网络请求
查看扫描证据(共 104 处,展示前 80 条)
- 读取本地文件apps/companion/src/capture.cjs:87
names = await fs.readdir(dir); - 读取本地文件apps/companion/src/capture.cjs:97
const stat = await fs.stat(file); - 删除本地文件apps/companion/src/capture.cjs:98
if (stat.mtimeMs < cutoff) await fs.unlink(file); - 写入本地文件apps/companion/src/capture.cjs:147
await fs.mkdir(dir, { recursive: true }); - 写入本地文件apps/companion/src/capture.cjs:161
await fs.writeFile(file, source.thumbnail.toPNG()); - 写入本地文件apps/companion/src/capture.cjs:278
await fs.writeFile(out, png); - 删除本地文件apps/companion/src/capture.cjs:334
files.map((file) => fs.rm(file, { force: true }).catch(() => {})), - 读取本地文件apps/companion/src/config.cjs:116
text = readFileSync(file, "utf8"); - 删除本地文件递归apps/companion/src/config.test.ts:96
t.after(() => rmSync(dir, { recursive: true, force: true })); - 写入本地文件apps/companion/src/config.test.ts:104
writeFileSync(file, '\uFEFF{"hotkey":"Alt+Space","allowBareTab":false}', 'utf8'); - 读取本地文件apps/companion/src/host-link.cjs:54
const parsed = JSON.parse(await readFile(file, "utf8")); - 发起网络请求apps/companion/src/host-link.cjs:126
const res = await fetch(`${endpoint.url}/dsh-work/api/events`, { - 写入本地文件apps/companion/src/log.cjs:41
await mkdir(path.dirname(file), { recursive: true }); - 写入本地文件apps/companion/src/log.cjs:42
await appendFile(file, line, "utf8"); - 读取本地文件apps/companion/src/log.cjs:52
const text = await readFile(file, "utf8"); - 写入本地文件apps/companion/src/log.cjs:55
await writeFile(file, lines.slice(-MAX_LINES).join("\n"), "utf8"); - 发起网络请求apps/companion/src/main.cjs:310
const res = await fetch(`${endpoint.url}/dsh-work/api/intent`, { - 读取本地文件apps/companion/src/main.cjs:364
const png = await fs.readFile(result.file); - 发起网络请求apps/companion/src/main.cjs:365
const started = await fetch(`${endpoint.url}/dsh-work/api/recognize`, { - 发起网络请求apps/companion/src/main.cjs:379
const res = await fetch( - 删除本地文件递归packages/plugin/src/artifact.test.ts:44
await rm(root, { recursive: true, force: true }); - 读取本地文件packages/plugin/src/artifact.test.ts:80
const onDisk = await readFile(path.join(root, ARTIFACT_DIR, 'nd_demo.md'), 'utf8'); - 写入本地文件packages/plugin/src/artifact.test.ts:104
await writeFile(absolute, 'x'.repeat(600 * 1024), { encoding: 'utf8' }).catch(async () => { - 读取本地文件packages/plugin/src/artifact.ts:90
const content = await readFile(absolute, 'utf8'); - 写入本地文件packages/plugin/src/artifact.ts:104
await mkdir(path.dirname(absolute), { recursive: true }); - 写入本地文件packages/plugin/src/artifact.ts:105
await writeFile(absolute, text, 'utf8'); - 写入本地文件packages/plugin/src/captures.test.ts:31
await writeFile(old, Buffer.alloc(1024)); - 写入本地文件packages/plugin/src/captures.test.ts:32
await writeFile(fresh, Buffer.alloc(2048)); - 写入本地文件packages/plugin/src/captures.test.ts:33
await writeFile(foreign, 'x'); - 写入本地文件packages/plugin/src/captures.test.ts:35
await utimes(old, past, past); - 读取本地文件packages/plugin/src/captures.test.ts:42
await assert.rejects(() => stat(old)); - 读取本地文件packages/plugin/src/captures.test.ts:43
assert.equal((await stat(fresh)).size, 2048); - 读取本地文件packages/plugin/src/captures.test.ts:44
assert.equal((await stat(foreign)).size, 1); - 删除本地文件递归packages/plugin/src/captures.test.ts:45
await rm(dir, { recursive: true, force: true }); - 写入本地文件packages/plugin/src/captures.test.ts:52
await writeFile(old, Buffer.alloc(10)); - 写入本地文件packages/plugin/src/captures.test.ts:54
await utimes(old, past, past); - 读取本地文件packages/plugin/src/captures.test.ts:60
assert.equal((await stat(old)).size, 10); - 删除本地文件递归packages/plugin/src/captures.test.ts:61
await rm(dir, { recursive: true, force: true }); - 删除本地文件递归packages/plugin/src/captures.test.ts:79
await rm(dir, { recursive: true, force: true }); - 读取本地文件packages/plugin/src/captures.ts:69
names = await readdir(dir); - 读取本地文件packages/plugin/src/captures.ts:84
info = await stat(full); - 删除本地文件packages/plugin/src/captures.ts:91
await unlink(full); - 写入本地文件packages/plugin/src/endpoint.ts:54
await mkdir(dir, { recursive: true }); - 读取本地文件packages/plugin/src/endpoint.ts:57
const existing = (await readFile(file, 'utf8')).trim(); - 写入本地文件packages/plugin/src/endpoint.ts:63
await writeFile(file, `${token}\n`, { encoding: 'utf8', mode: 0o600 }); - 写入本地文件packages/plugin/src/endpoint.ts:85
await mkdir(endpointDir(), { recursive: true }); - 写入本地文件packages/plugin/src/endpoint.ts:86
await writeFile(endpointFile(), `${JSON.stringify(endpoint, null, 2)}\n`, { - 读取本地文件packages/plugin/src/endpoint.ts:96
const parsed = JSON.parse(await readFile(file, 'utf8')) as Partial<Endpoint>; - 发起网络请求packages/plugin/src/http.test.ts:119
const posted = await fetch(`${h.base}/api/recognize`, { - 发起网络请求packages/plugin/src/http.test.ts:129
const polled = await fetch(`${h.base}/api/recognize/rc_1`); - 发起网络请求packages/plugin/src/http.test.ts:154
const res = await fetch(`${h.base}/api/recognize`, { method: 'POST', body: PNG }); - 发起网络请求packages/plugin/src/http.test.ts:167
const res = await fetch(`${h.base}/api/recognize`, { method: 'POST', body: 'not a png' }); - 发起网络请求packages/plugin/src/http.test.ts:179
const empty = await fetch(`${h.base}/api/recognize`, { method: 'POST' }); - 发起网络请求packages/plugin/src/http.test.ts:182
const wrongMethod = await fetch(`${h.base}/api/recognize`); - 发起网络请求packages/plugin/src/http.ts:436
const result = await options.advise.request(nodeId); - 发起网络请求packages/plugin/src/http.ts:480
const result = await options.learn.request(nodeId); - 发起网络请求packages/plugin/src/http.ts:533
const asked = await options.chat.request({ nodeId, question, history }); - 读取本地文件packages/plugin/src/index.ts:824
const raw = await readFile(path.join(HERE, '..', 'package.json'), 'utf8'); - 读取本地文件packages/plugin/src/store.test.ts:29
const raw = await readFile(path.join(root, '.dsh-work', 'work.json'), 'utf8'); - 删除本地文件递归packages/plugin/src/store.test.ts:34
await rm(root, { recursive: true, force: true }); - 删除本地文件递归packages/plugin/src/store.test.ts:54
await rm(root, { recursive: true, force: true }); - 读取本地文件packages/plugin/src/store.test.ts:66
const text = await readFile(journalPath, 'utf8'); - 写入本地文件packages/plugin/src/store.test.ts:70
await writeFile(journalPath, `${text}半行坏掉`, 'utf8'); - 删除本地文件递归packages/plugin/src/store.test.ts:74
await rm(root, { recursive: true, force: true }); - 读取本地文件packages/plugin/src/store.test.ts:83
const before = await readFile(path.join(root, '.dsh-work', 'journal.ndjson'), 'utf8'); - 读取本地文件packages/plugin/src/store.test.ts:88
const after = await readFile(path.join(root, '.dsh-work', 'journal.ndjson'), 'utf8'); - 删除本地文件递归packages/plugin/src/store.test.ts:92
await rm(root, { recursive: true, force: true }); - 读取本地文件packages/plugin/src/store.test.ts:108
const journal = await readFile(path.join(root, '.dsh-work', 'journal.ndjson'), 'utf8'); - 删除本地文件递归packages/plugin/src/store.test.ts:111
await rm(root, { recursive: true, force: true }); - 删除本地文件递归packages/plugin/src/store.test.ts:129
await rm(root, { recursive: true, force: true }); - 写入本地文件packages/plugin/src/store.ts:94
await mkdir(path.join(stateDir, 'captures'), { recursive: true }); - 写入本地文件packages/plugin/src/store.ts:190
await appendFile(this.journalPath, `${JSON.stringify(entry)}\n`, 'utf8'); - 删除本地文件packages/plugin/src/store.ts:232
await rm(this.snapshotPath, { force: true }); - 删除本地文件packages/plugin/src/store.ts:233
await rm(this.journalPath, { force: true }); - 读取本地文件packages/plugin/src/store.ts:273
return await readFile(file, 'utf8'); - 写入本地文件packages/plugin/src/store.ts:283
await writeFile(temporary, data, 'utf8'); - 写入本地文件packages/plugin/src/store.ts:285
await rename(temporary, file); - 删除本地文件packages/plugin/src/store.ts:287
await rm(temporary, { force: true }); - 读取本地文件packages/plugin/src/ui-open.ts:116
if (existsSync(candidate)) return candidate; - 执行外部命令来自配置/变量packages/plugin/src/ui-open.ts:127
const child = spawn(executable, [], { detached: true, stdio: 'ignore', windowsHide: true });
扫描于 2026/11/4(0 天前) · 范围 全包扫描 · 来源 GitHub 仓库
静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
人机协作的办公专注层:桌面置顶小条 + 任务面板 + 框选识别,人类执行、AI 建议。DSH 插件 + C++ 伴随层。
README
由 DeepSeek 最新模型翻译生成DSH Work
让人类与 AI 共享同一个任务进程。
DSH Work 是 DeepSeek Harness 的一款插件。装上它,桌面顶部会多出一条极窄的半透明玻璃条;按一下键,它看见你的屏幕,把你嘴里那句「我想做点什么」切成可执行的节点,然后人往前走一步,它在旁边递工具、提建议、必要时自己上手。
它不是又一个待办清单。它的定位是办公专注模式:你在做什么、做到哪儿、下一步该干嘛、这件事该不该交出去——这些本该由人脑维持的状态,现在有一个常驻进程替你维持着,并且它有心跳。
要改它、或者要跟它一起工作? 先读 项目说明:它写清了项目是什么、每层为什么存在、各自负责什么、工程规则是什么、踩过哪些坑。
只想知道现在做到哪了,读 接力板。
展开完整文档(README 剩余 1 节)
DSH Work
让人类与 AI 共享同一个任务进程。
DSH Work 是 DeepSeek Harness 的一款插件。装上它,桌面顶部会多出一条极窄的半透明玻璃条;按一下键,它看见你的屏幕,把你嘴里那句「我想做点什么」切成可执行的节点,然后人往前走一步,它在旁边递工具、提建议、必要时自己上手。
它不是又一个待办清单。它的定位是办公专注模式:你在做什么、做到哪儿、下一步该干嘛、这件事该不该交出去——这些本该由人脑维持的状态,现在有一个常驻进程替你维持着,并且它有心跳。
要改它、或者要跟它一起工作? 先读 项目说明:它写清了项目是什么、每层为什么存在、各自负责什么、工程规则是什么、踩过哪些坑。
只想知道现在做到哪了,读 接力板。
┌──────────────────────────────────────────────────────────┐
│ 伴随层(C++ / Win32,Electron 版保留可回退) │ │ 热键 · 截图框选 · 置顶玻璃小条 · 面板 · 托盘 │ └───────────────▲──────────────────────┬───────────────────┘ │ HTTP / SSE │ ┌───────────────┴──────────────────────▼───────────────────┐ │ 插件宿主(Node) 任务状态机 · 持久化 · AI 编排 · 工具 │ └───────────────▲──────────────────────┬───────────────────┘ │ 同源 HTTP │ ┌───────────────┴──────────────────────▼───────────────────┐ │ DSH 窗口内(React) 工作台 · 任务树 · 建议流 · 学习模式 │ └──────────────────────────────────────────────────────────┘
现在什么状态
P0 地基已完成:三层骨架跑通并互相认得——宿主侧有可回放的任务状态机与持久化,窗口内有玻璃条,桌面上有一条真正置顶、跨应用的玻璃条。
P1 进行中:全局热键唤出面板(小条的展开态)——当前节点居中,左右是已完成与待进行;Enter 完成并前进、Backspace 退一步、Tab 进框选。框完即识别:PNG 交给宿主,视觉模型一次调用拆成带目标与验收的任务树,落盘后小条与面板同时看到它。
文档里的图都是 node scripts/make-shots.mjs 用合成数据渲染真实界面得来的,不是桌面截图——仓库是公开的,桌面截图会把别人窗口里的东西一起带出去。
| 阶段 | 内容 | 状态 |
| P0 | 三层骨架 + 契约冻结 + core 状态机 + 置顶玻璃条 | ✅ |
| P1 | 热键 → 面板 → 框选截图 → 识别 → 任务树 → 卡片轮播 | 🚧 识别已接,轮播待做 |
| 原生切片一 | C++ 小条替代 Electron(318 KB vs 210 MB) | ✅ |
| 原生切片二 | 原生面板 + 托盘 | 🚧 进行中 |
| P2 | 建议流 · 交给 AI · 任务树编辑 | ⬜ |
| P3 | 玻璃与动效 · 多屏 · 离线 · 设置 | ⬜ |
| P4 | 学习模式 · 眼球追踪 · macOS | ⬜ |
设计原则
1. 协议优先。三端只能通过 docs/PROTOCOL.md 通信;任何一端都可以被重写而不动其他两端。
2. 单一真相源。任务状态只存在于插件宿主,伴随层与界面都是视图,不得自行改状态,只能提 Intent。
3. 事件日志即历史。所有变更以只追加的 journal.ndjson 落盘,可回放、可审计、可撤销。
4. 克制。理性克制的动效,遵循动画十二原则里的「预备、跟随、缓入缓出」,不追求炫技。
5. 可维护。每个决策写进 docs/ADR/,每个包自带 README,代码注释解释「为什么」而非「是什么」。
开发
pnpm install
pnpm test # 直接跑 .ts,无需构建(Node 22.18+ 原生类型擦除)
pnpm typecheck
pnpm build # esbuild 打插件与客户端两个 bundle
node scripts/shot.mjs # 用本机 Chrome 无头截图,肉眼验收界面
把插件挂进一个开发用 profile(不动你日常那个):
dsh dshwork-dev --from-default-profile web # 首次:建 profile
pnpm build # 每次改完客户端都要重打
dsh --profile dshwork-dev --port 64001 --no-open
端口被上一次的进程占着时,dsh 起不来而日志里看不出原因。先按端口杀: Get-NetTCPConnection -LocalPort 64001 -State Listen | % { Stop-Process -Id $_.OwningProcess -Force }
伴随层(桌面置顶玻璃条)单独跑:
cd apps/companion && ./node_modules/electron/dist/electron.exe .
在 DSH 的终端里启动前必须 Remove-Item Env:ELECTRON_RUN_AS_NODE —— DSH 自己的诊断环境会带上它,Electron 见到它会退化成纯 Node,窗口一个都不会出现。
排障看 ~/.dsh/dsh-work/companion.log。
文档索引:项目说明 · 架构 · 协议 · 数据模型 · 设计系统 · 路线图 · 当前任务
许可
MIT © 2026 liyangyu001-hue
制作
| 角色 | 是谁 |
| 产品取舍、美术方向、验收 | liyangyu001-hue |
| 架构、实现、文档、发布 | DeepSeek Harness Agent(AI 协作者,跑在 DeepSeek Harness 里) |
这个项目由人和 AI 代理结对完成:人决定「做成什么样」,代理负责「怎么做到、以及证明做到了」。
两者的分工与工作规则写在 项目说明 里——那不是给使用者看的,是给下一个接手的人。预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
liyangyu001-hue/dsh-work
桌面置顶小条帮你拆解任务、跟踪进度并给出下一步建议
相关插件 · 对话 / 记忆
上下文中枢oceanbase/powercontext
上下文跟着工作走 —— 跨会话、跨智能体、跨人。
★ 1,489已汉化DSH
73.1
智能体记忆库plastic-labs/honcho
Honcho 是记忆基础设施,用来构建有状态的智能体。这些智能体能理解不断变化的人、智能体、群组、项目和想法。
★ 7,918已汉化DSH
71.7
长程智能体控制面loopx-project/loopx
给 Agent 一个目标,让工作持续向前。
★ 6,358已汉化DSH
71.3
智能体上下文数据库volcengine/OpenViking
给 AI 智能体用的上下文数据库
★ 41,453已汉化DSH
71.3
长效机器人团队Fei2411/DS-Bot
Download DS Bot for Windows 10/11 64-bit / 下载 Windows…
★ 5,293已汉化DSH
71.2
可携带记忆层EverMind-AI/EverOS
为什么选择 EverOS
★ 13,797已汉化DSH
71.1
这是你的仓库?认领条目