docs(SKILL.md): add raw() usage and sql schema reminder

This commit is contained in:
tommy0103
2026-05-30 04:57:06 +08:00
parent cf8bd1154e
commit 5593990440
2 changed files with 71 additions and 28 deletions
+48 -27
View File
@@ -5,17 +5,16 @@
<img src=".github/assets/obelisk-wordmark-l2.svg" alt="Obelisk" width="540">
</picture>
Every past session, subagent, and workflow — searchable in natural language.
[![stars](https://img.shields.io/github/stars/tommy0103/obelisk?style=flat-square)](https://github.com/tommy0103/obelisk/stargazers)
[![version](https://img.shields.io/github/v/tag/tommy0103/obelisk?label=version&style=flat-square)](https://github.com/tommy0103/obelisk/releases)
[![license](https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square)](LICENSE)
Every past session, subagent, and workflow -- queryable by your agent.
**Humans should not browse session history. Agents should query it.**
</div>
<br />
<div align="center">
@@ -24,18 +23,37 @@ Every past session, subagent, and workflow — searchable in natural language.
<p>Ask in plain language. The agent writes the query, runs it, answers.</p>
</div>
---
## Not a session browser
Most history tools help humans find old chats.
Obelisk is built for agents. It exposes past work as structured data: sessions,
messages, tool calls, subagents, workflows, file history, failures, and parent
chains. The agent writes the query, runs it locally, and answers in plain language.
You don't manage history. You ask questions about past work.
## Why Obelisk
| Session library | Obelisk |
|---|---|
| Find an old chat | Answer a question about past work |
| Human browses snippets | Agent writes and runs a query |
| Search result list | Structured context and reasoning |
| Sessions as documents | Sessions as queryable memory |
| Good for recall | Good for investigation |
## What you can ask
```
/obelisk 上次那个 auth bug 我怎么修的
/obelisk 哪些文件这周被反复修改
/obelisk 最近 workflow 跑出来什么结果
/obelisk 我让 subagent 做过哪些代码 review
/obelisk 上次 auth bug 最后到底改了哪些文件,为什么这么改
/obelisk 这个文件最近在哪些 sessions 里被反复修改
/obelisk 找出最近失败的 tool calls,它们分别发生在哪些任务里
/obelisk 那个 review workflow 的 subagents 各自结论是什么
/obelisk 我之前有没有试过这个方案,结果为什么放弃了
```
Anything Claude Code has done before sessions, tool calls, subagents, workflows — is indexed and searchable. Ask in your own words.
Anything Claude Code has done before -- sessions, tool calls, subagents, workflows -- becomes structured, queryable memory. Ask in your own words.
## Install
@@ -58,19 +76,6 @@ First run builds the index (~5 seconds for 100 sessions). After that it rebuilds
- Node.js 22+ (uses built-in node:sqlite with FTS5)
- Claude Code with skills support.
## What gets indexed
| Layer | Source | What's captured |
|-------|--------|----------------|
| **Sessions** | `<project>/<sessionId>.jsonl` | Title, project, timestamps, git branch |
| **Messages** | user + assistant turns | Full text, model, token usage, parent chain |
| **Tool calls** | every tool invocation | Tool name, input, file paths touched |
| **Subagents** | `subagents/agent-<id>.jsonl` | Agent type, description, full conversation |
| **Workflows** | `workflows/wf_<runId>.json` | Script, structured result, agent count |
| **Workflow agents** | `subagents/workflows/wf_<runId>/` | Per-agent transcripts linked to workflow |
Full-text search via FTS5 covers all message text across every layer.
## How it works
```
@@ -83,7 +88,11 @@ Runs it via node runtime.mjs --query <script>
Reads the JSON result, answers you in natural language
```
The core idea: **don't design a query DSL** — let the agent write code. An agent that can write workflow scripts can also write query scripts. Same sandbox, same mental model.
**The core idea: don't make humans browse, tag, or organize sessions.**
Don't invent a rigid query DSL either.
Agents can write code. So Obelisk gives them a small local query runtime over
your past work.
The agent has a two-tier API. Most questions only need the simple layer:
@@ -99,6 +108,19 @@ The agent has a two-tier API. Most questions only need the simple layer:
The design is progressive disclosure: the agent doesn't see the full schema until it needs it.
## What gets indexed
| Layer | Source | What's captured |
|-------|--------|----------------|
| **Sessions** | `<project>/<sessionId>.jsonl` | Title, project, timestamps, git branch |
| **Messages** | user + assistant turns | Full text, model, token usage, parent chain |
| **Tool calls** | every tool invocation | Tool name, input, file paths touched |
| **Subagents** | `subagents/agent-<id>.jsonl` | Agent type, description, full conversation |
| **Workflows** | `workflows/wf_<runId>.json` | Script, structured result, agent count |
| **Workflow agents** | `subagents/workflows/wf_<runId>/` | Per-agent transcripts linked to workflow |
Full-text search via FTS5 covers message text across every layer, while the SQLite tables preserve the structure agents need for investigation.
## Structure
```
@@ -110,7 +132,7 @@ The design is progressive disclosure: the agent doesn't see the full schema unti
└── schema.md # Full table schema + advanced API + query patterns
```
## Design
## Implementation Notes
The index rebuilds incrementally — only new or modified JSONL files are re-parsed.
@@ -124,4 +146,3 @@ Zero npm dependencies. Uses Node 22's built-in node:sqlite with FTS5. The entire
MIT @tommy0103
+22
View File
@@ -58,6 +58,8 @@ Latest n sessions (default 10). Returns session rows with title, project, starte
Raw SQL. Use `?` placeholders. Returns array of row objects.
**Before writing your first SQL query, read `references/schema.md` for the full table schema, column names, and relationships.** Don't guess column names — the schema is your source of truth.
Tables: `sessions`, `messages`, `tool_calls`, `tool_results`, `subagents`, `workflows`, `workflow_agents`, `messages_fts`
### Other APIs
@@ -69,6 +71,26 @@ Tables: `sessions`, `messages`, `tool_calls`, `tool_results`, `subagents`, `work
- `workflowTree(runId)` -- workflow + its agents + all their messages
- `fileHistory(filePath)` -- every Edit/Write/Read on a file across sessions
- `failures(sessionId?)` -- tool calls that returned errors, with surrounding context
- `raw(uuid, opts?)` -- windowed access to the original JSONL line (bypasses index truncation)
### raw(uuid, opts?)
Some indexed fields (tool call inputs, tool results) are truncated to 10k chars. `raw()` reads the original JSONL line to recover the full content.
Returns: `{ text, totalLength, offset, limit, hasMore }`
opts: `{ offset: 0, limit: 10000 }` — character window into the raw JSONL line.
```js
// First window
const r = raw(messageUuid)
// r.text = first 10k chars of the original JSONL line
// r.totalLength = full line length
// r.hasMore = true if more content remains
// Scroll forward
const r2 = raw(messageUuid, { offset: 10000, limit: 10000 })
```
## Examples