Przejdź do treści
Biblioteka skilli
AI i agenci · Analiza

cq

/cq

Odpytuje historię sesji Claude Code poleceniem cq (SQL na transkryptach przez DuckDB): użyte narzędzia, błędy, polecenia, edytowane pliki i wywołane skille.

Repozytorium
cq ↗
Licencja
MIT
Ostatnia zmiana repozytorium
27.10.2026

Ocena i bezpieczeństwo

100/ 100Klasa: dobry
Format25 / 25
Frontmatter z nazwą i opisem, poprawna nazwa, opis do 1024 znaków, nazwa zgodna z folderem.
Odkrywalność25 / 25
Opis mówi, kiedy użyć skilla, ma sensowną długość i jest w 3. osobie.
Treść35 / 35
Co najmniej 150 słów i do 500 linii, nagłówki, listy kroków, przykłady albo kod.
Higiena15 / 15
Bez zaślepek typu TODO, bez ścieżek Windows, z licencją.
Ryzykobrak sygnałów w skanie
Pliki w paczce
1
Skrypty
0
Komentarze HTML
0
Adresy URL w SKILL.md
2
Przestarzałość

Brak sygnałów. Repozytorium zmienione 27.10.2026, bez odwołań do wycofanych modeli i API.

Licencja

MIT, otwarta: można używać i zmieniać, z zachowaniem informacji o autorze.

Co robi i kiedy

Odpytuje historię sesji Claude Code poleceniem cq (SQL na transkryptach przez DuckDB): użyte narzędzia, błędy, polecenia, edytowane pliki i wywołane skille.

Wyzwalacze z opisu

what tools have I usedhow many sessions todaywhat was that command I ranshow me errorswhich files have I been editingwhat skills get invoked
Oryginalny opis (EN)

Query past Claude Code sessions using the cq CLI (SQL over session transcripts via DuckDB). You MUST use this skill whenever the user asks about their Claude session history, tool usage, errors, or past commands. This includes questions like "what tools have I used", "how many sessions today", "what was that command I ran", "show me errors", "which files have I been editing", "what skills get invoked", or any question about what happened in previous Claude Code sessions. Also use when doing meta-work (skill development, plugin analysis, workflow review) where querying past session data would b

Jak działa

  1. Subcommands
  2. Global Flags
  3. Subcommand Flags
  4. View Schemas
  5. Querying JSON Input Fields
  6. Querying advisor() Calls
  7. Full-Text Search (cq search)
  8. Working With cq
  9. Tips for cq sql
  10. Error Recovery
Sekcje z nagłówków SKILL.md, w oryginale · 189 linii, 2 074 słów
Podgląd SKILL.md
---
name: cq
description: Query past Claude Code sessions using the cq CLI (SQL over session transcripts via DuckDB). You MUST use this skill whenever the user asks about their Claude session history, tool usage, errors, or past commands. This includes questions like "what tools have I used", "how many sessions today", "what was that command I ran", "show me errors", "which files have I been editing", "what skills get invoked", or any question about what happened in previous Claude Code sessions. Also use when doing meta-work (skill development, plugin analysis, workflow review) where querying past session data would be informative. If the user mentions sessions, transcripts, tool calls, or wants to recall something from a past conversation, this is the skill to use.
user_invocable: true
---

# cq: Query Claude Code Sessions

`cq` indexes Claude Code session transcripts into DuckDB and exposes them as SQL views. It reads JSONL files from `~/.claude/projects/`, caches them incrementally, and lets you query sessions, messages, tool calls, and tool results.

## Subcommands

| Command | Purpose |
|---------|---------|
| `cq sessions` | List sessions with metadata |
| `cq search "<QUERY>"` | Relevance-ranked full-text search over message text |
| `cq tools [NAME]` | Query tool calls, optionally filtered by tool name |
| `cq messages` | Query user/assistant messages |
| `cq projects` | Summarize projects by session/message/tool counts |
| `cq sql "<QUERY>"` | Run raw SQL against the views |
| `cq schema` | View schemas and example queries (source of truth) |
| `cq trace --session <ID>` | Render a session as a terminal waterfall (lanes, durations, gaps) |

## Global Flags

- `--project <NAME>` - Substring match on project name
- `--session <ID>` - Session ID (full UUID required, validates format)
- `--source <NAME>` - Scope to a named source (`main`, or a cenv env name); use `--all` to span every source. Every row carries a `source` column.
- `--harness <NAME>` - Scope to `claude` or `codex`; cannot combine with `--source`. cq automatically selects `codex` in Codex and `claude` everywhere else unless `--all` is set.
- `--all` - Remove inferred current-context scope (project, source, and harness)
- `--since <DURATION>` - Time filter (e.g. `7d`, `24h`, `30m`); applies to `search`/`sessions`/`tools`/`messages`, not `cq sql` (raw SQL ignores all scope flags)
- `--json` - Machine-readable JSON output
- `--table` - Aligned table with header
- `--limit <N>` - Max results (default 50, 0 for unlimited)
- `--offset <N>` - Skip first N results (for pagination)

## Subcommand Flags

- **sessions**: `--grep` (filter by content, repeatable/OR)
- **search**: `--type user|assistant`, `--all-matches` (every matching message rather than the best one per session)
- **tools**: `--grep` (filter inputs, repeatable/OR), `--result-grep` (filter by tool result content, repeatable/OR, ANDs with `--errors`), `--errors` (errors only), `--fields` (extract input fields as columns)
- **messages**: `--type user|assistant`, `--grep` (repeatable/OR)
- **trace**: `--session <ID>` (required), `--from`/`--to` (zoom into a time window), `--perfetto` (emit Chrome Trace Event JSON instead of the waterfall). `--perfetto` output's tool spans and "blocked on you" gaps carry an `args.detail` string (tool input, or the gap-closing message, truncated at 200 chars) so it renders directly in Firefox Profiler without a click.

## View Schemas

**sessions**: session_id, project, source, harness, started_at, ended_at, message_count, tool_call_count, user_message_count, subagent_count, first_user_message (counts are main-loop only)

**messages**: session_id, project, source, harness, uuid, parent_uuid, type, timestamp, text, tool_count, model, agent_id, is_sidechain, agent_type, workflow_id, prompt_origin, prompt_source, is_meta (`text` is the first text block of the message; later text blocks aren't included)

**tool_calls**: session_id, project, source, harness, message_uuid, tool_use_id, name, input (JSON), timestamp, agent_id, is_sidechain, agent_type, workflow_id. `advisor()` invocations appear here too, with `name = 'advisor'` (they use a `server_tool_use` block under the hood, not the standard `tool_use`).

**tool_results**: session_id, project, source, harness, timestamp, tool_use_id, is_error, content, agent_id, is_sidechain, agent_type, workflow_id. `advisor()` results appear here with `content` already unwrapped to the advisor's text.

**agents**: session_id, project, source, harness, agent_id, agent_type, description, parent_tool_use_id, spawn_depth, workflow_id, started_at, ended_at, tool_call_count. One row per subagent lane (Claude-only); backs `cq trace`'s lane names.

Subagent rows carry the parent `session_id`. Filter with `WHERE NOT is_sidechain` (main loop), `WHERE is_sidechain` (subagents), `WHERE agent_type = 'Explore'`, or `WHERE workflow_id IS NOT NULL`.

## Querying JSON Input Fields

Tool call inputs are stored as JSON. Extract specific fields with:

```sql
json_extract_string(input, '$.command')    -- Bash commands
json_extract_string(input, '$.file_path')  -- Read/Edit targets
json_extract_string(input, '$.skill')      -- Skill invocations
json_extract_string(input, '$.pattern')    -- Glob/Grep patterns
```

## Querying advisor() Calls

`advisor()` calls show up in `tool_calls`/`tool_results` like any other tool, under `name = 'advisor'`:

```sql
SELECT tc.session_id, tc.timestamp, tr.content
FROM tool_calls tc
JOIN tool_results tr ON tc.tool_use_id = tr.tool_use_id
WHERE tc.name = 'advisor'
ORDER BY tc.timestamp DESC
LIMIT 20;
```

## Full-Text Search (`cq search`)

Reach for `cq search` when you know roughly *what was discussed* but not the
exact wording. It ranks by BM25 relevance with stemming, so `cq search "dependency
migrations"` matches "migrate a dependency". Reach for `messages --grep` instead
when you need an exact substring, or when the ordering you want is chronological
rather than by relevance.

Terms are OR'd, not AND'd, so a multi-word query casts a wide net and leans on
ranking to sort it out. That is usually what you want, since it is what lets one
natural-language query beat a hand-assembled pile of grep patterns.

Results show the **best-scoring message per session**, plus a `matches` column
counting how many messages in that session hit. This matters because the index is
message-level and a session that discussed a topic at length would otherwise fill
the entire page. Pass `--all-matches` when you want every matching passage, for
example to read how a discussion developed within one session.

All global query filters work with search. To return every matching passage from
one known session, combine `--session` and `--all-matches`:

```bash
cq search "dependency migration" --session <SESSION_ID> --all-matches
```

`--json` returns the same result set as an array of objects. Search results include
`session_id`, `type`, `timestamp`, `text`, and `score`; collapsed results also
include `matches`. No-result and stale-index notices stay on stderr, so JSON on
stdout remains valid.

### Search results can be up to 5 minutes stale

The search index is a snapshot, and rebuilding it costs several times a normal
query, so cq lets it lag rather than rebuilding on every search. **A slightly
stale hit is expected behavior, not a bug.**

When cq serves a stale index it says so on stderr, and it escalates the message
when your own current session is among what is missing. Do not suppress stderr on
a `cq search` pipe or you will lose that signal.

What to do about it:

- Searching for something from **the conversation you are in right now**, or from
  the last few minutes: pass `--reindex`. This is the main case where the default
  will genuinely mislead you, because your recent messages may simply not be in
  the index, so you get no hit and nothing looks wrong. `--reindex` rebuilds the
  full transcript cache and search index; query filters such as `--session` narrow
  the returned results, not the rebuild work.
- Searching your **history** (the overwhelmingly common case): ignore it. Five
  minutes of lag is irrelevant when the target is from last week.
- `CQ_FTS_MAX_AGE` changes the window (`0s` refreshes every search, `1h` is
  lazier). `--no-reindex` skips the refresh entirely and errors if no index has
  been built yet.
- cq caps DuckDB per process (`CQ_DUCKDB_THREADS`, default half the cores;
  `CQ_DUCKDB_MEMORY_LIMIT`, default `4GB`; `auto` removes either cap). If a query
  fails with `Out of Memory Error`, cq prints the effective limits after the error:
  narrow the query first, or raise `CQ_DUCKDB_MEMORY_LIMIT` (for example `8GB`).

## Working With cq

- Use `--json` when parsing output programmatically or piping to other tools.
- Do not suppress stderr on a cq pipe (`cq ... --json 2>/dev/null | ...`). If the SQL errors, the error goes to stderr and stdout is empty, so the downstream consumer (e.g. `python3 -c json.load`) dies with a confusing `Expecting value: line 1 column 1` instead of the real cq error. Let stderr through, or redirect to a temp file and check it.
- Do not merge stderr into stdout on a cq pipe either (`cq ... --json 2>&1 | ...`). Progress messages ("Loaded N files", "Synced N new files") are written to stderr by design so stdout stays clean JSON; merging the streams puts those lines back in front of the JSON and breaks the parser. Redirect stderr to a file or the terminal instead: `cq ... --json 2>/tmp/cq.err | ...`.
- The convenience subcommands (`sessions`, `tools`, `messages`, `hooks`) cover most needs. Reach for `cq sql` when you need joins or aggregations across views.
- `--grep` can be repeated for an OR search (`--grep foo --grep bar` matches either), so a multi-term keyword sweep doesn't need to drop to raw SQL with a chain of `ILIKE ... OR ILIKE ...`.
- `tools --grep` searches the tool call's input (what was asked for); `tools --result-grep` searches the tool result's content (what came back, e.g. error text or output). Before `--result-grep` existed, searching result content required a raw `tool_calls JOIN tool_results` query — reach for `cq sql` only if you also need aggregation across that join, not just a text match.
- `--since` filters the convenience subcommands (`sessions`, `tools`, `messages`), but NOT `cq sql`: raw SQL runs verbatim and ignores `--since`/`--project`/`--session`. On `cq sql`, filter time with a string comparison instead, e.g. `WHERE timestamp >= '2026-05-28'`. cq uses DuckDB, not SQLite, so SQLite functions like `datetime()` will not work. Do NOT reach for `WHERE timestamp > now() - INTERVAL N DAY`: it errors (see Tips below).
- `cq` infers current-context scope from the current project, active Claude source, and active harness. The scope hint shows which context is being matched.
- Use `--project <name>` to query a different project (substring match, searches all project directories).
- Use `--all` to remove inferred current-context scope and query more broadly. Explicit filters still apply.
- When searching for work done in a different repo (e.g. karafka sessions while in pickleton), use `--project <name>` or `--all`. Auto-scoping only matches sessions from the current directory's project.
- `cq projects` always shows all projects regardless of auto-scoping, so you can see what's available.
- `cq trace --session <ID> --perfetto` emits Chrome Trace Event JSON. Pipe it into `trace_processor` for local SQL queries over the trace, or open it in the [Perfetto web UI](https://ui.perfetto.dev/) or [Firefox Profiler](https://profiler.firefox.com/).

## Tips for `cq sql`

- Use `<>` instead of `!=` in SQL queries. The shell can mangle `!=` into `\!=`, causing DuckDB parse errors.
- Avoid shell metacharacters in query strings where possible. Single-quote the SQL string to prevent expansion.

### Timestamps are strings

The `timestamp`, `started_at`, and `ended_at` columns are `VARCHAR` ISO 8601 strings (e.g. `2026-05-21T17:48:17.818Z`), not DuckDB timestamps. The format is fixed-width UTC, so lexical order equals chronological order. That means most of what you want already works on the strings:

- **Time windows:** filter on the string directly, e.g. `WHERE timestamp >= '2026-05-28'` (lexical order is chronological). `--since` does NOT apply to `cq sql`; it only filters the `sessions`/`tools`/`messages` subcommands.
- **Explicit ranges:** compare against a string literal, e.g. `WHERE timestamp >= '2026-05-28'`. Comparing against a `TIMESTAMP '...'` literal fails with `Cannot compare VARCHAR and TIMESTAMP`.
- **Sort / bucket by day:** `ORDER BY timestamp` works; `substr(timestamp, 1, 10)` gives the date for `GROUP BY`.

What does NOT work on the raw columns:

- `now() - INTERVAL N DAY` errors with `No function matches '-(TIMESTAMP WITH TIME ZONE, INTERVAL)'`. Compare against a string literal, or cast with `now()::TIMESTAMP - INTERVAL N DAY`. cq surfaces this hint automatically when the query fails.
- `strftime(...)`, `date_trunc(...)`, `extract(...)` need a real timestamp. For genuine per-row date math (e.g. correlating events within a window), cast inline: `timestamp::TIMESTAMP`.

### Aliasing extracted fields: avoid existing column names

`tool_calls` already has real columns named `agent_id`, `agent_type`, `session_id`, `project`, `source`, `harness`, `is_sidechain`, and `workflow_id` (see `cq schema tool_calls`). If you `SELECT json_extract_string(input, '$.some_field') AS agent_type` and then `GROUP BY agent_type`, DuckDB resolves the `GROUP BY` reference to the *real* `agent_type` column, not your alias, since column names win over aliases. The result is a confusing error unrelated to the actual mistake:

```
Error: Binder Error: column "input" must appear in the GROUP BY clause or must be part of an aggregate function.
```

The fix is just to pick an alias that doesn't collide, e.g. `AS extracted_agent_type`. This only bites when the alias happens to match a real column name on the view you're querying — check `cq schema <view>` if a `GROUP BY` error mentions a column you don't remember referencing.

## Error Recovery

When a query fails, returns unexpected results, or a column/view doesn't exist:

1. Run `cq schema` to check the current view definitions and example queries. This skill's inline schemas may be out of date with the installed version of cq.
2. Do not guess at column names or view structures. Check `cq schema` first.
3. If `cq schema` shows different schemas than what's documented here, trust `cq schema` and use what it shows.

If cq fails with `Cannot open file ".../cq/index.duckdb": Operation not permitted`, the cache DB is outside the agent sandbox's writable paths. Retry the command with the sandbox disabled (Claude Code: `dangerouslyDisableSandbox: true`).

Wersje

RepozytoriumWynikLicencja
Ta strona · technicalpickles/cq100MIT
mozilla-ai/cq100Apache-2.0

Migawka bazy z 28.10.2026 · wersja paczki 8aadb26c4e05 (skrót SHA-256 całej paczki)

Pobrania w ostatnich 30 dniach: 0 · ranking

Zgłoś problem z tym skillem: szkodliwa treść, błędny opis albo prośba autora o usunięcie.

Podobne skille

  • 90observability:session
    Odpytuje historię sesji Claude Code przez indeks DuckDB nad ~/.claude/projects/: zużycie tokenów, nad czym pracowano i w których sesjach omawiano dany temat.
  • 100sessions
    Przeszukuje historię sesji agentów kodujących w Claude Code, Codexie i Cursor i odpowiada na pytania o wcześniejsze próby oraz śledztwa.
  • 100claude-code-sessions
    Przeszukuje, analizuje i zarządza historią sesji Claude Code: znajdowanie dawnych sesji, zużycie tokenów, podział narzędzi, wznawianie pracy i zadania, z 11 skillami i panelem webowym.
  • 100query
    Odpowiada na pytania o użycie Claude Code, wykonując zapytania SQL tylko do odczytu na magazynie cclens.
  • 100claude-history-ingest
    Importuje historię rozmów i sesji Claude Code do Obsidiana jako skondensowaną wiedzę, z danych .claude, historii projektów i logów audytu.
  • 100mine-history
    Wydobywa i podsumowuje wnioski z transkryptów dawnych sesji Claude Code do dokumentacji projektu, wskazując powtarzające się wzorce.

Uwagi i zgłoszenia

Wiadomość trafi do Bartosza Sokolińskiego. Adres e-mail jest potrzebny tylko do odpowiedzi. Szczegóły w polityce prywatności.