Bundle
dsh-receipts
Mine local DSH session logs (JSONL) into personal 'usage & impact' receipts: Markdown day/week/month reports plus a self-contained HTML receipt, cross-referenced with local git log. Zero-network mining, privacy-first (reads only your own dshHome).
- Source
- 988hj7tczd-oss
- stars
- 1 stars
- License
- MIT
- Updated
- Updated 5 days ago
Readme
# 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:
```bash
pnpm install # link 到 dsh-src 的依赖
pnpm build # tsc 编译 lib/
dsh plugin --profile <name> add /path/to/dsh-receipts
```
装载后 agent 获得 `receipts` 工具:
| 参数 | 默认 | 说明 |
| --- | --- | --- |
| `period` | `month` | `week`=7 / `month`=30 / `quarter`=90 / `year`=365 或正整数天数(如 `"14"`) |
| `repo` | 无 | 项目名子串,过滤整个报告(匹配会话 cwd) |
| `outDir` | `dshHome` | 报告输出目录 |
| `redactPaths` | `false` | 绝对路径脱敏(`<redacted>/<basename>`) |
| `sessionsRoot` | `$DSH_HOME/sessions` | 覆盖会话日志根目录 |
| `git` | `true` | git log 交叉验证开关(关闭时标注「无法交叉验证(被禁用)」) |
输出两个文件:`receipts-<日期>.md` 与 `receipts-<日期>.html`(自包含);
`<日期>` 为最近活动日/生成日的 UTC 日期,格式 `YYYY-MM-DD`(如 `receipts-2026-08-20.md`)。
## 命令行直接使用
```bash
# 挖掘(摘要 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>`。
- 「零外发」是硬约束:挖掘脚本无任何网络模块(测试含网络白名单断言)。
## 开发
```bash
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.mjs` 的 `ZSTD_MAX_FRAME_BYTES`
帧大小护栏,跳过原因进入摘要与报告)。
- `receipts` 工具以子进程方式调用挖掘/报告脚本;脚本路径随包发布(必须保留
`scripts/` 与 `assets/` 两个目录)。
- 主题分类为关键词聚类的确定性实现,非语义分析;可按需扩展 `TOPIC_KEYWORDS`。
## License
[MIT](./LICENSE)。上游 anthropics/claude-plugins-official#receipts 仅作流程与
参数语义参考,实现全部自写。
## 权限、失败边界与 DSH STORE 状态
- [PERMISSIONS.md](./PERMISSIONS.md):运行时读取面 / 命令面(固定 argv,非 shell)/ 写面 / 外部服务 / 失败边界 / 供应链 / 文件权限信号(无 chmod/chown、644、无 setuid/setgid)。
- [docs/store-evidence.md](./docs/store-evidence.md):一次性 Profile 安装 → 启动(工具注册清单)→ 卸载步骤、本地离线证据、待宿主补录真实运行记录说明,并逐项回应 DSH STORE 五类审查信号(仓库 canonical 匹配 / Node 声明 / 供应链 / 文件权限 / 命令权限)。
- STORE 复检由 dsh-safe-plugin-manager 每 3 小时自动执行;本仓库已按清单契约声明(package.json 的 `repository` / `engines.node` / `dsh.compatibility` / `dsh.permissions`)。
Install
dsh plugin --profile web add github:988hj7tczd-oss/dsh-receipts
Profile: web
With the hub plugin installed, ask your agent to install it by name — it resolves the same plan shown here.
dsh plugin --profile web add github:stvlynn/dsh.fish#path:packages/dsh-plugin-hub
install dsh-receipts from the hub
- 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.