🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

任务复盘报告 Neo65536-engineer/dsh-agent-log

DeepSeek Harness
Neo65536-engineer38 天前有提交已提供中文文档扫描:高危

从本机会话日志还原任务全过程与结果

30.5/100
综合分
1
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/9/29 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

该插件未发布到 npm,按作者文档从 GitHub 源安装即可(静态检查只覆盖 npm 路径,不代表插件不可用)。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add Neo65536-engineer/dsh-agent-log
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:已验证
是什么
dsh 原生插件 · chat
装得上吗
本站已真实安装成功
非静态推断
L4 · 真实安装等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
更新放缓:最近一次提交在 38 天前
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查需源码安装

仓库 package.json 标记 private,未发布到 npm,需从源码安装

展开查看检查明细 ↓

以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。

✗npm 包dsh-agent-log(未发布到 npm,仅可源码安装)
✓Node 引擎要求 >=20 · 基线 Node 22.19 满足
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明

源码安装时若 pnpm 拦截 prepare 脚本,按其提示在 pnpm-workspace.yaml 的 allowBuilds 中放行后重跑。

验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/6 14:17:07

🔴 安全扫描发现高危能力自动 · 静态分析源码
v2.7.0
🔴 扫描:高危尚无人工评估

静态扫描发现安装期即执行代码,或命令参数由运行时变量拼接(参数来源无法静态判定,从严处理)。

命令参数由运行时变量拼接读写/删除本地文件发起外部网络请求
查看扫描证据(共 91 处,展示前 53 条)
  • 读取本地文件
    index.js:54
    const mtime = statSync(file).mtimeMs
  • 读取本地文件
    index.js:145
    for (const c of cands) if (existsSync(join(c, 'sessions'))) return c
  • 读取本地文件
    index.js:348
    const base = sessionCwd && existsSync(sessionCwd) ? sessionCwd : process.cwd()
  • 写入本地文件
    index.js:350
    mkdirSync(dirname(target), { recursive: true })
  • 写入本地文件
    index.js:351
    writeFileSync(target, text, 'utf8')
  • 发起网络请求
    client.js:216
    return fetch(`${ROUTE}?${q.join('&')}`).then(async (r) => {
  • 发起网络请求
    client.js:284
    fetch(`${ROUTE}${q}`, { signal: ac.signal })
  • 发起网络请求
    client.js:312
    fetch(`${ROUTE}?list=1`, { signal: ac.signal })
  • 读取本地文件
    core/session-log.mjs:21
    const buf = readFileSync(file)
  • 读取本地文件
    core/session-log.mjs:78
    if (!existsSync(root)) return []
  • 读取本地文件
    core/session-log.mjs:80
    for (const workspace of readdirSync(root)) {
  • 读取本地文件
    core/session-log.mjs:82
    if (!statSync(wsDir).isDirectory()) continue
  • 读取本地文件
    core/session-log.mjs:83
    for (const sessionId of readdirSync(wsDir)) {
  • 读取本地文件
    core/session-log.mjs:85
    if (!statSync(dir).isDirectory()) continue
  • 读取本地文件
    bin/dev-setup.mjs:39
    const looksLikeRuntime = (dir) => existsSync(join(dir, 'dsh-tools', 'package.json'))
  • 读取本地文件
    bin/dev-setup.mjs:52
    if (existsSync(profilesRoot)) {
  • 读取本地文件
    bin/dev-setup.mjs:53
    for (const name of readdirSync(profilesRoot)) {
  • 读取本地文件
    bin/dev-setup.mjs:55
    if (!statSync(join(profilesRoot, name)).isDirectory()) continue
  • 读取本地文件
    bin/dev-setup.mjs:74
    if (existsSync(linkPath)) {
  • 写入本地文件
    bin/dev-setup.mjs:106
    mkdirSync(linkDir, { recursive: true })
  • 删除本地文件递归
    bin/dev-setup.mjs:111
    rmSync(linkPath, { recursive: true, force: true })
  • 读取本地文件
    bin/install.mjs:97
    DEV_MARKERS.every((rel) => existsSync(join(PLUGIN_DIR, rel))) || existsSync(join(PLUGIN_DIR, '.git'))
  • 读取本地文件
    bin/install.mjs:137
    if (existsSync(join(dir, 'profiles')) || existsSync(join(dir, 'sessions'))) return { dir, from: '--home' }
  • 读取本地文件
    bin/install.mjs:152
    if (existsSync(join(dir, 'profiles')) || existsSync(join(dir, 'sessions'))) return { dir, from: cand.from }
  • 读取本地文件
    bin/install.mjs:160
    if (!existsSync(root)) return []
  • 读取本地文件
    bin/install.mjs:161
    return readdirSync(root).filter((name) => {
  • 读取本地文件
    bin/install.mjs:163
    return statSync(join(root, name)).isDirectory() && existsSync(join(root, name, 'package.json'))
  • 写入本地文件
    bin/install.mjs:260
    copyFileSync(join(oldest, f), dst)
  • 删除本地文件递归
    bin/install.mjs:270
    rmSync(backupRoot, { recursive: true, force: true })
  • 执行外部命令运行时拼接
    bin/install.mjs:412
    return execSync(`pnpm ${args}`, { cwd, encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'] })
  • 写入本地文件
    bin/install.mjs:526
    mkdirSync(backupDir, { recursive: true })
  • 写入本地文件
    bin/install.mjs:532
    copyFileSync(src, join(backupDir, f))
  • 写入本地文件
    bin/install.mjs:537
    writeFileSync(
  • 写入本地文件
    bin/install.mjs:543
    writeFileSync(PROFILE_PKG, desired, 'utf8')
  • 写入本地文件
    bin/install.mjs:579
    copyFileSync(join(backupDir, f), join(PROFILE_DIR, f))
  • 读取本地文件
    bin/verify-compose.mjs:53
    const names = existsSync(root)
  • 读取本地文件
    bin/verify-compose.mjs:54
    ? readdirSync(root).filter((n) => {
  • 读取本地文件
    bin/verify-compose.mjs:55
    try { return statSync(join(root, n)).isDirectory() && existsSync(join(root, n, 'package.json')) } catch { return false }
  • 读取本地文件
    bin/verify-compose.mjs:55
    try { return statSync(join(root, n)).isDirectory() && existsSync(join(root, n, 'package.json')) } catch { return false }
  • 读取本地文件
    bin/verify-compose.mjs:81
    if (existsSync(generations)) {
  • 读取本地文件
    bin/verify-compose.mjs:82
    for (const g of readdirSync(generations)) {
  • 执行外部命令固定命令
    bin/verify-compose.mjs:88
    return execSync('where dsh', { encoding: 'utf8' }).trim().split('\n')[0].trim()
  • 删除本地文件递归
    bin/verify-compose.mjs:110
    if (existsSync(TMP)) rmSync(TMP, { recursive: true, force: true })
  • 写入本地文件
    bin/verify-compose.mjs:111
    mkdirSync(TMP, { recursive: true })
  • 写入本地文件
    bin/verify-compose.mjs:116
    copyFileSync(join(SRC, f), join(TMP, f))
  • 执行外部命令运行时拼接
    bin/verify-compose.mjs:128
    execSync(`cmd /c mklink /J "${join(TMP, 'node_modules')}" "${srcModules}"`, { stdio: 'ignore' })
  • 执行外部命令运行时拼接
    bin/verify-compose.mjs:140
    out = execSync(`"${dsh}" --profile ${TMP_NAME} --dump-config`, {
  • 删除本地文件
    bin/verify-compose.mjs:197
    if (existsSync(nm)) rmSync(nm, { recursive: false, force: true })
  • 删除本地文件递归
    bin/verify-compose.mjs:198
    rmSync(TMP, { recursive: true, force: true })
  • 读取本地文件
    bin/worklog.mjs:24
    const ok = (c) => c && existsSync(join(c, 'sessions'))
  • 写入本地文件
    bin/worklog.mjs:118
    writeFileSync(out, md, 'utf8')
  • 写入本地文件
    bin/worklog.mjs:173
    writeFileSync(out, text, 'utf8')
  • 写入本地文件
    bin/worklog.mjs:183
    writeFileSync(out, md, 'utf8')
扫描于 2026/11/3(0 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

功能亮点

  • 从会话日志还原任务过程
  • 统计工具与文件读写
  • 汇总命令与测试结果
展开完整介绍(121 字)↓

只读工作汇报,给 DeepSeek Harness 用:从会话日志还原智能体任务到底干了什么——用了哪些工具、读了写了哪些文件、跑了哪些命令、测试结果、失败、token 用量,以及有没有跑完。完全离线,不用 API key,数据不出你的机器。

README

由 DeepSeek 最新模型翻译生成
dsh-agent-log DSH 插件。从本机的 DSH 会话日志里只读还原一次任务做了什么,输出一份《本次 Agent 工作报告》。 报告内容包括: - 这次的任务(你的原始输入) - 用了哪些工具、各调用多少次 - 执行了哪些命令 - 读了哪些文件、改了哪些文件 - 测试有没有通过 - 失败了几次、分别是什么原因 - 消耗了多少 Token - 最后完成了没有 数据全部来自本机会话日志。插件不联网,不需要 API key,不修改任何会话数据。 安装 两种安装方式,二选一。不要都用,否则插件会被加载两次。 桌面版(DSH Desktop) 桌面版的 profile 由应用自己管理,命令行改不了,请用应用内的插件管理器: 1. 侧边栏打开「插件」,点「添加插件」 2. 填入 github:Neo65536-engineer/dsh-agent-log 3. 点「安装」 4. 装完点「立即启用」。只安装不启用的话,插件不会加载 5. 等几秒,刷新页面(F5) 命令行(dsh web) dsh plugin --profile web add github:Neo65536-engineer/dsh-agent-log --profile 是必填的,要写你实际在跑的那个 profile(dsh web 一般是 web)。
展开完整文档(README 剩余 1 节)
dsh-agent-log

DSH 插件。从本机的 DSH 会话日志里只读还原一次任务做了什么,输出一份《本次 Agent 工作报告》。

报告内容包括:

- 这次的任务(你的原始输入)
- 用了哪些工具、各调用多少次
- 执行了哪些命令
- 读了哪些文件、改了哪些文件
- 测试有没有通过
- 失败了几次、分别是什么原因
- 消耗了多少 Token
- 最后完成了没有

数据全部来自本机会话日志。插件不联网,不需要 API key,不修改任何会话数据。

安装

两种安装方式,二选一。不要都用,否则插件会被加载两次。

桌面版(DSH Desktop)

桌面版的 profile 由应用自己管理,命令行改不了,请用应用内的插件管理器:

1. 侧边栏打开「插件」,点「添加插件」
2. 填入 github:Neo65536-engineer/dsh-agent-log
3. 点「安装」
4. 装完点「立即启用」。只安装不启用的话,插件不会加载
5. 等几秒,刷新页面(F5)

命令行(dsh web)

dsh plugin --profile web add github:Neo65536-engineer/dsh-agent-log

--profile 是必填的,要写你实际在跑的那个 profile(dsh web 一般是 web)。不填会报 required option '--profile ' not specified。

命令会自动把插件加进 profile 的组合,几秒后生效,不需要重启。

确认装上了

新开一个对话,让模型执行:

用 work_report 复盘一下这次任务

能出报告就是装好了。也可以在右侧边栏的「+」里找「Agent 工作报告」页签。

安装插件不需要重启 DSH。改动插件源码之后才需要重启。

用法

1. agent 工具 work_report

work_report({}) // 复盘当前会话
work_report({ turns: 3 }) // 只看最近 3 轮
work_report({ sessionId: "session-2e667305" }) // 指定会话(可只给前几位)
work_report({ format: "json" }) // 返回结构化数据
work_report({ out: "reports/task.md" }) // 同时写入文件
work_report({ format: "html", out: "报告.html" }) // 生成可打印的 HTML

out 用相对路径时,按这次会话的工作目录解析。

2. 右侧边栏面板

右侧边栏「+」→「Agent 工作报告」。7 个页签:总览、工具、命令、文件、测试、失败、轮次。

工具条上是刷新、自动刷新、下载 HTML、下载 Markdown、会话选择器。下载的 HTML 是自包含文件,可以直接打开或打印成 PDF。

面板默认显示它自己所属的那个会话。

3. 离线 CLI(不装插件也能用)

在仓库目录下执行:

node bin/worklog.mjs --list # 列出所有会话
node bin/worklog.mjs --latest # 最近一个会话的报告
node bin/worklog.mjs # 指定会话
node bin/worklog.mjs --out r.md # 写入文件
node bin/worklog.mjs --json # 输出 JSON

日报和周报(把多个会话按时间聚合):

node bin/worklog.mjs --period --since today
node bin/worklog.mjs --period --since 7d
node bin/worklog.mjs --period --since week
node bin/worklog.mjs --period --since 30d --out 月报.md
node bin/worklog.mjs --period --since 2026-09-20 --until 2026-09-25

--since / --until 可以用 today、yesterday、week、7d、30d 或 YYYY-MM-DD。

CLI 按 $DSH_HOME → ~/.dsh 的顺序找会话日志,也可以用 --home 指定。

4. HTTP 路由

GET /plugins/dsh-agent-log/report?format=json&sessionId=...&turns=N
GET /plugins/dsh-agent-log/report?format=markdown
GET /plugins/dsh-agent-log/report?format=html
GET /plugins/dsh-agent-log/report?list=1

这条路由挂在 DSH 的 web server 上,和其它接口一样需要认证,未认证请求返回 403。

报告里的判定规则

- 测试结果是三态的:通过、未通过、未判定。只有在退出码确实能归因到测试命令时才用它;命令被管道接走、或测试后面还有别的语句时会标「未判定」并写明原因,不会算成通过。
总览与面板也按三态显示(9(通过 4 / 失败 1 / 未判定 4)),不会把「未判定」吞掉让数字对不上。
- Windows 上 … | Select-Object -First N 会因为 broken pipe 非 0 退出。这类计入「疑似失败」,单独列出,不计入失败总数。
- 报告是快照。正在跑的那一轮标成「进行中」。
- 明细表最多列 80 行,「逐轮明细」也最多 80 轮,超出时会写明「只列前 80 条(共 N 条)」。
总览里的数字始终是全量,完整明细用 format: "json" 取,或看侧边栏面板。
- 轮次完成率的分母是已收尾的轮次;正在跑的那一轮还没有结论,不计入,报告里会注明。
- 会话日志是多个 zstd 帧拼起来的。如果有帧读不出来,报告开头会挂一条醒目提示(面板与 HTML 同样有),因为那意味着数字可能偏小,极端情况下结论会与实际相反。
- 没指定会话、插件也拿不到调用方身份时,会复盘最近活跃的会话,并在报告里标注这一点。

权限

| 项 | 值 |
| 网络 | 不使用,不发任何数据 |
| API key / 凭据 | 不需要 |
| 读取 | $DSH_HOME/sessions、$DSH_HOME/storages/session_projcache |
| 写入 | 只有显式传 out 时才写你指定的那个文件;不写会话数据 |
| 索引 / 缓存文件 | 不建;只有进程内存里 12 份日志的缓存 |

会话日志里是完整的对话内容,所以导出的 HTML / Markdown 报告也包含这些内容,分享前自己确认一下。

出问题

装了,但工具和面板都没有。
确认桌面版点过「立即启用」——只安装不启用的话插件不会加载。然后刷新页面。再确认没有同时用两种方式安装。

面板顶部有黄色提示「宿主加载的是旧版插件模块」。
这是改过插件源码之后的状态。Node 的 ESM 模块一旦加载就缓存住,HMR 只处理 Loader 条目的增删,不会重新加载改过的宿主模块。重启 DSH 即可。只安装、不改代码的话不会出现。

面板里「工具」「命令」「文件」是空的,但「总览」正常。
同上:客户端已经是新的,宿主还是旧的。重启 DSH。

报告里的数字和预期不一样。
检查是否用了 turns 参数——用了之后总览会按截断后的轮次重算,报告开头也会写明「本报告只统计最近 N 轮」。另外看总览下面的疑似失败说明。

复盘到的是别的会话。
只在没指定 sessionId、且插件拿不到调用方身份时发生,报告里会标注。显式传 sessionId 即可。

报告太长。
明细表默认截到 80 行。要完整数据用 format: "json",或者看侧边栏面板(面板读的是完整数据)。

兼容性

- DSH:0.1.5-rc.3、0.1.7-rc.1(桌面版)、0.1.7-rc.2(dsh web)实测可用
- Node:>= 20
- 运行时依赖:无。不需要 npm install,不需要构建
- 会话日志格式 v0–v4

升级 DSH 后可以用这两条确认插件还正常:

node bin/verify-loaded.mjs # 确认 work_report 在工具列表里
node bin/verify-compose.mjs # 确认插件还在 profile 的组合树里

卸载

- 应用内装的:侧边栏「插件」→ dsh-agent-log → 卸载
- 命令行装的:dsh plugin --profile remove dsh-agent-log
- 用仓库安装器装的:node bin/install.mjs --rollback(回滚到安装前的状态)

开发

见 DEVELOPMENT.md。

许可

MIT
预览分享卡片长什么样 ↓Neo65536-engineer/dsh-agent-log
分享 · DeepSeek Harness Hub
Neo65536-engineer/dsh-agent-log

从本机会话日志还原任务全过程与结果

这是你的仓库?认领条目

回到顶部