
Security News
Deno Goes the Way of the Dinosaur
Cloudflare is acquiring Deno’s team, which will provide another year of bug fixes and security updates before ending support for the runtime.
openharness-reader
Advanced tools
OpenHarness Reader — workspace file browser/editor with Markdown preview for DeepSeek Harness Web
OpenHarness Reader —— DeepSeek Harness Web 的工作区文件阅读/编辑器插件(平行项目,非壳功能)。
规划文档:000-file-editor-plugin.md(本仓库内跟踪)。
| 里程碑 | 内容 | 状态 |
|---|---|---|
| M1 | 骨架:package.json + cordis.patch.yml + host/client 两半 + esbuild;注册 details 面板(占位) | ✅ 2026-08-14 |
| M2 | 文件浏览:host fs RPC(list/stat/read)+ client 树/列表 | ✅ 2026-08-14(v0.2.0) |
| M3 | 编辑保存:CodeMirror 6 + ctx.fs 写回(版本守卫 + 冲突提示) | ✅ 2026-08-14(v0.2.0) |
| M4 | Markdown 渲染预览(GFM + 高亮) | ✅ 2026-08-14(v0.2.0) |
| 挂载方案改方案 1 | 彻底弃用 details 槽:client 改为 body portal + fixed 定位面板(照 DSH-better-sidebar);per-session store 管布局;apply 全包 try/catch + 错误条兜底;唯一官方槽位 = settings.section(list 槽) | ✅ 2026-08-14(v0.3.0) |
| v0.4.0 | 样式参考 dsh-better-sidebar:共享宽度布局(#root margin-right 推挤,非浮层覆盖)、VSCode 式文件标签页、文件夹/文件类型图标(sidebar 同款 glyph)、搜索栏置顶 + 「隐藏」checkbox、全量 i18n | ✅(v0.4.0) |
| v0.4.1 | 跟随 dsh rc.7 插件设置机制:host 半用 installSettingsSection 注册 openharness-reader 设置命名空间(maxReadBytes 变为用户可配置);浏览器半注册 settings.plugin.item keyed 卡片(rc.7「插件配置」标签页),替换并删除旧 settings.section 分区;peer 范围 ^0.1.0-rc.6 兼容 rc.6/rc.7 | ✅(v0.4.1) |
| v0.4.2 | 折叠按钮右上偏移(top:96px → 20px);README 新增「方式一:App 插件中心 / 方式二:命令行」安装 + 升级/卸载/本地开发/验证章节 | ✅(v0.4.2) |
| v0.4.3 | README 安装章节补 DSH App 下载链接(GitHub Releases) | ✅(v0.4.3) |
| v0.4.4 | 适配 DSH 0.1.1-rc.2:peer 范围放宽为 ^0.1.0-rc.6 || ^0.1.1-rc.2 双线覆盖,devDeps 升至 0.1.1-rc.2 并全量校验(typecheck / build / test 全绿);调研见 000-dsh-011rc2.md | ✅(v0.4.4) |
| v0.4.5 | 品牌位:按官方契约占用 sidebar.brand.mark / sidebar.brand.name(dsh 0.1.1+;rc7 自动 no-op),OpenHarness 统一品牌壳上侧边栏品牌行;槽位被占时自动让位 | ✅(v0.4.5) |
| v0.4.6 | 启动行为选项:设置卡片新增「默认展开 / 默认折叠」(localStorage prefs.autoOpen,默认展开=历史行为;折叠后新会话/新项目不再主动展开,点 Reader 竖条手动开);品牌位负优先级 shadow:以 priority:-100 压过先到的 priority-0 注册者(single 槽 lowest-renders 语义,修复实测冲突) | ✅(v0.4.6) |
| v0.4.7 / v0.4.8 | 适配 DSH 0.1.2-rc.1:host 半改用 settings.installSection()(0.1.2 移除了顶层 installSettingsSection());rpc.handle() 去掉 {authority:'loopback'} 第三参;大文件改为「只读打开并返回内容」而非拒绝;peer 收敛到 ^0.1.2-rc.1 单代;调研见 012-dsh-0.1.2-upgrade-plan.md | ✅(v0.4.7 / v0.4.8) |
| v0.5.0 | 适配 DSH 0.1.5(修「装了就整机启动失败」):dsh-client-connection@0.1.5 的 rpc.handle() 改为透过调用者 fiber 的 webServer 注册路由,而 cordis 服务代理会对 ctx 做 shadow 解包 —— 第三方 fiber 无论 entry 级 inject 还是运行时 ctx.inject(['connection','webServer']) 都照样抛 cannot get property "webServer" without inject;插件树加载是 fail-loud,于是 DSH 整个启动失败。改为自持 HTTP carrier:ctx.webServer.register() 挂 /openharness-reader prefix 路由 + ctx.connection.requestRejection() 同款 Host/Origin+鉴权围栏 + 复刻 client-request/server-response 信封(即 dsh-api-gateway 挂 WebSocket 路由的做法)。同时移除已下线的 @deepseek-ai/dsh-client-runtime 依赖与 SessionListState 类型导入,peer 升到 ^0.1.5-rc.1。调研见 013-dsh-0.1.5-upgrade-plan.md | ✅(v0.5.0) |
| M5 | npm 发布 + 壳 AUTO_INSTALL_PLUGINS 预装 | ⏳ |
样式参考:本插件的布局与视觉参考了 dsh-better-sidebar(MIT)——共享宽度推挤(
#root { margin-right: var(--ohr-width) },非浮层覆盖)、VSCode 式标签页、文件夹/代码文件类型图标(与 sidebar 的IconFolderOpen16/IconFolderClose16/IconCodeOutline16同款 glyph,内联 SVG 实现)、34px→28px 紧凑标签条、--dsw-alias-*主题 token 驱动。
#root 让出面板宽度(对话区被挤窄),折叠时恢复全宽;z-index:40 低于应用弹出层。标题栏右侧红色 × 收起面板;折叠后右侧靠上显示可展开的竖条。.git 等 dotfiles,取消勾选显示);目录优先排序;面板拖拽调宽 / 收起 / 窄屏抽屉(per-session 布局)。ctx.fs.writeText,以读取时版本做 replaceIfVersion CAS —— 磁盘文件被外部(如 agent 工具)改动时弹出冲突对话框:重新加载 / 覆盖保存。.md 文件支持 编辑 / 预览 切换;预览容器带 data-adhdgofly-highlight 属性契约,已装 adhdgofly-dsh-ext ≥ v0.1.2 时自动获得词性高亮(名绿/动红/形紫/其他灰,与对话共享色板/筛选/主题)。src/client/locales.ts 字典,随页面语言(<html lang>,zh → 中文,其他 → 英文)自动切换。.ohr-browser),文件树 overflow:auto 真正生效,深目录可上下滚动;编辑器视图滚动不受影响。.git 子项恒展开,已改按当前 entry 自身状态);dotfiles(.git/.DS_Store)默认隐藏,「隐藏」checkbox 控制显示。方案见 001-tree-collapse-style.md。useSyncExternalStore 无条件调用(修复 hook 数量突变导致的 Uncaught TypeError: Cannot read properties of undefined (reading 'length')——sessions 服务晚就绪时面板不挂载/半挂载),会话何时就绪都能稳定显示。maxReadBytes(默认 5 MB)的大文件与二进制文件(FS_NOT_TEXT)只读打开。maxReadBytes 作为用户可配置项出现在 设置 → 插件 → 插件配置 标签页(settings.plugin.item keyed 卡片);改完保存即持久化到 profile,刷新仍在。卡片自带 revision 设栅——并发修改会冲突重读而非静默覆盖。sidebar.brand.* 槽位契约(dsh-client-ui-sidebar@0.1.1-rc.2 白纸黑字邀请部署包替换鱼形 fallback),在侧边栏品牌行渲染「双括号托举节点」mark(展开行 / 收起轨道自适应壳给的尺寸)+ 「OpenHarness」双色词标。仅 0.1.1+ 生效——rc7 无此槽位声明,声明感知注入整体 no-op、官方鱼标原样保留;以负优先级 shadow 先到的占位注册(single 槽 lowest-renders 语义),同优先级冲突仍自动让位。ctx.fs 缝隙,并派发 fs/write-intent / fs/edit-intent / fs/observed 事件(actor 携带会话),与 agent 的 fs 工具共享观察状态与守卫。src/host/index.ts):注册 /openharness-reader RPC 通道。v0.5.0 起是自持 HTTP carrier:ctx.webServer.register({kind:'prefix', path:'/openharness-reader'}) 挂路由 + ctx.connection.requestRejection() 做与 /api 同款的 Host/Origin+鉴权围栏 + 复刻 client-request/server-response 信封(dsh-api-gateway 挂 WebSocket 路由的同款做法)。不再使用 ctx.connection.rpc.handle() —— dsh-client-connection@0.1.5 的 handle() 透过调用者 fiber 的 webServer 注册路由,而 cordis 服务代理的 ctx 捕获会被 shadow 解包,第三方 fiber 即使声明了 webServer 也抛 cannot get property "webServer" without inject;因插件树加载 fail-loud,这会直接让 DSH 启动失败(0.4.8 在 0.1.5 上的真实故障,见 013-dsh-0.1.5-upgrade-plan.md)。端点:list / stat / read / write / edit / rename / search。业务失败以稳定 FsErrorCode 结构化返回。entry 必须在 cordis.patch.yml 声明 inject: ['fs', 'connection'];webServer 在 apply 内用 ctx.inject(['connection','webServer']) 运行时取得(无 WebServer 的 headless/tui profile 只跳过频道,不影响设置命名空间)。settings 命名空间用 settings.installSection() 注册(schema 仅 maxReadBytes,schemastery 单一真源)。src/client/):body portal(v0.3.0 方案 1)+ 共享宽度布局(v0.4.0 方案 A,样式参考 dsh-better-sidebar)。apply() 自建 document.createElement('div')(带 data-openharness-reader)挂到 document.body,createRoot(host).render(<ReaderPanel/>);面板 fixed 定位(默认右侧),展开时通过 --ohr-width CSS 变量推挤 #root(margin-right),与 DSH 应用共享宽度而非覆盖。布局状态(宽/折叠/窄屏抽屉)在 per-session store(src/client/layout.ts);ctx.connection.rpc.call 调 host;ctx.sessions.list 取当前会话 workspace。settings.plugin.item(keyed 槽,key = openharness-reader,src/client/settings-card.tsx),经 ctx.get('settingsScope').bind({namespace}) 绑定命名空间(dsh-client-ui-settings 提供,见 dsh.client.inject),自研带标题栏的可折叠卡片外壳;scope.set 写入宿主持久化,revision 栅栏由 scope 自动处理;绝不注册 details。src/shared/protocol.ts。前置:本机已安装 DeepSeek Harness(DSH 0.1.5-rc.1 / rc.2),且已初始化 web profile(npx @deepseek-ai/dsh web 跑过一次即可)。当前版本 0.5.0。
# 1) 安装 DSH(首次)
npx @deepseek-ai/dsh web
# 2) 安装插件
npx @deepseek-ai/dsh plugin --profile web add openharness-reader
# 若 pnpm ≥ 10 报 ERR_PNPM_ADDING_TO_ROOT,命令末尾加 -w:
npx @deepseek-ai/dsh plugin --profile web add -w openharness-reader
⚠️ 命令行安装后必须重启 DSH 才生效
- 在正在运行的 DSH Web 终端按
Ctrl+C停止当前进程;- 重新启动:
npx @deepseek-ai/dsh web(若机器已把dsh装进 PATH,dsh web/dsh --profile web与之等价,任选其一)- 等 Web 界面重新打开后刷新浏览器页面。
不重启的话,正在运行的 DSH 进程的 boot 图里没有本插件,刷新页面也不会加载它。
npx @deepseek-ai/dsh plugin add 会:
~/.dsh/profiles/web 里 pnpm add 本包;dsh.bundle 声明,把 openharness-reader 追加进 dsh.profile.bundles,成为 profile 补丁层。# 升级到最新版(当前 0.5.0)
npx @deepseek-ai/dsh plugin --profile web update openharness-reader
# 卸载
npx @deepseek-ai/dsh plugin --profile web remove openharness-reader
Ctrl+C 停止 → npx @deepseek-ai/dsh web 重启 → 刷新浏览器。版本要求:DSH
0.1.5-rc.1/0.1.5-rc.2(peer 范围^0.1.5-rc.1)。 0.5.0 的 host 半按 0.1.5 的 WebServer / Connection 契约重建了频道 carrier,无法再跑在 0.1.2 及更早宿主上(旧宿主请装openharness-reader@0.4.8)。设置卡片(settings.plugin.item)与sidebar.brand.*品牌位在 0.1.5 仍然可用;sessions服务改由dsh-api-session-controller提供(插件已按{ ids, byId, current }结构鸭子类型读取,不依赖旧dsh-client-runtime)。 已对0.1.5-rc.2完成依赖面逐包比对、真实dsh web冷启动 + RPC 端到端验证 (typecheck / build / test 全绿),调研详情见013-dsh-0.1.5-upgrade-plan.md。
# 在插件仓库目录或其父目录执行(file: 相对路径以调用目录为锚)
npx @deepseek-ai/dsh plugin --profile web add file:../openharness-reader
file: 依赖是符号链接:客户端改动 npm run build 后刷新页面即可(DSH Web 无 HMR);patch / bundles 改动需重启 profile。安装后同样需要按上面的提醒重启一次才生效。
npx @deepseek-ai/dsh --profile web --dump-config | grep -A3 openharness-reader # 合成树里应有插件行
# 浏览器 DevTools → Network 应能看到 /plugins/openharness-reader/client.js 正常返回
npm install
npm run build # esbuild 双入口(lib/client.js + lib/index.js)
npm run typecheck # tsc --noEmit
npm test # 冒烟(bundle 形态)+ host RPC 行为测试(stub ctx)
发布流程见
010-dsh-plugin-publish.md;安装/升级/卸载见上文 §安装。
details 是 single slot(dsh-client-ui-layout 声明,kind: single / scope: session)——同一 priority 只允许一个注册,重复注册抛错,而 client web 的 boot sweep 对 apply 失败的 entry fail-loud(整机白屏 "HARNESS / Failed to load plugins")。v0.2.1 的「priority 探测 − 1」只是规避,仍依赖与 details 占用者的博弈。v0.3.0 起彻底弃用 details 槽:改 body portal + fixed 定位面板(照 DSH-better-sidebar),对任何 details 占用者(含 x6)零交集、零冲突,不依赖 priority 探测、不依赖加载顺序;唯一官方槽位仅限 list/keyed 槽(settings.section,带 id+order,list 槽消费全部 entry、注册永不冲突);整个 apply 包 try/catch,任何阶段失败只降级为「面板不显示 + console.error + 页面角落错误条」,绝不把错误抛出 apply 拖垮 boot。详见 000-file-editor-plugin.md §三/§五。adhdgofly-dsh-ext 高亮的关系(方案 A′ 属性契约,v0.3.3 + adhdgofly v0.1.2 已落地):代码内容与编辑器(contenteditable)天然被其跳过;MD 预览容器带 data-adhdgofly-highlight 属性,adhdgofly 每次处理自动采纳该容器(无需写 containers 配置、无需重载),未装 adhdgofly 时属性惰性无害。详见 000-file-editor-plugin.md §五。我(zuoguyoupan2023)开发维护的一系列 DeepSeek Harness(dsh)插件,均可按需通过 dsh plugin --profile web add <name> 安装:
| 插件 | 作用 | GitHub 仓库 | 安装 |
|---|---|---|---|
| adhdgofly-dsh-ext | DSH Web 界面词性高亮(名绿/动红/形紫/其他灰) | zuoguyoupan2023/adhdgofly-dsh-ext | dsh plugin --profile web add adhdgofly-dsh-ext |
| openharness-reader | 工作区文件浏览/编辑 + Markdown 预览 | zuoguyoupan2023/openharness-reader | dsh plugin --profile web add openharness-reader |
| openharness-reply-in-cn | 强制模型用简体中文回复,侧边栏「中文回复」项 | zuoguyoupan2023/openharness-reply-in-cn | dsh plugin --profile web add openharness-reply-in-cn |
| openharness-rule-for-dsh-plugin | 注入 DSH 插件开发的 CAN/SHOULD/MUST NOT 规范,侧边栏「插件开发规范」项 | zuoguyoupan2023/openharness-rule-for-dsh-plugin | dsh plugin --profile web add openharness-rule-for-dsh-plugin |
FAQs
OpenHarness Reader — workspace file browser/editor with Markdown preview for DeepSeek Harness Web
We found that openharness-reader demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.

Security News
Cloudflare is acquiring Deno’s team, which will provide another year of bug fixes and security updates before ending support for the runtime.

Security News
Anthropic’s free OSS Scanner uses Mythos and other Claude models to find open source vulnerabilities and send maintainers reports with proposed fixes.

Security News
On Front Lines’ Early Adopters: CISO podcast, Andrew Becherer shares lessons from Datadog, weighs the long-term costs of AI-built tools, and explains how founders can actually gain a CISO’s trust.