DeepSeek Harness 插件

plugin

给 DeepSeek Harness 的长期记忆,以纯 markdown 保存:一条事实一个文件,任何编辑器都能打开。索引 `MEMORY.md` 有 200 行 / 25KB 的硬上限,由 `ctx.tools.guard()` 强制执行——让已超限的索引继续变大的写入会被拒绝,而缩小它的重写一律放行,于是过大的索引可以一步步压缩下来。插件不会自行写入记忆,记什么由你和模型决定。同一个记忆库也被 Claude Code、Codex、Kiro、OpenClaw 使用。

跳到安装方式

来源信息

GitHub 仓库
tinqiao-oss/engramory
最近更新
2026年8月16日
分类
记忆
GitHub stars
160

安装

默认先复制一段 Prompt,让 Agent 读页面和仓库;需要自己装时再切到命令。

复制这段 Prompt,发给 DSH、Codex 或其他 Agent,让它先读页面和仓库。

请先不要安装。阅读这个 DeepSeek Harness 插件,说明它解决什么问题、会访问哪些文件、网络或密钥,以及如何安装和卸载。

插件页面:https://deepseekplugins.org/zh/plugins/tinqiao-oss/engramory~23plugin
GitHub:https://github.com/tinqiao-oss/engramory/tree/master/adapters/dsh/plugin
插件名:engramory#plugin
作者:tinqiao-oss
安装命令:dsh plugin --profile web add dsh-engramory

确认前不要执行安装命令。

检查来源文件

安装前先看这个插件目录里的 README 和其他文件。

文件资源管理器3 个文件
README.md来源说明 · 只读预览

[English](README.md) | [简体中文](README.zh-CN.md)

dsh-engramory

![dsh-xray](https://unstone.github.io/dsh-xray/registry.html#tinqiao-oss__engramory)

<sub>C2 is the level manifest.bundle.patch puts every mountable dsh plugin at (74.6% of the scanned ecosystem); it is the only flag on this card — no exec, eval, install script, outbound domain, or environment read.</sub>

Curated, file-based long-term memory for DeepSeek Harness — plain markdown notes you can open with anything, one store shared across every host you use, and an index cap that is a real refusal rather than a request. (If the store lives inside a project's git repo it must be git-ignored — memories carry machine-local detail; see SKILL.md §1. A dedicated private repo for the store itself is fine.)

Part of Engramory.

Why a plugin, when an AGENTS.md block already works

The block does carry the discipline, and for recall that is enough. Two things it cannot do:

The cap becomes deterministic. Engramory keeps its index under 200 lines / 25 KB because the index loads every session and everything past the cap silently stops being recalled. On most hosts that limit is rules plus a checker the agent has to remember to run. dsh exposes ctx.tools.guard() — a synchronous, monotonic refusal: once a guard returns a reason, no later listener can turn it back into an allow. So here the limit is enforced, not requested. Use 0.2.1 or later: 0.2.0 shipped before profile installs worked upstream and carried an inject declaration this Cordis does not accept — it installed but never activated (issue #8). Outside Claude Code, dsh is the first host with the shim actually written (a few others expose equivalent pre-write seams — see PORTING.md — but have no shim yet).

The protocol arrives with the plugin. The skill is registered at runtime through dsh's skill registry — via a reactive ctx.inject(['skills'], …) child, so a profile without a registry still gets the cap and one whose registry activates late still gets the skill — which means it does not depend on landing files in one of the five skill roots dsh scans, a path that is easy to get subtly wrong and fails silently when you do.

Install

dsh plugin --profile <name> add dsh-engramory

That is the whole install. The package ships a dsh.bundle manifest pointing at its own cordis.patch.yml, so the row is inserted into the profile's plugin tree for you — no hand-editing. To change a default, patch the EXISTING row by id in your profile's own patch layer — do not use a second - insert: (insert always appends, so you would end up with two engramory rows and the original caps still enforced):

- id: engramory
  config:
    indexName: MEMORY.md
    maxLines: 200
    maxBytes: 25600

A patch replaces the targeted row's whole config, so list every key you mean to keep.

For the store itself and the always-on block, use the installer in the Engramory repo (python tools/engramory_init.py dsh --install-skill). This plugin enforces the cap and supplies the protocol; it does not create the store.

Configuration

FieldDefaultMeaning
indexNameMEMORY.mdBasename treated as the memory index (case-insensitive; both file_path and str_replace_editor's path are checked). An empty or non-string value falls back to the default. Nothing else is inspected.
maxLines200Hard line cap. Non-positive or non-finite values fall back to the default.
maxBytes25600Hard UTF-8 byte cap (25 KB).
indexPathunsetAbsolute path of the ONE index to guard. Without it the guard matches on basename alone, so an unrelated MEMORY.md in another project is gated too; set this and only that exact file is. Compared by identity (symlinks and .. resolved; case-folded on Windows only), and a path that does not exist yet still has its first write guarded.
registerSkilltrueSet false to keep the cap but skip the runtime skill.
skillbuilt-inReplace the skill body with your own markdown.

What the guard actually does

CallDecision
write (or str_replace_editor create) ending within capsallow
write/create that GROWS the index past a capdeny, naming the numbers and what to compact
write/create that SHRINKS or keeps an over-cap indexallow — incremental compaction (210 → 205 → 198) must stay possible
Edit carrying old_str/new_str: result simulatedjudged by the RESULT, same grow/shrink rule as a write
Unsimulable partial (e.g. insert) on an over-cap indexdeny, telling the agent a shrinking whole-file write passes
Unsimulable partial on a healthy indexallow
read, view, or any unknown toolallow — recall must never be blocked, even over cap
Any write to any other fileallow — not the guard's business
Missing/unreadable current index on a whole-file writetreated as EMPTY (mirrors the Python guard) — a within-caps write passes, an over-cap first write is refused
Missing/unreadable index on a partial editallow — a guard must never block work over a path it cannot read
Malformed execution (no arguments, non-string path/content)allow — not recognisably a write

The deny rule mirrors hooks/engramory_index_guard.py exactly: refuse only a result that is over a cap AND grew past the current file. The line count ignores a trailing newline, so an index sitting exactly at the cap stays writable.

Known limits

  • An unsimulable partial that crosses the cap from under it is not caught. insert

and friends do not carry the resulting text. The breach is caught by the next whole-file write, or by engramory_check.py. What is guaranteed: an already-over index cannot be grown further, and a shrinking write always passes.

  • The tool roster follows dsh's documented tool-fs contract (write/edit with

file_path, str_replace_editor with path) and is deliberately conservative: unknown tools pass.

  • 0.2.0 never activated; 0.2.1 is the first version that runs. While the rc.6

preview bug blocked all third-party profile installs upstream, the only coverage a plugin could have was mocks — and 0.2.0's mock hid two activation bugs: an older-Cordis { required, optional } inject shape (read as waiting for services literally named required/optional, pending forever) and a bare ctx.skills read of an undeclared service (throws under Cordis' reflective context). The first field install caught both the moment installs became possible (issue #8). 0.2.1 fixes them, verified end to end on a live dsh 0.1.0-rc.7 web profile (0.2.0 reproduces the boot failure byte for byte; 0.2.1 boots and serves) and against the vendored @deepseek-ai/cordis resolver (activation with, without, and with a late-mounted skill registry). The test mock now mirrors the reflective-context access rules, and the guard's decision table stays covered by node --test (28 cases, run in Engramory's CI).

  • dsh is a developer preview and its plugin API can change. This plugin deliberately

touches only ctx.tools.guard() and a reactive ctx.inject(['skills'], …) child that registers the skill, so it stays cheap to fix.

License

MIT — see the Engramory repository.