dsh-memory-archiver: DSH plugin for writing files in memory directory without approval

Introduction

DSH’s file sandbox only offers three levels: read-only / workspace-write / danger-full-access; it does not support adding another “writable root”. The approval policy is also limited to ask / never, with no allow-always. Therefore, the requirement of “allowing memory archiving without approval while other operations still trigger approval” cannot be expressed with existing configurations.

dsh-memory-archiver is a plugin written to fill this gap. Below is an introduction to its positioning, tools, installation, and configuration.

What is it

Maintained by imaused, imaused/dsh-memory-archiver adds four memory archiving tools to DSH: memory_archive, memory_index, memory_patch, and memory_supersede.

Its approach differs from conventional configuration schemes: the plugin writes files using its own code (using node:fs, not passing through ctx.fs), so it does not enter the file sandbox and does not trigger approval. At the same time, it validates the writable scope within allowedRoots, rejecting any requests outside the scope. Operations other than these four tools still use workspace-write + ask, still triggering approval.

Four Tools

Tool Purpose
memory_archive Writes a memory file (dir + file + content, defaulting to rejecting overwrites; backing up automatically before overwriting; UTF-8 without BOM)
memory_index Appends a line to an index file or inserts by anchor (preserving original BOM and line breaks; skipping duplicate lines)
memory_patch Replaces a segment of text in place (backing up automatically before replacement; requires a unique match, or explicit replaceAll)
memory_supersede Completes “write new file + mark old file status: superseded + backup” in one go, without deleting any files

Please note that this plugin lacks a delete tool; cleanup only happens on old backups within .backup/.

Installation

Installation commands are from the project README. The plugin needs to be built from source or pointed to a directory directly:

npm pack
dsh plugin --profile <profile> add file:<absolute path of the tgz>

You can also point directly to the source code directory:

dsh plugin --profile <profile> add file:<repo directory>

After installation, restart DSH and open a new session, as tools are bound at session creation. To uninstall:

dsh plugin --profile <profile> remove dsh-memory-archiver

Default Roots and Configuration

By default, only one root is allowed: ~/.dsh/memory (~ resolves to USERPROFILE / HOME). To add more roots, there are two ways.

Via environment variable, using system path separators (Windows uses ;, Unix-like uses :):

DSH_MEMORY_ROOTS=C:/work/memory;D:/notes/memory

Or override in the profile’s cordis.patch.yml by id:

- id: memory-archiver
  name: dsh-memory-archiver
  config:
    allowedRoots:
      - 'C:/Users/you/.dsh/memory'
      - 'D:/work/memory'

Priority is configuration > environment variable > default value.

Backup and Retention Policy

Before overwriting or in-place correction, the old file is automatically backed up to <memory_dir>/.backup/<original_name>.<timestamp>.md, and the return value will include an extra backup field. After writing backups, old ones are automatically cleaned up:

Config Key Default Description
backupRetentionDays 30 Delete backups older than N days; <= 0 disables time-based cleanup
backupMaxBytes 0 Upper limit on total size of backup directory (bytes); 0 means no limit, deleting from oldest when exceeded
- id: memory-archiver
  name: dsh-memory-archiver
  config:
    backupRetentionDays: 30
    backupMaxBytes: 52428800

Cleanup targets only .md backups in .backup/, not the memory content itself.

Typical Usage

Write a new memory file:

memory_archive(dir: ".dsh/memory", file: "projects/foo.md", content: "...")

By default, if the file exists, it is rejected. Use overwrite explicitly if overwriting is needed. Use memory_patch to correct a segment of text in the original file. The target text must have a unique match in the file, otherwise it is rejected; use replaceAll explicitly if you want to replace all.

When a new conclusion is reached on the same topic, use memory_supersede to write the new file, mark the old file as status: superseded, and backup in one go, without needing to delete the old file first. The old file marking will work with the companion plugin dsh-kb-lite to lower its weight in searches.

This plugin handles “write”, while dsh-kb-lite handles “read”: kb-lite indexes the same batch of memory roots and retrieves them with references. Both plugins can be used separately, but together they provide the complete “write + retrieve” functionality.

The project source code comes with validation scripts:

npm test          # node --test test/core.test.mjs, 16 items
node test/smoke.mjs

Scenarios and Notes

Suitable for developers already using DSH who wish to replace “model traversing sandbox” with “plugin direct write” for memory archiving: they need to maintain memory files without approval while strictly limiting the writable scope to the memory directory.

Two points need to be clarified. First, the plugin runs inside the DSH main process and is not constrained by the file sandbox—this is by DSH’s design, as the sandbox protects against the model rather than the plugin. This plugin narrows this capability to only writing .md files within allowedRoots, rejecting any out-of-bounds requests (including .., junctions, symlink escapes), without writing credentials, connecting to the network, or spawning child processes. Second, check the source code and license before installation (the project states MIT).

The value of dsh-memory-archiver lies in turning a requirement that couldn’t be expressed with configuration—“memory archiving without approval, everything else as usual”—into four tools with boundaries, backups, and no deletion capability. Directory page: https://www.skillhub.cn/plugins/imaused/dsh-memory-archiver , Source: https://github.com/imaused/dsh-memory-archiver .

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

Xiaoye