Class: Ask::CodingProviders::Codex::CodexDB
- Inherits:
-
Object
- Object
- Ask::CodingProviders::Codex::CodexDB
- Defined in:
- lib/ask/coding_providers/codex/codex_db.rb
Overview
Queries Codex's SQLite database for thread/project data.
Codex stores sessions in ~/.codex/state_5.sqlite (threads table)
and full message history in JSONL rollout files.
Constant Summary collapse
- DEFAULT_DB =
File.("~/.codex/state_5.sqlite")
Instance Method Summary collapse
- #available? ⇒ Boolean
-
#find_recent_session ⇒ Object
Find the most recent session across all projects.
-
#find_recent_tui_session(workspace_path) ⇒ Object
Find the most recent TUI session in a workspace.
-
#find_sessions(directory:, limit: 20) ⇒ Object
Find sessions in a given directory.
-
#initialize(db_path = nil) ⇒ CodexDB
constructor
A new instance of CodexDB.
-
#list_projects ⇒ Object
List all projects (directories with threads), ordered by most recent.
-
#recent_sessions ⇒ Object
List recent sessions across all projects.
-
#session_directory(session_id) ⇒ Object
Look up a session's workspace directory by ID.
-
#session_history(session_id, limit: 100) ⇒ Object
Get session message history from the rollout JSONL file.
Constructor Details
#initialize(db_path = nil) ⇒ CodexDB
Returns a new instance of CodexDB.
15 16 17 |
# File 'lib/ask/coding_providers/codex/codex_db.rb', line 15 def initialize(db_path = nil) @db_path = db_path || DEFAULT_DB end |
Instance Method Details
#available? ⇒ Boolean
19 20 21 |
# File 'lib/ask/coding_providers/codex/codex_db.rb', line 19 def available? File.exist?(@db_path) end |
#find_recent_session ⇒ Object
Find the most recent session across all projects. Returns directory: or nil.
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/ask/coding_providers/codex/codex_db.rb', line 81 def find_recent_session return nil unless available? db = open_db row = db.get_first_row(<<~SQL) SELECT id, cwd FROM threads WHERE archived = 0 ORDER BY updated_at DESC LIMIT 1 SQL row ? { session_id: row["id"], directory: row["cwd"] } : nil rescue => e nil ensure db&.close end |
#find_recent_tui_session(workspace_path) ⇒ Object
Find the most recent TUI session in a workspace.
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/ask/coding_providers/codex/codex_db.rb', line 98 def find_recent_tui_session(workspace_path) return nil unless available? db = open_db row = db.get_first_row(<<~SQL, [workspace_path, workspace_path]) SELECT id, title, cwd FROM threads WHERE (cwd = ? OR ? LIKE cwd || '/%') AND archived = 0 ORDER BY updated_at DESC LIMIT 1 SQL return nil unless row { session_id: row["id"], title: row["title"], directory: row["cwd"] } rescue => e nil ensure db&.close end |
#find_sessions(directory:, limit: 20) ⇒ Object
Find sessions in a given directory. Returns [title:, updated:] or [].
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/ask/coding_providers/codex/codex_db.rb', line 54 def find_sessions(directory:, limit: 20) return [] unless available? db = open_db rows = db.execute(<<~SQL, [directory, directory, limit]) SELECT id, title, updated_at, preview FROM threads WHERE (cwd = ? OR ? LIKE cwd || '/%') AND archived = 0 ORDER BY updated_at DESC LIMIT ? SQL rows.map do |r| { session_id: r["id"], title: r["title"].to_s.empty? ? (r["preview"] || "(untitled)") : r["title"], updated: r["updated_at"] } end rescue => e [] ensure db&.close end |
#list_projects ⇒ Object
List all projects (directories with threads), ordered by most recent. Returns [directory:, session_count:] or [].
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/ask/coding_providers/codex/codex_db.rb', line 25 def list_projects return [] unless available? db = open_db rows = db.execute(<<~SQL) SELECT cwd AS directory, COUNT(*) AS session_count, MAX(updated_at) AS last_active FROM threads WHERE archived = 0 GROUP BY cwd ORDER BY last_active DESC LIMIT 20 SQL rows.map do |r| { project_id: r["directory"], directory: r["directory"], session_count: r["session_count"].to_i } end rescue => e [] ensure db&.close end |
#recent_sessions ⇒ Object
List recent sessions across all projects. Returns [title:, updated:, msg_count:] or [].
154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 |
# File 'lib/ask/coding_providers/codex/codex_db.rb', line 154 def recent_sessions return [] unless available? db = open_db rows = db.execute(<<~SQL) SELECT id, title, updated_at, preview FROM threads WHERE archived = 0 ORDER BY updated_at DESC LIMIT 50 SQL rows.map do |r| { session_id: r["id"], title: r["title"].to_s.empty? ? (r["preview"] || "(untitled)") : r["title"], updated: r["updated_at"], msg_count: 0 } end rescue => e [] ensure db&.close end |
#session_directory(session_id) ⇒ Object
Look up a session's workspace directory by ID.
121 122 123 124 125 126 127 128 129 130 131 |
# File 'lib/ask/coding_providers/codex/codex_db.rb', line 121 def session_directory(session_id) return nil unless available? db = open_db row = db.get_first_row("SELECT cwd FROM threads WHERE id = ?", [session_id]) row&.dig("cwd") rescue => e nil ensure db&.close end |
#session_history(session_id, limit: 100) ⇒ Object
Get session message history from the rollout JSONL file. Returns [role:, origin:] or [].
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 |
# File 'lib/ask/coding_providers/codex/codex_db.rb', line 135 def session_history(session_id, limit: 100) return [] unless available? db = open_db row = db.get_first_row("SELECT rollout_path, title, preview FROM threads WHERE id = ?", [session_id]) return [] unless row rollout_path = row["rollout_path"] return [] unless rollout_path && File.exist?(rollout_path) parse_rollout(rollout_path, limit) rescue => e [] ensure db&.close end |