为每个任务建立独立文件夹并维护进度文件
28.2/100
综合分
0
GitHub 星标
—
npm 周下载
—/5
用户评分
数据截至 2026/10/21 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add Zilong6666/dsh-task-workspace该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:仅索引
是什么
dsh 原生插件 · dev
装得上吗
本站尚未做安装检查
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 28 天前
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码v2.7.0🔵 扫描:含敏感能力尚无人工评估展开查看扫描说明与证据 ↓
安全扫描自动 · 静态分析源码
v2.7.0静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。
可执行外部命令读写/删除本地文件
查看扫描证据(共 72 处,展示前 36 条)
- 读取本地文件src/index.mjs:64
if (existsSync(file)) { - 读取本地文件src/index.mjs:66
Object.assign(merged, JSON.parse(readFileSync(file, 'utf8'))); - 写入本地文件src/index.mjs:84
mkdirSync(join(file, '..'), { recursive: true }); - 写入本地文件src/index.mjs:86
writeFileSync(file, `${JSON.stringify({ ...current, ...patch }, null, 2)}\n`, 'utf8'); - 读取本地文件src/index.mjs:303
if (existsSync(file)) { - 读取本地文件src/index.mjs:304
const body = readFileSync(file, 'utf8'); - 读取本地文件src/index.mjs:359
buckets = readdirSync(root, { withFileTypes: true }).filter((entry) => entry.isDirectory()); - 读取本地文件src/index.mjs:367
if (!existsSync(file)) continue; - 写入本地文件src/index.mjs:587
writeFileSync(progressFile, content, 'utf8'); - 读取本地文件src/store.mjs:166
if (!existsSync(path)) mkdirSync(path, { recursive: true }); - 写入本地文件src/store.mjs:166
if (!existsSync(path)) mkdirSync(path, { recursive: true }); - 读取本地文件src/store.mjs:186
return existsSync(path) && statSync(path).isDirectory(); - 读取本地文件src/store.mjs:186
return existsSync(path) && statSync(path).isDirectory(); - 读取本地文件src/store.mjs:202
if (existsSync(candidate) && statSync(candidate).isFile()) return candidate; - 读取本地文件src/store.mjs:202
if (existsSync(candidate) && statSync(candidate).isFile()) return candidate; - 读取本地文件src/store.mjs:209
if (!existsSync(taskDir) || !statSync(taskDir).isDirectory()) return undefined; - 写入本地文件src/store.mjs:268
writeFileSync(file, `${JSON.stringify(index, null, 2)}\n`, 'utf8'); - 写入本地文件src/store.mjs:307
mkdirSync(info, { recursive: true }); - 写入本地文件src/store.mjs:312
writeFileSync(exclude, `${current}${tail}${SESSION_MARKER}\n`, 'utf8'); - 写入本地文件src/store.mjs:336
writeFileSync(file, `${JSON.stringify(body, null, 2)}\n`, 'utf8'); - 写入本地文件src/store.mjs:413
mkdirSync(tasksRoot, { recursive: true }); - 执行外部命令固定命令src/store.mjs:685
return execFileSync('git', args, { cwd, encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'] }); - 删除本地文件src/store.mjs:717
if (progress !== undefined) unlinkSync(progress); - 读取本地文件src/tidy.mjs:74
entries = readdirSync(current, { withFileTypes: true }); - 读取本地文件src/tidy.mjs:88
bytes += statSync(join(current, entry.name)).size; - 读取本地文件src/tidy.mjs:112
return README_NAMES.some((name) => existsSync(join(dir, name))); - 读取本地文件src/tidy.mjs:125
names = readdirSync(dir, { withFileTypes: true }); - 读取本地文件src/tidy.mjs:142
const info = statSync(abs); - 读取本地文件src/tidy.mjs:150
mtimeMs = mtimeMs || statSync(abs).mtimeMs; - 写入本地文件src/tidy.mjs:435
mkdirSync(dirname(target), { recursive: true }); - 写入本地文件src/tidy.mjs:436
writeFileSync(target, markdown, 'utf8'); - 删除本地文件递归src/tidy.mjs:460
rmSync(item.path, { recursive: true, force: true }); - 删除本地文件递归src/tidy.mjs:475
rmSync(stray.path, { recursive: true, force: true }); - 读取本地文件src/cli.mjs:90
if (existsSync(direct)) return direct; - 读取本地文件src/cli.mjs:131
let content = readFileSync(progressFile, 'utf8'); - 写入本地文件src/cli.mjs:164
writeFileSync(progressFile, content, 'utf8');
扫描于 2026/10/31(1 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库
静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
DSH 任务工作区约定:每个任务一个文件夹,每个任务一份 PROGRESS.md(每次更新覆盖),任务拖长后按任务单独用 git。
README
由 DeepSeek 最新模型翻译生成dsh-task-workspace
给 DSH 加一条落得下地的工程约定:一个会话只用一个文件夹,一个任务一个进度文件(每次修改整体覆盖更新),任务过长就在任务目录里建 git 仓库。
- 英文文档:README.md
- 中文文档:本文件
它做什么
| 组成 | 效果 |
| 提示词段落 task-workspace | 每一轮对话都带着这条约定,任何工作区都生效 |
| 技能 task-workspace-convention | 同一份约定,可通过技能目录被检索到 |
| 工具 task_new | 建 <工作区根>/<任务名>-<YYYYMMDD>/PROGRESS.md(可选顺手 git init);本会话已有目录时直接复用(reused: true) |
| 工具 task_progress | 对那唯一的进度文件做整体覆盖更新;长摘要自动压缩;可选自动提交 |
| 工具 task_git | git init + .gitignore + 首次提交,或追加一次提交 |
| 工具 task_list | 列出当前工作区已有的任务目录 |
| 工具 task_tidy | 给每个顶层条目分类,重写工作区索引,并清理系统垃圾 / 缓存 / 过期备份 / 空目录 / 越界遗留任务目录(默认 dry run,apply: true 才删) |
展开完整文档(README 剩余 1 节)
dsh-task-workspace
给 DSH 加一条落得下地的工程约定:一个会话只用一个文件夹,一个任务一个进度文件(每次修改整体覆盖更新),任务过长就在任务目录里建 git 仓库。
- 英文文档:README.md
- 中文文档:本文件
它做什么
| 组成 | 效果 |
| 提示词段落 task-workspace | 每一轮对话都带着这条约定,任何工作区都生效 |
| 技能 task-workspace-convention | 同一份约定,可通过技能目录被检索到 |
| 工具 task_new | 建 <工作区根>/<任务名>-<YYYYMMDD>/PROGRESS.md(可选顺手 git init);本会话已有目录时直接复用(reused: true) |
| 工具 task_progress | 对那唯一的进度文件做整体覆盖更新;长摘要自动压缩;可选自动提交 |
| 工具 task_git | git init + .gitignore + 首次提交,或追加一次提交 |
| 工具 task_list | 列出当前工作区已有的任务目录 |
| 工具 task_tidy | 给每个顶层条目分类,重写工作区索引,并清理系统垃圾 / 缓存 / 过期备份 / 空目录 / 越界遗留任务目录(默认 dry run,apply: true 才删) |
| 命令行 dsh-task | 不用模型也能执行同样的操作 |
安装
dsh plugin --profile desktop add dsh-task-workspace
本地目录安装:
dsh plugin --profile desktop add /绝对路径/dsh-task-workspace
装好后重启该 profile(或开新会话),bundle 补丁才会被合成。
落盘形态
<工作区根>/ ├── .dsh-tasks.json # 轻量任务索引,写入时更新 ├── 竞品调研-20261002/ │ ├── PROGRESS.md # 这个任务唯一的进度文件 │ ├── .dsh-session.json # 记录这个目录属于哪个会话 │ ├── .git/ # 只有「任务过长」时才有 │ └── data/… # 任务产出 └── etl-refactor-20261003/ └── PROGRESS.md
一个会话在此工作区最多只有一个文件夹:.dsh-session.json 记录归属,同一会话再调 task_new 会复用该目录(reused: true,目录名不变),索引里的 sessionId 作为兜底。
PROGRESS.md 固定六段:目标 / 状态 / 当前进度 / 下一步 / 产出物 / 变更日志。
工具用法
task_new
{ "name": "竞品调研", "goal": "整理三家竞品的定价与功能差异", "init_git": true }
- 建 竞品调研-<当天日期>/ 及它的 PROGRESS.md;
- 同一天重复调用是幂等的,返回已有任务;
- 一个会话一个文件夹:本会话已有任务目录时直接复用(reused: true,保留原目录名),不再新建第二个;本会话的所有改动都落在该目录内;
- force: true 可接管同名但非空目录;
- slug 可覆盖目录名。
task_progress
{
"task_dir": "竞品调研-20261002", // 也可用 "task": "竞品" "summary": "已抓取 3 家官网定价页,A 家缺 API 价目", "changelog": "完成定价页抓取", "status": "进行中", "next": "补齐 A 家 API 价目\n输出对比表", "deliverables": "data/pricing.csv" }
- 覆盖「当前进度」而不是往里追加;摘要超过约 18 行会自动压成 ### 进度历史(压缩摘要) 加一个 折叠区保存原文,既不留垃圾也不丢历史;
- 「变更日志」只追加一行,不重写历史;
- 任务目录里已有仓库时自动提交(commit: false 可跳过,或把配置里的 autoCommit 设为 false);
- 什么都不传会报错,避免无意义的空写入。
task_git
{ "task_dir": "竞品调研-20261002", "message": "chore: 初始化任务仓库" }
初始化仓库并写入 .gitignore(.DS_Store、__pycache__/、node_modules/、.venv/、.tmp)后提交;再次调用就是提交当前状态。
task_list
列出当前工作区的任务目录,含状态、最后更新时间、是否已建仓库。
task_tidy
把工作区整理一遍:
- 给每个顶层条目归类:任务 / 产出 / 中间产物 / 工具 / 配置 / 散落文件;
- 覆盖重写索引文件(默认 工作区索引.md):按类别列出大小、文件数、最后修改、任务状态与目标;
- 单独报出大体积中间产物(超过 200 MB)但不动它们;
- 默认 dry run,apply: true 才真正删除,且只删可证明无用的东西:.DS_Store 一类系统垃圾、 __pycache__ / .pytest_cache、.pyc / .bak / .orig / .tmp / .tgz,以及落在工作区之外、里面只有自身 PROGRESS.md 的任务目录(cwd 出错留下的)——不碰任务内容,不碰产出;
- 空目录只列出、不删除(空的 parts/ 可能正是构建脚本期待的占位目录),要删得显式传 empty_dirs: true。
{ "workspace": "/path/to/workspace", "apply": true, "index": true, "empty_dirs": false }
索引每次运行都会整体重写,是给人读的,不要手工编辑。
命令行
dsh-task new "竞品调研" "整理定价差异" --git dsh-task progress 竞品调研 --summary "抓到 3 家" --changelog "完成抓取" dsh-task git 竞品调研 --message "chore: 初始化任务仓库" dsh-task list dsh-task config --root "/path/to/workspace"
退出码:0 正常,1 用法错误,2 操作失败。人读的信息走 stderr,结果路径走 stdout (所以 cd "$(dsh-task new …)" 可以直接用)。
配置
工作区根的解析顺序:工具参数 → 配置 workspaceRoot → $DSH_TASK_WORKSPACE_ROOT → $DSH_WORKSPACE_ROOT → 会话工作区目录 → $DSH_HOME。
显式指定的根目录不存在时会自动创建;node_modules/、/、临时目录、$HOME 本身会被拒绝。
配置文件位于 ${DSH_HOME}/dsh-task-workspace/config.json:
{
"enabled": true,
"workspaceRoot": "",
"defaultGit": false,
"autoCommit": true,
"sectionOrder": 61,
"promptEnabled": true,
"skillEnabled": true,
"template": "",
"gitAuthor": { "name": "", "email": "" }
}
- defaultGit: true:所有新任务默认建仓库;
- promptEnabled: false / skillEnabled: false:保留工具,但不注入提示词/技能;
- template:直接内联 PROGRESS.md 的 markdown 模板;
- gitAuthor:给没有全局 git 身份、也没有 ~/.gitconfig 的机器兜底(也可以用环境变量 $DSH_TASK_GIT_NAME / $DSH_TASK_GIT_EMAIL)。
profile 也可以在自己的补丁层覆盖同样的键:
- id: task-workspace
name: 'dsh-task-workspace'
config:
workspaceRoot: /Users/me/notes
defaultGit: true
什么时候该建仓库
约定给的触发条件很明确,满足任一即建:
- 预计超过 3 轮对话;
- 需要跨会话继续;
- 预计产出文件超过 10 个;
- 用户明确要求。
开发与自测
node test/run.mjs # 47 项:store、工具、真实 git、CLI、宿主 JSON Schema 子集、会话复用(一会话一文件夹)与 cwd 回退、内部目录护栏,不联网
node test/run.mjs --keep # 保留临时工作区便于检查
许可证
MIT
被应用独占的 profile
dsh plugin --profile desktop add … 会因为 desktop profile 归属 Electron 应用而拒绝执行。
scripts/install-into-profile.sh 只做那条命令本来会做的两件事:
bash scripts/install-into-profile.sh desktop --dry-run # 先看计划 bash scripts/install-into-profile.sh desktop # 建链接 + 写入 bundles
它把包链接进 <profile>/node_modules,并把包名追加到 dsh.profile.bundles;只就地修改这个数组,package.json 其余字节保持不变(这个文件由应用自己重写)。
首次改动前会备份 package.json.bak。装完重启该 profile。
两个只有真机启动才暴露的坑
(本插件已修好,这里记下来供二次开发参考)
- inject 必须挂在导出值上。 cordis-plugin-loader 用 exports.default ?? exports 归一化模块形状,所以只要模块有 default 导出,命名导出的 inject 就会被丢掉,报 Error: cannot get property "systemPrompt" without inject。正确写法是挂到函数属性: apply.inject = ['tools', 'systemPrompt']。
- required 是对象级关键字。 宿主会校验工具输出 schema 是否落在它自己的 JSON Schema 子集内(type/oneOf/properties/required/additionalProperties/items/enum/const 加注解),在标量属性上写 required: true 会报 JsonSchemaError: schema.properties.x.required is not supported on type "string"。
要写在对象上:{ type: 'object', required: ['dir'], properties: { dir: { type: 'string' } } }。预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
Zilong6666/dsh-task-workspace
为每个任务建立独立文件夹并维护进度文件
相关插件 · 开发 / 工程
隐私简历生成器reactive-resume/reactive-resume
Reactive Resume 已迁至 GitHub 上的…
★ 45,125已汉化MCP
71.7
AI 架构文档生成器sopaco/deepwiki-rs
🚀 Litho 已进化为 Terrain —— 给你的 AI 智能体一张会呼吸的代码库地图。
★ 3,157已汉化DSH
70.8
长时任务执行闭环AMAP-ML/LongHorizon-Harness
面向 Computer-Use Agent 的 Loop Engineering
★ 1,764已汉化DSH
70.5
AI 编程纪律方法包GanyuanRan/Aegis
让 AI 编程 agent 变得可信:少返工、更安全、说“完成”前先给证据。
★ 1,384已汉化DSH
69.6
多代理编排运行时Enderfga/claw-orchestrator
面向编程智能体的运行时。把 Claude Code、Codex、Antigravity、Grok…
★ 586已汉化MCP
69.4
记忆进化插件csyangwen/dsh-memory-evolve
dsh-memory-evolve 使用场景指南
★ 461已汉化DSH
67.9