DeepSeek Harness Plugin Hub

发布与管理完整 Harness Profiles,发现适合你的插件。

探索

插件目录环境预设文档中心动态

社区

发布插件联系我们报告问题

相关链接

Plugin Hub GitHubDeepSeek Harness 官方项目系统状态隐私说明
© 2026 DeepSeek Harness Plugin HubPowered byPaxTech

独立、非官方社区项目,与 DeepSeek 官方无隶属、授权或背书关系。

Cajita — DeepSeek Harness 插件(DSH Plugin)
DeepSeek Harness Plugin Hub
ProfilesPlugins分类动态文档登录管理 Profiles
ProfilesPlugins分类动态文档登录
← Plugins

@hpyperry/dsh-cajita

Cajita

DSH 小工具箱插件:编辑消息 / web_fetch 内网放行 / 提醒通知(设置卡片统一开关)

插件会安装到这里;不确定时保持 web。

npx -y @deepseek-ai/dsh plugin --profile web add @hpyperry/dsh-cajita@0.1.5
README兼容性版本

兼容性与来源证明

Cajita 以 @hpyperry/dsh-cajita 发布,当前版本为 0.1.5。Plugin Hub 会校验它的 manifest,并保存精确安装来源,便于复现安装结果。

DSH 兼容范围
*
运行环境
web
发布来源
npm
Registry 更新时间
2026/9/5

版本

0.1.5stable
2026/9/5

相关插件

正在加载相关插件…

最新版
0.1.5
DSH
*
HMR
重启进程
Tree shaking
未声明可安全裁剪
解包体积
372.5 kB
文件数
134
Surface
web
许可证
MIT
发布源
npm
GitHub
★ 0
周下载
0
最近提交
2026/9/5
查看源码 ↗
README Badge

点击下方 Badge 复制 Markdown,粘贴到 README 即可。

这是你的 Plugin?认领权益 · 优先安全扫描

验证 package.json 声明的 GitHub 仓库,即可管理这个公开页面。认领后,Hub 会优先安排当前版本的安全扫描,并在通过后公开展示结果。

认领这个 Plugin →
报告问题

README

dsh-cajita · DSH 小工具箱插件

DeepSeek Harness(DSH)插件:一个插件包、多个小工具。当前包含:

  • 任务 1 · 编辑消息——在用户消息的复制按钮旁新增「编辑」按钮,把误发送的未完成消息 在原消息位置覆盖一条与官方输入框同款的内联编辑卡继续编辑,编辑后作为一条新消息正常发送;
  • 任务 2 · web_fetch 内网放行(web-fetch-policy)——给官方 web_fetch 换一个带 「内网放行开关」的 fetch provider:默认与官方完全一致(只允许公网目标),在 设置 → 插件配置 打开开关后放行解析到私网/回环等内网地址的目标(TUN / 代理用户 的 DNS 常回 fake-ip/内网地址,不开会全部被拒);
  • 任务 3 · 回合完成通知(turn-notify)——agent 每回复完成一个回合、且页面不在 前台时,弹浏览器系统通知(需先授权一次);开关在 cajita 设置卡里。

npm:@hpyperry/dsh-cajita · 仓库:https://github.com/hpyperry/dsh-cajita

安装:dsh plugin --profile web add @hpyperry/dsh-cajita

✨ 工具清单

工具能力说明
📝编辑消息用户消息复制按钮旁新增「编辑」:内联覆盖编辑卡带出原消息文本,继续编写后发送新消息(与正常发送完全同管线)
🌐web_fetch 内网放行为官方 web_fetch 换上带开关的 provider:默认与官方一致(仅公网);设置里打开开关后放行私网/回环/内网目标(TUN / 代理用户必开)
🔔回合完成通知agent 每回复完成一个回合、页面不在前台时弹浏览器系统通知(可开关 + 授权按钮,默认开)

📦 安装

插件已发布到 npm(@hpyperry/dsh-cajita),直接按包名安装即可:

包名 @hpyperry/dsh-cajita 是 npm 安装/卸载身份;插件注册进 dsh 的 layer id 为 cajita(不带 dsh- 前缀,与 ref-lib 同模式: @hpyperry/dsh-ref-lib ↔ layer id ref-lib)。

# 从 npm 安装
dsh plugin --profile web add @hpyperry/dsh-cajita

npm 包自带构建产物(lib/),无需源码构建/授权;想要最新开发版或未发布改动时, 可用本地 link 形态安装源码目录(见下)。

安装后重启生效:dsh --profile web。

  • 本地开发期(改动即时生效,link 形态):dsh plugin --profile web add /path/to/dsh-cajita
  • 卸载:dsh plugin --profile web remove @hpyperry/dsh-cajita

发布(维护者)

cd /path/to/dsh-cajita
# 升版本(npm version patch 等)→ 构建并发布
npm publish        # prepare 自动跑 tsc + tsdown 产出 lib/

scoped 公开包所需配置(publishConfig.access: public)已在 package.json 内; 发布前请确认 npm whoami 已登录(账号需与 @hpyperry scope 一致)。

📝 编辑消息(任务 1)

行为

  1. 每条用户消息(含运行中插入的 steering 消息)的气泡下方,复制按钮旁出现「编辑」按钮;
  2. 点击后原消息位置覆盖一条与官方输入框同宽、同款视觉的内联编辑卡(ChatGPT 式), 文本域带出原消息文本(已发送的序列化文本),可直接继续编写;
  3. 点「发送」或按 Enter(Shift+Enter 换行、Esc 取消)即发送一条新消息——内容为 编辑后的文本,与输入框正常发送无任何差别(同一 input machine → 同一 adjudication → 同一 sink)。

编辑框为简单文本编辑(与 ChatGPT 一致,不含 / 命令与 @ 引用补全——官方 未提供第三方输入框的可插拔补全 API;需要完整 / @ 能力时,可把编辑文本 setDraft 进主输入框继续编辑,见下「边界」)。

边界与异常处理

边界处理
长文本(几万字)内联编辑框文本域是纯本地 state,不进输入机器、不跑装饰扫描,一次性回填/持续输入无 hang 风险;仅发送那一刻一次性 setDraft(O(n) 对账,毫秒级)
原消息含 /已发送文本是序列化后的文本;重新发送走同一判定:/未知命令 仍按普通消息发送(行为一致);若编辑后以已知命令开头,发送会执行命令——与输入框手动输入完全一致(官方行为),编辑卡内以提示明示
原消息含 @@引用 发送时已序列化为模型形态,回填后按字面文本发送(内容与气泡显示一致);编辑框为简单文本,无补全菜单(与 ChatGPT 一致)
输入框已有未发送草稿发送将替换输入框内容(发送成功后被清空),编辑卡内以提示明示
忙碌/会话移除adjudicating/submitting 或会话已移除时禁用发送
UI 规范全部使用官方 primitives 与 --dsw-* 设计令牌,编辑卡视觉与官方输入框一致(同款背景/圆角/阴影/宽度上限)

实现说明(官方 API 依据)

  • 挂载点:官方无面向「用户消息复制按钮旁」的加按钮槽位(conversation.chat.assistant-actions 仅 assistant),故以 priority -1 shadow conversation.chat.node 的 user/steering 键(ui-slots 的 shadow 机制:同 key 不同 priority 共存、数值最低者渲染—— 官方为 0,接管者必须为负),完整复刻官方 气泡(文本/图片/引用 chip/时间/复制),图片仍走官方 owner props renderMessageImages (→ conversation.message.images 槽位);
  • 编辑交互:ChatGPT 式内联覆盖编辑卡(原消息位置覆盖、宽度与官方输入框一致 ——--dsh-composer-card-max-width + 官方卡片令牌),Enter 发送 / Esc 取消;
  • 发送:session 标准 kit 的 inputActions(sessions.provide 提供 useInput + inputActions),setDraft(text) + submit()(默认 queue 模式 = 官方默认发送路径)。

⚙️ 插件设置(设置 → 插件配置 → cajita 工具箱)

整改后插件级设置收成一张与官方插件配置同风格的可展开卡片,两个即写开关 (写 $DSH_HOME/settings.yaml 的 cajita: 节,live 生效,无需重启):

  1. 编辑消息(默认开):开启 = 用户消息气泡提供「编辑」按钮(接管渲染); 关闭 = 实时撤销接管、恢复官方气泡显示,随时可再开;
  2. web_fetch 内网放行(默认关):关闭 = 与官方完全一致(只允许公网目标); 开启 = 放行解析到私网/回环/内网(如 TUN fake-ip)的目标——TUN/代理用户需要 开启。web_fetch 不设单独的"子功能启停":这个放行开关本身就是该功能。
  3. 回合完成通知(默认开):agent 每回复完成一个回合、且页面不在前台时,弹 浏览器系统通知;首次使用先在卡片里点「授权系统通知」。自己正盯着页时不打扰。

🌐 web_fetch 内网放行(任务 2 / web-fetch-policy)

为什么需要它

官方 web_fetch 的 fetch provider(@deepseek-ai/dsh-web-fetch-http)只允许访问 公网目标:解析结果里出现私网/回环/fake-ip(如 TUN 代理常见的 198.18.0.0/15 或 内网 DNS 回包)会整组拒绝(WEB_BLOCKED_URL)。TUN / 代理模式下 DNS 常被劫持成 非公网地址,导致 web_fetch 全部失败。官方没有关闭这项检查的开关。

做法(组合替换,不 fork)

插件把官方 web-fetch-http 行禁用,插入自带开关的 provider(id 仍为 http, base 组合 web.fetchProvider: http 的选择不变,模型侧 web_fetch 无感换用):

  • 默认(开关关)= 与官方逐字节等价:内部复用官方 HttpFetchProvider(默认 resolver), 非公网目标照旧拒绝——安装本插件不会改变官方安全行为;
  • 打开开关(放行内网)= 跳过内网 IP 检查:仍走官方 provider 的其余全部实现 (URL 校验、仅同源重定向、大小/字符上限、UA、超时翻译、地址钉扎连接),只是 换成"只解析、不校验公网"的 resolver。

边界与异常处理

边界处理
开关默认值默认关(与官方一致,仅公网);TUN/内网用户到设置里打开一次即持久化
关闭语义关闭 = 官方等价行为(provider 仍常驻但锁定限制模式);没有"真卸载式"的运行时开关——真回滚官方行需卸载插件并重启
装卸卸载插件即移除组合覆盖,官方 web-fetch-http 行自动恢复(回滚干净);patch 层不在 live watch 内,装卸/改组合后需重启 dsh web
设置迁移v0.1.2 的 cajita-web-fetch: 节已并入 cajita: 节(v0.1.3);旧节残留无害,可手工从 settings.yaml 删除
其它 profile本工具面向 --profile web;安装进没有 web-fetch-http 行的 profile 时,禁用补丁不命中(仅告警),设置卡片不展示,无副作用
设置不可写命名空间未 serve / 宿主只读时卡片整体隐藏或禁用(与官方卡片一致)

实现说明(官方 API 依据)

  • 组合:cordis.patch.yml 按行 id disabled: true 禁用 base 行 web-fetch-http (官方后层先例:web-app/cordis.patch.yml 禁用 base 行),并 insert 本插件行 (name 指向包 subpath 模块,同官方 @deepseek-ai/dsh-web-app/startup 用法);
  • provider 复用:HttpFetchProvider 公开导出且构造第二个参数即 resolver (web-fetch-http/src/provider.ts),默认实例 = 官方行为;放行实例 = 同官方类 + 本包 resolveAnyAddresses(只解析不做公网校验,resolver.ts);
  • live 开关:node half(cajita-web-fetch 行)唯一注册 settings 命名空间 cajita,scope.watch 订阅 allowInternal 即时切换 provider;editMessageEnabled 由浏览器端读取、驱动编辑消息条目运行时增删;
  • 设置卡片:宿主"插件配置" tab 的 settings.plugin.item keyed 槽位(key = 命名空间)是官方为仓库外插件预留的扩展点(ui-settings-plugins slot-contract 注释明示);卡片在自有 style 标签内复刻官方 PluginCard 视觉,经 ctx.settingsScope.bind({ namespace: 'cajita' }) 读写命名空间。

🧑‍💻 开发

pnpm typecheck   # tsc --noEmit
pnpm lint        # eslint(typescript-eslint recommended)+ prettier
pnpm test        # vitest(L0 纯函数 / L1 装载)
pnpm build       # tsc(node half)+ tsdown(client bundle)→ lib/
  • 结构:src/(node half:插件身份 + web-fetch-policy 行)+ src/client/ (web half:index.ts 编排「绑定设置 → TOOLS 动态注册 → 注册设置卡片」+ locales.ts 汇总;每个功能独立目录 src/client/<tool>/,自带 register/组件/ 纯逻辑/字典片段/样式标签;插件级设置表面在 src/client/settings/)+ tests/ (按功能子目录);
  • 单插件多工具:所有小工具共用一个插件包与 cajita 文案/设置命名空间;新功能 = 新目录 + 在 src/client/index.ts 的 TOOLS 注册表登记(见 AGENTS.md §6.2);
  • 热更新:src/client/* 改动 pnpm build:client 后浏览器 ≤0.5s 自动热更新; node half 改动需重启 dsh web。

隔离开发环境(scripts/dev-isolate.sh)

所有开发/联调一律在独立 DSH_HOME(默认 ~/.dsh-dev)进行,真实 ~/.dsh 零接触(2026-08-17 事故教训:直接在真实 profile 联调可能污染真实会话日志); rm -rf ~/.dsh-dev 即完全重置。

命令说明
./scripts/dev-isolate.sh首次运行自动把本插件装入隔离 profile(默认 ~/.dsh-dev)并启动 web
DEV_HOME=/tmp/dsh-dev ./scripts/dev-isolate.sh自定义隔离 home
PLUGIN=/path/to/other-plugin ./scripts/dev-isolate.sh隔离其他插件
DEV_HOME=/tmp/dsh-dev ./scripts/dev-isolate.sh --port 3090透传任意 dsh 参数(如 --port)
DSH_BIN=<绝对路径> ./scripts/dev-isolate.sh用指定版本的 dsh 可执行文件启动(多版本矩阵,见下)
DSH_HOME=$HOME/.dsh-dev dsh plugin --profile web add <插件路径>手动安装/重装插件(本地路径 = link 开发形态)
DSH_HOME=$HOME/.dsh-dev dsh --profile web --port 3090 --no-open手动启动隔离 web(--port 指定端口,--no-open 不自动开浏览器)
DSH_HOME=$HOME/.dsh-dev dsh plugin --profile web remove @hpyperry/dsh-cajita卸载插件
rm -rf $HOME/.dsh-dev完全重置开发环境

用指定版本的 dsh 测试(多版本兼容矩阵)

插件的依赖基线需要与宿主 dsh 版本族配对。默认 dev-isolate.sh 用 PATH 上的全局 dsh;要验证「本插件实现在 dsh 0.1.2-rc.1(当前 latest/next)上是否兼容」, 用 scripts/dsh-local.sh 取一个版本化本地安装(装进 ~/.dsh-tools/<版本>/, 与 npm 全局安装完全无关),再经 DSH_BIN 指给隔离环境:

# 例:在隔离环境用 dsh 0.1.2-rc.1 验证本插件(首次自动安装该版本 CLI)
DSH_BIN="$(DSH_VERSION=0.1.2-rc.1 ./scripts/dsh-local.sh)" \
  DEV_HOME="$HOME/.dsh-dev-rc1" \
  ./scripts/dev-isolate.sh --port 3091
  • 宿主 @deepseek-ai/dsh 的 npm dist-tag latest/next 均已是 0.1.2-rc.1: 任何无 pin 的全局安装都会升级生产宿主,安装脚本/验证一律显式 pin 版本;

  • 不同版本用独立 DEV_HOME(如 ~/.dsh-dev-rc1)与 profile,互不干扰; 依赖基线升级的破坏面/迁移结论记录在 docs/upgrade-dsh-*.md。

  • 提示:若全局 npm 缓存目录(~/.npm)存在 root 属主文件导致 npm install 报 EPERM,可先 npm cache verify 修复,或为 dsh-local.sh 指定可写的 npm_config_cache 环境变量。

  • 常用端口:--port 3090,浏览器访问 http://127.0.0.1:3090;

  • 验证加载:启动日志(stdout)会列出装载的插件与 client bundle;也可 curl -s http://127.0.0.1:3090/ | head 确认 web 在服务;client 注册是否生效 以浏览器 UI 为准(编辑按钮出现在用户消息复制按钮旁);

⚠️ 已知限制

  • 接管式渲染:为在用户消息复制按钮旁加按钮,本插件 shadow 官方 user/steering 气泡渲染器(priority -1,数值最低者渲染)。官方气泡视觉升级时需手动同步(快照结构变化由 typecheck 兜底);同 key 的第三方接管者按 shadow 链数值低者渲染;接管条目随「编辑消息」 开关运行时增删——关闭即 dispose、官方气泡即时恢复;
  • 运行时"关闭 ≠ 卸载"(web_fetch):关闭放行 = provider 锁定限制模式(行为与 官方逐字节等价,官方行仍被组合禁用);真回滚官方行需 dsh plugin remove 并重启;
  • 设置节迁移:v0.1.2 的 cajita-web-fetch: 设置节已并入 cajita: 节; 旧节残留无害,可手工从 settings.yaml 删除;
  • 系统通知受浏览器限制:需用户授权一次(设置卡内按钮);标签页需保持打开 (可后台/最小化);http://127.0.0.1 这类本地地址是安全上下文可用,局域网 IP / 0.0.0.0 / 非 https 部署不可用;同 origin 多标签页会各自弹通知(官方无跨 标签协调)。
  • 简单文本编辑:内联编辑框不含 / 命令与 @ 引用补全(官方未提供第三方输入框 的可插拔补全 API;官方输入框的补全落地硬接线到 composer 机器)。需要完整 / @ 能力时,可把编辑文本 setDraft 进主输入框继续编辑后发送;
  • 不编辑图片消息的图片:编辑框只编辑文本部分(图片随原消息保留在气泡中,编辑后 的新消息仅含文本);
  • 不重写已发送消息:发送的是一条新消息(与需求一致),历史消息不变。

📄 License

MIT,与 DeepSeek Harness 一致。

📚 更多

  • 项目开发约定(开发规范 / 测试标准 / 开发环境):见仓库 AGENTS.md
  • 上游仓库:https://github.com/hpyperry/dsh-cajita

相关插件

继续浏览 integrations-communication 分类下经过校验的插件。

Acp App@deepseek-ai/dsh-acp-appdsh ACP 配置文件包:基于 dsh-base 的仅限自动化的 JSON-RPC stdio 和进程生命周期管理Remote Web Ui@linxin666/dsh-remote-web-ui通过扫码配对访问 dsh Web GUI,共享一个官方界面:设置按钮旁的二维码可将手机和 PC 配对到同一个 Web GUI(手机采用竖屏触控适配层,PC 使用完整桌面界面),通过一次性令牌和 rPocketdsh-pocket把 DeepSeek Harness 装进你的口袋:一个包、一个设置页,手机扫码即同步访问电脑上的 DSH(局域网 + 公网,实时同屏)。DSCODE@toddzheng024/dscode-bundle完整的 DeepSeek 编码代理,支持持久化 shell、Ultra 协作和自动权限审查。