Skip to content
Back to skills

Session Logs

ASecurity

Generate cleaned session data (index.json + per-session files) from raw Claude Code JSONL logs. Use when asked to build, run, or refresh the session-log extraction pipeline.

  • 2 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 19, 2026
ai-agentsnode

Works with

  • claude code

Security analysis

A100/100

Pro scans all 2 files and shows the line behind each finding

Scanned September 19, 2026

npx -y skills add JurreBrandsen1709/agent-harness-workshop --skill session-logs --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Session Logs?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Session Logs
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/jurrebrandsen1709-session-logs/badge)](https://www.skillsdirectory.com/skills/jurrebrandsen1709-session-logs)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: session-logs
description: Generate cleaned session data (index.json + per-session files) from raw Claude Code JSONL logs. Use when asked to build, run, or refresh the session-log extraction pipeline.
---

# Session Logs

Run the bundled script from the repo root:

```
node .claude/skills/session-logs/scripts/generate-sessions.mjs [logs-dir] [output-dir] [harness-project-dir]
```

- `logs-dir` defaults to `harness-logs` — this repo's fabricated dataset of raw
  session transcripts. It never defaults to your real `~/.claude/projects/{slug}`
  logs, so running the skill without arguments can't accidentally analyze your
  own personal session history.
- `output-dir` defaults to `docs/log-schema`.
- `harness-project-dir` defaults to `todo-app` — used only to read
  `.claude/settings.json` there so `harness_signals` can name the actual registered
  hooks (not a generic guess).

This produces `index.json` + `sessions/{date}/{session_id}.json` (+ subagent files).
Everything in them is mechanical extraction — no LLM calls, no cross-session
judgment, no "this looks important" decisions. Specifically:

- Session identity, timestamps, models used, token/cost usage: read directly from the
  `cost-state`, `ai-title`, and `assistant` records (falling back to summing per-turn
  `message.usage` when no `cost-state` record exists yet — `cost_usd` stays `null`
  rather than guessing a price).
- Events are a line-by-line normalization of the raw records (user turns, tool
  calls/results, slash commands, plan-mode transitions, stop-hook summaries), with long
  text fields (over ~2000-4000 chars) replaced by a `preview` + `original_length_chars`.
- `harness_signals.hooks_observed_firing` for `UserPromptSubmit` hooks is computed by
  statically extracting the hook's injected literal string from its own source file
  and checking whether that exact substring appears in any user turn — a string
  match, not a semantic judgment. `Stop` hooks are matched via
  `stop_hook_summary.hookInfos[].command`. `PreToolUse`/`PostToolUse` hooks land in
  the top-level `hooks_not_observable` since their stdout/stderr isn't persisted in
  JSONL at all.
- `permission_denials`: a match on Claude Code's exact tool-rejection boilerplate
  ("The user doesn't want to proceed with this tool use. The tool use was
  rejected...") is tagged `confidence: "confirmed"` — verified against real denials
  found by running this script against another project's logs. A looser keyword
  regex is a fallback tagged `confidence: "heuristic"` — a lead, not a fact.
- Subagent transcripts (`{session_id}/subagents/*.jsonl`) are parsed identically and
  written to their own `sessions/{date}/{session_id}/subagents/{agent_id}.json`.
  `final_message_preview` on the parent's summary is a truncated excerpt, not a
  written summary.

`index.json` deliberately does **not** contain cross-session rollups, breakdowns, or
clustering — deciding what's relevant across sessions is an analysis judgment, not a
mechanical computation. Each session's index entry does carry a compact per-session
`harness_signals` summary (facts about *that* session only: `tool_error_tools`,
`repeated_failed_tools`, `skills_invoked`, `permission_denial_count`,
`hook_fire_counts`, `ended_in_error`), plus `ai_title` and a `first_prompt_preview` —
enough to scan across sessions without opening every session file individually.

If you add a new hook event type to this repo's harness beyond
`PreToolUse`/`PostToolUse`/`UserPromptSubmit`/`Stop`, update
`.claude/lib/hook-observability.mjs` (shared with the `harness-snapshot` skill) rather
than this script — both skills read hook classification from there.

Re-run this script any time raw logs change (regeneration is cheap and
side-effect-free).

Files in this skill

  • SKILL.md3.7 KB
  • scripts/generate-sessions.mjs22.1 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…