DeepSeek Harness Plugin Hub

Publish and manage complete Harness Profiles. Discover Plugins for your next setup.

Explore

PluginsPresetsDocsNews

Community

Publish a pluginContactReport an issue

Resources

Plugin Hub on GitHubDeepSeek HarnessSystem statusPrivacy notice
© 2026 DeepSeek Harness Plugin HubPowered byPaxTech

Independent and unofficial. Not affiliated with, authorized by, or endorsed by DeepSeek.

Task Workspace — DSH Plugin for DeepSeek Harness
← Plugins
T

dsh-task-workspace

Task Workspace

Task workspace convention for DSH: one folder per session, one PROGRESS.md per task (overwritten on every update), git init when the task runs long.

The plugin will be installed here. Keep web if you are unsure.

npx -y @deepseek-ai/dsh plugin --profile web add github:Zilong6666/dsh-task-workspace#9e409672fd6afe10fac60ee097fc2f4f47ebe772
READMECompatibilityVersions

Compatibility and provenance

Task Workspace is published as dsh-task-workspace and currently resolves to version 0.3.0. The Hub verifies its manifest and preserves the exact installation source for reproducible installs.

DSH compatibility
*
Runtime surfaces
any
Release source
github
Registry updated
10/4/2026

Versions

0.3.0stable
10/4/2026
0.2.1stable
10/3/2026
0.1.0stable
10/2/2026

Related plugins

Loading related plugins…

Latest
0.3.0
DSH
*
HMR
Process restart
Tree shaking
Safe tree shaking not declared
Unpacked size
Unavailable
Files
Unavailable
Surface
any
License
MIT
Source
github
GitHub
★ 0
Weekly downloads
0
Last push
10/4/2026
View source ↗
README badge

Click the badge to copy Markdown for your README.

Do you maintain this Plugin?Claim benefit · Priority security scan

Verify the GitHub repository declared in package.json to manage this listing. After you claim it, Hub will prioritize a security scan of the current version and publish the result when it passes.

Claim this Plugin →
Report an issue
DeepSeek Harness Plugin Hub
ProfilesPluginsCategoriesNewsDocsSign inManage Profiles
ProfilesPluginsCategoriesNewsDocsSign in

Related plugins

More verified plugins in productivity-workflow.

Client Ui Task Board@linxin666/dsh-client-ui-task-boardHost-authoritative task board for the DSH Web GUI with real session execution, Host cron scheduling, and optional cross-platform idle-sleep protection; mounted without DSH source changes.Web All@linxin666/dsh-web-allDSH Web UI 全家桶聚合插件:一键安装全部功能插件(task-board / git-graph / pet / remote-web-ui / web-ui-settings / skin-center / community-plugins / compat shim)。compat 桥接层已并入本包(src/client),无需独立 compat npm 包。Deepseek Ipptdeepseek-ipptiPolloWork PPT Studio and its curated slide templates as a native DeepSeek Harness conversation view.Codex Ui@michengai/dsh-codex-uiDSH Codex UI — 为 DeepSeek Harness Web 提供 Codex 风格侧栏、工作区会话树、全局搜索和轮次导航 · A Codex-style sidebar, workspace session tree, global search, and turn navigation for DSH Web

README

dsh-task-workspace

给 DSH 加一条落得下地的工程约定:一个会话只用一个文件夹,一个任务一个进度文件(每次修改整体覆盖更新),任务过长就在任务目录里建 git 仓库。

A DSH bundle that makes one convention stick: one folder per session, exactly one progress file per task (overwritten on every update), and per-task git once the task runs long.

  • 中文文档:README.zh.md
  • English docs: this file

What it does

PieceEffect
Prompt section task-workspaceThe convention is present in every turn, always, in every workspace
Skill task-workspace-conventionThe same convention, discoverable through the skill catalog
Tool task_newCreates <workspace>/<name>-<YYYYMMDD>/PROGRESS.md (optionally git init); a session that already owns a folder reuses it (reused: true) instead of creating a second one
Tool task_progressWhole-file overwrite of that one progress file; auto-compacts long summaries; optionally commits
Tool task_gitgit init + .gitignore + first commit, or a follow-up commit
Tool task_listWhat task folders already exist in this workspace
Tool task_tidyClassifies every top-level entry, rewrites the workspace index, and clears OS litter / caches / stale backups / empty folders / stray task folders (dry run unless apply: true)
CLI dsh-taskThe same operation without a model

Install

# from a profile (web / desktop / cli …)
dsh plugin --profile desktop add dsh-task-workspace

Or install from a local checkout:

dsh plugin --profile desktop add /absolute/path/to/dsh-task-workspace

Then restart the profile (or start a new session) so the bundle patch is composed.

The on-disk shape

<workspace>/
├── .dsh-tasks.json              # small task index, rebuilt/updated on write
├── 竞品调研-20261002/
│   ├── PROGRESS.md              # the ONLY progress file of this task
│   ├── .dsh-session.json        # which session owns this folder
│   ├── .git/                    # only when the task ran long
│   └── data/…                   # task output
└── etl-refactor-20261003/
    └── PROGRESS.md

One session owns at most one folder here. .dsh-session.json records the owner; task_new from the same session reuses that folder (reused: true, the original name is kept) and the workspace index carries the same sessionId as a fallback.

PROGRESS.md always has the same six sections: 目标 / 状态 / 当前进度 / 下一步 / 产出物 / 变更日志 (goal / status / current progress / next steps / deliverables / changelog).

Tools

task_new

{ "name": "竞品调研", "goal": "整理三家竞品的定价与功能差异", "init_git": true }
  • Creates 竞品调研-<today>/ and its PROGRESS.md.
  • Idempotent for the same day: calling it again returns the existing task.
  • One folder per session: when this session already owns a task folder in the workspace, that folder is reused (reused: true, folder name unchanged) rather than creating a second one — every change of this session stays inside it.
  • force: true adopts an existing non-empty folder of the same name.
  • slug overrides the folder slug.

task_progress

{
  "task_dir": "竞品调研-20261002",          // or "task": "竞品"
  "summary": "已抓取 3 家官网定价页,A 家缺 API 价目",
  "changelog": "完成定价页抓取",
  "status": "进行中",
  "next": "补齐 A 家 API 价目\n输出对比表",
  "deliverables": "data/pricing.csv"
}
  • Overwrites the 当前进度 section instead of appending to it. A summary longer than ~18 lines is automatically compacted into a ### 进度历史(压缩摘要) block plus a collapsible <details> archive, so nothing is lost and the file stays readable.
  • Appends one line to 变更日志 (history is never rewritten).
  • Commits inside the task repository when one exists (commit: false to skip, or set autoCommit: false in the config).
  • Passing nothing is an error, so the file never gets a meaningless touch.

task_git

{ "task_dir": "竞品调研-20261002", "message": "chore: 初始化任务仓库" }

Initializes the repository with a .gitignore (.DS_Store, __pycache__/, node_modules/, .venv/, *.tmp) and commits; a second call just commits the current state.

task_list

Lists the task folders of the current workspace with status, last update time and whether the task has its own repository.

task_tidy

Tidies the workspace the convention created it in:

  • classifies every top-level entry as 任务 / 产出 / 中间产物 / 工具 / 配置 / 散落文件;
  • rewrites the index file (工作区索引.md by default) — a table per category with size, file count, last change, task status and goal;
  • reports the heavy intermediate folders (over 200 MB) without touching them;
  • dry run unless apply: true, and even then it only removes provably disposable things: .DS_Store and friends, __pycache__ / .pytest_cache, *.pyc / *.bak / *.orig / *.tmp / *.tgz, and a task folder that landed outside the workspace holding nothing but its own PROGRESS.md (the "wrong cwd" accident) — never task content, never a README.
  • empty folders are listed but not deleted (an empty parts/ may be a placeholder a build script expects); pass empty_dirs: true to remove them too.
{ "workspace": "/path/to/workspace", "apply": true, "index": true, "empty_dirs": false }

The index is regenerated on every run and is meant to be read, not edited.

CLI

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"

Exit codes: 0 ok, 1 usage error, 2 operation failed. Human-readable output goes to stderr, the resulting path to stdout (so cd "$(dsh-task new …)" works).

Configuration

Resolution order for the workspace root: tool argument → config workspaceRoot → $DSH_TASK_WORKSPACE_ROOT → $DSH_WORKSPACE_ROOT → the session's workspace directory → $DSH_HOME. An explicit root is created when missing; node_modules/, /, the temp directory and $HOME itself are refused.

The config file lives at ${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 — every new task gets a repository right away.
  • promptEnabled: false / skillEnabled: false — keep the tools, drop the injected text.
  • template — path-free inline markdown template for PROGRESS.md.
  • gitAuthor — identity used for git -c user.name=… -c user.email=…, for machines with no global git identity ($DSH_TASK_GIT_NAME / $DSH_TASK_GIT_EMAIL also work).

A profile can override the same keys through its own patch layer:

- id: task-workspace
  name: 'dsh-task-workspace'
  config:
    workspaceRoot: /Users/me/notes
    defaultGit: true

When to create a repository

The convention's trigger is deliberately explicit — any one of:

  • more than ~3 turns expected,
  • must continue across sessions,
  • more than ~10 produced files,
  • the user asks for it.

Development

node test/run.mjs          # 47 checks: store, tools, real git, CLI, host JSON Schema subset, session reuse + session-cwd guards — no network
node test/run.mjs --keep   # keep the temporary workspace for inspection

License

MIT

Profiles owned by another application

dsh plugin --profile desktop add … refuses to run because the Electron app owns that profile. scripts/install-into-profile.sh does the two things that command would have done, and nothing else:

bash scripts/install-into-profile.sh desktop --dry-run   # show the plan
bash scripts/install-into-profile.sh desktop             # link + append to bundles

It links the package into <profile>/node_modules and appends the package name to dsh.profile.bundles, editing only that array in place so the rest of package.json stays byte-identical (the app rewrites that file itself). A package.json.bak is written before the first change. Restart the profile afterwards.

Runtime gotchas this plugin already handles

Both were only visible on a real boot, not in a stubbed unit test — worth knowing if you fork this plugin:

  • inject must hang off the exported value. cordis-plugin-loader normalizes module shapes with exports.default ?? exports, so a namespace-level inject export is dropped as soon as the module has a default export. A bare export const inject = […] next to export default apply gives you Error: cannot get property "systemPrompt" without inject. Attach it to the function: apply.inject = ['tools', 'systemPrompt'].
  • required is an object-level keyword. The host validates tool output schemas against its own JSON Schema subset (type/oneOf/properties/required/additionalProperties/items/enum/const plus annotations) and rejects required: true on a scalar property with JsonSchemaError: schema.properties.x.required is not supported on type "string". Put the list on the object: { type: 'object', required: ['dir'], properties: { dir: { type: 'string' } } }.