docs(readme): rewrite for dual-surface product (skill + app) and workspace structure

Rewrite README to reflect the current state of the project:
- Describe both surfaces: skill (agent-first retrieval) and app (human browser).
- Add Codex support section (unified schema, source tagging, child-thread mapping).
- Update Structure tree to match the packages/core workspace layout with all
  TypeScript modules (providers, persist, tx, write-coordinator, writer-lease).
- Document generated build outputs (packages/core/dist, dist/obelisk-skill).
- License badge corrected to AGPL-3.0 (skill artifact is MIT; source is AGPL).
- Skill invocation examples updated to /obelisk-skill.
- Add recap flow documentation.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
tommy0103
2026-07-12 00:59:33 +08:00
co-authored by Claude Opus 4.8
parent 8af0f9a31d
commit 410b0a8df3
+125 -126
View File
@@ -7,186 +7,185 @@
[![stars](https://img.shields.io/github/stars/tommy0103/obelisk?style=flat-square)](https://github.com/tommy0103/obelisk/stargazers) [![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) [![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) [![license](https://img.shields.io/badge/license-AGPL--3.0-blue.svg?style=flat-square)](LICENSE)
Every past session, subagent, and workflow -- queryable by your agent. Every past Claude Code and Codex session -- queryable by your agent, browsable by you.
**Humans should not browse session history. Agents should query it.**
</div> </div>
<br /> <br />
## Two sides of the same index
Obelisk has two sides that share one SQLite index:
**Skill side** — an agent skill that lets coding agents search and query their own session history. The agent writes JS queries, runs them locally, answers in plain language.
**App side** — an Electron desktop app for humans to browse sessions, manage memories, view usage stats, and see weekly recap cards.
Both read from the same `~/.obelisk/obelisk.sqlite` database. The indexer reads Claude Code transcripts from `~/.claude/projects` and Codex transcripts from `~/.codex/sessions`.
## Codex support
Obelisk indexes Claude Code and Codex into the same SQLite schema instead of keeping separate databases. Rows carry a `source` value (`claude` or `codex`), and Codex IDs are prefixed with `codex:` so they cannot collide with Claude session IDs.
Codex root threads become normal Obelisk sessions. Codex child threads are attached through the same `subagents` table when parent-thread metadata is available. Codex does not emit Claude-style workflow metadata, so workflow tables may be empty for Codex-only history.
For live app refresh, Obelisk watches `~/.claude/projects` and `~/.codex/sessions`. It does not watch the whole `~/.codex` root. Codex's `session_index.jsonl` is used as lightweight title/update metadata during indexing, not as the message transcript source.
## Skill: agent-first retrieval
<div align="center"> <div align="center">
<img src=".github/assets/demo.png" alt="Obelisk in action" width="540"> <img src=".github/assets/demo.png" alt="Obelisk App" width="720">
<br />
<p>Ask in plain language. The agent writes the query, runs it, answers.</p>
</div> </div>
## Not a session browser You can use obelisk like:
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, parent
chains, and human-approved markdown memories. 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-skill 上次 auth bug 最后到底改了哪些文件,为什么这么改
/obelisk 这个文件最近在哪些 sessions 里被反复修改 /obelisk-skill 这个文件最近在哪些 sessions 里被反复修改
/obelisk 找出最近失败的 tool calls,它们分别发生在哪些任务里 /obelisk-skill 找出最近失败的 tool calls,它们分别发生在哪些任务里
/obelisk 那个 review workflow 的 subagents 各自结论是什么 /obelisk-skill 那个 review workflow 的 subagents 各自结论是什么
/obelisk 我之前有没有试过这个方案,结果为什么放弃了 /obelisk-skill recap this week
``` ```
Anything Claude Code has done before -- sessions, tool calls, subagents, workflows -- becomes structured, queryable memory. Ask in your own words. ### Install
## Install
```bash ```bash
npx skills add tommy0103/obelisk-skill npx skills add tommy0103/obelisk-skill
``` ```
Or manually: copy `obelisk/` into your project's `.claude/skills/`. Or manually: copy `obelisk-skill/` into your project's `.claude/skills/`
Then in any Claude Code session: Then in any Claude Code session:
``` ```
/obelisk <your question> /obelisk-skill <your question>
``` ```
First run builds the index (~5 seconds for 100 sessions). After that it rebuilds incrementally. First run builds the index (~5 seconds for 100 sessions). After that it rebuilds incrementally.
### Requires ### How it works
- Node.js 22+ (uses built-in node:sqlite with FTS5)
- Claude Code with skills support.
## How it works
``` ```
You ask a question You ask a question
Agent writes a JS query against the SQLite index Agent writes a JS query against the SQLite index
Runs it via node runtime.mjs --query <script> Runs it via node $SKILL_DIR/scripts/runtime.js --query <script>
Reads the JSON result, answers you in natural language Reads the JSON result, answers in natural language
``` ```
When a retrieval produces a memory worth keeping, the agent proposes a markdown Core API: `search()`, `context()`, `sql()`, plus structured helpers (`sessions`, `memories`, `summaries`, `workflows`, `failures`, `fileHistory`, etc).
memory file. After user approval, it registers that file with the narrow
`runtime.mjs --attune <script>` runtime, which exposes only memory mutation
helpers such as `remember()` and `forget()`.
Memory is a synthesis cache, not a replacement for raw sessions. The agent can ### Memory layer
decide whether to use, ignore, or verify a memory during an answer. Persistent
changes still require human approval, but explicit corrections count: if you say
a memory is wrong, outdated, or should be replaced, the agent can archive or
update the exact matching record without a second confirmation.
**The core idea: don't make humans browse, tag, or organize sessions.** When a retrieval produces a conclusion worth keeping, the agent proposes a markdown memory file. After user approval, it registers the file with `runtime.js --attune <script>`. Memories are recalled via `memories()` in future sessions — a synthesis cache, not a replacement for raw evidence.
Don't invent a rigid query DSL either.
Agents can write code. So Obelisk gives them a small local query runtime over ## App: A surface for human
your past work.
The agent starts from a small core API, then uses structured shortcuts and A companion desktop app for browsing what the skill indexes.
references only when the question needs them:
**Core primitives** — the main CodeAct surface: <div align="center">
<img src=".github/assets/app-screenshot.png" alt="Obelisk App" width="720">
</div>
- `search(text)` — FTS5 full-text search, returns matches with surrounding context plus message `content_type` and `is_meta` - **Sessions** — browse all sessions with search, project filtering, readable tool calls (diffs, terminal output, file viewers)
- `context(uuid)` — full story around a message (parent chain, subagent/workflow metadata) - **Memory** — list and detail views for registered memory files
- `sql(query, ...params)` — read-only SQL for structured queries - **Activity** — GitHub-style heatmap, weekly/cumulative token charts
- **Recap** — shareable weekly/monthly recap cards with archetype theming
- **Settings** — data source configuration, auto-refresh, rebuild index
**Structured shortcuts** — overview, session, memory, summary, subagent, macOS only. Download from [Releases](https://github.com/tommy0103/obelisk/releases).
workflow, file-history, failure, raw-window, and parent-chain helpers over the
same SQLite data.
**References** — agent reads on demand when the task needs deeper structure:
- `references/schema.md` — full SQLite schema and API reference
- `references/query-patterns.md` — copyable CodeAct recipes for common retrieval tasks
- `references/retrieval-semantics.md` — query design frame for scoped and synthesis retrieval
- `references/recap/overview.md` — optional `/obelisk recap` card-by-card entrypoint
- `references/recap/pattern1-cover.md` and `references/recap/writing1-cover.md`
- `references/recap/pattern2-thinking.md` and `references/recap/writing2-thinking.md`
- `references/recap/pattern3-vibe.md` and `references/recap/writing3-vibe.md`
- `references/recap/pattern4-workflow.md` and `references/recap/writing4-workflow.md`
- `references/recap/pattern5-closing.md` and `references/recap/writing5-closing.md`
- `references/pitfalls.md` — scope, FTS, ordering, compact/raw, and field-name traps
The executable SQLite schema lives in `scripts/schema.sql`; `references/schema.md`
is the human/agent explanation of that contract.
The design is progressive disclosure with guardrails: the main skill keeps the
core contract and high-risk pitfalls visible, while longer recipes and the full
schema stay out of the first prompt until the agent needs them.
The optional recap references are only for the explicit `/obelisk recap` intent;
they are not part of the ordinary retrieval path. `references/recap/overview.md`
drives a card-by-card loop: read one card's retrieval pattern, gather that
card's evidence, read its writing reference, update the JSON, then continue.
This keeps schema, taste, and query planning from competing in one large prompt.
## What gets indexed ## What gets indexed
| Layer | Source | What's captured | | Layer | Source | What's captured |
|-------|--------|----------------| |-------|--------|----------------|
| **Sessions** | `<project>/<sessionId>.jsonl` | Title, project, timestamps, git branch | | **Sessions** | Claude `<project>/<sessionId>.jsonl`; Codex `sessions/YYYY/MM/DD/*.jsonl` | Title, project, timestamps, git branch, source |
| **Messages** | user + assistant turns | Full text, model, token usage, parent chain | | **Messages** | user + assistant turns | Full text, model, token usage, parent chain |
| **Tool calls** | every tool invocation | Tool name, input, file paths touched | | **Tool calls** | every tool invocation | Tool name, input, file paths |
| **Subagents** | `subagents/agent-<id>.jsonl` | Agent type, description, full conversation | | **Subagents** | Claude `subagents/agent-<id>.jsonl`; Codex child threads | Agent type, description, full conversation |
| **Workflows** | `workflows/wf_<runId>.json` | Script, structured result, agent count | | **Workflows** | Claude `workflows/wf_<runId>.json` | Script, result, agent count |
| **Workflow agents** | `subagents/workflows/wf_<runId>/` | Per-agent transcripts linked to workflow | | **Workflow agents** | Claude `subagents/workflows/wf_<runId>/` | Per-agent transcripts |
| **Memories** | markdown files registered by the agent after user approval | Prior conclusions linked to source sessions/messages and optional anchors | | **Memories** | registered markdown files | Conclusions linked to source sessions |
Full-text search via FTS5 covers message text across every session layer and ranked memory recall over registered memory summaries, while the SQLite tables preserve the structure agents need for investigation. Full-text search via FTS5 covers all layers.
## Structure ## Structure
``` ```
.claude/skills/obelisk/ packages/core/ # @obelisk/core npm workspace (TypeScript + ESM)
├── SKILL.md # Skill definition + simple API + examples ├── src/
├── scripts/ │ ├── providers/
│ ├── schema.sql # Executable SQLite schema │ ├── types.ts # Provider + IndexRecord contract
└── runtime.mjs # Indexer + query runtime (zero deps) │ ├── claude.ts # Claude Code adapter (line-incremental)
└── references/ │ │ └── codex.ts # Codex adapter (full-reparse)
├── schema.md # Full table schema + advanced API reference ├── persist.ts # Binding-agnostic record writer (upsert/merge)
├── query-patterns.md # Copyable retrieval recipes ├── tx.ts # Write transaction + connection config
├── retrieval-semantics.md # Query design frame for retrieval semantics ├── write-coordinator.ts # Bounded retry policy
├── recap-patterns.md # Compatibility pointer to references/recap/overview.md ├── writer-lease.ts # Cross-process single-writer lease (SQLite lock DB)
├── recap-writing.md # Compatibility pointer to per-card recap writing docs ├── core.ts # buildIndex / searchText / executeQuery / executeAttune
├── recap/ ├── indexer.ts # Skill orchestration (discover → persist → finalize)
│ ├── overview.md │ ├── parsing.ts # Pure helpers (node:sqlite-free, app-consumable)
│ ├── pattern1-cover.md │ ├── db.ts # node:sqlite lifecycle + migrations
│ ├── writing1-cover.md │ ├── query.ts # Query/attune sandbox API (helpers)
│ ├── pattern2-thinking.md │ ├── runtime.ts # Thin CLI shell (--build/--search/--query/--attune)
│ ├── writing2-thinking.md │ └── schema.sql # SQLite schema (single source of truth)
│ ├── pattern3-vibe.md ├── package.json
│ ├── writing3-vibe.md └── dist/ # Generated package JS, declarations, and schema
│ ├── pattern4-workflow.md
│ ├── writing4-workflow.md references/ # Agent-readable docs (progressive disclosure)
│ ├── pattern5-closing.md ├── schema.md
│ └── writing5-closing.md ├── api-reference.md
└── pitfalls.md # Scope, FTS, ordering, and compactness traps ├── query-patterns.md
├── retrieval-semantics.md
├── pitfalls.md
├── recap-patterns.md
├── recap-writing.md
└── recap/ # Per-card pattern + writing references
├── overview.md
├── pattern1-cover.md … pattern5-closing.md
└── writing1-cover.md … writing5-closing.md
app/ # Electron desktop app (electron-vite + Vue)
├── src/main/ # TypeScript main process (consumes shared core)
├── src/preload/ # CJS preload (sandbox)
├── src/renderer/ # Vue renderer
└── electron.vite.config.ts
packaging/ # Skill publish infrastructure
├── skill-package.json
├── skill-README.md
├── skill-LICENSE # MIT (relicensed for the skill artifact)
└── publish-skill.sh
SKILL.md # Skill definition (installed with the artifact)
CONTEXT.md # Project glossary
docs/adr/ # Architecture decision records (00010006)
``` ```
The optional `/obelisk recap` flow is loaded only for explicit `/obelisk recap` intent.
It starts at `references/recap/overview.md` and proceeds card-by-card:
- `references/recap/pattern1-cover.md` + `references/recap/writing1-cover.md`
- `references/recap/pattern2-thinking.md` + `references/recap/writing2-thinking.md`
- `references/recap/pattern3-vibe.md` + `references/recap/writing3-vibe.md`
- `references/recap/pattern4-workflow.md` + `references/recap/writing4-workflow.md`
- `references/recap/pattern5-closing.md` + `references/recap/writing5-closing.md`
### Generated build outputs
- `packages/core/dist/` is produced by `npm run build:core`. It is the compiled
`@obelisk/core` package: JavaScript, type declarations, and `schema.sql`.
- `dist/obelisk-skill/` is produced by `npm run build:skill`. It is the
install-ready skill artifact: readable plain JavaScript under `scripts/`,
`SKILL.md`, references, and the skill package metadata.
Both directories are generated and should not be edited by hand. The Electron
app imports `packages/core/src/` directly so electron-vite can bundle Core.
## Implementation Notes ## Implementation Notes
The index rebuilds incrementally — only new or modified JSONL files are re-parsed. The index rebuilds incrementally — only new or modified JSONL files are re-parsed.
@@ -204,4 +203,4 @@ Zero npm dependencies. Uses Node 22's built-in node:sqlite with FTS5. The entire
## License ## License
MIT @tommy0103 AGPL-3.0 @tommy0103