Skill: wufei-png/opencode-session-reader-cn (version 1.0.0)

--- name: opencode-session-reader description: 读取本地 OpenCode SQLite 数据库并执行跨目录 session 查询的技能，适用于会话检索、消息查看与 schema 检查。 --- # OpenCode Session Reader 读取本地 OpenCode SQLite 数据库，支持跨目录检索 session、message、part、project。 ## 适用场景 - 列出最近会话、按目录过滤、按标题搜索 - 读取某个 session 的 message JSON - 查看 OpenCode 数据库结构和索引（按需读取 `references/schema.md`） ## 工作流程 1. 通过 `opencode db path` 解析数据库路径。 2. 所有查询只读执行，避免误写。 3. 需要字段细节时再读取 `references/schema.md`。 ## 1. 解析数据库路径 ```bash if ! command -v opencode >/dev/null 2>&1; then echo "opencode command not found in PATH" >&2 exit 1 fi if ! DB_PATH="$(opencode db path 2>/dev/null)"; then echo "Failed to resolve OpenCode DB path via: opencode db path" >&2 exit 1 fi if [ -z "${DB_PATH:-}" ] || [ ! -f "$DB_PATH" ]; then echo "OpenCode DB not found: $DB_PATH" >&2 exit 1 fi echo "Using DB: $DB_PATH" ``` 列出当前存在的 DB 文件（无匹配也不会报错）： ```bash find "${XDG_DATA_HOME:-$HOME/.local/share}/opencode" -maxdepth 1 -name '*.db' -print 2>/dev/null ``` ## 2. 时间转换与格式化 **时间转换**：所有时间字段为毫秒级 Unix timestamp，可用 `datetime()` 直接在 SQL 中转换。 ```bash # 在 SQL 中转换（推荐，无需外部命令） datetime(time_updated/1000, 'unixepoch', 'localtime') # 用 shell 辅助变量计算时间范围 NOW_MS=$(date +%s000) LAST_7D=$((NOW_MS - 7*86400*1000)) # 最近 7 天 LAST_30D=$((NOW_MS - 30*86400*1000)) # 最近 30 天 ``` **表格对齐**：普通字段查询可通过 `column -t -s '|'` 对齐（SQLite 默认列分隔符为 `|`）；包含 `message.data` 这类长 JSON 字段时建议使用 `-json` 输出。 ```bash sqlite3 -readonly "$DB_PATH" "SELECT id, title, time_updated FROM session LIMIT 5;" | column -t -s '|' ``` ## 3. 常用只读查询 > 💡 不含长 JSON 字段的查询可追加 `| column -t -s '|'` 以对齐输出表格。 **列出最近 20 个 session（按更新时间倒序）** ```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 '|' ``` **按目录过滤 session** ```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 过滤 session（最精确的目录关联方式）** ```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` 字段，可通过 `SELECT id, worktree, name FROM project;` 查看项目列表。 **跨所有目录全量列出 session（带 project 信息）** ```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 天活跃的 session sqlite3 -readonly "$DB_PATH" \ "SELECT id, title, datetime(time_updated/1000,'unixepoch','localtime') as updated FROM session WHERE time_updated > $(( $(date +%s000) - 7*86400*1000 )) ORDER BY time_updated DESC LIMIT 20;" | column -t -s '|' # 今天创建的 session 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 '|' ``` **查看某 session 的消息内容** ```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 等关键字段（json_extract） 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 '|' # 搜索 message 内容（full-text like） sqlite3 -readonly "$DB_PATH" \ "SELECT id, json_extract(data, '$.role') as role, time_created FROM message WHERE data LIKE '%keyword%' ORDER BY time_created DESC LIMIT 20;" | column -t -s '|' ``` **搜索 session 标题** ```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, summary_additions, summary_deletions, summary_files, datetime(time_created/1000,'unixepoch','localtime') as created FROM session ORDER BY time_updated DESC LIMIT 20;" | column -t -s '|' ``` ## 4. 查看 schema ```bash sqlite3 -readonly "$DB_PATH" ".schema session" sqlite3 -readonly "$DB_PATH" ".schema message" sqlite3 -readonly "$DB_PATH" ".schema part" sqlite3 -readonly "$DB_PATH" ".schema project" ``` 完整字段与索引说明见 `references/schema.md`。 ## 5. 查看所有表 ```bash sqlite3 -readonly "$DB_PATH" ".tables" ``` ## 6. 示例输出 ``` id title directory updated ---------- ----------------------- -------------------------- ------------------- ses_abc123 My Session - 2026-03-24 /home/user/project 2026-03-24 10:00:00 ses_def456 Another Session /home/user/other 2026-03-23 15:30:00 ``` （配合 `| column -t -s '|'` 对齐后的效果） ## 7. 注意事项 - 数据库使用 WAL 模式，会产生 `.db-wal` 和 `.db-shm` 文件 - 所有时间字段为**毫秒级 Unix timestamp**，用 `datetime(ts/1000,'unixepoch','localtime')` 在 SQL 中直接转换 - `data` 字段为 JSON：做结构化抽取时用 `json_extract(data, '$.field')`，查看原始消息时优先 `sqlite3 -json` - Session 隔离按 `project_id`，跨目录检索时建议关联 `project.worktree` - 直接修改数据库可能导致数据损坏，操作前建议备份 - `account` / `control_account` 表含敏感凭证，查询时注意脱敏


Security scan verdicts — ClawScan: suspicious | static analysis: clean | VirusTotal: clean | SkillSpector: clean (LOW)