From claude-code
Query Claude Code session history for IDs, durations, tokens consumed, tool usage patterns, errors, permissions, and search past conversations by keyword or project. Use for usage introspection like 'tokens today' or 'find setup X'.
npx claudepluginhub bendrucker/claude --plugin claude-codeThis skill is limited to using the following tools:
Search and analyze Claude Code conversation history via a DuckDB index over JSONL session files.
CLAUDE.mdREADME.mdfixtures/sessions/-Users-test-project-feature/feature.jsonlfixtures/sessions/-Users-test-project/basic.jsonlfixtures/sessions/-Users-test-project/malformed.jsonlfixtures/sessions/-Users-test-project/multiple.jsonlfixtures/sessions/-Users-test-project/skills.jsonlfixtures/sessions/-Users-test-project/summary.jsonlfixtures/sessions/-Users-test-project/tools.jsonlfixtures/sessions/-Users-test-webapp/webapp.jsonlpackage.jsonresources/import.sqlresources/queries/errors.sqlresources/queries/permissions.sqlresources/queries/sandbox.sqlresources/queries/search.sqlresources/queries/skills.sqlresources/queries/stats.sqlresources/refresh.sqlresources/schema/01_tables.sqlCreates isolated Git worktrees for feature branches with prioritized directory selection, gitignore safety checks, auto project setup for Node/Python/Rust/Go, and baseline verification.
Executes implementation plans in current session by dispatching fresh subagents per independent task, with two-stage reviews: spec compliance then code quality.
Dispatches parallel agents to independently tackle 2+ tasks like separate test failures or subsystems without shared state or dependencies.
Search and analyze Claude Code conversation history via a DuckDB index over JSONL session files.
Current Session ID: ${CLAUDE_SESSION_ID}
The index refreshes automatically on first use per session. Subsequent queries skip the refresh for faster results. Pass --refresh to force a re-scan when the user asks for the latest data.
${CLAUDE_SKILL_DIR}/scripts/query.ts "SELECT model, SUM(output_tokens) as tokens FROM messages WHERE type = 'assistant' GROUP BY model"
${CLAUDE_SKILL_DIR}/scripts/query.ts --refresh "SELECT * FROM sessions ORDER BY start_time DESC LIMIT 5"
Built-in queries in resources/queries/ can be run by name with key=value params. Prefer these over writing SQL from scratch for common tasks:
${CLAUDE_SKILL_DIR}/scripts/query.ts search query=authentication limit=10
${CLAUDE_SKILL_DIR}/scripts/query.ts stats project=myapp after_date=2026-03-15
${CLAUDE_SKILL_DIR}/scripts/query.ts errors error_type=rejection limit=5
${CLAUDE_SKILL_DIR}/scripts/query.ts permissions project=bendrucker.me limit=10
${CLAUDE_SKILL_DIR}/scripts/query.ts sandbox limit=10
The project param matches against the directory name (last path component) using glob syntax. project=myapp matches exactly, project=myapp* matches the repo and its worktrees (myapp.feature-branch, myapp.bugfix, etc.).
search: find sessions by keyword (ILIKE on content_text and summary). Params: query, limit, after_date, before_date, projectstats: tool usage breakdown with error rates and aggregate totals. Params: after_date, before_date, projecterrors: recent tool errors with type filtering. Params: error_type (rejection or failure), limit, after_date, before_date, projectpermissions: tool calls the user rejected. Params: limit, after_date, before_date, projectsandbox: Bash calls that bypassed the sandbox (dangerouslyDisableSandbox), with back-links to prior failed sandboxed calls of the same command. Params: limit, after_date, before_date, projectmessages tableOne row per message. Schema is auto-detected from JSONL with snake_case renames for known fields.
| Column | Type | Description |
|---|---|---|
session_id | VARCHAR | Session UUID |
type | VARCHAR | user or assistant |
timestamp | TIMESTAMP | Message timestamp |
project_path | VARCHAR | Absolute path to the project directory |
git_branch | VARCHAR | Branch at time of message |
is_meta | BOOLEAN | System-injected user message (not human input) |
content_text | VARCHAR | Raw text content (string-content messages only) |
summary | VARCHAR | Conversation summary (joined from summary rows) |
input_tokens | BIGINT | Input token count — assistant rows only |
output_tokens | BIGINT | Output token count — assistant rows only |
duration_ms | BIGINT | Message duration in milliseconds |
is_sidechain | BOOLEAN | Whether the message is on a sidechain |
source_file | VARCHAR | Absolute path to the source JSONL file |
source_line | BIGINT | Line number in the source file (1-based) |
Unknown fields from JSONL pass through automatically via * EXCLUDE.
content_items tableOne row per content array element, with parent context merged in. Schema is fully auto-detected.
| Column | Type | Description |
|---|---|---|
type | VARCHAR | text, tool_use, tool_result, thinking |
text | VARCHAR | Text content |
name | VARCHAR | Tool name (for tool_use) |
id | VARCHAR | Tool use ID (for tool_use) |
tool_use_id | VARCHAR | Matching tool use ID (for tool_result) |
content | VARCHAR | Tool result text (for tool_result) |
is_error | BOOLEAN | Whether the tool result is an error |
session_id | VARCHAR | Session UUID (from parent message) |
timestamp | VARCHAR | Message timestamp (from parent message) |
project_path | VARCHAR | Project directory (from parent message) |
Additional fields (input, thinking, caller, signature, etc.) are auto-detected from real data.
sessions viewAggregated session-level data.
| Column | Type |
|---|---|
session_id | VARCHAR |
summary | VARCHAR |
start_time | TIMESTAMP |
end_time | TIMESTAMP |
duration | INTERVAL |
project_path | VARCHAR |
git_branch | VARCHAR |
user_messages | BIGINT |
assistant_messages | BIGINT |
tool_calls viewOne row per tool use.
| Column | Type |
|---|---|
tool_name | VARCHAR |
tool_id | VARCHAR |
session_id | VARCHAR |
project_path | VARCHAR |
timestamp | TIMESTAMP |
tool_errors viewTool results where is_error is true, joined with the originating tool call.
| Column | Type |
|---|---|
tool_id | VARCHAR |
error_content | VARCHAR |
tool_name | VARCHAR |
session_id | VARCHAR |
project_path | VARCHAR |
timestamp | TIMESTAMP |
error_type | VARCHAR (rejection or failure) |
permission_requests viewTool calls the user rejected (denied the permission prompt).
| Column | Type |
|---|---|
tool_name | VARCHAR |
tool_id | VARCHAR |
command | VARCHAR (Bash only) |
file_path | VARCHAR (Edit/Write only) |
description | VARCHAR |
session_id | VARCHAR |
project_path | VARCHAR |
timestamp | TIMESTAMP |
sandbox_bypasses viewBash calls that used dangerouslyDisableSandbox=true. Includes a back-link to the most recent prior failed sandboxed call with the same command, identifying retry patterns where the sandbox caused the initial failure.
| Column | Type | Description |
|---|---|---|
command | VARCHAR | The Bash command |
description | VARCHAR | Command description |
tool_id | VARCHAR | Tool use ID |
session_id | VARCHAR | Session UUID |
project_path | VARCHAR | Project directory |
timestamp | TIMESTAMP | When the bypass was used |
retried_tool_id | VARCHAR | Tool ID of the prior failed sandboxed call (NULL if no match) |
retried_error | VARCHAR | Error from the prior failed call (NULL if no match) |
Reusable filter helpers available in all queries:
date_filter(ts, after_val, before_val): filters by timestamp range, NULL values bypass the checkproject_filter(path, project_val): ILIKE match on project path, NULL bypassesTo retrieve the full JSONL line for a message (e.g., to inspect tool input):
sed -n '<source_line>p' <source_file>
Session logs are stored in ~/.claude/projects/<encoded-path>/<session-id>.jsonl where the encoded path replaces / with -. The CLI maintains a DuckDB index at $CLAUDE_PLUGIN_DATA/session.duckdb, rebuilt incrementally on each invocation.