--- name: obelisk description: > Search and query past Claude Code session history. Reactive: when the user asks "how did I fix X", "what did we do last time", "find the session where", "上次怎么修的", "之前的session", "历史记录". Proactive: when the user references past work you lack context for, when you're about to modify a file with complex edit history, when the user says "继续之前的" or "continue where we left off", or when understanding prior decisions would improve your current response. allowed-tools: - Read - Bash(node:*) - Write --- # obelisk Search and query Claude Code session history stored in `~/.claude/`. Obelisk indexes sessions, messages, tool calls, tool results, summaries, subagents, workflows, workflow agents, parent chains, and raw JSONL lines into SQLite + FTS5. Obelisk is a CodeAct memory layer: write a small JS query, run it locally, read the JSON, then answer. Do not turn history into a flat document or browse entire sessions by default. ## Quick Start The skill directory is provided as `$SKILL_DIR` at invocation time. Fast keyword search: ```bash node $SKILL_DIR/scripts/runtime.mjs --search "keyword" ``` Custom query: 1. Write a bounded JS query to a temp file, for example `/tmp/q.mjs`. 2. Run: ```bash node $SKILL_DIR/scripts/runtime.mjs --query /tmp/q.mjs ``` 3. Parse JSON stdout and answer with concise evidence. The query file runs inside `(async () => { ... })()`. Use `return` to emit JSON. ## Query Routing Before writing a query, classify the task. Progressive disclosure is useful, but skipping the relevant reference usually costs extra query rounds. - Read `references/schema.md` before raw `sql()` unless the needed table/column relationship is already explicit here. Do this before running the SQL, not after a missing-column error. - Read `references/retrieval-semantics.md` before multi-step retrieval, scoped project/file/session searches, or synthesis/conclusion/history questions. It defines the query design frame. - Read `references/query-patterns.md` when you need copyable query scripts: one-shot synthesis, learned detail passes, workflow trees, failure groups, file history, summaries, subagents, raw windows, or empty results. - Read `references/pitfalls.md` after an error or when helper fields, FTS syntax, aliases, or row shapes are unclear. If a helper row shape is unclear, first run a tiny scoped query and return `Object.keys(row)` or a compact sample. Do not invent field names. ## Core API ### `search(text, opts?)` Full-text search across main messages, subagent messages, and workflow-agent messages. Returns: ```js [{ message: { uuid, text, role, timestamp, model, cwd }, session: { id, title, project, started_at }, rank, context }] ``` `context` here means temporal neighbors: nearby messages in the same session by timestamp. It is not the parent chain. Use `context(uuid)` or `trace(uuid)` for causal/parent-chain context. Opts: `{ limit, sessionId, project, after, before, cwd }`. `project` is a SQL `LIKE` filter over `sessions.project`, not an exact project identity. Results are already ordered by FTS5 rank; lower rank sorts earlier. Prefer returned order over manually interpreting numeric rank unless you are deliberately using FTS5 semantics. ### `context(uuid)` Returns the full story around one indexed message: ```js { message, parentChain, session, subagent, workflow } ``` Use this after `search()` finds a promising message. It is the usual way to expand vertically from one evidence point without dumping the whole session. ### `sql(query, ...params)` Raw SQL with `?` placeholders. Returns array rows. Before writing non-trivial SQL, read `references/schema.md`. Common safe joins: - `tool_calls` does not have timestamps. Join `messages m ON m.uuid = tc.message_uuid`. - `tool_results` does not have timestamps. Join `messages m ON m.uuid = tr.message_uuid`. - For project/session filters, join `sessions s ON s.id =