个人开源项目,非 DeepSeek 官方产品。
38.6/100
综合分
11
GitHub 星标
—
npm 周下载
—/5
用户评分
数据截至 2026/10/27 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
该插件未发布到 npm,按作者文档从 GitHub 源安装即可(静态检查只覆盖 npm 路径,不代表插件不可用)。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add kermanx/dshw该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:已验证
是什么
dsh 原生插件 · other
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 8 天前
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查需源码安装engines.node 要求 >=24.0.0,不满足 Node 22.19.0
展开查看检查明细 ↓
以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。
✗npm 包dshw(未发布到 npm,仅可源码安装)
✗Node 引擎要求 >=24.0.0 · 基线 Node 22.19 不满足
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明
源码安装时若 pnpm 拦截 prepare 脚本,按其提示在 pnpm-workspace.yaml 的 allowBuilds 中放行后重跑。
验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/30 15:55:04
安全扫描自动 · 静态分析源码v2.7.0🔵 扫描:含敏感能力尚无人工评估展开查看扫描说明与证据 ↓
安全扫描自动 · 静态分析源码
v2.7.0静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。
可执行外部命令读写/删除本地文件发起外部网络请求
查看扫描证据(共 112 处,展示前 103 条)
- 读取本地文件src/cli.ts:171
await access(path) - 读取本地文件src/clone.ts:49
await access(path) - 读取本地文件src/clone.ts:60
const entries = await readdir(MANAGED_ROOT, { withFileTypes: true }).catch(() => []) - 读取本地文件src/clone.ts:68
const names = await readdir(candidate, { withFileTypes: true }).catch(() => []) - 写入本地文件src/clone.ts:158
await mkdir(CLONES_ROOT, { recursive: true }) - 删除本地文件递归src/clone.ts:171
await rm(destination, { recursive: true, force: true }) - 写入本地文件src/clone.ts:189
await mkdir(CLONES_ROOT, { recursive: true }) - 删除本地文件递归src/clone.ts:199
await rm(destination, { recursive: true, force: true }) - 删除本地文件递归src/clone.ts:223
await rm(clone.path, { recursive: true, force: true }) - 写入本地文件src/dsh-runtime.ts:53
await mkdir(dirname(HARNESS_RUNTIME_ROOT), { recursive: true }) - 读取本地文件src/dsh-runtime.ts:63
path: await realpath(HARNESS_RUNTIME_ROOT), - 删除本地文件递归src/dsh-runtime.ts:71
await rm(HARNESS_RUNTIME_ROOT, { recursive: true, force: true }) - 读取本地文件src/dsh-runtime.ts:81
if ((await readFile(readyPath, 'utf8')).trim() === marker - 写入本地文件src/dsh-runtime.ts:93
await writeFile(readyPath, `${marker}\n`) - 读取本地文件src/dsh-runtime.ts:107
await access(path) - 读取本地文件src/dsh-runtime.ts:129
const actual = await realpath(HARNESS_RUNTIME_ROOT) - 读取本地文件src/dsh-runtime.ts:135
const info = await lstat(actual) - 读取本地文件src/dsh-runtime.ts:137
await access(join(actual, '.git')) - 读取本地文件src/install.ts:36
const sourceRoot = await realpath(DSHW_ROOT) - 读取本地文件src/install.ts:55
validateInstallation(record, await realpath(DSHW_ROOT)) - 写入本地文件src/install.ts:71
mkdir(DATA_ROOT, { recursive: true }), - 写入本地文件src/install.ts:72
mkdir(dirname(HARNESS_ROOT), { recursive: true }), - 写入本地文件src/install.ts:73
mkdir(dirname(HARNESS_RUNTIME_ROOT), { recursive: true }), - 写入本地文件src/install.ts:74
mkdir(CLONES_ROOT, { recursive: true }), - 写入本地文件src/install.ts:75
mkdir(LOG_ROOT, { recursive: true }), - 写入本地文件src/install.ts:76
mkdir(WORKER_ROOT, { recursive: true }), - 删除本地文件递归src/install.ts:111
await rm(temporary, { recursive: true, force: true }) - 读取本地文件src/install.ts:117
path: await realpath(HARNESS_ROOT), - 读取本地文件src/install.ts:145
const actual = await realpath(HARNESS_ROOT) - 读取本地文件src/install.ts:150
const sourceInfo = await lstat(HARNESS_ROOT) - 读取本地文件src/install.ts:152
const info = await lstat(actual) - 写入本地文件src/service.ts:141
await mkdir(CLONES_ROOT, { recursive: true }) - 写入本地文件src/service.ts:2104
await appendFile(join(LOG_ROOT, `${handle.runId}.log`), `${line}\n`, 'utf8').catch(() => {}) - 发起网络请求src/service-manager.ts:180
response = await fetch(`http://${HOST}:${PORT}/api/state`, { signal: AbortSignal.timeout(8_000) }) - 发起网络请求src/service-manager.ts:196
response = await fetch(`http://${HOST}:${PORT}${path}`, { - 发起网络请求src/service-manager.ts:226
const response = await fetch(`http://${HOST}:${PORT}/api/identity`, { signal: AbortSignal.timeout(1_000) }) - 读取本地文件src/service-manager.ts:245
info = await lstat(SERVICE_PLIST) - 读取本地文件src/service-manager.ts:251
const owner = parseServiceOwner(await readFile(SERVICE_PLIST, 'utf8')) - 写入本地文件src/service-manager.ts:294
await mkdir(dirname(SERVICE_PLIST), { recursive: true }) - 写入本地文件src/service-manager.ts:296
await writeFile(temporary, contents, { mode: 0o600 }) - 写入本地文件src/service-manager.ts:297
await rename(temporary, SERVICE_PLIST) - 读取本地文件src/service-manager.ts:321
return await realpath(path) - 执行外部命令来自配置/变量src/util.ts:43
const child = spawn(command, args, { - 读取本地文件src/util.ts:129
return JSON.parse(await readFile(path, 'utf8')) as T - 写入本地文件src/util.ts:137
await mkdir(dirname(path), { recursive: true }) - 写入本地文件src/util.ts:139
await writeFile(temporary, `${JSON.stringify(value, null, 2)}\n`) - 写入本地文件src/util.ts:140
await rename(temporary, path) - 读取本地文件src/repos.ts:9
await access(path) - 写入本地文件src/repos.ts:38
await mkdir(dirname(root), { recursive: true }) - 读取本地文件src/git.ts:51
return await realpath(result.stdout.trim()) - 读取本地文件src/git.ts:56
return await realpath(resolve(cwd, result.stdout.trim())) - 写入本地文件src/state.ts:36
await mkdir(dirname(EVENT_LOG_FILE), { recursive: true }) - 读取本地文件src/state.ts:39
logSize = (await stat(EVENT_LOG_FILE)).size - 写入本地文件src/state.ts:43
await writeFile(EVENT_LOG_FILE, state.events.map(record => `${JSON.stringify(record)}\n`).join('')) - 写入本地文件src/state.ts:77
this.#logWriteChain = this.#logWriteChain.then(() => appendFile(EVENT_LOG_FILE, `${JSON.stringify(record)}\n`)) - 读取本地文件src/state.ts:127
const size = (await stat(path).catch(() => ({ size: 0 }))).size - 写入本地文件src/worker-config.ts:199
await writeFile(this.#secretFile, `${lines.join('\n')}${lines.length === 0 ? '' : '\n'}`, { mode: 0o600 }) - 写入本地文件src/worker-config.ts:200
await chmod(this.#secretFile, 0o600) - 读取本地文件src/worker-config.ts:234
return parseEnv(await readFile(filename, 'utf8')) as Record<string, string> - 读取本地文件src/dsh.ts:107
const template = await readFile(join(DSHW_ROOT, 'prompts', 'review.md'), 'utf8') - 读取本地文件src/dsh.ts:121
const template = await readFile(join(DSHW_ROOT, 'prompts', filename), 'utf8') - 写入本地文件src/dsh.ts:147
await mkdir(directory, { recursive: true }) - 写入本地文件src/dsh.ts:148
await mkdir(controlRoot, { recursive: true, mode: 0o700 }) - 写入本地文件src/dsh.ts:149
await chmod(controlRoot, 0o700) - 写入本地文件src/dsh.ts:153
await writeFile(patchPath, [ - 写入本地文件src/dsh.ts:213
await writeFile(plistPath, plist, { mode: 0o600 }) - 读取本地文件src/dsh.ts:297
const source = await readFile(join(LOG_ROOT, `${runId}.log`), 'utf8') - 读取本地文件src/dsh.ts:398
const stderr = (await readFile(join(dirname(handle.requestPath), 'worker.stderr.log'), 'utf8')).trim() - 写入本地文件src/dsh.ts:414
await mkdir(LOG_ROOT, { recursive: true }) - 读取本地文件src/dsh-launch-env.ts:31
fallback = parseEnv(readFileSync(userEnvFile, 'utf8')) - 写入本地文件src/codex.ts:42
await mkdir(directory, { recursive: true }) - 写入本地文件src/codex.ts:43
await mkdir(controlRoot, { recursive: true, mode: 0o700 }) - 写入本地文件src/codex.ts:44
await chmod(controlRoot, 0o700) - 写入本地文件src/codex.ts:79
await writeFile(plistPath, plist, { mode: 0o600 }) - 发起网络请求src/codex-runtime.ts:19
client.request('config/read', { cwd, includeLayers: false }), - 发起网络请求src/codex-runtime.ts:72
const response = await client.request('model/list', { limit: 100, ...(cursor === undefined ? {} : { cursor }) }) - 读取本地文件src/codex-runtime.ts:107
await access(candidate, constants.X_OK) - 执行外部命令来自配置/变量src/codex-app-server.ts:22
this.#child = spawn(executable, ['app-server', '--stdio'], { cwd, env: process.env, stdio: ['pipe', 'pipe', 'pipe'] }) - 发起网络请求src/codex-app-server.ts:38
await this.request('initialize', { clientInfo: { name: 'dshw', title: 'dshw', version: '0.1.0' } }) - 发起网络请求plugin/src/data.ts:121
const response = await fetch(`${baseUrl}/api/state`) - 写入本地文件src/codex-session-worker.ts:89
await mkdir(dirname(request.controlSocketPath), { recursive: true }) - 删除本地文件src/codex-session-worker.ts:90
await rm(request.controlSocketPath, { force: true }) - 写入本地文件src/codex-session-worker.ts:91
const eventStream = createWriteStream(request.eventLogPath, { flags: 'a' }) - 写入本地文件src/codex-session-worker.ts:92
const outputStream = createWriteStream(request.outputLogPath, { flags: 'a' }) - 写入本地文件src/codex-session-worker.ts:134
await writeFile(join(dirname(request.resultPath), 'final.txt'), `${output}\n`) - 删除本地文件src/codex-session-worker.ts:143
await rm(request.controlSocketPath, { force: true }) - 发起网络请求src/codex-session-worker.ts:200
const response = await client.request('turn/start', codexTurnStartParams(threadId, prompt, request.worker)) - 发起网络请求src/codex-session-worker.ts:218
await client.request('turn/steer', { - 发起网络请求src/codex-session-worker.ts:229
await client.request('turn/interrupt', { threadId, turnId: activeTurnId }) - 发起网络请求src/codex-session-worker.ts:234
const threadResponse = await client.request('thread/start', codexThreadStartParams(request)) - 发起网络请求src/codex-session-worker.ts:258
await client.request('turn/interrupt', { threadId, turnId: activeTurnId }).catch(() => {}) - 写入本地文件src/codex-session-worker.ts:275
await chmod(request.controlSocketPath, 0o600) - 写入本地文件src/dsh-session-plugin.ts:104
await mkdir(dirname(request.controlSocketPath), { recursive: true }) - 删除本地文件src/dsh-session-plugin.ts:105
await rm(request.controlSocketPath, { force: true }) - 写入本地文件src/dsh-session-plugin.ts:106
const eventStream = createWriteStream(request.eventLogPath, { flags: 'a' }) - 写入本地文件src/dsh-session-plugin.ts:107
const outputStream = createWriteStream(request.outputLogPath, { flags: 'a' }) - 写入本地文件src/dsh-session-plugin.ts:175
await writeFile(join(dirname(request.resultPath), 'final.txt'), `${output}\n`) - 删除本地文件src/dsh-session-plugin.ts:290
await rm(request.controlSocketPath, { force: true }) - 写入本地文件src/dsh-session-plugin.ts:305
await chmod(request.controlSocketPath, 0o600) - 读取本地文件src/dsh-session-plugin.ts:332
for (const group of await readdir(packagesRoot, { withFileTypes: true })) { - 读取本地文件src/dsh-session-plugin.ts:335
for (const candidate of await readdir(groupRoot, { withFileTypes: true })) { - 读取本地文件src/dsh-session-plugin.ts:339
const manifest = JSON.parse(await readFile(join(directory, 'package.json'), 'utf8')) as { name?: string; main?: string } - 发起网络请求src/worker-progress.ts:20
await fetch(progressUrl, {
扫描于 2026/11/3(0 天前) · 范围 入口闭包 + 全包扫描 · 来源 GitHub 仓库
静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
界面预览
1 张 · 点击查看大图功能亮点
- PR工作流
DeepSeek Harness 的 PR 工作流插件
README
由 DeepSeek 最新模型翻译生成dshw
个人开源项目,非 DeepSeek 官方产品。
dshw 是 DeepSeek Harness 的本机 PR 工作流工具,以看板形式嵌入 Harness Web。它会自动追踪你创建的、以及 assign 给你的 PR,克隆到本地独立目录,持续同步目标分支、监控 CI,并在需要时用 dsh Agent 自动处理冲突合并、修复 CI 失败、解决 review 评论。
功能
- Pull requests:按仓库列出你创建或 assign 给你的 open PR,展示 CI、review、合并与同步状态;冲突、落后、失败检查都有一键或自动处理入口。stacked PR 以 target master 的 PR 为顶层根节点,所有直接和间接依赖它的 PR 按深度优先顺序连续排列,统一缩进一层;其他 PR 保持顶层
- Reviews:列出待你 review 的 PR
- Git:仓库分支与提交历史可视化
- Jobs:后台任务列表与详情,运行中的任务可 steer、暂停、终止
- Logs:服务与任务日志
- Settings:
- Repos:选择要监控的 GitHub 仓库(勾选并排序,顺序即各页展示顺序)
- Workers:配置 dsh / Codex 等执行器
- System:更新 dshw、同步主仓库、清理过期 worktree
展开完整文档(README 剩余 1 节)
dshw 个人开源项目,非 DeepSeek 官方产品。 dshw 是 DeepSeek Harness 的本机 PR 工作流工具,以看板形式嵌入 Harness Web。它会自动追踪你创建的、以及 assign 给你的 PR,克隆到本地独立目录,持续同步目标分支、监控 CI,并在需要时用 dsh Agent 自动处理冲突合并、修复 CI 失败、解决 review 评论。 功能 - Pull requests:按仓库列出你创建或 assign 给你的 open PR,展示 CI、review、合并与同步状态;冲突、落后、失败检查都有一键或自动处理入口。stacked PR 以 target master 的 PR 为顶层根节点,所有直接和间接依赖它的 PR 按深度优先顺序连续排列,统一缩进一层;其他 PR 保持顶层 - Reviews:列出待你 review 的 PR - Git:仓库分支与提交历史可视化 - Jobs:后台任务列表与详情,运行中的任务可 steer、暂停、终止 - Logs:服务与任务日志 - Settings: - Repos:选择要监控的 GitHub 仓库(勾选并排序,顺序即各页展示顺序) - Workers:配置 dsh / Codex 等执行器 - System:更新 dshw、同步主仓库、清理过期 worktree 支持同时监控多个仓库;新增仓库后,它的 PR 会被自动发现并展示。 看板会跟随所在面板的宽度排版:窄侧栏将视图选择和工具按钮收在一行,PR 以标题、分支和状态摘要呈现,点击状态行展开具体操作;宽面板保留多列表格。「展开看板」可临时放大整个工作区;在窄侧栏打开 Review diff 时也会自动展开,返回后恢复原列表与滚动位置。样式尺寸参考 VS Code Classic 的 SidebarTitle、ActionBar、SelectBox 和 Pane。 安装 在「DS 内部插件市场」安装「DSHW 工作看板」即可加载看板插件。看板连接本机 http://127.0.0.1:7849 服务;仍需按下述步骤在 macOS 上安装并启动 dshw daemon。 前置条件 - macOS - Node.js 24+ - pnpm - Git - GitHub CLI,并已运行 gh auth login - DeepSeek Harness 步骤 git clone https://github.com/kermanx/dshw.git cd dshw pnpm install pnpm dshw start # 初始化并后台启动服务 首次启动会准备托管仓库与运行时、构建插件、注册 LaunchAgent,可能需要几分钟。 然后把看板装进你的 dsh: dsh plugin --profile web add "$PWD" 重启你的 dsh Web 服务(停掉后重新运行 dsh web),刷新页面即可在左侧栏的标准面板列表看到看板入口。需要支持 sidebar.panellist 与 main 面板接口的新版 Harness。插件列表在启动时组装,新增插件必须重启 dsh web 才会生效。 使用要点 - 看板数据由本机后台服务实时提供,无需手动刷新 - 服务默认监听 127.0.0.1:7849,可用环境变量 DSHW_PORT 修改;换端口后在看板的连接失败界面修改服务地址即可 - 更新:git pull 后运行 pnpm dshw restart 即可。 - 卸载:dsh plugin --profile web remove dshw,再重启 dsh web Worker 配置 Settings 的 Workers 页可以维护多个执行器配置并拖动排序,第一项即默认执行器。支持: - dsh:填写 Provider、模型、API Key 等即可使用 - Codex:使用本机 Codex CLI 与登录状态 - Claude Code:仅保留入口,尚未接入 直接输入的 API Key 不会出现在配置文件里,而是以受限权限单独保存。PR 操作按钮左键使用默认执行器,右键可为本次任务选择其他执行器。 任务控制 运行中的任务可以: - Steer:在下一个 step 前插入指令 - 暂停 / 继续:暂停当前 turn,输入新指令后继续同一个任务 - 终止:结束任务 daemon 重启后会重新接管运行中的任务。 安全与运维 - dshw 只注册当前用户的 LaunchAgent,不使用 sudo,不创建系统级服务 - 所有数据都在仓库的 .dshw/ 目录内(已被 Git 忽略) - worker 使用独立的运行环境,不会写入你的全局配置 - 每份 clone 有独立身份;不同安装互不干扰,冲突操作会明确拒绝 常用命令 pnpm dshw start # 初始化并启动 pnpm dshw stop # 停止 pnpm dshw restart # 构建插件并重启 pnpm dshw status # 查看状态 pnpm dshw code # 打开当前分支对应的 worktree pnpm dshw doctor # 检查环境 开发 pnpm check # 类型检查 + 构建 + 测试 修改正式服务代码后运行 pnpm dshw restart。
预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
kermanx/dshw
个人开源项目,非 DeepSeek 官方产品。
相关插件 · 其他
模型破甲清洗YuJunZhiXue/dsh-purge
⚔️ DeepSeek Harness 网络安全红队工具dsh-purge
★ 16,148已汉化DeepSeek 客户端
73
女娲蒸馏alchaincyf/nuwa-skill
输入名人名字,提炼其思维模型与决策方式供你调用
★ 37,308已汉化DSH
72
逆向分析桥接Fanqi89/dsh-rea
REA(Reverse Engineer Anything)MCP 桥接,用来把 REA 逆向工具接入 DSH 插件
★ 51已汉化DSH
72
语音女友beiyege-01/dsh-voice-ai-girlfriend
语音 AI 女友Voice AI girlfriend for DeepSeek Harness:Whisper…
★ 888已汉化DSH
71.6
红队越狱测试套件Minglink/dsh-infinite-gen-5
DeepSeek v4.1 flash 逆向工具无限五代 求 Star 收藏 ⭐欢迎大家提交项目的改进
★ 3,759已汉化DSH
71.4
协同办公空间dream-num/univer-workspace
一个让人类与 AI Agent 共同创作、协作和审阅的开源 Office 工作空间。
★ 2,266已汉化DSH
70.7