Preface

When running agents in DSH (DeepSeek Harness), many teams implement “memory” as a set of local Markdown / JSONL archives: diary logs, growth status, and event streams are saved to disk separately, and Python scripts handle cross-device merging. While these practices treat files as the source of truth with fixed formats, daily viewing, searching, cautious appending, or modifying a few lines often requires opening an editor directly or memorizing a bunch of script commands, which also fails to integrate with the Harness settings page.

The following is an introduction to the community plugin dsh-memory-board (Maintainer: S3K926, Category: Memory). It moves the same archive into a “Memory” panel on the DSH Web settings page: overview, search, append, and edit with guards and backups, without creating a database or changing the archive format. The repository GitHub is licensed under MIT; the community directory page can be found at skillhub.cn.

What is this

dsh-memory-board is a bundle plugin for DSH: the Host side registers /api/memory/* routes and parses the archive, while the Client side renders five segments in settings.section (id: memory, label: Memory, order: 120). The core promise is stated plainly in the README—the file is still the source of truth; recognizing the archive root relies solely on characteristic files (身份.md, 日记.md, 生长\状态.md must all be present). If it cannot recognize them, it stops or lets you manually fill in/select the location on the panel; it does not “scan the disk to guess the root.”

The plugin reads and writes to the configured archive directory with the permissions of the current DSH process; it is recommended to read through the repository source code and LICENSE before installation, and confirm that readOnly and the panel “Enable Write” switch meet your security expectations.

Core Features

Five-Segment Panel in Settings Page

Segment Function
Overview Four cards for Diary / Status / Growth Records / Event Stream (count, sequence, metadata, size, mtime); write switch; append one growth record line; new device bootstrap; sync area.
Diary Reverse chronological list, click to view original text (pre-wrap, no Markdown rendering); eight-line form for adding; permanent deletion requires typing #N exactly.
Status Section list and body viewing; modify only a specific section’s body (title line preserved); permanent deletion requires typing the section title exactly.
Event Stream Recent 30 / 100 / 300 entries, fields include ts / kind / source / id / topic / summary, read-only.
Search Keyword (space-separated tokens, all-match) read-only filtering of 记忆\事件流.jsonl, does not call 生长\记忆.py search.

The top bar always displays the archive root and read-only mode; missing fields show “(Unreadable)”, and errors display an error line instead of a blank screen.

Read/Write and Guards

Writing to disk uniformly goes through writeWithGuards: Fingerprint Rejection (refuses if modified externally) → Idempotent Skip (no write if content is identical) → Full Backup before modification → Write to temp file then rename → Read back verification. Backups are placed in <root>\归档-旧版本与记录\写入备份\; permanent deletion also involves archiving deleted content and a secondary panel confirmation (sequence number or section title must be typed exactly). 记忆\事件流.jsonl and 身份.md / 开场.md are read-only on the panel side; CRLF line endings and UTF-8 without BOM are preserved upon writing back.

Supported write operations include: appending growth record lines, six-segment diary appending (metadata and diary_version updated according to archive rules), editing status section bodies, permanent deletion of diary entries or status sections, and initializing a six-file skeleton in an empty directory (existing archives are always rejected, force is not exposed to routes).

Archive Root and Panel State

Archive root resolution priority (README updated 2026-09-25): Position selected on panel > Config root > Environment variable DSH_MEMORY_ROOT > Auto-recognition > Default $DSH_HOME/memory (~/.dsh if DSH_HOME is not set). Panel state is written to $DSH_HOME/memory-panel.json. The top of the settings page allows “Select location…”: prefers the DSH directory picker, otherwise manual path entry; if determined to be an existing archive, empty directory, or missing characteristic files, it respectively corresponds to claiming, bootstrapping, or only prompting which files are missing.

Cross-Device Sync

Merging still calls the original 合并记忆.py / 合并日记.py / 合并状态.py / 回流包.py in the archive; the plugin provides /sync/status, /sync/dryrun (without --apply), and /sync/merge (whitelisted scripts, write switch, confirm=yes, dry run first, confirmation box requires typing the script name exactly). 恢复.py, 备份.py, and 自主轮次.py are never allowed.

Installation and Activation

This plugin is a bundle. In package.json, dsh.bundle.patch points to cordis.patch.yml, inserting a line into the Loader entry table via the patch. The steps provided in the official README are as follows (no dsh plugin add github:... commands):

  1. Place the entire plugin directory into your local plugin directory, e.g., ~/.dsh/plugin-src/dsh-memory-board.
  2. Copy and edit the local config:
cp cordis.patch.example.yml cordis.patch.yml

Modify root and other items as needed in cordis.patch.yml (this file is already in .gitignore and not committed to the repository).

  1. Add dsh-memory-board to dsh.profile.bundles in the profile’s package.json (or install via your plugin management tool).
  2. Restart DSH, hard refresh the page → Settings → “Memory” should appear on the left side. The browser Console will show [memory-panel] Registered settings page "Memory"... and logs for each route registration.

package.json declares the engine requirement dsh >= 0.1.7-rc.2; the current plugin version is 1.3.0.

Configuration

Key Default Description
root None Archive root; can also rely on DSH_MEMORY_ROOT or $DSH_HOME/memory
readOnly true When true, write operations are unavailable on both Host and panel; to write, set to false and restart, then enable write on the panel
templatesDir None Template directory for new device bootstrap; also DSH_MEMORY_TEMPLATES or $DSH_HOME/memory-templates, otherwise uses plugin templates/basic
device 【New Device】 Default device label for bootstrap, replaces 【Device】 in the skeleton

Typical Usage

Read-only Browsing and Searching

After installation and pointing to an existing archive, view statistics for the four core files in “Overview”; switch the limit in “Event Stream”; perform keyword filtering on the event stream in “Search”. The write switch does not need to be opened throughout the process.

Appending Diary or Status After Enabling Write

  1. Set readOnly to false in cordis.patch.yml and restart DSH.
  2. Click “Enable Write” in the overview and confirm.
  3. Complete the form in the “Diary” or “Status” segment; write operations undergo API secondary confirmation (e.g., confirm=yes), and it is recommended to include the file fingerprint fp= you read to coordinate with the rejection logic.

The Host side route prefix is /api/memory/, e.g., GET /api/memory/diary, POST /api/memory/diary/append (requires write to be unlocked). For the complete route table, see the “Interface” section in the repository README.

New Device Bootstrap

In the overview or “Select location” flow, perform bootstrap on an empty directory: write 6 skeleton files with 【Placeholder】 (开场.md, 身份.md, 日记.md, 生长\状态.md, 生长\生长记录.md, 记忆\事件流.jsonl), and mark that this is a skeleton, not real memory. The target path must be filled in by you; the config root is not used by default to avoid mistakenly overwriting existing archives.

Check Dry Run Before Merging

In the sync area, select which=合并记忆|合并日记|合并状态|回流包, call the dry run interface to view the report first, then execute merge (real run with --apply, timeout 180 seconds) after the write switch is open and the script name is confirmed.

Local Self-Test

The repository provides module-level self-tests, which can be executed in the plugin directory:

node --check index.js
node --check client.js
node index.js --selftest
node index.js --selftest /path/to/your/archive
node index.js --selftest --keep

The exit code is 1 on failure.

Use Cases and Notes

Suitable for: Users already using (or planning to use) file-based local memory archives, who want to view and search uniformly in the DSH settings page, and perform small amounts of appending or editing under clear guards; cross-device sync still relies on Python merge scripts within the archive, simply triggering dry runs and merges on the panel.

Notes:

  • The plugin does not implement a second set of merge logic, nor does it move memory into a database; the format and numbering space fully obey existing file conventions.
  • Default is Read-only (config readOnly: true + panel write switch off) to avoid uninformed disk writes.
  • The running identity is the same as the DSH process; archive paths and memory-panel.json fall under the $DSH_HOME (default ~/.dsh) system; pay attention to environment variables in multi-instance or portable deployments.
  • The community directory skillhub.cn has no official affiliation with DeepSeek / High-Flyer; the DSH ecosystem emphasizes “Everything is a plugin”, so selection should be based on the repository README and source code.

Conclusion

dsh-memory-board connects “local memory archives” to the DSH settings page: reading, searching, guarded writing, and sync previews, while always acknowledging the files on disk as the source of truth. For installation details, API, and self-test commands, refer to the GitHub Repository README; for community entries, see the Plugin Directory Page.