Bundle
dsh-paperclip
Zero-intrusion DeepSeek Harness bundle: π upload button with pending popover, read_document multi-format tool (txt/pdf/docx/xlsx/json/md/ini/conf), Settings β General toggle. Standard Cordis bundle, no DSH source changes.
- Source
- runfali
- License
- MIT
- Updated
- Updated 2 days ago
Readme
# dsh-paperclip
> A zero-intrusion bundle for DeepSeek Harness: π upload button with popover Β· `read_document` multi-format reader Β· Settings β General toggle. Adapts to light / dark themes.
[](LICENSE)
[](package.json)
[](package.json)
**English** | [δΈζ](README.zh-CN.md)
## Features
- **π Upload button + popover** β Borderless π button in the composer. A small β΄ next to it shows the count; click to expand upward and see pending files (filename only). Click Γ to remove. Files are uploaded immediately and the server path is appended to the message on send.
- **`read_document` tool** β Read `txt / json / conf / md / ini / pdf / docx / xlsx` with `offset` / `limit` paging. Text formats work zero-dependency; `pdf / docx / xlsx` show a hint when optional deps are missing.
- **One toggle** β **Settings β General** has an βEnable file uploadsβ switch. Off hides the button and blocks uploads. No extra tabs.
- **Theme-aware** β Uses DSH design tokens, looks correct in light and dark mode.
- **Zero-intrusion** β Standard Cordis `bundle` plugin, no DSH source changes.
## Requirements
- DeepSeek Harness `dsh >= 0.1.0-rc.8` (`web` profile)
- Node.js `>= 22`
## Install
```bash
git clone https://github.com/runfali/dsh-paperclip.git
cd dsh-paperclip
pnpm install
pnpm build # builds lib/client.js (browser bundle)
dsh plugin --profile web add .
# restart manually: dsh web
```
Uninstall:
```bash
dsh plugin --profile web remove dsh-paperclip
```
Restart `dsh web` to apply.
## Configuration
Edit in **Settings β Plugin Config β paperclip** or override in `~/.dsh/profiles/web/cordis.patch.yml` (full replacement):
| Field | Default | Description |
|---|---|---|
| `enabled` | `true` | Show button and enable uploads |
| `maxBytes` | `67108864` | Per-upload byte cap |
| `uploadDir` | `""` | Persist directory; empty β `~/.dsh/uploads/paperclip` (content-addressed, deduped) |
| `allowedExtensions` | `[]` | Whitelist (empty = allow all) |
| `readLimit` | `2000` | `read_document` line window |
| `maxFileBytes` | `67108864` | `read_document` per-file byte cap |
| `sheetRowLimit` | `200` | `xlsx` rows kept per sheet |
Example:
```yaml
- id: paperclip
config:
enabled: true
maxBytes: 67108864
uploadDir: ""
allowedExtensions: []
readLimit: 2000
maxFileBytes: 67108864
sheetRowLimit: 200
```
## Usage
**Upload**: Click π to pick files. If needed, click β΄ to expand the list above the input; Γ removes a file. Type a message and Send β the list clears and paths are sent with the message.
**Read**: The model calls `read_document({ file_path, format: "auto", offset: 1, limit: 2000 })`.
## Security
- Only loopback `Host`, same-origin `Origin`, `Sec-Fetch-Site` check; only `POST` / `DELETE`.
- Byte cap checked twice, filename sanitized, `DELETE` confined to `uploadDir`.
- Default dir `~/.dsh/uploads/paperclip`, content-addressed and deduped.
## Known Limitations
- Pending list is in-memory; reload clears it (files remain).
- No GC β only Γ deletes.
- `pdf / docx / xlsx` need optional deps (`pnpm add pdf-parse mammoth xlsx` inside the plugin directory); text formats work without them.
## License
[MIT](LICENSE)
Install
dsh plugin --profile web add github:runfali/dsh-paperclip
Profile: web
With the hub plugin installed, ask your agent to install it by name β it resolves the same plan shown here.
dsh plugin --profile web add github:stvlynn/dsh.fish#path:packages/dsh-plugin-hub
install dsh-paperclip from the hub
- 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.