dsh-fs-compact
DiscoveredToken-lean filesystem tools for DeepSeek Harness (fs_read / fs_grep / fs_glob / fs_replace).
dsh-fs-compact
Token-lean filesystem tools for DeepSeek Harness (DSH): fs_read, fs_grep,
fs_glob and fs_replace with compact plain-text output, paths relative to
the session cwd, and a read-before-replace safeguard.
Unofficial community plugin. Not affiliated with or endorsed by DeepSeek.
Tools
| Tool | Purpose |
|---|---|
fs_read | UTF-8 text as numbered lines, 800-line default, offset to continue; files above 8 MB are streamed |
fs_grep | Regex search (pure JavaScript, no native binary); mode = files / content / count |
fs_glob | *, **, ?, [a-z], {a,b} glob; returns cwd-relative paths |
fs_replace | Global regex replace, validated in two phases, dryRun preview |
Design choices:
- plain-text output, no JSON envelope or bookkeeping fields;
- the path is printed once per group, relative to the session cwd;
- compact tool schemas to keep the prompt small;
fs_replacewarns when a target was never read first (or only partially read);- no
.git,node_modules,dist,targettraversal.
Install
Requires DSH >=0.2.1-rc.3.
# npm (recommended)
dsh plugin --profile <profile> add dsh-fs-compact
# pin a version
dsh plugin --profile <profile> add dsh-fs-compact@0.3.1
From GitHub instead — dsh plugin forwards its arguments to pnpm:
dsh plugin --profile <profile> add "github:marya505/dsh-fs-compact"
If Git cannot reach GitHub over HTTPS (for example CRYPT_E_NO_REVOCATION_CHECK
on Windows), install the pinned tarball:
dsh plugin --profile <profile> add "https://codeload.github.com/marya505/dsh-fs-compact/tar.gz/347518e9d222fb70289068f26ad43992510a9598"
Local development checkout:
dsh plugin --profile <profile> add "file:<path-to-checkout>"
<profile> is the DSH profile you use, for example desktop. If dsh is not on
PATH, run the CLI from your DSH installation, for example
<DSH install>/resources/runtime/cli/bin/dsh (.cmd on Windows).
Updating. Remove and re-add the package, then restart:
dsh plugin --profile <profile> remove dsh-fs-compact
dsh plugin --profile <profile> add dsh-fs-compact
A local file: checkout uses its path in the second command instead; pnpm
hard-links it, so editing the source also requires the remove + add.
Enable / disable
Enabled as a profile bundle. To turn it off without uninstalling, add to
~/.dsh/profiles/<profile>/cordis.patch.yml:
- id: dsh-fs-compact
disabled: true
If another installed plugin also provides file tools, disable one of the two sets so the model is not offered overlapping tools.
Uninstall
dsh plugin --profile <profile> remove dsh-fs-compact
Then restart DSH. To disable without uninstalling, use the disabled: true
entry above.
Compatibility
- DSH
>=0.2.1-rc.3(tested on0.2.1-rc.3). - Node.js 20+ for development and tests.
- Pure JavaScript; no native binary and no runtime dependencies.
Security model
fs_read,fs_grepandfs_globare read-only. The plugin makes no network calls and spawns no processes.fs_replacefollows the host sandbox policy resolved at call time:read-onlyrejects writes;workspace-writeallows writes only inside the workspace and the OS temporary directory;danger-full-accessallows any writable path;- any other mode is rejected (fail closed).
- Directory scans skip
.git,node_modulesand build output, skip symlinks, and stop at 50,000 files / 256 MB. fs_replacevalidates every target (match count, file size, output size and policy) before writing anything; an over-limit call changes nothing.
See SECURITY.md for vulnerability reporting.
Semantics
Globs. A pattern is matched against paths relative to the searched path.
A pattern without / also matches basenames, so *.js stays recursive while
src/*.js is a one-level path filter. include, exclude and replace's
glob all use the same implementation.
Replacement strings. fs_replace uses String.replace, so $1 (capture
group), $& (whole match), $<name> (named group) and $$ (literal $) are
available. Write $$ when you want a literal dollar sign.
Limits and failure behavior. fs_replace first plans every file — counts
matches, checks maxReplacements, file size and the sandbox policy — and only
then writes. An over-limit call changes nothing and says so. Individual write
failures are reported as skipped instead of aborting the whole batch (already
written files are not rolled back).
Scanning. Scans stop at 50,000 files or 256 MB and say so. Symlinks are
skipped. Output is capped at 24,000 chars; fs_grep reports files skipped as
too large / unreadable / binary.
Why it is a bundle, not a plain dependency
DSH's plugin list only shows profile layers: packages whose package.json
has dsh.bundle.patch. A plain dependency still loads if something inserts it,
but the market UI never lists it (the CLI even warns
declares no dsh.bundle — installed as a plain dependency, not a profile layer).
This package therefore ships:
package.json→dsh.bundle.patch: ./cordis.patch.ymlcordis.patch.yml→ theinsertentry that mounts the plugin
On dsh plugin add, DSH's reconcile step applies that patch and appends
dsh-fs-compact to dsh.profile.bundles, which is what makes it visible as an
installed plugin.
Registration gotcha
ctx.tools.register() requires output: { schema, render }. Omitting
output.schema throws TypeError: tool "x" must declare output { schema, render },
and if that throw happens inside ctx.effect(...) it is swallowed — the prompt
section still appears, so the plugin looks installed while none of its tools
exist. The schema must match the value execute returns; this plugin returns
{ text: string }.
Tools are registered under ctx.inject(['tools']) only. The sandbox policy is
resolved at call time, so a missing sandboxPolicy service cannot make the
tools silently disappear.
Development
git clone https://github.com/marya505/dsh-fs-compact.git
cd dsh-fs-compact
node --test
The suite runs against os.tmpdir() fixtures and covers read paging/streaming,
grep modes and context merging, glob semantics, replace atomicity, policy
fail-closed behavior, error-code mapping and the registration entry.
License
MIT © 2026 marya505
Comments
Loading…
Similar plugins
by whitefirer
dsh(DeepSeek Harness)插件:让 agent 读写浏览器所在机器的本地文件——File System Access 授权 + WS 中继,含非安全上下文兼容模式
★ 4
↓ 128/wk
MIT
JavaScript
Aug 23, 2026
dsh plugin --profile web add dsh-browser-fsby ZK-Andy
Resident-index grep for DeepSeek Harness that shadows the built-in grep/glob tools under the same names: repeated content searches hit an in-memory index ranked by access/modification frecency, and gl
★ 0
↓ 74/wk
MIT
TypeScript
Oct 10, 2026
dsh plugin --profile web add dsh-frecencyby 173787247
DeepSeek Harness WSL plugin (dsh-wsl-media)
★ 1
MIT
JavaScript
Sep 30, 2026
dsh plugin --profile web add dsh-wsl-mediaby dondai44423
First-class DonSeTch plugin for DeepSeek Harness: fetch, search and crawl as native dsh tools with an auto-updating verified binary
★ 3
AGPL-3.0
TypeScript
Oct 22, 2026
dsh plugin --profile web add @dsh-external/donsetchby xiaoso456
DeepSeek Harness 基础工具增强:持久 bash、结构化 read、多模式 edit、原子 write、双引擎 grep/glob、图像直读,一个插件全覆盖
★ 15
↓ 718/wk
MIT
TypeScript
Oct 26, 2026
dsh plugin --profile web add @xiaoso/dsh-tool-plusby devacc8
File Explorer for DeepSeek Harness: right-side resizable file tree (expand/collapse, search, syntax-highlighted preview, in-panel editing) with one-click VS Code / system file manager open
★ 0
MIT
TypeScript
Sep 18, 2026
dsh plugin --profile web add dsh-file-explorer