PerryLink/dsh-github
PerryLink/dsh-github官方级 GitHub CI 集成:composite action.yml、轮询 PR 评审机器人(幂等行内评论 + status-check 门禁)以及 PR/issue 工具,所有写入走人工审批门。
/backstory 命令与工具:为每一行标注最后改动它的 git 提交,以及写下它的 agent 轮次与提示词;数据取自按行持久化的账本(以内容哈希防漂移)、DSH-* 提交尾注或实时会话日志。
English · 中文
给任意一行代码问一句它的来龙去脉——它做什么,以及为什么在这儿。
一个 DeepSeek Harness(dsh)插件。
git blame 告诉你一行是谁、什么时候写的;dsh-backstory 补上真正重要的那部分——
面对陌生代码时你想知道的:它做什么、为什么存在——依据是最后改动它的那次提交,
外加 agent 自己的历史:哪一轮写了这行,以及触发它的那句 prompt。
L1 · a5d49e9 … 🧬t14
export const greeting_de = "Willkommen"
🧬 origin · turn 14 — you asked: "支持德语双语" [ledger-hash]
git blame → 谁 / 何时 / 哪次提交。dsh-backstory → 这行做什么 + 为什么在这儿,一处给全。git blame 永远给不了的 dsh 原生溯源——
哪一轮写的、你当时说了什么——精确到每一行(🧬t14)也精确到文件。每一行按"哪个来源最精确"依次归属:
[ledger-hash])—— 每次 write/edit 都被记录到仓库内提交的
.dsh/backstory.jsonl,带上被改动行的内容哈希。按文本匹配,所以一行在文件里
上下移动(行号漂移)也照样命中。跨 session、跨机器、跨人持久保留。[commit])—— 一旦带着 DSH-Turn / DSH-Prompt trailer 提交,
git blame → sha → trailer 就能还原溯源,而且漂移由 git 自己处理。[session])—— 当前 session 里、东西还没落进 ledger 之前,
从 exec.agent.session.events 重建。三层都会优雅降级:没有 ledger、没有 trailer、甚至没有 git,你依然能拿回源码行。
同一套引擎,两种用法。
无需 DeepSeek Harness。把客户端指向 backstory-mcp 二进制即可,它通过 stdio 走
Model Context Protocol,暴露 backstory 和 backstory_remember 两个工具。Claude Code:
claude mcp add backstory -- npx -y dsh-backstory
或直接写进任意客户端的 MCP 配置:
{
"mcpServers": {
"backstory": { "command": "npx", "args": ["-y", "dsh-backstory"] }
}
}
在你想查询历史的那个仓库目录下运行 —— 服务器会相对于工作目录读取 git 和 .dsh/
账本。独立服务器用的是 git 原生溯源(commit trailer + 已提交的账本);实时的「按 turn」
会话来源是下面 dsh 插件独有的。
dsh plugin add dsh-backstory
安装后,dsh 宿主会应用 package.json 里声明的 bundle patch
(dsh.bundle.patch → cordis.patch.yml),把插件插入运行中的
composition,无需额外接线。
git clone https://github.com/MeghanBao/dsh-backstory.git
cd dsh-backstory
npm install
npm run typecheck # tsc --noEmit
npm test # blame 解析、provenance、ledger、hash 归属、git e2e
npm run build # 把 MCP server 编译到 dist/(backstory-mcp 二进制)
npm run mcp # 从源码通过 stdio 运行 MCP server
独立的 cordis.yml 只加载 dsh 插件,方便本地迭代。
直接输入 /backstory 命令,可带文件和行范围:
/backstory src/auth.ts:40-60
/backstory utils/date.ts
或用自然语言问 agent(用的是同一个 backstory 工具):
src/auth.ts 第 88 行的来龙去脉是什么?"utils/date.ts 10–40 行,以及每部分为什么在那儿"工具会返回每一行 + 最后改动它的提交(作者、日期、信息),以及——若已知——写下它的
agent 轮次/prompt(🧬t<turn>)。agent 用代码本身讲做什么,用提交信息 + 溯源讲
为什么。不在 git 仓库里时优雅降级为只给源码。
backstory| 参数 | 类型 | 说明 |
|---|---|---|
path | string(必填) | 绝对路径或相对工作区路径 |
line | number | 起始行(1 起);省略则读整个文件 |
endLine | number | 结束行;默认等于 line |
整文件读取上限 400 行。
插件通过 tools/post-execute 观察器自动把每次 write/edit 记录到
.dsh/backstory.jsonl——把这个文件提交,溯源就随仓库走。
若想再把溯源锚进 git 历史(漂移交给 git 处理),每个 clone 装一次
prepare-commit-msg 钩子:
npm run install-hook
之后每次提交都会把暂存文件对应的最新 ledger 记录自动折进 trailer:
DSH-Turn: 14
DSH-Prompt: 支持德语双语
DSH-Session: 0f3a…
钩子是尽力而为(绝不阻断提交)、幂等(--amend 也安全)、删掉即停用;若已有同名钩子
会备份为 *.backup。
解释一行要花一次模型调用,所以解释会被缓存。agent 解释完 backstory 结果里
unexplained 的那些行后,调用 backstory_remember 把它们存下来——按每行的内容 hash
存进 .dsh/backstory-notes.jsonl。下次未改动的行会直接带着 explanation(↳)返回,
只有文本变了的行才需要重新解释。省钱,且永不过时。
prompt 会存进 ledger(并经钩子进 commit trailer),所以在写入前会自动脱敏常见密钥——
OpenAI / GitHub / AWS / Slack / Google 密钥、JWT、Bearer token,以及
password / token / secret / api_key 这类 键=值 会被替换成 [REDACTED]。
用 .dsh/backstory.config.json 可关闭记录或加自定义规则:
{ "record": true, "redactPatterns": ["ACME-\\d+"] }
或用环境变量全局关闭:DSH_BACKSTORY_DISABLE=1。
⚠️ 脱敏是尽力而为的模式匹配,不是保证——push 前先看提交,敏感内容直接 opt-out。
.dsh/backstory.jsonl
(轮次、prompt、被改动行、内容 hash);跨 session/机器/人保留。✅DSH-* commit trailer,经 git blame → sha → trailer
还原,漂移交给 git;外加 prepare-commit-msg 钩子安装器(npm run install-hook),
自动把 ledger 记录折进 trailer。✅.dsh/backstory.config.json /
DSH_BACKSTORY_DISABLE 的 opt-out。✅/backstory 用户命令(注册为 dsh skill),带 file:line 参数驱动工具。✅backstory_remember →
.dsh/backstory-notes.jsonl),只重解释变动的行。✅backstory-mcp):同一套引擎通过 Model Context
Protocol 暴露,任意 MCP 客户端(Claude Code、Cursor……)都能用 backstory /
backstory_remember,无需 dsh。复用 git 原生核心,编译到 dist/ 并发布到 npm。✅针对 dsh 开发者预览版构建——API 可能变动。blame 解析、provenance 引擎、ledger、
hash 归属、git-blame 与 commit-trailer 路径共 43 个测试覆盖(纯逻辑 + 对真实临时仓库
的 e2e)。所有运行时接触点(exec.agent.session.events、tools/post-execute 记录器)
都做了防御处理并优雅降级,工具不会崩。
MIT © Meghan Bao