Back to home@988hj7tczd-oss

dsh-receipts

Mine local DSH session logs (JSONL) into personal usage & impact receipts: Markdown day/week/month reports plus a self-contained HTML receipt

Stars
0
Language
JavaScript
Created
Aug 24, 2026
Updated
Aug 24, 2026

Introduction

dsh-receipts

[!IMPORTANT] 依赖前置:相邻 dsh-src 检出(link: 依赖) 本项目在开发形态下使用 link: 依赖指向相邻的 DeepSeek Harness 源码检出(dsh-src), 与当前仓库保持同一父目录布局(<parent>/dsh-src)。克隆本仓库后:

  1. 先把官方 deepseek-ai/deepseek-harness 检出到与本仓库同级的 dsh-src/ 目录,并执行其 pnpm install && pnpm run build
  2. 再按下方「安装」一节执行本仓库的 pnpm install --offline && pnpm build 与测试。 发布到 npm 的版本会尽量把 link: 依赖替换为 registry 真实版本;无法替换的内部包保持 link:,见各包 README 说明。

从 DSH 本地会话日志挖取「使用与影响报告」(Receipts)——个人「工作流水账」。

纯本地数据构建:挖取本机 DSH 会话日志(JSONL),交叉本机 git log,输出 Markdown 日报/周报/月报 + 自包含 HTML receipt(单文件、无外链,可直接 离线打开或发给别人)。

项目定位(对齐上游 receipts 思路,实现自写,MIT): 向主管 justify 使用/花费、自省「我到底用它干了啥」。 2026-08 调研:dsh receipts worklog 工作日志 实时搜索 0 结果,无人做。

特性

  • 零配置:数据源是本机 $DSH_HOME/sessions 下已有的会话日志(session.jsonl / session.jsonl.zstd),无需联网、无需注册。
  • 零网络挖掘:挖掘阶段是纯本地 Node 脚本(文件 IO + 正则 + JSON 解析), 零 API 调用;唯一一次模型调用(可选)是「摘要 → 书面报告」润色,摘要强制 ≤ 20KB(超出先截断再写)。
  • 交叉验证:每个仓库本地 git log(无网络),把 commit 活动与会话活动互相校验; 仓库缺失时报告标注「无法交叉验证」。
  • 隐私:只读自己的 dshHome 日志;--redact 开关对报告中的绝对路径脱敏; 报告绝不外发。

目录结构

dsh-receipts/
├── cordis.yml                  # DSH bundle patch:挂载 receipts 插件行
├── package.json                # dsh.bundle.patch 声明 + 构建/测试脚本
├── src/index.ts                # 装配(tools/fsp 注入 + systemPrompt 指引 + 注册工具)
├── src/tools/receipts.ts       # defineTool:周期/项目过滤/输出路径/脱敏
├── scripts/mine-transcripts.mjs # 日志 → 摘要 JSON(零网络;none + zstd 两种模式)
├── scripts/report.mjs          # 摘要 JSON → Markdown + 自包含 HTML(模板内嵌)
├── assets/template.html        # 自包含 HTML 模板(无外部资源)
├── tests/
│   ├── fixtures/logs/          # 三份 fixture 会话日志(明文 + zstd)
│   └── smoke.e2e.ts            # 离线冒烟/E2E 测试(14 项,覆盖全部验收标准)
├── README.md
└── LICENSE                     # MIT

安装与使用(DSH 插件)

构建并安装到 profile:

pnpm install          # link 到 dsh-src 的依赖
pnpm build            # tsc 编译 lib/
dsh plugin --profile <name> add /path/to/dsh-receipts

装载后 agent 获得 receipts 工具:

参数默认说明
periodmonthweek=7 / month=30 / quarter=90 / year=365 或正整数天数(如 "14"
repo项目名子串,过滤整个报告(匹配会话 cwd)
outDirdshHome报告输出目录
redactPathsfalse绝对路径脱敏(<redacted>/<basename>
sessionsRoot$DSH_HOME/sessions覆盖会话日志根目录
gittruegit log 交叉验证开关(关闭时标注「无法交叉验证(被禁用)」)

输出两个文件:receipts-<日期>.mdreceipts-<日期>.html(自包含); <日期> 为最近活动日/生成日的 UTC 日期,格式 YYYY-MM-DD(如 receipts-2026-08-20.md)。

命令行直接使用

# 挖掘(摘要 JSON 打到 stdout)
node scripts/mine-transcripts.mjs --root ~/.dsh/sessions --period month --repo my-project --redact

# 报告(摘要文件 → Markdown + HTML)
node scripts/report.mjs --summary /tmp/summary.json --out-dir ~/receipts --base-name receipts-2026-08-20

压缩模式(注意事项:DSH 日志默认 Zstd)

  • compression: 'none':日志为明文 UTF-8 JSONL,逐行解析,最省事。
  • 默认 Zstd:DSH 的 session-persistence-jsonl 把日志写成多帧拼接session.jsonl.zstd(每 append 批一帧)。本插件自动解压:
    1. 优先 Node 内建 node:zlib 的 Zstd——先按帧边界(RFC 8878 块头布局以 DSH 自身扫描器为准)切出每一帧,再逐帧解码拼接内容;
    2. 内建不可用时回退 zstd -dc CLI;
    3. 两者皆无时跳过该文件并在摘要中记录——skipped 清单(路径 + 原因)与 totals.skippedSessions 计数进入 Markdown/HTML 报告(概览「跳过文件数」+ 告警块),提示改用 compression: 'none',不会产出「假空」报告。

成本策略

  • 挖掘阶段:零网络、零模型调用(文件 IO + 正则)。
  • 报告阶段:模板渲染,同样零模型调用(比上游更省;需要叙事润色时,可用摘要 数据让模型做一次调用)。
  • 摘要上限:SUMMARY_BYTES_CAP = 20KB(紧凑 JSON 计字节),超出按 「会话文件线索 → 文件改动 → 按天 → 工具频次 → 主题 → 会话条目 → 项目条目」 的顺序逐步截断,绝不丢弃核心统计。

隐私

  • 只读 dshHome/sessions(或显式 sessionsRoot),只写 outDir(默认 dshHome)。
  • 报告默认展示绝对路径;--redact / redactPaths: true 折叠为 <redacted>/<basename>
  • 「零外发」是硬约束:挖掘脚本无任何网络模块(测试含网络白名单断言)。

开发

pnpm test          # 离线冒烟/E2E:14 项断言,覆盖验收标准 1-5
pnpm typecheck     # tsc --noEmit(src + tests)
pnpm build         # tsc → lib/

测试覆盖:

  1. fixture JSONL → 会话数/工具调用数与日志实际一致(抽查断言);
  2. week/month/数字周期过滤 + repo 子串过滤;
  3. HTML 单文件自包含(无外部资源、占位符替换、离线可开);
  4. 挖掘脚本网络白名单(源码不含网络模块/fetch,模板无外部 URL);
  5. git 交叉仅在有仓库时进行,缺失时报告标注「无法交叉验证」(含临时 git 仓库 验证 commit 数);另有多帧 zstd 拼接回归测试。

已知限制

  • 周期判定以会话活动与时间窗的重叠为准(创建于窗外但窗内有活动的会话计入)。
  • zstd 文件较大时逐帧解码会占用较多内存;单帧压缩数据超过 64MB 上限时按解码 失败处理并跳过该文件(scripts/mine-transcripts.mjsZSTD_MAX_FRAME_BYTES 帧大小护栏,跳过原因进入摘要与报告)。
  • receipts 工具以子进程方式调用挖掘/报告脚本;脚本路径随包发布(必须保留 scripts/assets/ 两个目录)。
  • 主题分类为关键词聚类的确定性实现,非语义分析;可按需扩展 TOPIC_KEYWORDS

License

MIT。上游 anthropics/claude-plugins-official#receipts 仅作流程与 参数语义参考,实现全部自写。