OpenCode Session Toolkit
Read the local OpenCode SQLite database and query or export sessions, messages, parts, and projects across directories.
All commands below assume the workdir is this skill directory. For Markdown export, run the bundled script directly:
CODEBLOCK0
When to use
- - List recent sessions, filter by directory, or search by title
- Read message JSON for a specific session
- Export matched sessions into one-Markdown-per-session archives
- Inspect database schema and indexes (load
references/schema.md only when needed)
Workflow
- 1. Resolve the database path with
opencode db path. - Run all queries in read-only mode.
- Load
references/schema.md only when field-level details are required.
1. Resolve the database path
CODEBLOCK1
List existing DB files (no error when there is no match):
CODEBLOCK2
2. Time conversion and output formatting
Time conversion: all time fields are Unix timestamps in milliseconds. Convert them directly in SQL with datetime().
CODEBLOCK3
Table alignment: for normal fields, pipe SQLite output to column -t -s '|' (| is SQLite's default delimiter). For long JSON fields such as message.data, prefer -json output.
CODEBLOCK4
3. Common read-only queries
Tip: For queries without large JSON fields, append | column -t -s '|' for aligned table output.
List the latest 20 sessions (most recently updated first)
CODEBLOCK5
Filter sessions by directory
CODEBLOCK6
Filter sessions by project_id (most precise project linkage)
CODEBLOCK7
INLINECODE10 maps to project.id. List projects with:
CODEBLOCK8
List sessions across all directories (with project info)
CODEBLOCK9
Filter by time range
CODEBLOCK10
Read message content for one session
CODEBLOCK11
Extract fields from message.data JSON
CODEBLOCK12
Search session titles
CODEBLOCK13
View session summary stats
CODEBLOCK14
4. Export sessions to Markdown
The export script writes one session per Markdown file. By default:
- - filename = INLINECODE13
- time filtering uses
time_updated unless --time-field created is passed - INLINECODE16 /
step-finish parts are skipped to reduce noise - when
project.name is empty, project folder names fall back to the worktree basename, or INLINECODE19
Export sessions for one project
CODEBLOCK15
INLINECODE20 matches by substring against project_id, project.name, project.worktree, and session.directory.
Export sessions in a time range
CODEBLOCK16
Accepted time formats:
- - ISO date: INLINECODE25
- ISO datetime: INLINECODE26
- Unix seconds / milliseconds
Full export grouped by project
CODEBLOCK17
Output example:
CODEBLOCK18
Useful extra filters
- -
--session-id ses_xxx: exact session export - INLINECODE28 : match session titles
- INLINECODE29 : match session directories
- INLINECODE30 : filter archived sessions
- INLINECODE31 : choose which session time goes into the filename
- INLINECODE32 : export only certain part types
- INLINECODE33 : drop noisy part types
- INLINECODE34 : overwrite existing files instead of appending the session id to avoid collisions
If no filters are provided, the script requires --all to avoid accidental full-database exports.
5. Inspect schema
CODEBLOCK19
For complete field and index notes, see references/schema.md.
6. List all tables
CODEBLOCK20
7. Example output
CODEBLOCK21
(Aligned with | column -t -s '|'.)
8. Notes
- - OpenCode uses SQLite WAL mode, so
.db-wal and .db-shm files are expected. - Time fields are Unix timestamps in milliseconds. Convert with
datetime(ts/1000,'unixepoch','localtime'). - INLINECODE41 fields are JSON. Use
json_extract(data, '$.field') for structured extraction, and prefer sqlite3 -json for raw message inspection. - Session isolation is anchored by
project_id; for cross-directory queries, joining project.worktree is recommended. - Direct writes can corrupt data. Back up before any non-read-only operation.
- INLINECODE46 and
control_account tables may contain sensitive credentials. Redact outputs when sharing.
OpenCode Session Toolkit
读取本地 OpenCode SQLite 数据库,跨目录查询或导出会话、消息、片段和项目。
以下所有命令均假设工作目录为此技能目录。如需 Markdown 导出,直接运行捆绑脚本:
bash
./scripts/exportopencodesessions.py --help
使用场景
- - 列出最近会话,按目录筛选,或按标题搜索
- 读取特定会话的消息 JSON
- 将匹配的会话导出为每个会话一个 Markdown 文件的归档
- 检查数据库模式和索引(仅在需要时加载 references/schema.md)
工作流程
- 1. 使用 opencode db path 解析数据库路径。
- 以只读模式运行所有查询。
- 仅在需要字段级详细信息时加载 references/schema.md。
1. 解析数据库路径
bash
if ! command -v opencode >/dev/null 2>&1; then
echo opencode 命令未在 PATH 中找到 >&2
exit 1
fi
if ! DB_PATH=$(opencode db path 2>/dev/null); then
echo 通过 opencode db path 解析 OpenCode 数据库路径失败 >&2
exit 1
fi
if [ -z ${DBPATH:-} ] || [ ! -f $DBPATH ]; then
echo 未找到 OpenCode 数据库:$DB_PATH >&2
exit 1
fi
echo 使用数据库:$DB_PATH
列出现有数据库文件(无匹配时不报错):
bash
find ${XDGDATAHOME:-$HOME/.local/share}/opencode -maxdepth 1 -name *.db -print 2>/dev/null
2. 时间转换与输出格式化
时间转换:所有时间字段均为 Unix 毫秒时间戳。在 SQL 中直接使用 datetime() 进行转换。
bash
在 SQL 中转换(推荐,无需外部命令)
datetime(time_updated/1000, unixepoch, localtime)
Shell 辅助变量用于时间窗口
NOW_MS=$(date +%s000)
LAST
7D=$((NOWMS - 7
864001000))
LAST
30D=$((NOWMS - 30
864001000))
表格对齐:对于普通字段,将 SQLite 输出通过管道传递给 column -t -s |(| 是 SQLite 的默认分隔符)。对于长 JSON 字段(如 message.data),建议使用 -json 输出。
bash
sqlite3 -readonly $DBPATH SELECT id, title, timeupdated FROM session LIMIT 5; | column -t -s |
3. 常用只读查询
提示:对于不含大 JSON 字段的查询,追加 | column -t -s | 以获得对齐的表格输出。
列出最近 20 个会话(按最近更新时间排序)
bash
sqlite3 -readonly $DB_PATH \
SELECT id, title, directory,
datetime(time_updated/1000,unixepoch,localtime) as updated
FROM session
ORDER BY time_updated DESC
LIMIT 20; | column -t -s |
按目录筛选会话
bash
sqlite3 -readonly $DB_PATH \
SELECT id, title, datetime(time_updated/1000,unixepoch,localtime) as updated
FROM session
WHERE directory LIKE /path/to/project%
ORDER BY time_updated DESC
LIMIT 20; | column -t -s |
按 project_id 筛选会话(最精确的项目关联)
bash
sqlite3 -readonly $DB_PATH \
SELECT s.id, s.title, s.directory,
datetime(s.time_updated/1000,unixepoch,localtime) as updated
FROM session s
WHERE s.project_id = your-project-id
ORDER BY s.time_updated DESC
LIMIT 20; | column -t -s |
project_id 映射到 project.id。使用以下命令列出项目:
bash
sqlite3 -readonly $DB_PATH SELECT id, worktree, name FROM project; | column -t -s |
列出所有目录中的会话(含项目信息)
bash
sqlite3 -readonly $DB_PATH \
SELECT s.id, s.title, s.directory, p.worktree,
datetime(s.time_updated/1000,unixepoch,localtime) as updated
FROM session s
LEFT JOIN project p ON s.project_id = p.id
ORDER BY s.time_updated DESC
LIMIT 50; | column -t -s |
按时间范围筛选
bash
最近 7 天活跃的会话
sqlite3 -readonly $DB_PATH \
SELECT id, title, datetime(time_updated/1000,unixepoch,localtime) as updated
FROM session
WHERE time_updated > $(( $(date +%s000) - 7
864001000 ))
ORDER BY time_updated DESC
LIMIT 20; | column -t -s |
今天创建的会话(本地时间)
sqlite3 -readonly $DB_PATH \
SELECT id, title, datetime(time_created/1000,unixepoch,localtime) as created
FROM session
WHERE date(time_created/1000,unixepoch,localtime) = date(now,localtime)
ORDER BY time_created DESC
LIMIT 20; | column -t -s |
读取单个会话的消息内容
bash
sqlite3 -readonly -json $DB_PATH \
SELECT m.id, datetime(m.time_created/1000,unixepoch,localtime) as created, m.data
FROM message m
WHERE m.session_id = your-session-id
ORDER BY m.time_created ASC;
从 message.data JSON 中提取字段
bash
提取关键字段,如 role 和 modelID
sqlite3 -readonly $DB_PATH \
SELECT id,
json_extract(data, $.role) as role,
json_extract(data, $.modelID) as model,
datetime(time_created/1000,unixepoch,localtime) as created
FROM message
WHERE session_id = your-session-id
ORDER BY time_created ASC; | column -t -s |
使用 LIKE 搜索消息负载文本
sqlite3 -readonly $DB_PATH \
SELECT id, json
extract(data, $.role) as role, timecreated
FROM message
WHERE data LIKE %keyword%
ORDER BY time_created DESC
LIMIT 20; | column -t -s |
搜索会话标题
bash
sqlite3 -readonly $DB_PATH \
SELECT id, title, directory, datetime(time_updated/1000,unixepoch,localtime) as updated
FROM session
WHERE title LIKE %keyword%
ORDER BY time_updated DESC
LIMIT 20; | column -t -s |
查看会话摘要统计
bash
sqlite3 -readonly $DB_PATH \
SELECT title, summaryadditions, summarydeletions, summary_files,
datetime(time_created/1000,unixepoch,localtime) as created
FROM session
ORDER BY time_updated DESC
LIMIT 20; | column -t -s |
4. 将会话导出为 Markdown
导出脚本将每个会话写入一个 Markdown 文件。默认情况下:
- - 文件名 = 会话标题 + 创建时间
- 时间筛选使用 time_updated,除非传递了 --time-field created
- 跳过 step-start / step-finish 片段以减少噪音
- 当 project.name 为空时,项目文件夹名称回退到 worktree 的基本名称,或 global
导出一个项目的会话
bash
./scripts/exportopencodesessions.py \
--project opencode-session-toolkit \
--output-dir ./exports/opencode-session-toolkit
--project 通过子字符串匹配 project_id、project.name、project.worktree 和 session.directory。
导出时间范围内的会话
bash
./scripts/exportopencodesessions.py \
--start 2026-03-01 \
--end 2026-03-24T23:59:59 \
--time-field updated \
--output-dir ./exports/march
接受的时间格式: