Turn DeepSeek Harness sessions into daily, weekly, handoff and article reports, with a verifiable HTML export and a receipt that re-checks the saved file.
Install
# from GitHub (first run asks for allowBuilds approval — follow the hint, retry)
dsh plugin --profile web add github:ciceroyang/dsh-report-studio
Any plugin you install runs third-party code with your own permissions — it can read your files, use your credentials, and reach the network, and tool approvals don’t sandbox it. GitHub-sourced plugins also run build scripts at install time — pnpm blocks those until you allow them, so an install can stop with ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED or ERR_PNPM_IGNORED_BUILDS; dsh prints the exact key to add under allowBuilds in your profile’s pnpm-workspace.yaml, and the install works on the next run. Allowing a build is a trust decision: only install sources you trust, and pin a commit (github:owner/repo#sha).
README
When your agent finishes work, have it write up what happened — into something you can actually hand over.
Turn one session into a daily report / weekly report / handoff document / WeChat-article draft, each sealed with a verifiable receipt block (report hash + artifact hashes) so later changes to the saved report or referenced artifacts are detectable.
Status: usable. See Releases for current versions. Tracks the Harness developer preview; interfaces may change.
Features
- 4 ready templates:
daily,weekly,handoff,article - Deterministic session extraction: user asks, todo snapshots, turn/step stats, token ledger, tool calls, produced files, shell commands, errors and blocks — all read from the durable session event log, never from the model's memory
- Verifiable receipt block: session id, workspace, generation time, report SHA-256 and artifact SHA-256 appended to every saved report
- Safe persistence: target paths are confined to the session workspace;
absolute-path escapes and
..traversal are rejected - Report index:
report_indexlists every saved report with kind, date, session and verification status, and can write the index as Markdown or HTML - Customizable templates: override built-in templates wholesale (placeholders below)
- No build step: plain ESM; install via
dsh pluginor load with a--patchoverlay
Install
Requires Node.js ≥ 18 and DeepSeek Harness.
Option 1: plugin install (needs pnpm)
dsh plugin --profile web add github:ciceroyang/dsh-report-studio#v0.4.7
Option 2: local source overlay (no pnpm)
git clone https://github.com/ciceroyang/dsh-report-studio.git
# my-report.yml (the plugin path MUST be absolute):
# - insert:
# - id: report-studio
# name: '/absolute/path/to/dsh-report-studio/index.js'
dsh web --patch ./my-report.yml
Usage
Tell the agent either of:
- "Write today's work report."
- "Turn this session into a handoff document for the next person."
The bundled work-report skill teaches the agent the full workflow:
report_generateproduces a draft with hard data plus[[待写:…]]prose slots;- the agent fills the slots from session facts only;
report_savewrites the file and appends the receipt;- the agent replies with the saved path and the report hash.
Default save location: reports/<kind>-<date>.md inside the workspace.
For an instant draft preview without a model round trip, type the slash command:
/report daily # weekly / handoff / article also work
Tools
report_generate
| Argument | Required | Meaning |
|---|---|---|
kind |
yes | daily / weekly / handoff / article |
title |
no | custom title; falls back to the session title |
period |
no | period label (e.g. "2026-08-11 ~ 2026-08-17") for weekly |
Returns the full Markdown draft; prose sections are [[待写:…]] markers.
report_save
| Argument | Required | Meaning |
|---|---|---|
content |
yes | final Markdown (receipt is appended automatically) |
path |
no | target path; defaults to reports/<kind>-<date>.md |
kind |
no | used for the default filename |
artifacts |
no | produced file paths; existing files get hashed into the receipt |
format |
no | md (default) / html — standalone forwardable document; the original Markdown is embedded in a hidden source block so report_verify still verifies it |
Returns the absolute path, report SHA-256, and verified artifact hashes.
report_week
Aggregates every persisted session of the current workspace (logs under
$DSH_HOME/sessions) plus the live session into a weekly draft with a
per-session table. Reading historical logs needs Node ≥ 22.15 (built-in zstd);
older Node degrades gracefully to the current session only.
report_verify
Independently re-checks a saved report's receipt: recomputes the report SHA-256 and every artifact hash, reporting match/missing per item.
| Argument | Required | Meaning |
|---|---|---|
path |
yes | saved report file (inside the workspace) |
dir |
no | batch mode: verify every .md and .html report under this workspace-relative directory; returns matched/mismatched/no-receipt summary |
report_index
Lists every saved report under a directory (default reports/, recursive, .md and .html) as an index: kind, date, session, verification status and artifact count. Verification reuses report_verify's logic, so the index shows at a glance which reports are still intact.
| Argument | Required | Meaning |
|---|---|---|
dir |
no | directory to index (workspace-relative); default reports |
format |
no | md (default) or html |
save |
no | optional path to write the index to; without it the tool returns text only and writes nothing |
report_publish
Publish a report to Feishu (custom bot webhook) or Notion (page); target=dry previews the payload without sending anything.
| Argument | Required | Meaning |
|---|---|---|
target |
yes | feishu / notion / dry |
content |
no | report text; otherwise read from path |
path |
no | saved report file (inside the workspace) |
title |
no | Feishu prefix / Notion page title |
Configuration: plugin config publish.feishuWebhook / publish.notionToken + publish.notionParentPageId, or env vars FEISHU_WEBHOOK / NOTION_TOKEN / NOTION_PARENT_PAGE_ID. Real publishing fails loudly without them; dry mode always works.
| Argument | Required | Meaning |
|---|---|---|
title |
no | custom title |
period |
no | period label, e.g. "2026-08-11 ~ 2026-08-17" |
Custom templates
Templates are plain Markdown with stable placeholders (data sections are filled deterministically by the plugin):
{{TITLE}} {{DATE}} {{PERIOD}}
{{META}} session id / workspace / time range / title
{{TASKS}} user asks + latest todo snapshot
{{STATS}} turns / steps / tool calls / token ledger / end reasons
{{TOOLS}} tool call table
{{FILES}} produced and read files
{{COMMANDS}} shell commands run
{{ERRORS}} tool errors and blocks
{{TIMELINE}} per-turn timeline
{{SESSIONS}} weekly session table (report_week aggregation)
Prose sections are written as [[待写:…]] and must be filled before saving.
Point the plugin at a custom directory:
- insert:
- id: report-studio
name: dsh-report-studio
config:
templatesDirs:
- '/absolute/path/to/my-templates'
Copy any file from this repo's templates/ directory as a starting point.
Receipt example
## 报告凭据 Report Receipt
| 项 | 值 |
|---|---|
| 会话 Session | session-1c1e5d0c-… |
| 工作区 Workspace | /Users/you/project |
| 生成时间 Generated | 2026-08-14T08:00:00.000Z |
| 报告哈希 Report SHA-256 | 9f2c… |
| 产物 Artifacts | README.md → 3a1b… |
Scheduled weekly reports
Two paths (the work-report skill picks per the session's actual capability):
In-harness (official tools): with dsh-schedule mounted, say "generate my weekly report every Friday 18:00" and the agent implements it via
schedule_create(time zone must be explicit).System-level (zero deps, all data sections automatic):
scripts/auto-weekly.mjsneeds no model — it aggregates the week's sessions, fills every data section and saves a draft with [[待写:…]] prose slots. Point launchd/cron at it for Friday 18:00, then open a session and say "fill and save".node scripts/auto-weekly.mjs <workspace> --out reports/weekly-auto.md
Known limitations
- report_week cross-session aggregation reads historical logs under $DSH_HOME/sessions (multi-frame zstd); historical reading needs Node ≥ 22.15.
- Persistence uses Node's
fsdirectly, outside the Harness fs policy layer; path-escape protection lives inside the plugin. - Report tools require an agent-bound session (web and headless both qualify).
Docs & examples
- 中文实战教程:从零到发布 — 完整开发复盘,含 6 个实测坑
- Plugin scaffold — generate the same project layout in one command
- Environment doctor — one-command local diagnostics (port/deps/profiles/logs)
- Example daily report — 真实会话产出的日报样例(凭据块)
Contributing
Issues and PRs welcome (typos, new templates, translations, tests). Before pushing:
npm test
License & funding
MIT. If this saves you from writing another daily report:
- Mainland China: Afdian (pays out to Alipay; GitHub Sponsors cannot pay out there)
- Elsewhere: GitHub Sponsors
Built for the open-source community, in the spirit of DeepSeek Harness: everything is a plugin.
Links
More in this category
tt-a1i/archify#integrations/deepseek-harness★ 89901
Generate validated, self-contained interactive architecture, workflow, sequence, data-flow, and lifecycle diagrams from repositories or system descriptions.
dream-num/dsh-univer-office★ 614
Give DeepSeek Harness a real office environment. Univer Office Plugin brings spreadsheets, docs, slides, canvases, relational tables, and more into one runtime — with connected data, validation, versioned changes, and isolated worktrees for multi-agent collaboration.
ECNU/EduWork#dsh-knowledge-studio★ 246
A workspace-based Studio for source-grounded reports, slides, tables, mind maps, quizzes, flashcards, audio and video, using DSH models and shared artifact services. Office generation requires Python 3.12+ with its dependencies and DSH_OFFICE_PYTHON configured; media rendering requires Chromium, and local ASR additionally requires whisper.cpp and a model.
PerryLink/dsh-industry-research★ 214
Deterministic industry research reports for DeepSeek Harness — company and industry research flows produce structured, verifiable reports from staged evidence.
HuanLinOTO/dsh-plugin-mineru★ 48
Expose MineRU document parsing tools to the model.
PolinniZhong/dsh-knit★ 47
Puts the Markdown documents, source files, images and video that already exist anywhere in the session workspace into the DSH sidebar, ranked by relevance to the current conversation. The default lexical mode matches your recent messages against title, summary and body locally with IDF weighting (BM25) — no model calls, no network, nothing leaves the machine. The list comes from scanning the workspace rather than from a recent-files list, so restarting DSH or opening a new session does not empty it. Results are organised into a three-tier reading order (primary / supporting / related) with a verifiable reason on every row — which field matched, which document cites this one — and one click opens an in-place preview: Markdown as rendered text, relative-path images actually drawn, source code with the host's own syntax highlighting, video streamed over HTTP Range. The same Context Pack is exposed to the agent as a knit_docs tool. Later versions added read evidence and lifecycle tracking (attribution is frozen at the moment of reading), pin / exclude (exclusion applies before retrieval, and is undoable), relation evidence (references / imports / tests, with line numbers) and an incremental index reused across restarts. Since v0.23 there is also an optional hybrid mode: it is off by default and only runs once you configure an Ollama or OpenAI-compatible embedding provider yourself. When it runs, what leaves the machine is your query text plus each candidate file's title and summary — a Markdown summary is an excerpt of the body's first paragraph (at most 60 characters), a code file's summary is its workspace-relative directory, and an image or video contributes its file name; full bodies and absolute paths are not sent, and a loopback provider keeps everything on this machine. Since v0.24 it also associates uncommitted changes: a read-only git status (fixed argv, no shell, whitelisted child-process environment) combined with the same reference / import / test / mention evidence shows which files a change is likely to drag along, and it is off by default. The benefit of semantic retrieval still awaits a real-provider run, so no recall improvement is claimed.
Community comments
Comments are public GitHub Discussions. Loading them connects to GitHub and Giscus; a GitHub account is required to post.