SkillAgentSearch skills...

csift

The missing tool to sift your Claude Code sessions: regex search across all record types, recover files, extract images, inspect subagent topologies, match between plan files and sessions.

Install / Use

npx skills add wdhwg001/csift

Installs into whichever agent you are using.

About this skill
📄

SKILL.md

Installable skill definition

Quality Score

86/100

Supported Platforms

Claude Code
<div align="center"> <img src="assets/logo.svg" alt="csift logo" width="168" /> <h1>csift</h1> <p><sub>Pronounced <strong>"c-sift"</strong> (<em>see-sift</em>)</sub></p> <p><strong>The missing tool for Claude Code session transcripts.</strong></p> <p> <strong>search</strong>, <strong>recover</strong>, <strong>monitor</strong>, and <strong>audit</strong> any Claude Code session straight from the <code>.jsonl</code> logs. </p> <p> <img alt="Rust 1.89+" src="https://img.shields.io/badge/Rust-1.89%2B-dea584?logo=rust&logoColor=white" /> <img alt="search: pure regex" src="https://img.shields.io/badge/search-pure%20regex-7c9cff" /> <img alt="embeddings: none" src="https://img.shields.io/badge/embeddings-none-22d3ee" /> <img alt="coverage: 95.6%" src="https://img.shields.io/badge/coverage-95.6%25-4ade80" /> <img alt="built for Claude Code" src="https://img.shields.io/badge/built%20for-Claude%20Code-d97757" /> <img alt="written by Claude Code" src="https://img.shields.io/badge/written%20by-Claude%20Code-d97757" /> <img alt="license: MIT" src="https://img.shields.io/badge/license-MIT-a78bfa" /> </p> </div>
──────────────────────────────────────────────────────────────────────────────
 ❯ what that session decide about rate limiting and wheres the code?
──────────────────────────────────────────────────────────────────────────────

⏺ Bash(csift search "rate limit" @13d9645a -t agent --since 1d)
  matches  1 exchange · 1 session · oldest first

  13d9645a·t42  2026-06-20 22:14:07.811 AEST(UTC+10)
    ▸ agent.message  L8821  Added a sliding-window limiter (10 req/min/IP); the 429 path now
                    returns Retry-After and logs the offending IP — gateway/src/rate_limit.rs:88.
  matched 1 exchange · 1 session · label=agent

One regex, the complete round-trip, token-efficient output. No embeddings, no database, no daemon.

Why csift

Claude Code's sessions are plain text in JSONL, so why csift, not grep?

Yes. It has every prompt, thought, tool call, file edit, pasted image, and subagent it spawned. But one of these may happen to you:

  • "It deleted my project files, then apologized."

    Running --dangerously-skip-permissions, it wiped the files it had built, said sorry, and stopped dead. Asked to dig them back out of its own session, it fumbled around (the edits spanned subagents, every restore came back partial) and then quietly started rewriting them from memory as it panicked and decided that was "easier".

  • "It lost my design images after a compaction, then asked me to re-send them."

    The images were right there in the conversation. One compaction later the agent acts like they never existed: the compaction handed it lossy text fragments instead, and it believed them.

  • "Which session does jazzy-twilight-sparkle.md belong to?"

    The plan file carries the architecture that matters. Its invented name says nothing about which session wrote it, and the binding lives in an EnterPlanMode tool call, a needle in the haystack.

  • "The machine crashed with three sessions open. Which was which?"

    Frontend, backend, debugging, and claude --resume gives you a lineup with no faces.

  • "I literally just said that."

    A few compactions into a long run, the agent still knows its task. Everything you actually said and read is gone, and nothing keeps the last few turns mechanically the way codex or pi do.

  • "I DID tell you. In the question dialog."

    It searched its own session by user roles, found nothing, and concluded you never said it. You said it in AskUserQuestion.

  • "You're the orchestrator. Why can't you see which session is stuck?"

    Because, it explains, an unanswered AskUserQuestion is never written to disk at all, "so there's nothing I can watch." Or worse: "Yes, I can interpret it from the thinking."

  • "You said it stopped but it's waiting for a subagent!"

    It apologized, found a "root cause" by searching all other jsonl files. When you have another session to orchestration in the same project, it wouldn't even know whether it's stopped. Or worse, it found a turn duration metadata and believed it must be the true stop. It is not.

Each of these ends the same way: the agent says ~~You are absolutely right.~~, then stumbles through a one-off script over raw JSON and gets it subtly wrong.

csift is the missing tool it should have had.

✨ Highlights

  1. Recover files & deleted plans.

    csift recover analyzes and aggregates every edit/read and restores the file's exact bytes, at any point in time, in diff patches or final files, and honors Claude Code's file-modified markers. Shell traffic counts too: a heredoc or literal echo written through Bash, and a clean cat/head/sed -n read, replay as real content under strict admission gates. When it can't reliably recover due to modified boundaries, it salvages what survived with gaps marked.

  2. 🖼 Images back out.

    csift image lists, dedups, and extracts them, addressable by the same [Image #N] handle the session uses. (#N was never a unique id. csift copes.)

  3. 📝 Plan ↔ Session matched.

    csift plan finds the plan a session wrote.
    csift plan --reverse jazzy-twilight-sparkle.md names the session that owns a file.
    Both directions.

  4. 📇 Sessions you can tell apart.

    csift list identifies every session by its first and last messages.
    It is the completion claude --resume never had.

  5. 🧵 Un-clip a compaction.

    A summary keeps task state and context. The conversation is a different axis, and csift verbatim reconstructs the clipped back-and-forth within a --budget. Wire it into a hook and every compaction arrives with the recent dialogue attached.

  6. 🏷 Typed search.

    A background task's completion notice is a "user" role.
    A subagent's return: also "user".
    Your AskUserQuestion answer: a tool result.
    csift stepped in every one of these traps already, so csift search -t user.answer (one of 33 {role}.{class}.{sub} labels) finds exactly what a naive grep swears was never said.
    Some labels exist because the format hides things: user.unsent finds the message you esc-recalled and never actually sent, user.queued finds what you typed into the queue while a turn was running, harness.meta.turn-duration is the record behind the "Done in 1m 5s" line, and agent.thinking.narration separates the API's one-line summaries from the reasoning they summarize.

  7. 🛎 Pending questions, on the record.

    csift ships a hook that records AskUserQuestion / ExitPlanMode / MCP elicitations to a sidecar file, and every csift surface merges the unresolved ones in transparently. An orchestrator can finally see which session is stuck waiting on a human, and on what.

  8. 🩺 Is it actually stopped?

    An end-of-turn record is not a stop. The turn behind "Crunched for 46m 26s · done 11:00 am · 1 shell still running" wrote a turn_duration line carrying a duration, a message count, and nothing else. The running shell lived only in the REPL's memory. csift status does not take that line's word for it. It joins the harness's session registry, the transcript's tail (an unreturned tool call means in flight), every child lane's own tail, the task list, and a process probe into one verdict: running, waiting on children, waiting on a human, idle, or dead, with the evidence named. Live lanes and open tasks stay visible while finished ones fold to a count. Every background shell, async agent and Monitor the session ever launched is listed with its age and whether it came back, because the harness writes nothing about a running one and long sessions carry dozens of zombies. csift wait --until stop --timeout 300 blocks until it really stops, exits 124 on timeout with a report of what the session did meanwhile, and takes a lens (--background-since now, --ignore-background 'npm run dev') so a dev server that never returns does not hold the wait forever. The timeout is required, on purpose. The one corner of csift that answers "now" instead of "what happened", point-in-time by design.

  9. 🔎 Round-trips, not lines.

    A hit returns the whole exchange, rebuilt from the uuid/parentUuid graph: the matched tool call with its result, the user turn with the agent's reply. This is the context that grep or Claude's ad-hoc scripts can never reliably provide.

  10. 🌳 Subagent topology.

    Kind, lifecycle, and the parent→child tree of every spawned agent, plus detection of lanes frozen on a pending permission approval.

  11. 🤖 Designed for humans and LLMs.

    Output is terse, re-feedable, and even structural. Simply install the skill and your Claude will gain the power.

  12. 🔒 Local, read-only, no magic.

    Pure regex. No embeddings, no index, no database, no daemon, no network, no telemetry, no hidden detections. It reads files already on your disk and never mutates your session histories.

  13. Rust + mmap + SIMD newline scan + byte prefilters + rayon.

    200 MB transcripts and multi-GB corpora in about a second, quick enough to call from inside a hook without noticing.

Install

cargo install csift

Requires Rust 1.89+. Or from source:

git clone https://github.com/wdhwg001/csift.git
cd csift
cargo install --path .        # builds the optimized binary and puts `csift` on your PATH
# …or just `cargo build --release` → ./target/release/csift

csift reads ~/.claude by default; point it elsewhere with --claude-home <DIR> or Claude Code's own $CLAUDE_CONFIG_DIR. csift <command> --help is the full manual.

Teach it to your agent

csift's primary user is the agent itself: output is terse, parseable, and every record carries a re-feedable handle. The skill teaches Claude Code when and how to reach for it:

npx skills add wdhwg001/csift

Quickstart

csift <command> [TARGET] [flags]. A target is a positional @<uuid> (a session), an @<agent-hex> (a subagent), a project path, or . (this cwd); omit it to scan every project.

| You want to… | Run | | ----------------------------------------------------- | -------------------------------------------------------- | | find what a session said about a topic | csift search "TOPIC" @<uuid> | | fetch the exact record a hit cited (full / raw bytes) | csift show @<uuid> --line 46550 [--raw] | | peek a live session's last few turns | csift show @<uuid> --turn -3.. | | token / tool / turn aggregates | csift stats @<uuid> | | identify "which session is this" | csift list . | | see which files a session changed | csift files @<uuid> --by file | | restore a file from the transcript | csift recover @<uuid> --file /abs/x.rs --out /abs/x.rs | | get back a deleted plan | csift recover @<uuid> --file @plan --out plan.md | | un-clip the turns a compaction dropped | csift verbatim @<uuid> --budget 40000 | | inspect a session's subagents | csift agents @<uuid> | | identify the current session | csift whoami | | pull a pasted image back out | csift image @<uuid> --out ./imgs | | is that session still running, and on what | csift status @<uuid> | | blo

Truncated for display — read the full file on GitHub.

Related Skills

View on GitHub
GitHub Stars29
CategoryDevelopment
Updated1d ago
Forks0

Languages

Rust

Security Score

97/100

Audited on Sep 4, 2026

1 info