Skip to content
dsh.fish
Bundle

@xiaozhugez/dsh-project-memory

Project-scoped AI memory: records pitfalls and user habits per project, injects them into future conversations

Source
xiaozhugez
stars
2 stars
License
MIT
Updated
Updated 4 days ago

Readme

# dsh-project-memory

[English](#english) | [中文](#中文)

---

<a id="english"></a>

## English

A [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) plugin that
lets the AI **learn from each project** — recording pitfalls and user coding
habits, then injecting them into future conversations so the AI gets smarter
the more you use it.

### What it does

When you hit a common error, show a coding habit, or explicitly ask the AI to
remember something, the AI calls the `memory_write` tool to save it. Every
future conversation in that project (or across all projects, for user-scoped
memories) automatically receives those memories as context, so the AI builds on
past lessons without being told again.

**Three contributions:**

| Contribution | Who uses it | What it does |
|---|---|---|
| `memory_write` tool | the AI model | Records a pitfall, habit, preference, or fact |
| `agent/pre-step` injection | automatic | Prepends all memories to every model request |
| `/memory` command | you (human) | View, add, edit, delete, and clear memories |

### Two scopes

- **User memory** (`user`) — applies to **all projects**. Lives in
  `<DSH_HOME>/memory.yaml` (`~/.dsh/memory.yaml` by default).
- **Project memory** (`project`) — applies to the **current project only**.
  Lives in `<projectRoot>/.dsh/memory.yaml`, where project root is the nearest
  `.git` ancestor directory.

Both scopes are human-editable (the YAML files are plain text) and can be
managed via the `/memory` command.

### Categories

Every memory has one of four categories:

| Category | Meaning | Example |
|---|---|---|
| `pitfall` | A common error and its fix | "on Windows, use `file://` URLs for ESM imports" |
| `habit` | A user coding convention | "all code comments in Chinese" |
| `preference` | A workflow choice | "run tests before pushing" |
| `fact` | Important project context | "this project requires Node >= 22" |

### The `/memory` command

```text
/memory                                     list all memories (user then project)
/memory list user                           list only user-scoped memories
/memory list project                        list only project-scoped memories
/memory add user habit: all comments in CN  add a user-scoped memory
/memory add project pitfall: never push main add a project-scoped memory
/memory edit 2 new content here             edit the memory at index #2
/memory delete 1                            delete by index (from /memory list)
/memory delete <id>                         delete by full UUID (searches both scopes)
/memory clear project                       clear all project memories
/memory clear                               clear all memories (both scopes)
```

Indices are continuous: user memories come first (#1..), then project memories.
The same index works for `edit` and `delete`.

### Install

#### From npm (recommended)

```sh
npx @deepseek-ai/dsh plugin --profile web add @xiaozhugez/dsh-project-memory
```

Prebuilt code — installs in one step, no build permission needed.

#### From GitHub

```sh
npx @deepseek-ai/dsh plugin --profile my-profile add github:xiaozhugez/dsh-project-memory
```

A git install fetches source and runs the `prepare` script (`tsdown`) to build
`lib/index.js`. pnpm ≥10 refuses to run a git dependency's build script until
it is explicitly allowed, so the first `add` fails. Copy the package key pnpm
prints into that profile's `pnpm-workspace.yaml`:

```yaml
allowBuilds:
  dsh-project-memory: true
```

Then re-run the `add` command. Treat this as permission to execute the
package's code on your machine at install time — only allow packages whose
source you trust, and pin a commit (`github:xiaozhugez/dsh-project-memory#<sha>`)
so a later push cannot silently change what runs.

#### From local directory

```sh
npx @deepseek-ai/dsh plugin --profile my-profile add ./project-memory-plugin
```

### Uninstall

```sh
npx @deepseek-ai/dsh plugin --profile web remove @xiaozhugez/dsh-project-memory
```

### Verify

```sh
npx @deepseek-ai/dsh --profile web --dump-config   # confirm project-memory is in the tree
npx @deepseek-ai/dsh web                             # start using it
```

### Config

Override via a profile or home patch above this bundle:

```yaml
- id: project-memory
  name: '@xiaozhugez/dsh-project-memory'
  config:
    memoryDir: .dsh      # directory under project root; default .dsh
    autoInject: true      # inject memories into model context; default true
```

### Manual editing

Both memory files are plain YAML and safe to edit directly:

- User: `~/.dsh/memory.yaml`
- Project: `<projectRoot>/.dsh/memory.yaml`

```yaml
memories:
  - id: some-uuid
    category: pitfall
    content: never commit directly to main
    createdAt: '2026-08-19T10:00:00.000Z'
```

The in-memory cache checks the file mtime on every read, so manual edits are
picked up on the next request within the same session — no restart needed.

### Development

This plugin is developed outside the `packages/` workspace as an independent
plugin, following the [Harness plugin development guide](https://deepseek-harness.github.io/deepseek-harness/develop/basic/).

Build the runtime artifact from source:

```sh
pnpm install   # runs prepare → tsdown → lib/index.js
pnpm build     # re-run the build alone
```

To test during development, run from the harness repo root with the dev overlay
(which mounts the TypeScript source directly through tsx):

```sh
pnpm dsh web --patch ./project-memory-plugin/cordis.yml
```

Then open `http://127.0.0.1:3080`. The plugin's `memory_write` tool and `/memory`
command are available in the session.

### Files

```
project-memory-plugin/
├── package.json           # dsh bundle manifest (dsh.bundle.patch) + deps
├── pnpm-workspace.yaml     # autoInstallPeers:false (dsh peers come from the host)
├── tsdown.config.ts        # standalone build: src/ → lib/index.js (no type-check)
├── cordis.patch.yml         # installable bundle patch (uses package name)
├── cordis.yml              # dev overlay (uses absolute source path)
├── src/
│   ├── index.ts            # three registrations: tool + command + pre-step
│   └── store.ts            # dual-scope storage, mtime cache, YAML persistence
└── tests/
    ├── command.spec.ts      # store layer: loadAllMemories/updateMemory/clearMemories/mtime
    └── dispatch.spec.ts     # command dispatch: list/add/edit/delete/clear
```

---

<a id="中文"></a>

## 中文

一个 [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) 插件,
让 AI **越用越懂你** —— 记录你踩过的坑和代码习惯,在以后的对话中自动注入,
让 AI 在同一个项目里越用越聪明。

### 功能介绍

当你遇到一个常见报错、展现出某种代码习惯,或明确要求 AI 记住某件事时,AI 会调用 `memory_write` 工具把它记下来。之后在该项目(或所有项目,取决于记忆范围)的每次对话中,这些记忆会自动作为上下文注入,AI 就能在过往经验上继续积累,而不必你反复说明。

**三个组成部分:**

| 组成 | 使用者 | 作用 |
|---|---|---|
| `memory_write` 工具 | AI 模型 | 记录一个踩坑、习惯、偏好或事实 |
| `agent/pre-step` 注入 | 自动触发 | 把所有记忆追加到每次模型请求 |
| `/memory` 命令 | 你(人类) | 查看、添加、编辑、删除、清空记忆 |

### 两种范围

- **用户级记忆**(`user`)—— 适用于**所有项目**。存储在
  `<DSH_HOME>/memory.yaml`(默认 `~/.dsh/memory.yaml`)。
- **项目级记忆**(`project`)—— 仅适用于**当前项目**。存储在
  `<项目根>/.dsh/memory.yaml`,项目根为最近一层含 `.git` 的目录。

两种范围都可以直接手动编辑(YAML 纯文本),也可以通过 `/memory` 命令管理。

### 记忆分类

每条记忆属于以下四类之一:

| 分类 | 含义 | 示例 |
|---|---|---|
| `pitfall` | 常见错误及其解决办法 | "Windows 上 ESM 导入要用 `file://` URL" |
| `habit` | 用户的代码习惯 | "所有代码注释用中文" |
| `preference` | 工作流偏好 | "推送前先跑测试" |
| `fact` | 重要的项目上下文 | "本项目要求 Node >= 22" |

### `/memory` 命令

```text
/memory                                     列出所有记忆(用户级在前,项目级在后)
/memory list user                           只列出用户级记忆
/memory list project                        只列出项目级记忆
/memory add user habit: 所有注释用中文        添加用户级记忆
/memory add project pitfall: 不要直接推 main  添加项目级记忆
/memory edit 2 新的内容                       编辑编号 #2 的记忆
/memory delete 1                            按编号删除(/memory list 显示的序号)
/memory delete <id>                         按 UUID 删除(两个范围都搜)
/memory clear project                       清空项目级记忆
/memory clear                               清空所有记忆(两个范围)
```

编号是连续的:用户级记忆排前面(#1..),项目级排后面。`edit` 和 `delete`
用的是同一套编号。

### 安装

#### 从 npm 安装(推荐)

```sh
npx @deepseek-ai/dsh plugin --profile web add @xiaozhugez/dsh-project-memory
```

已预构建,一步安装,无需构建授权。

#### 从 GitHub 安装

```sh
npx @deepseek-ai/dsh plugin --profile my-profile add github:xiaozhugez/dsh-project-memory
```

Git 安装会拉取源码并运行 `prepare` 脚本(`tsdown`)构建出 `lib/index.js`。
pnpm ≥10 要求显式授权才会运行 git 依赖的构建脚本,所以第一次 `add` 会失败。
把 pnpm 打印的包名填进该 profile 的 `pnpm-workspace.yaml`:

```yaml
allowBuilds:
  dsh-project-memory: true
```

然后重新运行 `add` 命令。请注意:这等于授权该包在你的机器上、安装时执行
它的代码。只对你信任其源码的包授权,并固定 commit
(`github:xiaozhugez/dsh-project-memory#<sha>`),防止后续推送悄悄改变执行内容。

#### 从本地目录安装

```sh
npx @deepseek-ai/dsh plugin --profile my-profile add ./project-memory-plugin
```

### 卸载

```sh
npx @deepseek-ai/dsh plugin --profile web remove @xiaozhugez/dsh-project-memory
```

### 验证

```sh
npx @deepseek-ai/dsh --profile web --dump-config   # 确认 project-memory 出现在配置树中
npx @deepseek-ai/dsh web                             # 启动使用
```

### 配置

通过 profile 或 home patch 在本 bundle 之上覆盖:

```yaml
- id: project-memory
  name: '@xiaozhugez/dsh-project-memory'
  config:
    memoryDir: .dsh      # 项目根下的存储目录;默认 .dsh
    autoInject: true      # 是否注入记忆到模型上下文;默认 true
```

### 手动编辑

两个记忆文件都是纯 YAML,可以直接编辑:

- 用户级:`~/.dsh/memory.yaml`
- 项目级:`<项目根>/.dsh/memory.yaml`

```yaml
memories:
  - id: some-uuid
    category: pitfall
    content: never commit directly to main
    createdAt: '2026-08-19T10:00:00.000Z'
```

内存缓存在每次读取时检查文件 mtime,所以手动编辑后**同一会话内的下一次请求**
就能生效 —— 无需重启。

### 开发

本插件在 `packages/` 工作区之外独立开发,遵循
[Harness 插件开发指南](https://deepseek-harness.github.io/deepseek-harness/develop/basic/)。

从源码构建运行时产物:

```sh
pnpm install   # 会自动运行 prepare → tsdown → lib/index.js
pnpm build     # 单独重新构建
```

开发时测试,在 harness 仓库根目录用 dev overlay 运行(通过 tsx 直接加载
TypeScript 源码):

```sh
pnpm dsh web --patch ./project-memory-plugin/cordis.yml
```

然后打开 `http://127.0.0.1:3080`。会话中即可使用 `memory_write` 工具和
`/memory` 命令。

### 文件结构

```
project-memory-plugin/
├── package.json           # dsh bundle 清单 (dsh.bundle.patch) + 依赖
├── pnpm-workspace.yaml     # autoInstallPeers:false(dsh peer 由宿主提供)
├── tsdown.config.ts        # 独立构建:src/ → lib/index.js(不做类型检查)
├── cordis.patch.yml         # 可安装的 bundle patch(用包名引用)
├── cordis.yml              # 开发 overlay(用源码绝对路径)
├── src/
│   ├── index.ts            # 三个注册点:工具 + 命令 + pre-step 注入
│   └── store.ts            # 双范围存储、mtime 缓存、YAML 持久化
└── tests/
    ├── command.spec.ts      # 存储层:loadAllMemories/updateMemory/clearMemories/mtime
    └── dispatch.spec.ts     # 命令分发:list/add/edit/delete/clear
```

Install

dsh plugin --profile web add github:xiaozhugez/dsh-project-memory

Profile: web

  • This package builds from source on install. pnpm will ask you to allow its build script — that is permission to run the package’s code on your machine, outside the agent sandbox. Only allow sources you trust.
  • This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.
Source