chsum
Work logs and reload-ready context from your Claude Code conversations.
Nothing here is generated by a model. Every line of output is either copied verbatim from a transcript or computed from it, so nothing can be invented. That matters because the output is designed to be pasted back into a future Claude session, where a plausible-but-wrong sentence would become ground truth.
The idea
Your own prompts already are a faithful record of what you were trying to do. Extracted in order they read as the story of the session — most of what a summary would have said, without the risk:
**m1**
> can you open a chrome page to the site, it is running on 3000
**m7**
> sherpa-onnx-tts.worker.js:267 [Sherpa Worker] Initialization failed…
**m137**
> when I speed up the text to speech, it ends up sounding like a chipmunk
**m153**
> The toolbar is no longer working to slow it down or speed it up live
Blockquoting is functional, not cosmetic: a quoted reply containing ## Summary
would otherwise forge a section of the digest. Everything else — dates, duration,
branch, files, commands — is parsed straight out of the transcript.
Requirements
claude-historyon yourPATH- Python 3.10+. No third-party packages, no model, no network.
Install
pipx install chsum # from a checkout: pipx install .
Or as a Claude Code plugin, which brings the skill with it:
/plugin marketplace add InDate/indate-tools
/plugin install chsum@indate-tools
The plugin carries the skill; the chsum command still comes from pipx.
pipx, not pip install --user: chsum is an application, so it gets its own venv
and one symlink on PATH. pipx install --editable . while working on it.
A real command rather than a shell alias, because an alias doesn't exist for scripts, hooks, or agents.
Usage
chsum # every session in this project, one line each
chsum -n 5 # just the five most recent
chsum --since 7d # only the last week
chsum --all # across every project
chsum last # most recent real session, as context
chsum last -n 2 # the one before that
chsum find "text to speech playback speed" # locate a conversation
chsum digest <ch_ref> # write a digest file
chsum digest <ch_ref> --stdout # print it instead
chsum digest --file path/to/session.jsonl # address by file
chsum context <ch_ref> # reload artifact, for pasting into Claude
chsum context <ch_ref>/<agent-id> # one subagent's own digest
chsum journal --since 7d # work log for this project
chsum journal --since 2w --all # across every project
Bare chsum lists the project's sessions, newest activity first:
ref date dur prompts files agents title
ch_c120431a267b202aebf0b38f6c3c1b69 2026-08-06 5h38m 78 14 - Plan 3D house model…
ch_da4e99d42e5efab11ebdedc22fb65145 2026-08-05 3h03m 30 12 5 Set up cdp-tools server
ch_b99f11b7c257dafc8b93f53480ba3804 2026-08-05 6s 1 0 - empty (untitled)
Listing is the default because picking is the common case, and "most recent" is
often a session you abandoned after one prompt. Those are flagged empty rather
than hidden — knowing a session was a dead end is the answer to "where did that
work go". Activity means a file edited, a notable command, an agent spawned, or a
second prompt.
chsum last is chsum context on the most recent session with activity, ordered
by last activity so one you resumed yesterday beats one you started last week.
Run from inside Claude Code, the session doing the running is excluded.
Everything scopes to the current project; --all widens. Digests land in
~/.claude/chsum/digests/<uuid>.md (--out to change).
Subagents
A subagent's edits and commands fold into its parent's totals — otherwise a
session that delegated everything reads as no activity. Files no parent turn
touched are marked (agent). Each agent gets a line in Delegated, and an
address:
chsum context ch_da4e99d42e5efab11ebdedc22fb65145/a728cd49179f1a356
Its task, files, commands, and last message. Everything past the one-line summary is fetched on demand, so a heavily-delegated session doesn't produce a digest nobody wants to read.
<parent-ref>/<agent-id> resolves to <uuid>/subagents/agent-<id>.jsonl. chsum's
own scheme, not claude-history's — see Notes on correctness.
Search modes
--hybrid (default) and --semantic are best for conceptual recall but are slow:
tens of seconds warm, and several minutes on the very first run while the
embedding index builds. Use --lexical (sub-second) for identifiers, filenames,
and error strings, or --exact for exact tokens.
What a digest contains
| Section | Source |
|---|---|
| Frontmatter — ref, title, project, branch, start, duration, counts | computed |
| What I asked for — your prompts, verbatim, in order | copied |
| Files changed / Commands run | parsed from tool calls |
| Delegated — one line per subagent, with its address | parsed from sidecars |
| Where I left off — last prompt and last reply, verbatim | copied |
| — found by two separate backward scans, so they may be far apart and are not a Q&A pair | |
Drill down — mN → ma_… anchor map |
computed |
An agent digest has the same shape minus the intent trail — an agent gets one instruction, so Task is a single block — and no anchor map (see below).
Output is budgeted, because it lands in a future context window: quotes clip,
lists cap. Every truncation is marked ([+N chars, read the anchor], …and N more) so you always know when you're seeing a fragment.
Notes on correctness
Several things here are non-obvious and were established by measuring, not assuming:
- Duration excludes idle time. Sessions get resumed hours or days later, so first-record-to-last-record wildly overstates effort — one session in the corpus reads as 92 hours. Gaps over 30 minutes are treated as "walked away".
- Anchors are content-addressed, so they can collide. Two messages with
byte-identical text (
[Request interrupted by user], say) share one anchor, andread --anchorthen fails withambiguous-ref. Ambiguous anchors are detected and never published — every anchor a digest prints resolves to exactly one message. - Most "user" records aren't from you. They're tool results, interrupts, and
harness scaffolding. Those are filtered out;
prompts:counts what you typed. outlinehas two output shapes — segment ranges for long conversations, per-message lines for short ones. Both are handled.- Subagent transcripts aren't conversations in their own right and never appear
in the listing, matching
claude-history's discovery rules. claude-historyhas no per-agent ref.--subagentsinlines agent messages into the parent read untagged, so they can't be sliced apart. Sidecars are parsed directly, which is why agent digests carry noma_anchors — those are claude-history's to mint, and a fabricated one is worse than none.- An agent's last message isn't necessarily its conclusion, so the section is Last thing it said. An interrupted agent ends mid-thought.
- Agent counts take the larger of two sources —
Agent/Taskcalls in the parent, and sidecars on disk. Sidecars go missing; an agent that spawns its own outnumbers the visible calls. - Scratch paths (
/tmp, scratchpads, plan files) are excluded from "files changed" so the work log shows real project changes.
Adding prose later
There is a deliberately unimplemented Summariser seam at the bottom of
chsum.py. A TL;DR is the one thing extraction can't produce; the intended order
is Haiku first to set a quality bar and a price, then a local MLX backend measured
against it.
The rule for any backend: it gets the already-extracted material, and its output is additive — layered on top of the verbatim record so a wrong sentence can always be checked against the quotes beneath it.
If you do go local, note that the model in mlx-community/DeepSeek-R1-Distill-Qwen-14B-MLX
is 139 GB of unquantised weights. The 4-bit build is …-14B-4bit at 8.32 GB. On a
16 GB machine the binding constraint is KV cache, not context length: this architecture
costs 192 KB/token at fp16 (96 KB with kv_bits=8), so after 8.32 GB of weights you get
roughly 18k–36k tokens of usable input, not the 131k the config advertises.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file chsum-1.0.2.tar.gz.
File metadata
- Download URL: chsum-1.0.2.tar.gz
- Upload date:
- Size: 21.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
eff05726fa4f25d27fd4339df80987e68859f9f4edbd1391193e391760f02f40
|
|
| MD5 |
c585d2d065ee48116f870e5d15806a6e
|
|
| BLAKE2b-256 |
f14b608036cff9fe607205886f608fea769be42e459eb6a41c241dadd6954bbe
|
Provenance
The following attestation bundles were made for chsum-1.0.2.tar.gz:
Publisher:
publish.yml on InDate/chsum
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
chsum-1.0.2.tar.gz -
Subject digest:
eff05726fa4f25d27fd4339df80987e68859f9f4edbd1391193e391760f02f40 - Sigstore transparency entry: 2371021196
- Sigstore integration time:
-
Permalink:
InDate/chsum@f0771e7da24ace4eca58a25e0d7220ebb9055a1b -
Branch / Tag:
refs/tags/v1.0.2 - Owner: https://github.com/InDate
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@f0771e7da24ace4eca58a25e0d7220ebb9055a1b -
Trigger Event:
push
-
Statement type:
File details
Details for the file chsum-1.0.2-py3-none-any.whl.
File metadata
- Download URL: chsum-1.0.2-py3-none-any.whl
- Upload date:
- Size: 20.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ca36a12159396f95035c277cd79460753000b005cf760948c78d3ec85464fef6
|
|
| MD5 |
a3c978947a4c78af03850cb96a3b85d8
|
|
| BLAKE2b-256 |
60140860f73270e8069d2b47e2b0773ecee650e624fec852d2ac93b744c50d78
|
Provenance
The following attestation bundles were made for chsum-1.0.2-py3-none-any.whl:
Publisher:
publish.yml on InDate/chsum
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
chsum-1.0.2-py3-none-any.whl -
Subject digest:
ca36a12159396f95035c277cd79460753000b005cf760948c78d3ec85464fef6 - Sigstore transparency entry: 2371021206
- Sigstore integration time:
-
Permalink:
InDate/chsum@f0771e7da24ace4eca58a25e0d7220ebb9055a1b -
Branch / Tag:
refs/tags/v1.0.2 - Owner: https://github.com/InDate
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@f0771e7da24ace4eca58a25e0d7220ebb9055a1b -
Trigger Event:
push
-
Statement type: