Claude Code-history-ingest — Claude Code skill: Claude Code history
Mines your Claude CLI session logs and turns them into Obsidian wiki pages. Useful once rollout files pile up and the decisions inside them are hard to find.
npx skills add Ar9av/obsidian-wiki --skill codex-history-ingest -a claude-codeWhat codex-history-ingest does
The skill reads ~/.codex/: session_index.jsonl, the rollout logs under sessions/**/rollout-*.jsonl, and history.jsonl when transcript persistence is on. It keeps user intent and assistant-visible output, and drops token accounting, tool plumbing and raw command dumps. Sessions get clustered by topic rather than by date, so one wiki page can draw on a dozen conversations spread across months.
You need a vault path and a history path before the first run. Config resolution follows the protocol in llm-wiki/SKILL.md: an inline @name override first, then a walk up the working directory for .env, then global config, then a setup prompt. CODEX_HISTORY_PATH defaults to ~/.codex.
Append mode checks .manifest.json and processes only files that are new or newer than their ingested_at stamp. Full mode reprocesses everything, which is what you want after wiki-rebuild. Rollout logs can carry API keys and injected prompts, so the skill strips credentials and summarizes transcripts instead of quoting them.
What it helps with
- recover recurring decisions from old Claude sessions
- group conversations by topic instead of by date
- write only what changed since the last ingest run
- strip API keys and tokens from transcripts before they land in notes
- link sessions from different projects through their
cwd
Example prompts for the agent
- run Claude-history-ingest over my Claude sessions and update the wiki
- do a full re-ingest of Claude history after wiki-rebuild
- show me which rollout files are new since the last run
How to install codex-history-ingest
1Skills CLI (Vercel)
npx skills add Ar9av/obsidian-wiki --skill codex-history-ingest -a claude-code2Manually: put the files in place
~/.claude/skills/codex-history-ingest/SKILL.mdCopy the whole skill folder; for one project use .claude/skills/codex-history-ingest/
1Skills CLI (Vercel)
npx skills add Ar9av/obsidian-wiki --skill codex-history-ingest -a codex2Manually: put the files in place
.agents/skills/codex-history-ingest/SKILL.mdFor all projects use ~/.agents/skills/
1Skills CLI (Vercel)
npx skills add Ar9av/obsidian-wiki --skill codex-history-ingest -a cursor2Manually: put the files in place
.cursor/skills/codex-history-ingest/SKILL.mdCursor also reads .agents/skills/ and .claude/skills/
1GitHub CLI
gh skill install Ar9av/obsidian-wiki codex-history-ingest2Manually: put the files in place
.github/skills/codex-history-ingest/SKILL.md1Skills CLI (Vercel)
npx skills add Ar9av/obsidian-wiki --skill codex-history-ingest -a gemini-cli2Platform CLI
gemini skills install https://github.com/Ar9av/obsidian-wiki --path .skills/codex-history-ingestManually: put the files in place
.devin/skills/codex-history-ingest/SKILL.mdThe legacy .windsurf/skills/ path still works
Skills CLI (Vercel)
npx skills add Ar9av/obsidian-wiki --skill codex-history-ingest -a opencodeClaude.ai
Zip the folder and upload it in Settings → Capabilities → Skills
Step by step, with commands for each platform: How to install skills in Claude Code: five ways
Questions about codex-history-ingest
How do I install Claude-history-ingest in Claude?
Run npx skills add Ar9av/obsidian-wiki --skill codex-history-ingest -a claude-code. The skill file then sits at ~/.claude/skills/codex-history-ingest/SKILL.md.
What does Claude-history-ingest do?
It reads Claude CLI session history and distills it into Obsidian pages: projects, concepts, recurring techniques. Chronology is not the point; durable knowledge is.
How is it different from wiki-agent?
This skill ingests the whole Claude history and files it into the wiki. wiki-agent handles targeted recall on a single topic.
Source text
SKILL.md · MIT
---
name: codex-history-ingest
description: >
Ingest Codex CLI conversation/session history into Obsidian as distilled knowledge. Use for importing or mining ~/.codex sessions, rollout files, indexes, or transcript logs; use wiki-agent for targeted topic-only recall.
---
# Codex History Ingest — Conversation Mining
You are extracting knowledge from the user's past Codex sessions and distilling it into the Obsidian wiki. Session logs are rich but noisy: focus on durable knowledge, not operational telemetry.
This skill can be invoked directly or via the `wiki-history-ingest` router (`/wiki-history-ingest codex`).
## Before You Start
**Writing profile:** Before drafting or rewriting natural-language Markdown, read and apply the `Writing Profile Resolution` section in `llm-wiki/SKILL.md`. Framework schema, provenance, safety, and operation-specific requirements take precedence.
`WRITING.md` preferences apply only to newly drafted or rewritten natural-language Markdown; preserve source content and structured records.
1. **Resolve config** — follow the Config Resolution Protocol in `llm-wiki/SKILL.md` (inline `@name` override → walk up CWD for `.env` → global config → prompt setup). This gives `OBSIDIAN_VAULT_PATH` and `CODEX_HISTORY_PATH` (defaults to `~/.codex`)
2. Read `.manifest.json` at the vault root to check what has already been ingested
3. Read `index.md` at the vault root to understand what the wiki already contains
## Ingest Modes
### Append Mode (default)
Check `.manifest.json` for each source file. Only process:
- Files not in the manifest (new session rollouts, new index files)
- Files whose modification time is newer than `ingested_at` in the manifest
Use this mode for regular syncs.
### Full Mode
Process everything regardless of manifest. Use after `wiki-rebuild` or if the user explicitly asks for a full re-ingest.
## Codex Data Layout
Codex stores local artifacts under `~/.codex/`.
```
~/.codex/
├── sessions/ # Session rollout logs by date
│ └── YYYY/MM/DD/
│ └── rollout-<timestamp>-<id>.jsonl
├── archived_sessions/ # Archived rollout logs
├── session_index.jsonl # Lightweight index of thread id/name/updated_at
├── history.jsonl # Local transcript history (if persistence enabled)
├── config.toml # User config (contains history settings)
└── state_*.sqlite / logs_*.sqlite # Runtime DBs (usually skip)
```
### Key data sources ranked by value
1. `session_index.jsonl` — best inventory source for IDs, titles, and freshness
2. `sessions/**/rollout-*.jsonl` — rich structured transcript events
3. `history.jsonl` — useful fallback/timeline aid if enabled
Avoid ingesting SQLite internals unless the user explicitly asks.
## Step 1: Survey and Compute Delta
Scan `CODEX_HISTORY_PATH` and compare against `.manifest.json`:
- `~/.codex/session_index.jsonl`
- `~/.codex/sessions/**/rollout-*.jsonl`
- `~/.codex/archived_sessions/**` (optional; only if user asks for archived history)
- `~/.codex/history.jsonl` (optional fallback)
Classify each file:
- **New** — not in manifest
- **Modified** — in manifest but file is newer than `ingested_at`
- **Unchanged** — already ingested and unchanged
Report a concise delta summary before deep parsing.
## Step 2: Parse Session Index First
`session_index.jsonl` typically has entries like:
```json
{"id":"...","thread_name":"...","updated_at":"..."}
```
Use it to:
- Build a canonical session inventory
- Prioritize recent/high-signal sessions
- Map rollout IDs to human-readable thread names
## Step 3: Parse Rollout JSONL Safely
Each `rollout-*.jsonl` line is an event envelope with:
```json
{
"timestamp": "...",
"type": "session_meta|turn_context|event_msg|response_item",
"payload": { ... }
}
```
### Extraction rules
- Prioritize user intent and assistant-visible outputs
- Favor `response_item` records with user/assistant message content
- Use `event_msg` selectively for meaningful milestones; ignore pure telemetry
- Treat `session_meta` as metadata (cwd, model, ids), not user knowledge
### Skip/noise filters
- Token accounting events
- Tool plumbing with no semantic content
- Raw command output unless it contains reusable decisions/patterns
- Repeated plan snapshots unless they add novel decisions
### Critical privacy filter
Rollout logs can include injected instructions, tool payloads, and sensitive text. Do not ingest verbatim system/developer prompts or secrets.
- Remove API keys, tokens, passwords, credentials
- Redact private identifiers unless relevant and approved
- Summarize instead of quoting raw transcripts
## Step 4: Cluster by Topic
Do not create one wiki page per session.
- Group by stable topics across many sessions
- Split mixed sessions into separate themes
- Merge recurring concepts across dates/projects
- Use `cwd` from metadata to infer project scope
## Step 5: Distill into Wiki Pages
Route extracted knowledge using existing wiki conventions:
- Project-specific architecture/process -> `projects/<name>/...`
- General concepts -> `concepts/`
- Recurring techniques/debug playbooks -> `skills/`
- Tools/services -> `entities/`
- Cross-session patterns -> `synthesis/`
For each impacted project, create/update `projects/<name>/<name>.md` (project name as filename, never `_project.md`).
### Writing rules
- Distill knowledge, not chronology
- Avoid "on date X we discussed..." unless date context is essential
- Add `summary:` frontmatter on each new/updated page (1-2 sentences, <= 200 chars)
- Add confidence and lifecycle fields to every new page:
```yaml
base_confidence: 0.42
lifecycle: draft
lifecycle_changed: <obsidian-wiki memory now --date>
```
Leave `lifecycle` unchanged on update.
- Add provenance markers:
- `^[extracted]` when directly grounded in explicit session content
- `^[inferred]` when synthesizing patterns across events/sessions
- `^[ambiguous]` when sessions conflict
- Add/update `provenance:` frontmatter mix for each changed page
## Step 6: Update Manifest, Log, and Index
### Update `.manifest.json`
For each processed source file:
- `ingested_at`, `size_bytes`, `modified_at`
- `source_type`: `codex_rollout` | `codex_index` | `codex_history`
- `project`: inferred project name (when applicable)
- `pages_created`, `pages_updated`
Add/update a top-level project/session summary block:
```json
{
"project-name": {
"source_path": "~/.codex/sessions/...",
"last_ingested": "TIMESTAMP",
"sessions_ingested": 12,
"sessions_total": 40,
"index_updated_at": "TIMESTAMP"
}
}
```
### Update special files
Update `index.md`, `log.md`, and `hot.md` with one locked call:
```bash
obsidian-wiki memory sync CODEX_HISTORY_INGEST \
sessions=<sessions> pages_updated=<pages_updated> \
pages_created=<pages_created> mode=<mode> \
--takeaways "Ingested 12 Codex sessions; surfaced recurring patterns in CLI tooling and shell scripting."
```
Never hand-edit `index.md`, `log.md`, or `hot.md` — the command takes the lock that keeps a parallel writer from dropping your update. `--takeaways` is the one-line conceptual summary that used to go in Recent Activity;
omit it to leave the previous takeaways untouched.
See `.skills/llm-wiki/references/MEMORY.md` for the full procedure.
## Privacy and Compliance
- Distill and synthesize; avoid raw transcript dumps
- Default to redaction for anything that looks sensitive
- Ask the user before storing personal/sensitive details
- Keep references to other people minimal and purpose-bound
## Reference
See `references/codex-data-format.md` for field-level parsing notes and extraction guidance.
## QMD Refresh After Vault Writes
QMD is a search index, not the source of truth. If `$QMD_WIKI_COLLECTION` is empty or unset, skip this step. Run it only after this skill has written or rewritten vault markdown. If QMD refresh fails, do not roll back the vault changes; report the QMD status separately.
Use `$QMD_CLI` if set; otherwise use `qmd`.
```bash
${QMD_CLI:-qmd} update
```
If the output says vectors are needed or embeddings may be stale, run:
```bash
${QMD_CLI:-qmd} embed
```
Verify the collection with either:
```bash
${QMD_CLI:-qmd} ls "$QMD_WIKI_COLLECTION"
```
or, when a specific page path is known:
```bash
${QMD_CLI:-qmd} get "qmd://$QMD_WIKI_COLLECTION/<page>.md" -l 5
```
Record one of:
- `QMD refreshed: update + embed + verified`
- `QMD refreshed: update only + verified`
- `QMD skipped: QMD_WIKI_COLLECTION unset`
- `QMD skipped: qmd CLI unavailable`
- `QMD failed: <short error summary>`
© Ar9av · MIT · Ar9av/obsidian-wiki