tommy0103andCodex 49158e9b9c docs(readme): add local development and debug instructions for the app
- Add "Run locally" section: clone → cd app → npm ci → npm run dev, with a
  note on first-run indexing, source directories, and WSL auto-detection.
- Add "Debug the app" section: HMR, DevTools shortcuts, main-process logs,
  Node inspector attachment, and isolated HOME for testing.
- Note that better-sqlite3 may need platform build tools if no prebuilt binary
  is available.
- Fix "macOS only" → mention prebuilt for macOS, runnable from source on all
  platforms.
- Fix typo: "A surface for human" → "for humans".
- Fix manual install path wording.

Co-Authored-By: Codex (GPT-5) <noreply@openai.com>
2026-07-16 03:18:23 +08:00

Obelisk

stars version license

Every past Claude Code and Codex session -- queryable by your agent, browsable by you.


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

Obelisk App

You can use obelisk like:

/obelisk 上次 auth bug 最后到底改了哪些文件,为什么这么改
/obelisk 这个文件最近在哪些 sessions 里被反复修改
/obelisk 找出最近失败的 tool calls,它们分别发生在哪些任务里
/obelisk 那个 review workflow 的 subagents 各自结论是什么
/obelisk recap this week

Install

npx skills add tommy0103/obelisk-skill

Or manually: copy obelisk-skill/skills/obelisk into your project's .claude/skills/`

Then in any Claude Code session:

/obelisk <your question>

First run builds the index (~5 seconds for 100 sessions). After that it rebuilds incrementally.

How it works

You ask a question
  ↓
Agent writes a JS query against the SQLite index
  ↓
Runs it via node $SKILL_DIR/scripts/runtime.js --query <script>
  ↓
Reads the JSON result, answers in natural language

Core API: search(), context(), sql(), plus structured helpers (sessions, memories, summaries, workflows, failures, fileHistory, etc).

Memory layer

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.

App: A surface for humans

A companion desktop app for browsing what the skill indexes.

Obelisk App
  • Sessions — browse all sessions with search, project filtering, readable tool calls (diffs, terminal output, file viewers)
  • Memory — list and detail views for registered memory files
  • 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

Prebuilt releases are currently available for macOS from Releases. The source app can be run locally on macOS, Windows, and Linux.

Run locally

Install Node.js 22 and npm, then run the app from its own package directory:

git clone https://github.com/tommy0103/obelisk.git
cd obelisk/app
npm ci
npm run dev

electron-vite starts the renderer dev server and launches Electron. On first run, Obelisk creates ~/.obelisk/obelisk.sqlite, indexes the available Claude Code and Codex transcripts, and then watches them for changes. The default sources are ~/.claude/projects and ~/.codex/sessions; use Settings to point the app at different directories. On Windows, Obelisk also checks common WSL distributions for the Claude Code directory.

Debug the app

  • Renderer changes use Vite hot module replacement. Open Electron DevTools with Cmd+Option+I on macOS or Ctrl+Shift+I on Windows/Linux.
  • Main-process and preload logs appear in the terminal running npm run dev; their source changes are rebuilt by electron-vite.
  • To attach a Node debugger to the Electron main process, start it with npm run dev -- --inspect=5858, then attach your debugger to port 5858.
  • The development app reads and updates the real ~/.obelisk index. Back it up before testing destructive rebuilds. For an isolated run, launch with a disposable home directory (HOME=/tmp/obelisk-dev npm run dev on macOS/Linux, or set a temporary USERPROFILE first on Windows), then select fixture source directories in Settings.

better-sqlite3 provides prebuilt binaries for common platforms. If npm ci falls back to compiling it locally, install the platform's C/C++ build tools and run npm ci again.

What gets indexed

Layer Source What's captured
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
Tool calls every tool invocation Tool name, input, file paths
Subagents Claude subagents/agent-<id>.jsonl; Codex child threads Agent type, description, full conversation
Workflows Claude workflows/wf_<runId>.json Script, result, agent count
Workflow agents Claude subagents/workflows/wf_<runId>/ Per-agent transcripts
Memories registered markdown files Conclusions linked to source sessions

Full-text search via FTS5 covers all layers.

Structure

packages/core/                # @obelisk/core npm workspace (TypeScript + ESM)
├── src/
│   ├── providers/
│   │   ├── types.ts          # Provider + IndexRecord contract
│   │   ├── claude.ts         # Claude Code adapter (line-incremental)
│   │   └── codex.ts          # Codex adapter (full-reparse)
│   ├── persist.ts            # Binding-agnostic record writer (upsert/merge)
│   ├── tx.ts                 # Write transaction + connection config
│   ├── write-coordinator.ts  # Bounded retry policy
│   ├── writer-lease.ts       # Cross-process single-writer lease (SQLite lock DB)
│   ├── core.ts               # buildIndex / searchText / executeQuery / executeAttune
│   ├── indexer.ts            # Skill orchestration (discover → persist → finalize)
│   ├── parsing.ts            # Pure helpers (node:sqlite-free, app-consumable)
│   ├── db.ts                 # node:sqlite lifecycle + migrations
│   ├── query.ts              # Query/attune sandbox API (helpers)
│   ├── runtime.ts            # Thin CLI shell (--build/--search/--query/--attune)
│   └── schema.sql            # SQLite schema (single source of truth)
├── package.json
└── dist/                     # Generated package JS, declarations, and schema

references/                   # Agent-readable docs (progressive disclosure)
├── schema.md
├── api-reference.md
├── 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.
  • Skill publishing stages that artifact at skills/obelisk/ in the obelisk-skill repository; only README.md and LICENSE remain at the repository root for npx skills discovery.

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

The index rebuilds incrementally — only new or modified JSONL files are re-parsed. When the optional app is running, it is the active indexer: it watches Claude project files and builds in a worker thread. A fresh __app_heartbeat__ alone means the daemon owns writes, so the skill remains read-only; a separate SQLite writer lease prevents cross-process writes from overlapping. The __app_last_successful_build__ marker records index freshness, not ownership.

Zero npm dependencies. Uses Node 22's built-in node:sqlite with FTS5. The entire runtime is ~400 lines.

20K lines of scattered JSONL → something the agent can search() and sql() against in milliseconds.


License

AGPL-3.0 @tommy0103

S
Description
Fork of tommy0103/obelisk (AGPL-3.0): agent memory/search layer. Includes local fix so recent() accepts options objects.
Readme AGPL-3.0
8.4 MiB
Languages
JavaScript 51.3%
TypeScript 23%
Vue 15.4%
CSS 5.7%
HTML 4.4%
Other 0.2%