Skip to content
dsh.fish
Bundle

dsh-auto-paste

dsh-auto-paste — a DeepSeek Harness plugin (tool template, extended with a web client paste listener): 在输入框粘贴大段文本时自动保存为附件文件。

Source
sakuraqqq
stars
2 stars
License
MIT
Updated
Updated yesterday

Readme

# dsh-auto-paste

> A DeepSeek Harness plugin generated by [`create-dsh-plugin`](https://www.npmjs.com/package/create-dsh-plugin) (tool template) and extended with a web client paste listener.
> 由 create-dsh-plugin 生成并扩展的 DeepSeek Harness 插件:输入框大段粘贴自动存为附件文件。

## Release / 发布状态

- **npm**:`dsh-auto-paste@0.1.2`([npm 页面](https://www.npmjs.com/package/dsh-auto-paste))—— 已发布到官方源 `registry.npmjs.org`,`dist-tag: latest`。安装:`npm i dsh-auto-paste`(或 `--save-exact` 锁版)。
- **源仓库**:`https://github.com/sakuraqqq/dsh-auto-paste`,tag `v0.1.0`。
- **许可**:MIT(见下)。
- **同步提示**:npm 发布后国内镜像(npmmirror)同步有几秒到几分钟延迟,以官方 registry 为准。

## License / 许可

MIT License — Copyright (c) 2026 misakamaster。
本插件以 MIT 许可开源:可自由使用、修改、再分发(含商用),需保留版权声明与许可文本。详见 [LICENSE](LICENSE)。
**反馈**(bug/建议)欢迎提交:QQ 群测试反馈或直接联系作者。

## What it does / 功能

1. **Web 客户端粘贴钩子(主路径)** — `dsh.client.platform: web`。在输入框粘贴超过阈值(默认 500 字符)的文本时:
   - 客户端拦截粘贴事件,通过现有 connection RPC(`/api` → Typert gateway)调用宿主 `pasteStore/savePaste`;
   - 宿主把文本写入当前会话工作区的 `pastes/<时间戳>.txt`;
   - 输入框里插入文件路径引用(如 `[已保存大段粘贴为附件: pastes/20260815-103000.txt (1234 字符)]`),消息里引用该路径,模型可读该文件。
   - 保存失败时回退为普通粘贴(原始文本直接进输入框),不丢数据。
   - 超过 **1 MiB** 的文本会被服务端拒绝(大小上限,防资源耗尽):报错并回退为普通粘贴,不落盘。
2. **save_paste 工具(纪律兜底)** — 宿主同时注册 `save_paste` 工具,模型在用户贴大段文字时可主动调用,把文本持久化为 `pastes/<时间戳>.txt` 并在回复中引用路径。建议在项目 `AGENTS.md` 加一行纪律:

   ```markdown
   ## dsh-auto-paste 纪律
   用户粘贴大段文字(约 500 字符以上)时:若输入框钩子未拦截,主动调用 save_paste 工具
   把文本存入 pastes/<时间戳>.txt,并在回复中引用该工作区相对路径,不要复述原文。
   ```

## Install / 安装与激活

**方式一:从 npm 安装(推荐)**

```sh
npm i dsh-auto-paste                          # 最新版(dist-tag: latest);--save-exact 可锁版
npm i dsh-auto-paste@0.1.2                    # 或指定版本
# 在插件父目录执行,以包名注册到目标 profile:
dsh plugin --profile web add dsh-auto-paste
dsh --profile web            # 重启 web profile,观察: [dsh-auto-paste] host ready ...
# 刷新浏览器页面后,控制台可见: [dsh-auto-paste] client paste listener ready (minChars=500)
```

**方式二:本地目录安装(开发/调试)**

```sh
# 在插件父目录(本仓库根)执行;相对路径锚定调用目录:
dsh plugin --profile web add ./dsh-auto-paste
dsh --profile web
```

改动插件后:`pnpm install && pnpm run build`(tsc → dist/),然后重启 `dsh --profile web` 并刷新页面。`minChars` 阈值在 `cordis.patch.yml` 的 row config 中调整。

## Verification without an API key / 无 key 验证

```sh
dsh --profile web --dump-config | grep dsh-auto-paste   # 配置层含本行
dsh plugin --profile headless add ./dsh-auto-paste
dsh --profile headless "run a probe"                    # host 半身加载;模型调用会 MISSING_CREDENTIAL
```

## Manifest checklist / 清单自查

- [x] `dsh.bundle.patch` → `./cordis.patch.yml`(dsh 加载插件的硬性要求,缺失只会被当作普通依赖安装)
- [x] `dsh.client.platform: web` + `exports["./client"]` → `dist/client.js`
- [x] `exports["./typert"]` → `dist/typert.host.js`(typert-loader 自动注册 remote 调用)
- [x] 代码无外发数据:插件不发起任何网络请求,只写工作区 `pastes/` 下的本地文件

## Dependencies pinned / 依赖锁定

- `@deepseek-ai/dsh-tools`: `0.1.0-rc.6` (exact — the **`next`**-tag line; npm `latest` is stale).
- `@deepseek-ai/cordis`: `^4.0.1` (peerDependency — host provides it; runtime import of `Service` resolves through the profile's node_modules).
- `zod`: `^4.4.3` (Typert host schema instances, same line as in-box host remotes).

## Pitfalls / 坑(从真实 spike 提炼,防呆)

1. Node version: DSH requires Node ^22.19.0 || >=24.0.0. Older Node (e.g. v22.17) only warns EBADENGINE but may hit runtime issues — upgrade if you can.
   - Node 版本:DSH 要求 ^22.19.0 || >=24.0.0。旧版本(如 v22.17)只告警 EBADENGINE,不阻断,但建议升级。
2. npm dist-tag trap (the big one): `@deepseek-ai/dsh-tools` `latest` is a STALE 0.0.1-rc.1; the real line is under the `next` tag (0.1.0-rc.x). This scaffold pins the next-tag version for you — never `npm i @deepseek-ai/dsh-tools` over it.
   - npm dist-tag 坑(最大):`@deepseek-ai/dsh-tools` 的 latest 是过期的 0.0.1-rc.1,正确版本在 next tag。本脚手架已锁 next 版本,勿再手动 npm i 覆盖。
3. Version-line alignment: keep every `@deepseek-ai/dsh-*` package on the same `0.1.0-rc.x` line so pnpm does not install two module copies.
   - 版本线对齐:所有 @deepseek-ai/dsh-* 包统一用同一 0.1.0-rc.x 线,避免 pnpm 装两份模块。
4. `@deepseek-ai/cordis` is a peerDependency: import only `type { Context }` where possible (erased at compile). At runtime the host hands you `ctx` — the `Service` base class import resolves through the profile's node_modules.
   - @deepseek-ai/cordis 是 peerDep:尽量只 import type(编译期擦除),运行时 ctx 由宿主传入。
5. Pure ESM: package.json must set `"type": "module"`; build with `module: esnext` + `moduleResolution: bundler` to keep bare specifiers.
   - 纯 ESM:package.json 必须 "type": "module";tsc 用 module:esnext + moduleResolution:bundler 保留 bare specifier。
6. `dsh plugin add <dir>` anchors relative paths to the INVOKING directory — run it from the parent directory, not from inside the plugin.
   - dsh plugin add <dir> 的相对路径锚定调用目录——要在插件的父目录执行。
7. In the bundle `cordis.patch.yml`, `name` is a package name (resolved via node_modules / `$DSH_HOME/profiles/node_modules`), not a relative path.
   - bundle 的 cordis.patch.yml 里 name 用包名(走 node_modules 解析),不要用相对路径。
8. Registrations are effects: `ctx.tools.register()` / `ctx.on()` auto-dispose on unload. Wrap your OWN resources (timers/connections) in `ctx.effect(() => { acquire; return cleanup })`.
   - 注册是 effect:ctx.tools.register()/ctx.on() 卸载自动清理;自己的资源(timer/连接)要包 ctx.effect(() => {…; return cleanup})。
9. Load order = service dependencies, never file order: `export const inject = ['tools']` makes the plugin wait until `ctx.tools` is ready.
   - 加载顺序靠服务依赖(inject),不靠文件顺序。
10. Full end-to-end (model actually calls your tool) needs `DEEPSEEK_API_KEY`; without it `--verify` proves load/list/event, and the model call fails with MISSING_CREDENTIAL.
    - 端到端(模型真正调工具)需 DEEPSEEK_API_KEY;无 key 时 --verify 只能证明加载/列出/事件,模型调用会 MISSING_CREDENTIAL。

Install

dsh plugin --profile web add github:sakuraqqq/dsh-auto-paste

Profile: web

  • This package builds from source on install. pnpm will ask you to allow its build script — that is permission to run the package’s code on your machine, outside the agent sandbox. Only allow sources you trust.
  • This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.
Source