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.

Global Todo — DSH Plugin for DeepSeek Harness
DeepSeek Harness Plugin Hub
ProfilesPluginsCategoriesNewsDocsSign inManage Profiles
ProfilesPluginsCategoriesNewsDocsSign in
← Plugins
G

dsh-global-todo

Global Todo

Global, cross-session todos for DeepSeek Harness: one list owned by the human and the agent together, with creation time, attached documents and links, and one-click hand-off to an agent session. 全局待办:跨会话一份清单,记录加入时间,可挂文档与地址,可一键交给 Agent 继续干。

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

npx -y @deepseek-ai/dsh plugin --profile web add github:LUgABeEEE/dsh-global-todo#ec275821c7c6124fd8eedd33e51f5c8965eb87d8
READMECompatibilityVersions
The panel: count chips, grouped list, urgent rows markedOne row opened: inline editing, attachments with 打开 / 复制路径, activity

Compatibility and provenance

Global Todo is published as dsh-global-todo and currently resolves to version 0.2.0. The Hub verifies its manifest and preserves the exact installation source for reproducible installs.

DSH compatibility
*
Runtime surfaces
web
Release source
github
Registry updated
10/14/2026

Versions

0.2.0stable
10/14/2026

Related plugins

Loading related plugins…

Latest
0.2.0
DSH
*
HMR
Process restart
Tree shaking
Safe tree shaking not declared
Unpacked size
Unavailable
Files
Unavailable
Surface
web
License
MIT
Source
github
GitHub
★ 0
Weekly downloads
0
Last push
10/16/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

Related plugins

More verified plugins in productivity-workflow.

Acp App@deepseek-ai/dsh-acp-appThe dsh ACP profile bundle: automation-only JSON-RPC stdio and process lifecycle over dsh-baseExperimental Schedule Bundle@deepseek-ai/dsh-experimental-schedule-bundleOptional bundle that adds Schedule, its task page, and time context to the Web compositionAb Ocrdsh-ab-ocr--- description: "The out-of-tree ocr tool: recognizes a scanned PDF or image page by page, merges the pages in order only after the last one, and saves one Markdown document with the heading levels the model decided." kind: "package-reference" ---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 包。

README

dsh-global-todo

One todo list for the whole DeepSeek Harness, owned by you and written by your agent too.

Every entry records when it was added, carries a description, can attach any number of documents and addresses, and can be handed to an agent session with one click — so "continue this" is a button, not a paragraph of context you retype.

中文说明


Why another todo plugin

DSH's built-in todo_write belongs to one agent session: whole-list replacement, three states, and a plan that disappears when the session does. The community plugins that fix that split into two camps — the ones that dispatch work to agents (auto-resume, bound sessions) and the ones that accept real document attachments. This plugin does both, on one record:

built-in todo_writedsh-global-todo
Ownerone agent sessionyou — across sessions and workspaces
Writingwhole-list replacementper-field, human and agent
When it was addednot trackedcreatedAt, immutable, shown everywhere
Contexttitle + statedescription + documents and addresses
Hand-off—one click: reuse the bound conversation or open a session
Storagesession event logone JSON file you can cat, edit, diff and back up

Screenshots

The panel: count chips, grouped list, urgent rows marked

One row opened: inline editing, attachments with 打开 / 复制路径, activity

Both are produced by npm run preview, which renders the real client half to static HTML with no Host and no dependencies.

Requirements

  • DeepSeek Harness 0.2.x (developed and verified against 0.2.0-rc.2)
  • Node.js >= 22.19.0 (the Web profile's own requirement)
  • No runtime dependencies. Nothing is imported from @deepseek-ai/*.

Install

# from npm
dsh plugin --profile web add dsh-global-todo

# or from a checkout, which is also the development path
dsh plugin --profile web add /absolute/path/to/dsh-global-todo

The plugin is a Loader row, not a hot-loaded script: restart the host (dsh web) after installing, then refresh the page. A "待办 / Todos" entry appears in the sidebar.

To roll back:

dsh plugin --profile web remove dsh-global-todo

Your list is not touched by install or uninstall: it lives outside the plugin, at $DSH_HOME/global-todo/todos.json.

Using it

The panel

  • Add — type a title and press Enter. "More fields" reveals the description, the attachment box (one document path or URL per line), tags, priority and a due time.
  • Filters — all / open / doing / done / overdue, plus a text search across titles, descriptions, tags and attachments. The count chips in the header are filters too.
  • Grouped by urgency — overdue / today / next up / later / no due date / done, each collapsible, because "what is late" is the first question a list has to answer.
  • Rows — show added <time> (<age>) with the exact timestamp on hover, the priority, the due time, the tags, the attachment count, and which side created the entry.
  • Details — edit title, description, priority and due time inline; attach or detach documents and addresses (with 打开 / 复制路径 on each); read the activity trail.
  • Undo a delete — deleting keeps the record for eight seconds and offers 撤销, which restores it verbatim: same id, same creation time, same attachments.
  • Keyboard — / focuses search, n focuses the new-todo field, Esc collapses the open detail. Row actions appear on hover or keyboard focus.
  • Reachable from the LAN and from a tunnel — the routes defer to the Host's connection fence (which honours --trusted-host); the plugin's own loopback check is only the fallback for a Host without that service. /health reports fence so you can see which one is in force.
  • Auto-collect (off by default) — a panel switch. When on, a conversation you are in that finishes a clean turn is asked once whether anything needs following up, at most once every 30 minutes, and only if you are actually in that conversation (never a dispatch target, a subagent or a background run). Aborted and failed turns are skipped, and the cooldown is booked before the question is asked so a repeated event cannot become a loop. The switch is Host state, so it survives the panel being closed and is reported by /health.
  • Collect per conversation — the Collect action sits on each conversation's group header in the list, asks that conversation to record what needs following up, and the items land under it. The toolbar keeps a "collect from this chat" fallback, shown only when the current conversation has no group yet. A conversation that is not running is resumed first, like a hand-off.
  • Batch assignment — switch on 选择, tick a few todos, and one click sends each one to the conversation that wrote it, else to a same-workspace conversation, else to a target you pick. That is an attempt order: an unloadable target means the next one is tried. Anything with nowhere to go comes back with a picker rather than being sent somewhere unchosen, and one failure does not abort the batch.

Agent tools

ToolPurpose
global_todo_addRecord an item — description, attachments, tags, priority, due time
global_todo_noteAppend a progress note — where you are, what blocks you, who must decide
global_todo_captureRecord a batch: for 「抓一下待办」 or a turn that produced several follow-ups; each entry is validated on its own
global_todo_listQuery by state, tag or text; every row carries its creation time
global_todo_getRead one item in full, including attachments and the last hand-off
global_todo_updateChange any field of one item; "" clears, [] empties
global_todo_linkAttach or detach documents and addresses
global_todo_doneMark done, back to open, or in progress
global_todo_removeDelete permanently (done items should be marked, not deleted)

Live check

The test suite uses doubles; npm run check:live checks the wired Host instead — the routes the panel actually calls, the list it actually reads, and a record that survives delete-then-undo. It creates a temporary record, compares every field after the round trip (id, creation time, attachments, tags, level, due time, description), asserts that bound records carry sessionAlive/sessionDir, and removes its temporary record even when it fails. It needs a running Host, so it is not part of verify.

Proactive capture

A guidance section is injected into the system prompt (turn it off with guidance: false). It states both sides of the policy, because a prompt that only says "remember things" produces noise, and a noisy list is worse than an empty one:

  • record on your own initiative when the user mentions something that needs following up across sessions (waiting on a reply, due next week, a decision pending, a promise), when a turn ends with a step that should not continue in that session, or when the user says 「记一下 / 别忘了 / 回头办」;
  • do not record what you can finish in this step, the session's own plan, or small talk;
  • say in one line what you recorded — do not restate the description;
  • say 「抓一下待办」 and the agent scans the recent conversation, records the batch with global_todo_capture and answers with a summary.

The boundary: it records, it never starts work. The list belongs to the human, and starting a task stays a human decision (see the non-goals in ROADMAP).

HTTP API

The panel talks to the host over these routes. They are fenced by the host connection fence when that service is present, and by a strict loopback check otherwise.

MethodPathBody / query
GET/api/global-todo/liststatus, query, tag, sort, limit
GET/api/global-todo/getid
POST/api/global-todo/capture{ sessionId? } — ask the current conversation to collect its follow-ups
GET/api/global-todo/health— (store location, counts, dispatch capabilities, plus tool registration and whether the completion watcher attached — both fail quietly, so both are reported)
POST/api/global-todo/create{ title, description?, links?, tags?, priority?, dueAt? }
POST/api/global-todo/update{ id, ...fields }
POST/api/global-todo/status{ id, status }
POST/api/global-todo/remove{ id }
POST/api/global-todo/restore{ todo } — put a removed record back verbatim (undo)
POST/api/global-todo/link{ id, add?: [...], remove?: [value | index] }
POST/api/global-todo/dispatch{ id, mode?: auto|bound|new|current, sessionId?, dir? }

Errors are typed: 400 for a rejected value, 404 for an unknown id, 413 for an oversized body, 403 for a request that fails the fence, 502 when a hand-off cannot reach the agents service. The body is always { ok, ... } with a machine reason.

Where the data lives

$DSH_HOME/global-todo/todos.json, or any absolute path you set:

# the profile's cordis.patch.yml
- id: global-todo
  config:
    storePath: /home/me/notes/global-todos.json   # a synced or versioned folder
    dispatchDir: /home/me/projects/thing          # default cwd for a new session
    requireExistingFiles: true                    # refuse a document that is not there yet

The file is the artifact: plain JSON, one record per todo, written through a temp file and rename(), with a write lock that serializes the human's and the agent's edits. A damaged file is reported (store-corrupt) rather than silently reset, and a single mangled record is skipped instead of taking the list down. Back it up by copying it.

Design decisions

Attachments are references, not uploads. A document is an absolute path that stays where it is; an address is a URL. Nothing is copied into plugin storage, so a document stays editable and diffable, the list stays small, and a dispatched agent opens the very same path with its own tools. URLs carrying credentials are refused, because the list, the audit trail and every prompt would otherwise keep a copy of the secret.

Creation time is first-class. createdAt is set once and never rewritten. The panel shows it, the tools return it as both epoch and ISO, and the dispatch prompt includes it, because "when did this land on my plate" is half of what a global todo is for.

One write path. The panel and the tools both call the same service functions, so a validation rule, an audit entry or the write lock cannot exist on one side only.

A failed hand-off is louder than a successful one. Success and failure are both recorded on the todo, and the panel shows the failure with its reason. A dispatch that silently did nothing is worse than one that never happened.

Optional services degrade, they do not crash. webServer, tools, agents, agentPresets, workspaceRegistry and agentDefaultModel are all reached through ctx.inject or a guarded ctx.get. A lean composition loses exactly that surface.

See docs/DESIGN.md for the data model and the rejected alternatives, and docs/ROADMAP.md for what could come next.

Development

npm run check     # parse every file, assert the shipping shape, and — when a DSH
                  # profile is present — validate every tool schema against the
                  # Host's own validator
npm test          # 100+ unit, contract and bundle tests, zero dependencies
npm run verify    # both

There is no build step. The host half is plain ESM under lib/; the client half is a classic script that registers itself with window.__ModuleLoader__, so no bundler, TypeScript toolchain or CI artifact is involved. lib/client.js edits take effect on a page refresh; host-half edits need a host restart.

npm run preview   # render the panel to preview/panel.html (+ a detail variant)
lib/
  index.js     host entry: store + service + dispatcher + the three surfaces
  store.js     one JSON file: atomic writes, serialized updates, tolerant loads
  model.js     the todo entity: validation, patches, status, attachments, activity
  links.js     attachment rules (pure: no filesystem access)
  service.js   the single write path, filters and sorting
  routes.js    the HTTP surface for the panel
  tools.js     the seven agent tools
  dispatch.js  handing a todo to an agent session
  errors.js    typed failures with stable machine codes
  client.js    the browser half (panel + sidebar entry)
test/          unit, service, tool, route, dispatch, bundle and manifest tests
tools/         preview.mjs — render the panel to static HTML without a Host
docs/          DESIGN.md (data model and rejected alternatives), ROADMAP.md

Contributions are welcome — read CONTRIBUTING.md first.

Security

The HTTP surface is local-only, the list is a local file, and no credential is ever stored. Please report vulnerabilities as described in SECURITY.md.

License

MIT © 2026 LUgABeEEE

  • Search syntax — tag:release (or #ops), is:overdue, is:active, has:link, has:note, level:p0, plus free words combined with AND (which also match note text). A search without a colon behaves exactly as it always did.
  • Progress notes — an append-only trail per todo (count on the row, full text and an add box in the detail). An agent reporting a blocker writes here instead of rewriting your description, and writing one makes automatic completion stand down.
  • Dead attachments are flagged — a file link whose target is gone is marked on the row and labelled in the detail. Computed on read, never stored.
  • Where a new conversation goes — a hand-off that opens one joins the workspace owning the conversation that wrote the todo (and starts in that workspace's directory), so "continue this work" does not land beside unrelated sessions. The picker also lists the workspaces (+ new conversation · <workspace>), and a named workspace wins over the inherited one. The working directory only decides when neither is known.
  • The picker lists what you actually use, newest first, without archived conversations. The order is the sidebar's recency key (updatedAt). Conversations sharing a title get a short id suffix, and a target that is no longer listed (archived since it was chosen) is shown as (archived) instead of appearing as a different conversation.
  • You pick the target — the toolbar shows 交给:[ conversation ▾ ], listing your conversations: whichever you choose is sent with authoritative: true and the Host honours it verbatim, with no inference on top. The list marks the conversation the Host would have chosen on its own, 自动 restores that behaviour, and + a new conversation starts a fresh context. A choice is remembered, and changing it is one click in the same control — what you see is what happens.
  • A receipt for every hand-off — the panel says which conversation received the work and offers to open it. A dispatch starts work elsewhere, so staying silent looked exactly like "nothing happened".
  • Hand to agent — the panel says where it will go before you press it, and the default is current: the conversation you last wrote in (read from the session log, keeping only source.kind === 'user' messages — the plugin's own injected hand-off messages are excluded, or each dispatch would drag the next one to its own target; the id is also kept next to the data so a restart does not forget it). auto prefers the conversation this todo already owns, then the current one, and only then opens a fresh session; new always opens one; bound insists on the bound conversation and says why if it is gone. When nothing usable can be resolved the hand-off fails with a reason instead of quietly opening another conversation.
  • Grouping — the toolbar offers conversation / time / level and defaults to conversation: everything one agent conversation submitted collapses into a single entry that says how many it holds, so a few 「抓一下待办」 runs do not turn the list into a wall of rows. A conversation with one item shows that row directly; items with no source conversation (added in the panel) sit under 手动添加. time is the original overdue / today / soon / later / no-due buckets, level groups by priority.
  • Levels P0–P3 — P0 urgent / P1 high / P2 normal (default) / P3 low, with a badge on the row. Records written before levels existed keep their high/normal/low, so nothing needed a migration. A conversation group shows the highest level it holds, and a green dot marks a group with a conversation still running.
  • Collect from this chat — one button injects "record what this conversation needs to follow up, with global_todo_capture" into the conversation you are in, so a chat turns into todos without typing them out. The prompt states what not to record as well (session plans, small talk, finished work) — a capture instruction without that ceiling only produces noise.
  • Automatic completion — when a handed-off session closes its turn cleanly, the Host finishes the todo itself: the agent's closing message becomes the summary and the files that turn touched become the artifacts. No waiting for the model to remember a tool call. A finished row shows 完成于 … plus artifact chips, and its detail carries a completion section you can open or copy paths from. Two guards matter: only a session this plugin just dispatched to can complete itself (idle chatter in a bound conversation must not finish work), and a turn that failed or was interrupted is never marked done — an open todo is far better than a failed job wearing a "done" label. global_todo_done with summary and artifacts remains the primary path; the watcher is the safety net.
  • Working directory — the toolbar says where a new session will start. It follows the conversation you are in by default; 选择 picks one explicitly and remembers it, and 跟随当前会话 clears that choice. A todo also remembers the directory it was written from (taken from the tool call's own context), and that is inherited too. With none of the three available, the hand-off is refused with a reason — a session without a working directory is a session where the agent can do nothing.