dsh-agent-context-hub
Manifest validOne read-only index of every local AI-agent session (Codex, Claude Code, DSH, Trae, or any JSONL source) grouped by project, plus an append-only shared board for decisions and handoffs so switching ag
dsh-agent-context-hub · 上下文中枢
把本机所有 AI agent 的会话历史合并成一份只读索引塞进 DSH,再给这些 agent 一块都能读写的上下文板。换 agent(Codex → Claude Code → Trae → DSH)时上下文不再断层,同一时刻所有 agent 看的是同一份「谁在哪个项目上做过什么、当时怎么定的」。
- 包名:
dsh-agent-context-hub,DSH bundle + 客户端面板,面板名「上下文中枢」 - 索引版本:
INDEX_VERSION = 5 - 数据目录:默认
~/.dsh/agent-context(DSH_AGENT_CONTEXT_HOME可覆盖) - 磁盘契约与 HTTP 契约见 CONTRACT.md,给 agent 用的技能见 SKILL.md
它解决什么
| 问题 | 现在的样子 |
|---|---|
| 这个方案上次在 Codex 里定过什么? | 打开面板按项目或关键词搜,直接看当时那段对话 |
| 三个 agent 轮流改同一个仓库,历史散在三个目录 | 索引按 cwd 归并,同一项目下的 Codex / Claude / DSH / Trae 会话排在同一个分组里 |
远程机器 rag_research 上的 Codex 会话在本机看不见 | 元数据先进索引,点开正文时再用 ssh ... cat 现取 |
| Trae 的对话只在它自己的云端,本机翻不到 | Trae 适配器索引它本地落盘的「记忆摘要」(每回合 intent / outcome / learned + topics.md),行上标「摘要」,点开按回合重放,并明说原文不在本机 |
| 结论只留在聊天里,下一个 agent 只能猜 | 写一条 decision / handoff 到共享板,任何 agent 都能读到 |
| 新会话要人肉翻译上一轮结论 | digest 把共享板压成一段 Markdown,直接贴进新会话 |
三个能力
| 能力 | 入口 | 说明 |
|---|---|---|
| 跨 agent 会话索引 | 面板「会话」标签页 / GET list / cli list | 只读;按项目分组,每行带来源 agent 徽标与时间;搜索命中标题、项目、首条人类提问、会话 ID;远程会话打开时才读正文 |
| 共享上下文板 | 面板「共享上下文」标签页 / `GET | POST shared/cli context、cli share、cli digest` |
| 可编程接口 | CLI + HTTP + SKILL.md | 让 agent 自己去查别的 agent 的旧活、把结论写回共享板,不需要用户转述 |
三个能力共用一份数据:索引决定「有哪些会话、属于哪个项目」,共享板决定「哪些结论要跨 agent 传」,CLI / HTTP 是同一份数据的两个出口(面板走 HTTP)。
安装
插件以 DSH bundle 形式安装。三种方式按环境选一种。
前提:Node ≥ 22.15(dsh 适配器用 zlib.zstdDecompressSync 逐帧解开 DSH 的多帧 zstd 会话;Node 20 上该来源会被跳过并在 warnings 里说明,其它来源照常)。
A. 有 dsh 启动器(推荐)
dsh plugin add "C:\path\to\agent-context-hub"
市场发布后(见 docs/MARKET.md)也可以直接按仓库地址装(npm 发布是可选的):
dsh plugin add github:<owner>/dsh-agent-context-hub
B. 没有 dsh 启动器(本机当前状态)
本机 Web 版的 dsh 不在 PATH 上,走 DSH 自带的插件管理器:在 DSH 会话里说「安装本地插件 C:\path\to\agent-context-hub」,agent 会调用 plugin_manager 安装;也可以手动改 profile 的 package.json(只列出相关字段,合并进现有文件,不要整体覆盖):
{
"dependencies": {
"dsh-agent-context-hub": "link:C:/path/to/agent-context-hub"
},
"dsh": {
"profile": {
"bundles": ["dsh-agent-context-hub"]
}
}
}
改完保存并刷新 DSH 页面。profile 目录一般是 ~/.dsh/profiles/<profile>/(本机为 ~/.dsh/profiles/desktop/)。
装完的三步验证
-
刷新页面(F5)。
client.js由 host 在页面加载时注入,装完不刷新就看不到侧栏图标——这是最常见的一次性「装失败」假象。 -
确认 host 活着:
curl.exe -s http://127.0.0.1:56842/agent-context/api/ping返回
{"ok":true,"at":"2026-10-30T08:53:02.917Z","name":"agent-context-hub"}即正常。 -
触发第一次扫描并确认分会话数(本机实测 250 个会话、4.7 秒左右):
node lib/cli.mjs scan
数据在哪里
路径(默认 ~/.dsh/agent-context) | 内容 | 能删吗 |
|---|---|---|
index.json | 合并后的索引快照 | 能,重扫即重建 |
remote/remote-<host>.json | SSH 远程会话的元数据片段 | 能,下次 sync-remote.mjs 重建 |
shared.jsonl | 共享上下文,一行一条 | 不能,这是唯一不可重建的数据 |
inbox/*.jsonl | 通用接入(任意 agent 追加) | 能,但等于丢掉那些 agent 的历史 |
sources.json | 额外登记的 glob 数据源 | 能,等于注销那些来源 |
sync.log | 定时任务日志(按大小轮转) | 能 |
换目录:
$env:DSH_AGENT_CONTEXT_HOME = "D:\agent-context"
node lib/cli.mjs paths
paths 会打印实际生效的六个位置:
dataHome %USERPROFILE%\.dsh\agent-context
indexPath %USERPROFILE%\.dsh\agent-context\index.json
remoteDir %USERPROFILE%\.dsh\agent-context\remote
sharedFile %USERPROFILE%\.dsh\agent-context\shared.jsonl
inboxDir %USERPROFILE%\.dsh\agent-context\inbox
sourcesFile %USERPROFILE%\.dsh\agent-context\sources.json
用起来
面板
侧栏进入「上下文中枢」,两个标签页:
- 会话:左列 330px 按项目分组的会话列表,行首是来源 agent 徽标(
Codex/Claude/DSH/Trae/接入),搜索框同时匹配标题、项目、首条提问和会话 ID;右侧正文按消息分段,工具输出折叠。只保存摘要的来源(Trae)行尾带「摘要」角标,正文页头也会写明「摘要模式(原文在云端)」。 - 共享上下文:按类型与 agent 过滤、按关键词搜索,右上「+ 写入」记录一条决策或交接。
远程会话行会标出 SSH host,点开时才取正文(提示「正在从 <host> 读取会话…(首次打开约 1~3 秒)」)。索引里只有元数据,所以列表刷新不依赖远程机器的连通性。
CLI
node lib/cli.mjs scan # 全量重扫并写 index.json
node lib/cli.mjs list --limit 5 # 列出最近的会话
node lib/cli.mjs show --id dsh:7f8730e6-82cd-4f06-b046-0e03bd037ec1
node lib/cli.mjs stats
node lib/cli.mjs share --title "索引改为按内容摘要" --body "..." --kind decision --tags index,search
node lib/cli.mjs context --q 索引 --limit 10
node lib/cli.mjs digest --limit 5
node lib/cli.mjs paths
不传子命令时等价于 list。退出码:0 成功,1 失败,3 没有任何结果(空搜索也算正常结束,方便脚本判断)。
真实输出(本机 2026-11-02 18:24 摘录):
$ node lib/cli.mjs scan
Codex 196 会话 · 189 文件 · 1309 ms
Claude Code 未启用(本机没有数据)
DSH 60 会话 · 60 文件 · 3342 ms
Trae 16 会话 · 21 文件 · 33 ms
通用接入 未启用(本机没有数据)
合计 272 会话 / 62 项目 / 2113 MB · 远程 112 · 可搜索 261 会话(775 条摘要) · 4686 ms
! [Codex] session_index 列出 116 个会话,其中 32 个没有本地或远程 rollout 文件(只有索引记录,正文不可读)
索引已写入 %USERPROFILE%\.dsh\agent-context\index.json
$ node lib/cli.mjs list --limit 2
[dsh ] 2026-10-30 16:50 new-chat
将codex中所有的会话都复制到 t
id=dsh:ca46840b-dc63-4011-8483-2a9d059986ff
[dsh ] 2026-10-30 16:50 new-chat
You are writing documentation for
id=dsh:7f8730e6-82cd-4f06-b046-0e03bd037ec1
共 250 条,显示 2 条
每行格式是 [agent] 时间 项目 + 缩进的标题 + id=agent:会话id(会话正文 id 一律带 agent 前缀,跨 agent 的同名 id 不会串)。带 --q 时还会多一行 ↳ 片段 显示命中位置。
$ node lib/cli.mjs show --id dsh:7f8730e6-82cd-4f06-b046-0e03bd037ec1 --max-messages 3
# You are writing documentation for
agent=dsh id=7f8730e6-82cd-4f06-b046-0e03bd037ec1 cwd=%USERPROFILE%\Documents\Codex\2026-09-29\new-chat
--- user 2026-10-30T16:46:40+08:00
You are writing documentation for a DSH (DeepSeek Harness) plugin. …
show 默认最多 200 条消息(--max-messages 可调),被截断时末尾会标「(已截断)」;远程会话额外打印 remote=ssh:<host>。
$ node lib/cli.mjs stats
索引 2026-11-02T18:24:42+08:00 · version 5
Codex 196 会话 / 189 文件 / 1309 ms
Claude Code 未启用
DSH 60 会话 / 60 文件 / 3342 ms
Trae 16 会话 / 21 文件 / 33 ms
通用接入 未启用
会话 272 · 项目 62 · 文件 270 · 重复 105 · 字节 2216004295 · 可搜索 261/272 · 耗时 4686 ms
! [Codex] session_index 列出 116 个会话,其中 32 个没有本地或远程 rollout 文件(只有索引记录,正文不可读)
各来源的数据从哪来
| 来源 | 本机数据 | 正文完整度 |
|---|---|---|
codex | ~/.codex/sessions/**/rollout-*.jsonl(含远程主机经 SSH 同步的元数据) | 完整,按需读全文 |
claude-code | ~/.claude/projects/<slug>/<uuid>.jsonl | 完整,按需读全文 |
dsh | ~/.dsh/sessions/**(多帧 zstd) | 完整,按需读全文 |
trae | ~/.trae-cn/memory/projects/<project>/<yyyyMMdd>/session_memory_*.jsonl + topics.md | 只有摘要:每回合 intent / outcome / learned,原文在 Trae 云端 |
inbox | ~/.dsh/agent-context/inbox/*.jsonl,给没有适配器的 agent 用 | 取决于写入方 |
Trae 的行按会话 ID 合并跨天文件,标题优先取 topics.md 的 topic 摘要;cwd 从 AppData/Roaming/Trae CN/User/workspaceStorage/*/workspace.json 反查,查不到就归到「未知项目」。打开这类会话时,正文第一条固定是一句说明「Trae 只在本地保存记忆摘要」,避免把摘要误当原文。
$ node lib/cli.mjs context --limit 3
[decision] 2026-10-30T16:40:45+08:00 dsh 上下文中枢插件开工
把 codex-sessions 泛化成多 agent 上下文中枢:Codex/Claude Code/DSH 适配器 + 共享上下文。
tags: plugin,context
共 1 条(总库 1 条)
$ node lib/cli.mjs share --title "索引改为按内容摘要" --body "detail=... 的理由" --kind decision --tags index,search
已写入共享上下文:decision · 索引改为按内容摘要
id=<uuid> at=<iso8601>
$ node lib/cli.mjs digest --limit 2
- **decision** 上下文中枢插件开工 — dsh · 2026-10-30T16:40:45+08:00 _plugin,context_
把 codex-sessions 泛化成多 agent 上下文中枢:Codex/Claude Code/DSH 适配器 + 共享上下文。
digest 的输出就是可以整段贴给模型的 Markdown:每条一行标题,正文最多取前 6 行。
HTTP
前缀 /agent-context/api,本机 Web 端口 56842:
| 方法 | 路径 | 用途 |
|---|---|---|
| GET | /agent-context/api/ping | 存活探针 |
| GET | /agent-context/api/list | 会话列表(refresh=1 强制重扫) |
| GET | /agent-context/api/sources | 各数据源的探测状态与统计 |
| GET | /agent-context/api/stats | 全局统计、警告、面板注入自检 |
| GET | /agent-context/api/shared | 共享上下文列表(q / agent / kind / cwd / limit) |
| POST | /agent-context/api/shared | 写一条共享上下文 |
| GET | /agent-context/api/digest | 共享板导出成 Markdown |
| GET | /agent-context/api/transcript?id=<agent:id> | 单个会话正文 |
| GET | /agent-context/api/client.js | 面板脚本(由 host 注入页面) |
| POST | /agent-context/api/beacon | 面板自检埋点(204,不落盘) |
curl.exe -s "http://127.0.0.1:56842/agent-context/api/shared?limit=1"
{"entries":[{"id":"c8b77f84-0725-4ae3-b2d3-3a0dce4f4de2","at":"2026-10-30T16:40:45+08:00","agent":"dsh","kind":"decision","title":"上下文中枢插件开工","body":"把 codex-sessions 泛化成多 agent 上下文中枢:Codex/Claude Code/DSH 适配器 + 共享上下文。","tags":["plugin","context"],"refs":[],"cwd":"C:/work/my-project"}],"total":1,"all":1,"counts":{"decision":1},"agents":{"dsh":1},"badLines":0}
写一条:
curl.exe -s -X POST "http://127.0.0.1:56842/agent-context/api/shared" `
-H "content-type: application/json" `
-d '{"kind":"decision","agent":"dsh","title":"索引改为按内容摘要","body":"因为完整正文太大。","tags":["index"]}'
成功返回 201 与 {"entry":{...}};title 与 body 全空返回 400,请求体超过 256 KB 返回 413。完整字段与错误码见 CONTRACT.md。
定时同步
本机跑的是一个 Windows 计划任务,每天 09:45 刷新索引:
| 组件 | 作用 |
|---|---|
scripts/sync.ps1 | 先跑远程元数据扫描,再跑本地全量 scan;写 sync.log,按 1 MB 轮转 |
scripts/sync-remote.mjs | 只扫远程文件的头尾元数据,经 ssh 抓取 → remote/remote-<host>.json |
scripts/register-task.ps1 | 注册/更新计划任务,默认 09:45、交互式登录、错过补跑、30 分钟上限 |
注册(默认任务名 AgentContextSync):
powershell -ExecutionPolicy Bypass -File .\scripts\register-task.ps1
# 想换名字:-TaskName CodexSessionSync
查状态与手动跑一次:
Get-ScheduledTaskInfo -TaskName AgentContextSync
powershell -ExecutionPolicy Bypass -File .\scripts\sync.ps1
sync.ps1 退出码:
| 码 | 含义 |
|---|---|
0 | 索引已更新 |
1 | 同步出错(看 sync.log) |
2 | 找不到 lib/cli.mjs,安全空转(打包路径变了) |
3 | 一个会话都没读到 |
4 | 找不到可用的 node |
注意:register-task.ps1 有一道保护——同名任务的 action 必须同时匹配 agent-context-hub 与 sync.ps1,否则 exit 5 并保持原任务不动。旧版本留下的 CodexSessionSync(指向旧的 codex-sessions 包)不会被自动接管,也不再刷新本插件的数据;确认不再需要后注销:
Unregister-ScheduledTask -TaskName CodexSessionSync -Confirm:$false
自测
node lib/test.mjs # 52 个用例,约 6 秒
node lib/test.mjs shared # 只跑名字里带 shared 的用例
node lib/test.mjs --list # 列出全部用例名
用例覆盖五个适配器(codex / claude-code / dsh / trae / inbox)、索引合并与去重、findSession、共享板、转录读取、路径覆盖与 CLI 退出码;全部在临时目录里跑,不碰真实数据。
隐私与只读
- 源目录只读:
~/.codex、~/.claude、~/.dsh/sessions只stat+read,插件从不写入、不移动、不删除、不加锁。Codex 正在写的 rollout 文件也按「头尾窗口」读取,避免与codex.exe抢文件。 - 唯一的写入:
~/.dsh/agent-context/下的索引、远程片段、日志,以及shared.jsonl的追加(不重写、不删除、不改既有行)。 - 远程只读:
ssh <host> cat -- '<绝对路径>';元数据扫描只读文件头尾,不执行远端任何写操作。 - 不联网、不埋点:除你自己配置的
ssh之外没有出网请求;beacon只把面板自检状态留在内存里给stats看,不落盘、不外发。 - 敏感内容的落点:
index.json会保存每个会话最多 20 条提问摘要(每条约 120 字,元数据片段更短),远程片段最多 20 条 × 200 字。索引文件是本机明文,按普通本地数据处理;不想留就删数据目录。
排错
| 症状 | 原因 | 处理 |
|---|---|---|
| 装完侧栏没有「上下文中枢」 | 页面没刷新,client.js 尚未注入 | 刷新页面(F5);仍无则查 GET stats 里的 client.inBootGraph |
| 面板一直转圈 / 一直「读取中」 | 首扫还没结束,或 host 未加载 | 等 5~10 秒;GET ping 若无响应说明 host 没起来 |
| 某个来源显示「未启用(本机没有数据)」 | 该 agent 没装、没会话,或不在默认路径 | Claude Code 需要 ~/.claude/projects(也支持 CLAUDE_CONFIG_DIR);Trae 需要 ~/.trae-cn/memory 或 ~/.trae/memory |
| Trae 会话点开只有总结、没有原文 | Trae 不把对话落在本机,只写记忆摘要 | 属预期;topics.md + 每回合 intent/outcome 就是本机能拿到的全部 |
| Codex 会话只有索引记录、正文打不开 | session_index 有记录但 rollout 文件不存在(旧机器/已清理) | 属预期,stats.warnings 会写清多少个 |
正文返回 502 | 远程 ssh 失败或超时 | 报错里带 host 与 stale;先手工 ssh rag_research cat 验通 |
启动日志出现 disk index version X != 5 | 磁盘索引是旧版本 | 正常:host 会丢弃旧索引并重扫覆盖 |
共享板写入 413 | 请求体超过 256 KB | 拆成多条,或把长文放 refs 指向会话/文件 |
| 搜索不到刚出现的会话 | 索引是 10 分钟内的快照 | 面板或 GET list?refresh=1 触发重扫 |
改了 lib/*.mjs 但不生效 | index.js 与 lib/ 都是进程内 ESM,模块一经 import 就被缓存 | 部分自动生效:host 每次请求比对 lib/**/*.mjs 的大小与 mtime,变了就带版本号重新 import lib/hub.mjs、lib/shared.mjs、lib/transcript.mjs;其余模块(lib/sources/* 适配器、`lib/parser |
卸载
-
从 profile 移除:用插件管理器停用/卸载,或从
~/.dsh/profiles/<profile>/package.json的dependencies与dsh.profile.bundles里删掉dsh-agent-context-hub,刷新页面。 -
可选:删数据目录
~/.dsh/agent-context(shared.jsonl删了就没了)。 -
可选:取消计划任务
Unregister-ScheduledTask -TaskName AgentContextSync -Confirm:$false
卸载不会动任何源会话目录;装回去扫一遍就能恢复索引。
进一步阅读
- CONTRACT.md —— 磁盘与 HTTP 契约(索引字段、共享条目、事件格式、路由与版本守卫)
- SKILL.md —— 给 agent 的技能:怎么查别人的旧活、怎么写共享板、怎么读正文不炸上下文
- CHANGELOG.md —— 版本变更
- docs/MARKET.md —— 上架 DSH 插件市场的清单
node scripts/publish.mjs --owner <账号> --dry-run—— 一条命令把仓库准备好上架;node scripts/preflight.mjs --live --port <端口>—— 上架前置自检node scripts/github-setup.mjs all --pr—— 有 token 后一条命令建仓、push、加 topic、开市场 PR- docs/ADAPTER-CONTRACT.md、docs/FORMAT-DSH.md —— 写新适配器时的内部约定
Comments
Loading…
Similar plugins
by HarryHeYu
Cross-agent session continuity for DeepSeek Harness — continue work from Codex, Claude Code, Grok, ZCode and more with sessionFlow.
★ 2
MIT
TypeScript
Oct 31, 2026
dsh plugin --profile web add dsh-sessionflowImport local Codex CLI/Desktop, Claude Code CLI, and Claude Desktop conversations into DSH with project grouping, semantic history, and tool activity; bind an existing or replacement workspace and con
★ 0
dsh plugin --profile web add dsh-assembly.resumeby ZSeven-W
DeepSeek Harness (DSH) plugin: dispatch work to DSH agents from Claude Code / Codex — native subagent progress, in-host worker sessions with per-tier presets, and a multimodal bridge that lends the te
★ 192
↓ 553/wk
MIT
JavaScript
Oct 8, 2026
dsh plugin --profile web add @zseven-w/dsh-crewby ishuowang
Native DSH rooms for connecting independent Sessions and provider-backed AI members—without bundled roles or scenarios.
★ 4
MIT
TypeScript
Sep 4, 2026
dsh plugin --profile web add dsh-agent-team-room本地 AI agent 请求日志面板
★ 0
MIT
JavaScript
dsh plugin --profile web add @yxzpro/agent-actaby catsenior507
Assembled context for DeepSeek Harness: a context tree over the session surface with per-node assemble modes (full / key / off), agent-authored presets, and a panel that decides what the model actuall
★ 2
MIT
TypeScript
Oct 17, 2026
dsh plugin --profile web add @dsh-external/dsh-client-plugin-context-assembler