dshbase

插件目录 / Storage / dsh-files

dsh-files

已验证 · 实测可装 taxueseek

✓ 持续维护 基于 8 个官方 DSH 包 纯 TypeScript

查看 GitHub ↗ ← 返回插件目录

26Stars
5Forks
3未关闭 issue
TypeScript语言
2026-08-24最近推送
跨平台平台

功能简介

DeepSeek Harness双面插件:会话隔离文件上传,彩色卡片+文档读取工具,含嗅探与LRU缓存

我们的评价
可用 — 实测通过,社区增长中

DeepSeek Harness双面插件:会话隔离文件上传,彩色卡片+文档读取工具,含嗅探与LRU缓存 实测能干净安装、正常启动。社区在增长,是个稳妥选择。

「已验证」表示我们的自动化 CI 在干净 profile 里实际执行了 dsh plugin add 并启动成功——仅此而已。功能描述与版本兼容性均为作者声明。这不是安全审计,也不代表对第三方代码的背书。

README

dsh-files: one package. A composer paperclip for uploads, a document-reading tool for the model, and native image support for vision models.

dsh-files

One package, one line of cordis config. A composer paperclip for uploads, a document-reading tool for the model, and native image support that hands JPEG/PNG/WebP/GIF to any vision-capable model.

DeepSeek Harness composer: paperclip upload button and colored file cards

DeepSeek Harness dual-face plugin. Three capabilities:

  • Upload — paperclip button, folder button, and drag-and-drop anywhere; @ file candidates; local session-isolated storage with TTL sweep and sha256 dedup. Files are written under <session-workdir>/.dsh-filess/<sessionId>/ so the agent's fs backend can always resolve them.
  • Native images — JPEG/PNG/WebP/GIF uploads are handed to the harness core attachment pipeline (ctx.attachments → base64 image_url), so any model that declares an image input modality actually sees the picture, rendered through the stock native image rail.
  • Document reading — the read_document tool reads text / PDF / DOCX / XLSX with content sniffing, encoding fallback, paged reads, per-sheet XLSX access, an LRU parse cache and cooperative cancellation.

Features

Upload

  • Three entry points: a paperclip button in the composer toolbar for multi-select files, a folder button for an entire directory (the browser flattens the tree and preserves relative paths per sub-directory), and drag-and-drop anywhere on the page (a drag overlay hints while hovering). Batch uploads are bounded to 4 concurrent requests, and a per-file failure never blocks the rest.

Batch folder upload: multiple images uploaded at once and shown as a grid

  • Folder batch upload: selecting or dropping a folder recursively flattens its files, keeps the sub-directory layout under the session dir, and uploads with bounded concurrency — so a whole folder's content lands in one go.
  • @ dual-source candidates: typing @ lists both the current session's uploaded files (absolute paths) and the session workspace files (relative paths the agent resolves against its cwd), so you can reference an existing worktree file without re-uploading.
  • Colored file cards: the badge is colored by the byte-sniffed real format (PDF red / DOC blue / XLS green / TXT gray), so a disguised file (e.g. an exe renamed to .pdf) is never shown as its fake extension; each card shows name, size and a remove button.
  • Security rail: loopback host + same-origin + sec-fetch-site triple check; trustedHosts for public-domain / reverse-tunnel deploys (bare host matches any port, host:port matches exactly, same semantics as dsh web --trusted-host); file-name sanitization (control chars, path separators, dot segments and leading dots stripped, truncated by UTF-8 bytes with code-point alignment so emoji never splits a surrogate); unknown session 403; concurrency limit (default 4) → 429; oversized body rejected early with the request drained so keep-alive is not left hanging.
  • Read hint: the upload response carries a readHint (cost / estimatedChars) so the client can pre-judge how expensive a file is to read.
  • Lifecycle: TTL sweep (default 7 days) with empty session dirs reaped, optional per-session storage quota (maxUploadBytesPerSession, 507 over limit), and sha256 content dedup (same content under a different name stores one file).

Native images

  • Uploaded raster images (JPEG / PNG / WebP / GIF) no longer land as a local path that read_document cannot read — they go through the harness core attachment pipeline: createDraftImagesaddImages to the composer draft, then serializeDraftImages → base64 image_url at request time via the provider adapter.
  • Any image-capable model works: because the wire form is the supplier-neutral base64 image_url, every model that declares inputModalities: [text, image] (DeepSeek vision, Dots3, LongCat, OpenRouter vision models, …) actually sees the picture — not just DeepSeek.
  • Native UI: the attachment is rendered by the harness's stock conversation.input.attachments rail — thumbnail, click-to-zoom lightbox, native remove — so images look native instead of a grey badge card. dsh-files does not inject that slot; it hands the image to the core and lets the official components render it.

Vision model reading an uploaded image through the native pipeline

Document reading

  • Content sniffing: PDF header, ZIP central-directory members (docx/xlsx), UTF-8 (fatal), UTF-16 BOM, UTF-16 without BOM, and GB18030 — all decided from bytes, never the extension. A spoofed extension (an executable or an image renamed to .pdf) is rejected.
  • Encoding chain: UTF-16 BOM → UTF-8 (fatal, rejects NUL) → GB18030 (fatal) → UTF-16 without BOM (high-confidence guard), so Chinese GBK and BOM-less UTF-16 files both read.
  • Paged reads: line numbers + offset/limit pagination for long documents; the window character budget is tiered by format (text full, xlsx 3/4, pdf/docx 1/2, see maxOutputChars) and truncates with an explicit marker that counts surviving lines, steering the model to page incrementally.
  • Line-number policy by format: text (code/config) carries line numbers for precise location; PDF/DOCX/XLSX paragraph streams drop them to save tokens.
  • XLSX sheet-level reads: the sheet parameter returns that worksheet in full (not row-capped); other sheets fold into a merged read (first 5 by default) with an explicit truncation marker; list_sheets lists every sheet name without reading cells, and an out-of-range sheet reports the available list.
  • Timeout: read_document single-run timeout readTimeoutMs (default 120s) so large PDF parses don't rely on a hard-coded value.
  • Scanned-doc notice: a PDF with no text layer returns an explicit notice instead of an empty string, so the model doesn't mistake it for an empty file.
  • Parse cache: LRU with a dual budget (entry count + bytes), keyed on (targetKey, content sha256, format, sheet, listSheets) — content changes always invalidate it, not just the file version.
  • Size pre-check: stat first, then reject over maxFileBytes with FS_TOO_LARGE without reading bytes.
  • Cooperative cancellation: parses listen to the execution signal and abort on user cancel / session close.
  • Measured reading: the system prompt guides "probe structure first, then read precisely, stop when enough", keeping the context budget for task reasoning.
  • UI projection: tool results are projected via presentationMeta into a card: 'read', reusing the official file-read card (line numbers / highlight / scroll); the model side only receives compact line text.

Security

  • Parser dependencies are maintained libraries with no known vulnerabilities: pdfjs-dist (Mozilla), mammoth, read-excel-file (read-only).
  • ZIP central-directory probing never expands members; member count and member-name length are capped, and malicious archives are rejected safely.
  • File reads go through ctx.fs, inheriting the session sandbox and fs-observation policy with the same privileges as the built-in read tool.
  • Upload content is not hard-allowlisted (all extensions allowed by default); the session sandbox is the backstop.

Install

dsh plugin --profile web add dsh-files
# restart dsh web

Configuration

- id: upload-toolkit
  name: 'dsh-files'
  config:
    maxFileBytes: 25165824        # per-document read byte cap
    readLimit: 800                # default lines per call (cheap pagination)
    sheetRowLimit: 200            # rows kept per worksheet
    maxSheets: 5                  # sheets read per workbook
    cacheEntries: 16              # parse-cache entry count
    cacheMaxBytes: 67108864       # parse-cache byte budget
    maxOutputChars: 24000         # per-call window budget (text full; xlsx 3/4; pdf/docx 1/2; truncate w/ marker)
    readTimeoutMs: 120000         # read_document single-run timeout
    uploadMaxBytes: 25165824      # per-upload byte cap
    allowedExtensions: []         # upload extension allowlist (empty = all)
    uploadTtlMs: 604800000        # upload retention (7 days)
    sweepIntervalMs: 3600000      # sweep interval
    maxConcurrentUploads: 4       # concurrent upload bodies
    maxUploadBytesPerSession: 0   # per-session storage quota (0 = unlimited)
    uploadDir: /abs/path          # fallback upload root when there is no sessions service
    trustedHosts: []              # extra trusted upload hosts, e.g. dsh.example.com or dsh.example.com:443 (bare host matches any port); default empty = loopback only

trustedHosts shares the semantics of dsh web --trusted-host: when serving over a public domain / reverse tunnel (Caddy, frp), the browser Origin is https://domain while TLS terminates upstream. The default loopback-only upload rail would silently 403 every upload (the old paperclip "did nothing"). Add the deploy domain to trustedHosts to restore uploads; the Origin check compares only the host part, so upstream TLS termination still passes.

Development

pnpm install
pnpm test          # upload / parse / cache regression
pnpm build         # esbuild client bundle
npx tsc --noEmit   # type check

License

MIT

安装

🧩 让 Agent 自动装(推荐)

装一次目录插件,之后本站所有插件都能让 DeepSeek Harness 自动找、自动装:

dsh plugin add dshbase-catalog

然后对 agent 说「帮我装 dsh-files」,它会在目录里找到并自动安装。文档:dshbase-catalog · 已验证场景包

该插件是 GitHub 源码(未发 npm)——直接从仓库装:

Web profile:

dsh plugin --profile web add github:taxueseek/dsh-files

Headless(CLI)profile:

dsh plugin --profile headless add github:taxueseek/dsh-files

实测报告

验证通过:从 GitHub 源码完成 L1 安装 + L2 加载 + L3 运行(dsh 0.1.0-rc.6)。

使用场景

给 agent 持久存储——数据库、文件存储或持久层——让状态跨会话留存。

适合谁

任务需要读写结构化数据并跨运行保留的人。

二次开发建议

存储后端和数据模型是缝——插新数据库、加 schema 或暴露查询工具。

安全:尚未扫描——我们的每日静态扫描将很快覆盖它。

分享徽章

Storage 里更多

浏览全部 7795 个插件 →