yindf/taskfold
Context folding for DeepSeek Harness (DSH): wrap work in named tasks, fold finished spans into short summaries, recall originals on demand.
Project Overview项目介绍
A context management plugin for DeepSeek Harness. It folds finished coding tasks into concise summaries, stores full original content for on-demand recall, reduces token usage and prevents context window overflow. Designed for long AI coding sessions. It does not auto-check DSH compatibility, and only degrades gracefully without data corruption on incompatible setups.
这是DeepSeek Harness的上下文管理插件,按任务折叠已完成工作,用短摘要替代完整对话记录,原始内容可随时调取,能降低Token消耗、避免上下文窗口占满。适用于长时AI编码会话,未自动检测DSH版本兼容性,不兼容时仅功能降级不会损坏数据。
请帮我了解并安装插件:【taskfold】【https://github.com/yindf/taskfold】
Send this message to DSH in your current session. CLI install commands may not be accurate across systems — DSH will figure it out for you.把上面这条消息直接发给当前会话里的 DSH,让它帮你了解并安装。安装命令不一定准确,发给 DSH 更稳。
Or use CLI install (for developers)或使用命令行安装(适合开发者)
CLI Install命令行安装
dsh plugin --profile web add dsh-taskfold
把 yindf/taskfold 加入你的 DSH 配置(web profile)即可启用。
READMEREADME
effectively infinite context for your coding agent
Keep long AI coding sessions fast, cheap, and readable: finished work is folded into a short summary, and the full original content is always one call away.
For DeepSeek Harness (DSH).
Quickstart
dsh plugin --profile <your-profile> add dsh-taskfold
Published on npm as dsh-taskfold — prebuilt, so it skips dsh's allowBuilds build approval. Straight from GitHub also works: add github:yindf/taskfold.
Restart dsh — every session on that profile gets the tools. The agent then wraps its work in named tasks:
task_begin("fix the login bug") … the work … task_end("fix the login bug")
and that whole span collapses into one titled summary, still readable back with fold_recall.
Why you want it
Long sessions drown in their own history: every request re-sends hours of finished work — old tool outputs, debug logs, abandoned attempts. Costs climb, the model gets distracted, and eventually the context window fills up.
taskfold fixes this the way a good notebook does. While working, the agent wraps each task with task_begin("fix the login bug"). When the task is done, task_end closes it and replaces the entire back-and-forth with a short titled summary:
Before: [800 messages of raw debugging…]
After: "fix the login bug" — summary: what was tried, what failed and why,
what changed, what the user decided. (~1 screen)
The conversation stays readable, every request gets cheaper, and the model keeps the lessons without dragging the transcript along.
Nothing is lost. Every fold saves the exact original messages to a file, and fold_recall({ fold: N }) can regenerate it at any time. Fold first, look later — like closing a book you can reopen.
How it relates to dsh's built-in compaction
Same goal, different moment — and they compose.
- dsh's built-in compaction is automatic and pressure-driven. It fires when the window is nearly full, picks a range by token pressure, and replaces it with a summary; the original events stay in the session log, shadowed rather than deleted.
- taskfold is explicit and task-scoped. You fold each finished task as you go, so the summary is written while its span is still in context — accurate by construction — and it is titled, so the session stays navigable.
- Because you fold early, the window rarely fills. In the measured session below the peak was 20.7% instead of 59.5%, so pressure compaction fires later, or not at all — and when it does fire, there is less left to summarize.
- Every fold is addressable.
fold_recall({ fold: N })returns the exact original messages, not a re-summary.
How it works (plain words)
- Named tasks. The agent opens a task before starting work and closes it when done. Open tasks survive restarts; closing is well-ordered (innermost first), and a failed close never corrupts anything — just retry.
- Folding = closing + summarizing in one call. The summary is written once, while the original span is still in context, so it's accurate — not a "summary of a summary".
- Summaries keep what matters. The summarizer is instructed to preserve user decisions and feedback (verbatim where wording matters), pitfalls and why things failed, what changed, and the outcome.
- Gentle guardrails. If the agent forgets the discipline, a short hint appears in its context. Hints are events, not state: one is published only when the condition appears or its wording changes, nothing is published once the condition clears (the model already complied and does not need to be told), and there is no wrapper, supersession header, or expiry notice — no noise when the flow is healthy.
- Cheap on the cache. Folding only rewrites a middle chunk of history; the stable prefix (system prompt, tools, earlier context) stays cache-friendly.
What it saves (measured)
One real session — 411 model steps, 26 folds — read from the harness's own usage records:
| Without folding | With taskfold | |
|---|---|---|
| Total prompt tokens | 142,654,308 | 52,127,098 (−63.5%) |
| Largest single request | 594,909 | 206,896 (−65%) |
| Context window used at peak | 59.5% | 20.7% |
The mechanism: folding moved 441,100 tokens of finished work off the surface. Because that history would otherwise be re-sent on every later request, it added up to 90,527,210 tokens never sent. Producing the 26 summaries cost 3,550,270 tokens (3.9% of the saving, and most of it cache reads); the biggest single fold took 40,422 tokens out of the conversation in one call.
Most of those tokens would have been cache reads rather than fresh input — cheaper, but still billed and still occupying the window. In longer sessions that is the difference between staying inside the context window and not.
One session, one task shape — your numbers will differ. The mechanism is the point: finished work leaves the surface, the stable prefix stays cached, and the model keeps the lessons instead of the transcript.
What it adds
Four agent tools (plus the reminders above):
| Tool | One-liner |
|---|---|
task_begin({ name }) |
Open a named task. |
task_end({ name }) |
Close it and fold its whole span into one titled summary. |
list_folds |
List all folds (number, size, title). |
fold_recall({ fold }) |
Bring back any fold's original content on demand. |
In the Web GUI, the current open-task stack also shows as a live dock above the composer (like the todo panel): outermost first, the innermost task highlighted, with the closing/pending counts — read straight from the session's taskMarks projection, no extra events.


Other ways to install
Every release attaches a prebuilt dsh-taskfold-<version>.tgz. Plugin storefronts offer that asset — or the npm package — instead of the build-from-source command, which also skips dsh's allowBuilds approval step — see the latest release.
Supported dsh versions
- alpha channel — supported through
0.1.5-alpha.2(verified 2026-09-10: the offline suite — 117 tests, all green; a host-API probe against the realdsh-compaction-basic/dsh-llm/dsh-sessionpackages — engine class export, thesummarizehook,BlockAssembler, the session surface/deriveEventMessageAPI, andScopedEngineconstruction through the plugin's own shim context; an end-to-end fold through the real engine and assembler — prefix-anchored envelope, fenced span index with true line numbers, span bytes untouched, archive footer; a seam audit of 25 runtime assertions confirmingagent/pre-step,agent/turn-stopping,sessionProjections.register/stateOf,systemPrompt.section/context,tools.register, and thedsh-compaction-basiccompaction discriminator all keep their shapes; and live folding on the running 0.1.5-alpha.2 host, where the mounted plugin copy is byte-identical to this repo's HEAD blobs. No code change was needed. The host-side API drift found in the previous round persists:dsh-sessionstill does not exportdecodeStorageRecord/packChunkRuns, which this plugin never uses — it imports onlydsh-compaction-basicanddsh-llm— so the offline region-transaction replay that relied on them stays out of the verification chain; the live fold covers that path instead). - rc channel — supported through
0.1.5-rc.2(verified 2026-09-11 on 0.34.1: the offline suite — 162 tests, all green; a byte-level seam audit of all 240 first-party@deepseek-aipackages between0.1.5-rc.1and0.1.5-rc.2— 231 differ only in theirpackage.jsonversion fields, 7 change implementation files (the message-feedback group:dsh-client-ui-message-feedback,dsh-message-feedback,dsh-command-feedback,dsh-client-ui-chat,dsh-client-ui-deliverables,dsh-client-ui-sidebar, plus thedsh-web-frontendshell), no package is added or removed, and the two this plugin imports —dsh-compaction-basicanddsh-llm— are byte-identical in implementation; a host-API probe against the real rc.2 packages — engine class export, itssummarizeprototype, subclassing, andBlockAssemblerwithpush/blocks; a client-contract sweep across both builds —conversation.input.dock,useProjection,__ModuleLoader__, andslots.injectall identical, with the dock's ownerdsh-client-ui-conversation, the reference consumerdsh-client-ui-goal, and the bundle registrydsh-client-modulesbyte-identical; and live folding on the running 0.1.5-rc.2 host, where the mounted plugin copy is byte-identical to this repo's v0.34.0 tag blobs — 1/1 fold passesverify-cache --since-restart(98.6% prefix-cache hit). No code change was needed; the record it supersedes —0.1.5-rc.1— stood as written).dsh,dsh-compaction-basic, anddsh-llmship version-locked, so one number covers the whole surface. - Upper bound: untested, not enforced. dsh does not yet expose host-version negotiation to plugins, so nothing rejects an incompatible host automatically — on an incompatible dsh, folds degrade (tasks still close, unfolded) rather than corrupt. After each dsh upgrade, re-check this section and update it with test results.
- Optional hook:
agent/turn-stopping— since 0.26.0 the archive drain also runs at turn end, folding turn-final deliverables while the provider prefix cache is still hot. Hosts without the hook simply keep the previous pre-step-only semantics (folds still happen, one turn later); the registration is wrapped so its absence never breaksapply().
For maintainers
- Layout:
plugins/(the two mounted rowscompact-region.mjsandcompact-stats.mjs, plus the shared plain modules they import —events.mjs,task-marks.mjs,fold-instruction.mjs,fold-engine.mjs,fold-drain.mjs,lifecycle-nudges.mjs,lifecycle-injection.mjs,span-preview.mjs, plus the browser half:task-stack-ui.mjs— the dock's source of truth, generated intotaskfold-client.mjsbyscripts/build-client.mjs),scripts/release.mjs,scripts/verify-cache.mjsandscripts/build-client.mjs,test/(npm test),assets/(README banner, the social-preview image to upload in repo settings, and the store screenshots listed inscreenshots.json),docs/(docs/README.mdindex plus thedocs/design/notes anddocs/adr/decisions — deliberately kept out of the npm package),CHANGELOG.md. - Releasing:
node scripts/release.mjs draft→ review the CHANGELOG entry →node scripts/release.mjs release(CHANGELOG is the single source of truth for versions). If this release changes which dsh versions are supported, update the "Supported dsh versions" section in both READMEs before releasing — the release script reminds you. Keep that section to one line per channel: the newest verifiedalpha, then the newest verifiedrc; delete historical alpha/rc entries instead of listing them. - Fold cache verification is part of the flow. After every dsh upgrade — and before any release that touches the fold envelope — run
node scripts/verify-cache.mjs --since-restartagainst a live session log, and record the numbers in the CHANGELOG entry. It exits non-zero when a fold's summarizer call re-pays its span — the test isuncached − span > --tail-budget, i.e. a positive tail, which is the signature of the prefix envelope no longer matching the host's summarization input. The offline suite pins the structural precondition (one system message, strict prefix); only a live log can show the actual cache read. - Design decisions and history live in
CHANGELOG.mdand indocs/(docs/README.mdis the index; thedocs/design/notes anddocs/adr/decisions ship with the repo, not with the npm package).
If this saves you tokens
A star helps other dsh users find it — in this ecosystem, that is how a plugin gets discovered. Numbers from your own sessions are welcome in Discussions.
License
MIT. Developed against the DeepSeek Harness (@deepseek-ai/*, MIT) public packages.
MemTensor/MemOS
vshulcz/deja-vu
adoresever/graph-memory
mnemon-dev/mnemon
modusensus/dsh-mneme
Phant0Meow/dsh-meow-memory