9Epuuuu
dsh-plugin-folder-tidy
DeepSeek Harness dynamic plugin: a round tidy button left of the model selector — click tidies the working folder, long-press picks another folder. 整理文件夹按钮插件
- Stars
- 0
- Language
- JavaScript
- Created
- Aug 15, 2026
- Updated
- Aug 15, 2026
Introduction
dsh-plugin-folder-tidy 🧹
整理文件夹按钮 · DeepSeek Harness (DSH) Web GUI 动态插件 Folder Tidy Button · a dynamic Cordis plugin for the DeepSeek Harness (DSH) Web GUI
中文
在 DSH Web GUI 对话框输入行「模型选择」的左侧添加一个 34px 圆形按钮(与「提交对话」按钮同尺寸),图标为文件夹 + 右下角小扫帚:
- 点击(短按):自动整理当前会话的工作文件夹
- 长按(约 0.5 秒,显示进度环动画):打开目录选择器,自行挑选任意文件夹进行整理
- 整理完成后在界面底部弹出 toast 显示结果(如「已整理 3 个文件:图片 ×2 · 压缩包 ×1」)
整理规则
| 分类文件夹 | 扩展名 |
|---|---|
| 图片 | png jpg jpeg gif webp svg ico bmp tif tiff avif heic |
| 文档 | md txt pdf doc docx xls xlsx ppt pptx csv odt rtf epub |
| 压缩包 | zip rar 7z tar gz bz2 xz tgz |
| 音视频 | mp3 wav flac aac m4a ogg mp4 mkv avi mov wmv webm flv |
| 安装包 | exe msi apk dmg deb rpm appx |
| 日志 | log |
安全设计:
- 只处理目标文件夹顶层的文件,不递归子目录
- 只移动明确的「内容类」文件(白名单扩展名);代码、配置、锁文件一律不动
README.md、AGENTS.md、CLAUDE.md与隐藏文件(.开头)始终保留原位- 目标分类文件夹自动创建;重名文件自动加
(2)序号,绝不覆盖 - 沙箱策略感知:跟随调用会话的访问模式——
workspace-write会话只能整理工作区内的文件夹;切到danger-full-access后可整理任意文件夹 - 只移动、不删除、不上传;无任何网络访问
交互细节
- 短按整理当前文件夹;长按 500ms 触发目录选择(进度环动画提示)
- 目录选择优先使用 Host 原生选择器(
workspaces.pickDirectory);浏览器环境自动回退到自绘目录浏览对话框(面包屑导航 + 文件夹列表 + 「整理此文件夹」按钮) - 键盘支持:Enter / Space 触发整理;按钮带
aria-label与悬停提示 - 整理中图标呼吸动画,完成后 toast 自动消失(约 4 秒)
文件结构
plugin/
host.js Host 半:注册包内 tidy RPC;用 shell 服务执行 PowerShell 完成分类移动
client.js Client 半:注册 conversation.input.right 按钮与 shell.overlay 浮层(toast + 目录选择)
安装
方式一:DSH 动态插件(推荐,无需构建)
- 打开 DSH Web GUI 的任意会话
- 使用
cordis_define定义插件:code.host/code.client分别取本仓库plugin/host.js与plugin/client.js中export default function () { … }的函数体(return { … }部分) - 使用
cordis_run激活,并在运行卡片中批准(单勾 = 仅授权当前版本;双勾 = 自动批准该插件的后续版本)
也可以直接对会话中的 agent 说:
用动态 Cordis 插件实现:在输入行模型选择左侧加一个与发送按钮同尺寸的圆形按钮,图标是文件夹+右下角小扫帚;点击整理当前工作文件夹,长按可选择文件夹。参考仓库 dsh-plugin-folder-tidy 的 plugin/host.js 与 plugin/client.js。
方式二:嵌入预设
将两个函数体按 DSH 文档《editing-cordis-compositions》嵌入自己的 agent preset 插件行。
运行时依赖
- Host:服务
fs、shell、sandboxPolicy、sessions;内建harness、btoa - Client:服务
slots、timer、workspaces;内建styles、React、host
插件对缺失的服务做 ctx.get 可选检查;conversation.input.right 与 shell.overlay 两个 Slot 由 DSH Web GUI 声明。
工作原理
- Client 按钮把目标路径与
sessionId通过包内 RPC(host.call('tidy', …))发给 Host - Host 用
sessions.get(sessionId)取出调用会话,经sandboxPolicy.resolve({ session })解析该会话的真实沙箱策略(这样用户在会话里切换的访问模式才会生效),并把它传给 shell 执行器 - Host 生成一段自包含的 PowerShell 脚本(路径经 UTF-8 Base64 传输,杜绝注入/引号问题),通过
shell.run执行:列顶层文件 → 白名单分类 →Move-Item(冲突自动加序号)→ 输出 JSON 统计 - 结果回传 Client,由
shell.overlay的 toast 显示
已知限制
- 只整理顶层文件,不递归;如需递归/预览/更多分类请自行扩展
CATEGORY_MAP - 移动由 PowerShell 完成,Windows 上开箱即用;其他平台需将脚本换成对应 shell 语法
- 目录浏览回退仅列出子目录(不含文件),与 DSH
listDirectory契约一致
License
English
Adds a 34px round button (same size as the Send button) to the left of the model selector in the DSH Web GUI composer tool row, with a folder + little broom icon:
- Click (short press): tidy the current session's working folder
- Long-press (~0.5s, progress-ring animation): open a folder picker and tidy any folder you choose
- A toast at the bottom reports the result (e.g. "3 files organized: Images ×2 · Archives ×1")
Tidy rules
| Category folder | Extensions |
|---|---|
| 图片 (Images) | png jpg jpeg gif webp svg ico bmp tif tiff avif heic |
| 文档 (Documents) | md txt pdf doc docx xls xlsx ppt pptx csv odt rtf epub |
| 压缩包 (Archives) | zip rar 7z tar gz bz2 xz tgz |
| 音视频 (Media) | mp3 wav flac aac m4a ogg mp4 mkv avi mov wmv webm flv |
| 安装包 (Installers) | exe msi apk dmg deb rpm appx |
| 日志 (Logs) | log |
Safety design:
- Only top-level files are moved; subdirectories are never recursed into
- Only clear "content" files (whitelisted extensions) move; code, config and lock files stay put
README.md,AGENTS.md,CLAUDE.mdand dotfiles are always left in place- Category folders are created on demand; name collisions get a
(2)suffix — nothing is ever overwritten - Sandbox-aware: follows the calling session's access mode — a
workspace-writesession can only tidy inside its workspace; switch todanger-full-accessto tidy any folder - Move-only: no deletions, no uploads, no network access
Interactions
- Short press tidies the current folder; a 500ms long-press opens folder picking (progress ring feedback)
- Picking prefers the Host native picker (
workspaces.pickDirectory) and falls back to a built-in browse dialog (breadcrumbs + folder list + "Tidy this folder" button) in plain browsers - Keyboard: Enter / Space triggers tidy; the button carries an
aria-labeland a hover tooltip - Breathing icon while busy; toast auto-dismisses after ~4s
Files
plugin/
host.js Host half: registers the package-private tidy RPC; runs a PowerShell classification/move script via the shell service
client.js Client half: registers the conversation.input.right button and the shell.overlay surface (toast + folder picker)
Installation
Option 1: DSH dynamic plugin (recommended, no build step)
- Open any session in the DSH Web GUI
- Use
cordis_defineto define the plugin:code.host/code.clientare the function bodies (thereturn { … }part) ofexport default function () { … }inplugin/host.jsandplugin/client.js - Activate with
cordis_runand approve on the run card (single check = this version only; double check = auto-approve future versions of the same plugin)
Or simply tell the agent in the session:
Build a dynamic Cordis plugin: a round button the same size as the send button, left of the model selector, icon = folder with a small broom; click tidies the current working folder, long-press picks a folder. See plugin/host.js and plugin/client.js of the dsh-plugin-folder-tidy repo.
Option 2: embed in a preset
Embed both function bodies as a plugin row in your own agent preset, following the DSH "editing-cordis-compositions" guide.
Runtime dependencies
- Host: services
fs,shell,sandboxPolicy,sessions; builtinsharness,btoa - Client: services
slots,timer,workspaces; builtinsstyles,React,host
Optional services are read via ctx.get with absence checks; the conversation.input.right and shell.overlay slots are declared by the DSH Web GUI.
How it works
- The Client button sends the target path plus
sessionIdto the Host through the package-private RPC (host.call('tidy', …)) - The Host resolves the calling session via
sessions.get(sessionId)and derives its real sandbox policy withsandboxPolicy.resolve({ session })— so the access mode the user switched to in that session takes effect — and passes that policy to the shell executor - The Host builds a self-contained PowerShell script (path delivered as UTF-8 Base64, injection-safe), runs it through
shell.run: list top-level files → whitelist classification →Move-Item(collision-safe suffixing) → JSON stats on stdout - The result returns to the Client and is shown by the
shell.overlaytoast
Known limitations
- Top-level files only; extend
CATEGORY_MAPif you want recursion, preview, or more categories - File moves are done by PowerShell — works out of the box on Windows; port the script for other platforms
- The browse-dialog fallback lists subdirectories only (no files), matching the DSH
listDirectorycontract