@letta-ai/letta-code 0.14.16 → 0.15.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,162 @@
1
+ ---
2
+ name: Migrating from Codex and Claude Code
3
+ description: Find and search historical conversation data from Claude Code and OpenAI Codex CLIs. Use when you need to understand a user's coding patterns, learn about a project from past sessions, or bootstrap agent memory from historical context.
4
+ ---
5
+
6
+ # Migrating from Codex and Claude Code
7
+
8
+ This skill helps you discover, search, and extract useful information from historical Claude Code and OpenAI Codex conversations stored on the user's machine.
9
+
10
+ ## When to Use This Skill
11
+
12
+ - During `/init` to bootstrap agent memory with project context
13
+ - When the user asks about their previous coding sessions
14
+ - To understand coding patterns, preferences, or project history
15
+ - To find context about a specific project or problem the user worked on before
16
+
17
+ ## Scripts
18
+
19
+ This skill includes ready-to-use scripts for common operations:
20
+
21
+ | Script | Purpose |
22
+ |--------|---------|
23
+ | `scripts/detect.sh` | Detect available history and show summary |
24
+ | `scripts/list-sessions.sh` | List sessions for a project |
25
+ | `scripts/search.sh` | Search across all history by keyword |
26
+ | `scripts/view-session.sh` | View a session in readable format |
27
+
28
+ ### Quick Start
29
+
30
+ ```bash
31
+ # Detect what history data exists
32
+ ./scripts/detect.sh
33
+
34
+ # List sessions for current project
35
+ ./scripts/list-sessions.sh claude
36
+ ./scripts/list-sessions.sh codex
37
+
38
+ # Search for a keyword across all history
39
+ ./scripts/search.sh "database migration"
40
+ ./scripts/search.sh "auth" --claude --project /path/to/project
41
+
42
+ # View a specific session
43
+ ./scripts/view-session.sh ~/.claude/projects/-path-to-project/session.jsonl
44
+ ./scripts/view-session.sh session.jsonl --tools --thinking
45
+ ```
46
+
47
+ ## Data Locations
48
+
49
+ ### Claude Code (`~/.claude/`)
50
+
51
+ | Path | Contents |
52
+ |------|----------|
53
+ | `history.jsonl` | Global prompt history (all projects) - **always available** |
54
+ | `projects/<encoded-path>/` | Per-project conversation sessions - **may not exist for older projects** |
55
+ | `projects/<encoded-path>/sessions-index.json` | Quick session metadata lookup |
56
+ | `projects/<encoded-path>/<session-uuid>.jsonl` | Full conversation history |
57
+ | `settings.json` | User preferences (model, plugins) |
58
+
59
+ **Path Encoding**: Claude encodes project paths by replacing `/` with `-`:
60
+ - `/Users/foo/repos/myproject` → `-Users-foo-repos-myproject`
61
+
62
+ **Important**: Session files may not exist for older projects (cleaned up or not persisted). In this case, `history.jsonl` still contains the user's prompts but not full conversations. The scripts will automatically fall back to searching history.jsonl.
63
+
64
+ ### OpenAI Codex (`~/.codex/`)
65
+
66
+ | Path | Contents |
67
+ |------|----------|
68
+ | `history.jsonl` | Global prompt history — uses `.ts` (seconds) and `.text` fields (NOT `.timestamp`/`.display`) |
69
+ | `sessions/<year>/<month>/<day>/rollout-*.jsonl` | Session files by date |
70
+ | `config.toml` | User config (model, trusted projects) |
71
+
72
+ **Important format difference**: Codex uses `.ts` (seconds) and `.text`, while Claude uses `.timestamp` (milliseconds) and `.display`. Adjust jq queries accordingly.
73
+
74
+ ## Quick Searches
75
+
76
+ ### Find Sessions for Current Project
77
+
78
+ ```bash
79
+ # For Claude Code - encode current path
80
+ ENCODED=$(pwd | sed 's|/|-|g')
81
+ ls ~/.claude/projects/$ENCODED/ 2>/dev/null
82
+
83
+ # Check sessions index for quick metadata
84
+ cat ~/.claude/projects/$ENCODED/sessions-index.json 2>/dev/null | jq '.entries[] | {firstPrompt, messageCount, modified}'
85
+
86
+ # If session files don't exist, search history.jsonl instead
87
+ cat ~/.claude/history.jsonl | jq --arg p "$(pwd)" 'select(.project == $p)'
88
+ ```
89
+
90
+ ### Search by Project Name (Fallback)
91
+
92
+ When session files don't exist (older/cleaned up projects), search history.jsonl:
93
+
94
+ ```bash
95
+ # Search by exact project path
96
+ cat ~/.claude/history.jsonl | jq 'select(.project == "/path/to/project")'
97
+
98
+ # Search by project name (partial match)
99
+ cat ~/.claude/history.jsonl | jq 'select(.project | contains("project-name"))'
100
+
101
+ # List all prompts for a project
102
+ cat ~/.claude/history.jsonl | jq -r 'select(.project | contains("myproject")) | "\(.timestamp / 1000 | strftime("%Y-%m-%d %H:%M")) \(.display[0:80])..."'
103
+ ```
104
+
105
+ ### Search Prompt History
106
+
107
+ ```bash
108
+ # Claude - search all prompts
109
+ cat ~/.claude/history.jsonl | jq 'select(.display | test("keyword"; "i"))'
110
+
111
+ # Codex - search all prompts (.text field, .ts in seconds)
112
+ cat ~/.codex/history.jsonl | jq 'select(.text | test("keyword"; "i"))'
113
+ ```
114
+
115
+ ### Find User Messages in Sessions
116
+
117
+ ```bash
118
+ # Claude - extract user messages from a session
119
+ cat ~/.claude/projects/<path>/<session>.jsonl | jq 'select(.type == "user") | .message.content'
120
+
121
+ # Codex - extract user messages from a session
122
+ cat ~/.codex/sessions/<path>/rollout-*.jsonl | jq 'select(.type == "event_msg" and .payload.type == "user_message") | .payload.message'
123
+ ```
124
+
125
+ ### Analyze Tool Usage Patterns
126
+
127
+ ```bash
128
+ # Claude - what tools does the user's assistant use most?
129
+ cat ~/.claude/projects/<path>/<session>.jsonl | jq 'select(.type == "assistant") | .message.content[]? | select(.type == "tool_use") | .name' | sort | uniq -c | sort -rn
130
+
131
+ # Codex - tool usage
132
+ cat ~/.codex/sessions/<path>/rollout-*.jsonl | jq 'select(.type == "response_item" and .payload.type == "function_call") | .payload.name' | sort | uniq -c | sort -rn
133
+ ```
134
+
135
+ ## Extracting Context for Memory Blocks
136
+
137
+ ### Projects the User Has Worked On
138
+
139
+ ```bash
140
+ # Claude - list all projects with activity counts
141
+ cat ~/.claude/history.jsonl | jq -s 'group_by(.project) | map({project: .[0].project, count: length}) | sort_by(-.count)'
142
+ ```
143
+
144
+ ### Recent Session Summaries
145
+
146
+ Claude sessions may contain summary entries:
147
+ ```bash
148
+ cat ~/.claude/projects/<path>/<session>.jsonl | jq 'select(.type == "summary") | .summary'
149
+ ```
150
+
151
+ ### Common Workflows/Commands
152
+
153
+ Look for patterns in Bash tool calls:
154
+ ```bash
155
+ cat ~/.claude/projects/<path>/<session>.jsonl | jq 'select(.type == "assistant") | .message.content[]? | select(.type == "tool_use" and .name == "Bash") | .input.command' | head -20
156
+ ```
157
+
158
+ ## Detailed Format Documentation
159
+
160
+ For complete format specifications, see:
161
+ - [references/claude-format.md](references/claude-format.md) - Claude Code JSONL structure
162
+ - [references/codex-format.md](references/codex-format.md) - OpenAI Codex JSONL structure
@@ -0,0 +1,212 @@
1
+ # Claude Code Data Format Reference
2
+
3
+ ## Directory Structure
4
+
5
+ ```
6
+ ~/.claude/
7
+ ├── history.jsonl # Global prompt history
8
+ ├── projects/ # Per-project data
9
+ │ └── -Users-...-<path>/ # Encoded directory paths
10
+ │ ├── sessions-index.json # Quick session metadata
11
+ │ ├── <session-uuid>.jsonl # Full conversation sessions
12
+ │ └── agent-<id>.jsonl # Agent-specific sessions
13
+ ├── settings.json # User preferences
14
+ ├── statsig/ # Analytics
15
+ └── debug/ # Debug logs
16
+ ```
17
+
18
+ ## Path Encoding
19
+
20
+ Claude encodes project paths by replacing `/` with `-`:
21
+ ```
22
+ /Users/username/repos/myproject → -Users-username-repos-myproject
23
+ ```
24
+
25
+ To encode a path programmatically:
26
+ ```bash
27
+ ENCODED=$(pwd | sed 's|/|-|g')
28
+ ```
29
+
30
+ ## Global History (`history.jsonl`)
31
+
32
+ Each line is a JSON object representing a user prompt:
33
+
34
+ ```json
35
+ {
36
+ "display": "fix this test: npm run test:unit",
37
+ "pastedContents": {},
38
+ "timestamp": 1759105062139,
39
+ "project": "/Users/username/repos/myproject",
40
+ "sessionId": "0fd6a5d1-c1e4-494f-82d6-9391ccc1797d"
41
+ }
42
+ ```
43
+
44
+ | Field | Description |
45
+ |-------|-------------|
46
+ | `display` | The user's prompt text |
47
+ | `pastedContents` | Any pasted content (files, images) |
48
+ | `timestamp` | Unix timestamp in milliseconds |
49
+ | `project` | Working directory path |
50
+ | `sessionId` | Links to session file |
51
+
52
+ ## Sessions Index (`sessions-index.json`)
53
+
54
+ Quick metadata lookup without parsing full session files:
55
+
56
+ ```json
57
+ {
58
+ "version": 1,
59
+ "entries": [
60
+ {
61
+ "sessionId": "0fd6a5d1-c1e4-494f-82d6-9391ccc1797d",
62
+ "fullPath": "/Users/username/.claude/projects/-Users-sarah-repos-myproject/0fd6a5d1-....jsonl",
63
+ "fileMtime": 1768524387632,
64
+ "firstPrompt": "fix the failing test in auth.ts",
65
+ "messageCount": 14,
66
+ "created": "2026-01-16T00:39:26.583Z",
67
+ "modified": "2026-01-16T00:46:27.609Z",
68
+ "gitBranch": "feature/auth-fix",
69
+ "projectPath": "/Users/username/repos/myproject",
70
+ "isSidechain": false
71
+ }
72
+ ]
73
+ }
74
+ ```
75
+
76
+ ## Session Files (`<session-uuid>.jsonl`)
77
+
78
+ Each line is a JSON object. Message types:
79
+
80
+ ### User Message
81
+
82
+ ```json
83
+ {
84
+ "type": "user",
85
+ "uuid": "8705b595-71fb-4a97-be0b-edc2fe934724",
86
+ "parentUuid": null,
87
+ "sessionId": "079c7831-6083-4b29-9fe2-534da46f2585",
88
+ "cwd": "/Users/username/repos/myproject",
89
+ "gitBranch": "main",
90
+ "timestamp": "2025-12-23T03:01:20.501Z",
91
+ "message": {
92
+ "role": "user",
93
+ "content": "please help me fix the lint errors"
94
+ }
95
+ }
96
+ ```
97
+
98
+ ### User Message with Tool Results
99
+
100
+ When responding to tool calls, content is an array:
101
+
102
+ ```json
103
+ {
104
+ "type": "user",
105
+ "message": {
106
+ "role": "user",
107
+ "content": [
108
+ {
109
+ "type": "tool_result",
110
+ "tool_use_id": "toolu_01FTU3GpL9GpoJXd8WitDSd2",
111
+ "content": "Exit code 0\nChecked 265 files...",
112
+ "is_error": false
113
+ }
114
+ ]
115
+ }
116
+ }
117
+ ```
118
+
119
+ ### Assistant Message
120
+
121
+ Content is always an array with multiple block types:
122
+
123
+ ```json
124
+ {
125
+ "type": "assistant",
126
+ "uuid": "64064220-5503-44f1-8f3c-d6862b249309",
127
+ "parentUuid": "8705b595-71fb-4a97-be0b-edc2fe934724",
128
+ "message": {
129
+ "role": "assistant",
130
+ "model": "claude-opus-4-5-20251101",
131
+ "content": [
132
+ {
133
+ "type": "thinking",
134
+ "thinking": "The user wants me to fix linting errors. Let me first run the lint command.",
135
+ "signature": "EowCCkY..."
136
+ },
137
+ {
138
+ "type": "text",
139
+ "text": "I'll run the linter to see what errors exist:"
140
+ },
141
+ {
142
+ "type": "tool_use",
143
+ "id": "toolu_01FTU3GpL9GpoJXd8WitDSd2",
144
+ "name": "Bash",
145
+ "input": {
146
+ "command": "bun run lint",
147
+ "description": "Run linter"
148
+ }
149
+ }
150
+ ],
151
+ "usage": {
152
+ "input_tokens": 10,
153
+ "cache_creation_input_tokens": 4691,
154
+ "cache_read_input_tokens": 14987,
155
+ "output_tokens": 3
156
+ }
157
+ }
158
+ }
159
+ ```
160
+
161
+ ### Content Block Types
162
+
163
+ | Type | Fields | Description |
164
+ |------|--------|-------------|
165
+ | `thinking` | `thinking`, `signature` | Chain-of-thought reasoning |
166
+ | `text` | `text` | Final response text |
167
+ | `tool_use` | `id`, `name`, `input` | Tool invocation |
168
+
169
+ ### Summary Entry
170
+
171
+ Auto-generated conversation summaries:
172
+
173
+ ```json
174
+ {
175
+ "type": "summary",
176
+ "summary": "The user asked me to fix linting errors in the auth module...",
177
+ "leafMessageId": "abc-123",
178
+ "timestamp": "2025-12-23T03:05:00.000Z"
179
+ }
180
+ ```
181
+
182
+ ## Settings (`settings.json`)
183
+
184
+ ```json
185
+ {
186
+ "apiKey": "sk-ant-...",
187
+ "customApiKey": "sk-ant-...",
188
+ "permissions": {
189
+ "allow": ["Bash(npm run lint)", "Read"],
190
+ "deny": ["Bash(rm -rf)"]
191
+ }
192
+ }
193
+ ```
194
+
195
+ ## Useful jq Queries
196
+
197
+ ```bash
198
+ # List all unique projects with session counts
199
+ cat ~/.claude/history.jsonl | jq -s 'group_by(.project) | map({project: .[0].project, count: length}) | sort_by(-.count)'
200
+
201
+ # Extract all user messages from a session
202
+ cat session.jsonl | jq 'select(.type == "user") | .message.content | if type == "string" then . else .[0].text // .[0].content // empty end'
203
+
204
+ # Get all tool calls in a session
205
+ cat session.jsonl | jq 'select(.type == "assistant") | .message.content[]? | select(.type == "tool_use") | {name, input}'
206
+
207
+ # Find sessions that modified specific files
208
+ cat session.jsonl | jq 'select(.type == "assistant") | .message.content[]? | select(.type == "tool_use" and .name == "Write") | .input.file_path'
209
+
210
+ # Get token usage statistics
211
+ cat session.jsonl | jq 'select(.type == "assistant") | .message.usage | select(. != null)'
212
+ ```
@@ -0,0 +1,229 @@
1
+ # OpenAI Codex Data Format Reference
2
+
3
+ ## Directory Structure
4
+
5
+ ```
6
+ ~/.codex/
7
+ ├── history.jsonl # Global prompt history
8
+ ├── sessions/ # Per-session data, organized by date
9
+ │ └── <year>/
10
+ │ └── <month>/
11
+ │ └── <day>/
12
+ │ └── rollout-<timestamp>.jsonl # Session files
13
+ ├── config.toml # User configuration
14
+ └── instructions.md # Custom instructions file
15
+ ```
16
+
17
+ ## Global History (`history.jsonl`)
18
+
19
+ Each line is a JSON object representing a user prompt:
20
+
21
+ ```json
22
+ {
23
+ "text": "fix the failing test in auth.ts",
24
+ "ts": 1759105062
25
+ }
26
+ ```
27
+
28
+ | Field | Description |
29
+ |-------|-------------|
30
+ | `text` | The user's prompt text |
31
+ | `ts` | Unix timestamp in seconds |
32
+
33
+ Note: Unlike Claude Code, Codex history doesn't include the project path. You need to correlate with session files to determine project context.
34
+
35
+ ## Configuration (`config.toml`)
36
+
37
+ ```toml
38
+ model = "o4-mini"
39
+
40
+ [history]
41
+ persistence = "across-sessions"
42
+ save_inputs = true
43
+
44
+ [[project_doc_approval]]
45
+ project_directory = "/Users/username/repos/myproject"
46
+
47
+ [[full_auto_approval]]
48
+ project_directory = "/Users/username/repos/myproject"
49
+ ```
50
+
51
+ Key fields:
52
+ - `model` - Default model
53
+ - `project_doc_approval` - Projects where docs auto-approval is enabled
54
+ - `full_auto_approval` - Projects with full auto-approval (trusted)
55
+
56
+ ## Session Files (`rollout-<timestamp>.jsonl`)
57
+
58
+ Each line is a JSON object. Event types:
59
+
60
+ ### Session Metadata
61
+
62
+ First entry in each session file:
63
+
64
+ ```json
65
+ {
66
+ "type": "session_meta",
67
+ "payload": {
68
+ "model_provider": "openai",
69
+ "model_name": "o4-mini",
70
+ "cwd": "/Users/username/repos/myproject",
71
+ "session_id": "sess_abc123",
72
+ "git": {
73
+ "branch": "main",
74
+ "commit": "abc1234"
75
+ }
76
+ },
77
+ "ts": 1759105062
78
+ }
79
+ ```
80
+
81
+ ### User Message
82
+
83
+ ```json
84
+ {
85
+ "type": "event_msg",
86
+ "payload": {
87
+ "type": "user_message",
88
+ "message": "fix the failing test in auth.ts"
89
+ },
90
+ "ts": 1759105063
91
+ }
92
+ ```
93
+
94
+ ### Agent Reasoning
95
+
96
+ ```json
97
+ {
98
+ "type": "event_msg",
99
+ "payload": {
100
+ "type": "agent_reasoning",
101
+ "text": "I need to look at the test file to understand what's failing..."
102
+ },
103
+ "ts": 1759105064
104
+ }
105
+ ```
106
+
107
+ ### Function Call (Tool Use)
108
+
109
+ ```json
110
+ {
111
+ "type": "response_item",
112
+ "payload": {
113
+ "type": "function_call",
114
+ "id": "fc_abc123",
115
+ "call_id": "call_abc123",
116
+ "name": "shell",
117
+ "arguments": "{\"command\":[\"cat\",\"src/tests/auth.test.ts\"]}"
118
+ },
119
+ "ts": 1759105065
120
+ }
121
+ ```
122
+
123
+ Common function names:
124
+ - `shell` - Execute shell commands
125
+ - `file_edit` - Edit files
126
+ - `file_read` - Read files
127
+ - `create_file` - Create new files
128
+
129
+ ### Function Call Output
130
+
131
+ ```json
132
+ {
133
+ "type": "response_item",
134
+ "payload": {
135
+ "type": "function_call_output",
136
+ "call_id": "call_abc123",
137
+ "output": "import { test, expect } from 'bun:test';\n..."
138
+ },
139
+ "ts": 1759105066
140
+ }
141
+ ```
142
+
143
+ ### Assistant Message
144
+
145
+ ```json
146
+ {
147
+ "type": "response_item",
148
+ "payload": {
149
+ "type": "message",
150
+ "role": "assistant",
151
+ "content": [
152
+ {
153
+ "type": "output_text",
154
+ "text": "I found the issue. The test is failing because..."
155
+ }
156
+ ]
157
+ },
158
+ "ts": 1759105067
159
+ }
160
+ ```
161
+
162
+ ### Background Event (Exec Approval)
163
+
164
+ ```json
165
+ {
166
+ "type": "event_msg",
167
+ "payload": {
168
+ "type": "exec_approval_request",
169
+ "command": ["npm", "run", "test"]
170
+ },
171
+ "ts": 1759105068
172
+ }
173
+ ```
174
+
175
+ ## Key Differences from Claude Code
176
+
177
+ | Feature | Claude Code | Codex |
178
+ |---------|-------------|-------|
179
+ | **History format** | Includes project path | No project path |
180
+ | **Session organization** | By project directory | By date |
181
+ | **Path encoding** | Replace `/` with `-` | N/A |
182
+ | **Tool call format** | `tool_use` blocks | `function_call` events |
183
+ | **Thinking** | `thinking` blocks | `agent_reasoning` events |
184
+ | **Timestamps** | Milliseconds | Seconds |
185
+ | **Session index** | `sessions-index.json` | None (scan date dirs) |
186
+ | **Config format** | JSON | TOML |
187
+
188
+ ## Useful jq Queries
189
+
190
+ ```bash
191
+ # List all sessions with their project directories
192
+ find ~/.codex/sessions -name "*.jsonl" -exec sh -c 'echo "$1: $(head -1 "$1" | jq -r ".payload.cwd // \"?\"" 2>/dev/null)"' _ {} \;
193
+
194
+ # Get all user messages from a session
195
+ cat rollout-*.jsonl | jq -r 'select(.type == "event_msg" and .payload.type == "user_message") | .payload.message'
196
+
197
+ # Get all tool calls from a session
198
+ cat rollout-*.jsonl | jq 'select(.type == "response_item" and .payload.type == "function_call") | {name: .payload.name, args: .payload.arguments}'
199
+
200
+ # Find sessions that used shell commands
201
+ cat rollout-*.jsonl | jq -r 'select(.type == "response_item" and .payload.type == "function_call" and .payload.name == "shell") | .payload.arguments | fromjson | .command | join(" ")'
202
+
203
+ # Get assistant text responses
204
+ cat rollout-*.jsonl | jq -r 'select(.type == "response_item" and .payload.type == "message" and .payload.role == "assistant") | .payload.content[]? | select(.type == "output_text") | .text'
205
+
206
+ # Search history by keyword
207
+ cat ~/.codex/history.jsonl | jq -r --arg kw "test" 'select(.text | test($kw; "i")) | "\(.ts | strftime("%Y-%m-%d %H:%M")) \(.text)"'
208
+
209
+ # Find all trusted projects
210
+ grep -A1 "full_auto_approval" ~/.codex/config.toml 2>/dev/null
211
+ ```
212
+
213
+ ## Session File Naming
214
+
215
+ Session files follow the pattern:
216
+ ```
217
+ rollout-<ISO-timestamp>.jsonl
218
+ ```
219
+
220
+ Example: `rollout-2025-12-23T03:01:20.501Z.jsonl`
221
+
222
+ Sessions are organized by date:
223
+ ```
224
+ sessions/
225
+ └── 2025/
226
+ └── 12/
227
+ └── 23/
228
+ └── rollout-2025-12-23T03:01:20.501Z.jsonl
229
+ ```