@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.
- package/letta.js +7335 -5536
- package/package.json +1 -1
- package/skills/initializing-memory/SKILL.md +236 -157
- package/skills/migrating-from-codex-and-claude-code/SKILL.md +162 -0
- package/skills/migrating-from-codex-and-claude-code/references/claude-format.md +212 -0
- package/skills/migrating-from-codex-and-claude-code/references/codex-format.md +229 -0
- package/skills/migrating-from-codex-and-claude-code/scripts/detect.sh +113 -0
- package/skills/migrating-from-codex-and-claude-code/scripts/list-sessions.sh +87 -0
- package/skills/migrating-from-codex-and-claude-code/scripts/search.sh +137 -0
- package/skills/migrating-from-codex-and-claude-code/scripts/view-session.sh +110 -0
- package/skills/syncing-memory-filesystem/SKILL.md +117 -43
|
@@ -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
|
+
```
|