← Files Portable ResumeARCHIVED FILE
skills/.portable-resume/runtime/portable_resume/adapters/codex_sqlite.py
10.4 KB · Oct 4, 2026 · 12:33 UTC
"""Codex state SQLite list/probe helpers (extracted from codex adapter)."""
from __future__ import annotations
import contextlib
import os
import sqlite3
import stat
import uuid
from pathlib import Path
from typing import Any, Iterator
from ..bounds import DEFAULT_BOUNDS, ReadBudget
from ..diagnostics import DiagnosticError
from ..model import Query, SessionSummary
from ..paths import canonicalize_cwd, is_within, same_cwd
from ..snapshot import private_sqlite_connection, query_only_live_sqlite
from . import codex as _codex
SQLITE_FORMAT = _codex.SQLITE_FORMAT
_exact_uuid_ref = _codex._exact_uuid_ref
_within = _codex._within
_numeric_time = _codex._numeric_time
_trusted_zstd = _codex._trusted_zstd
_rollout_id = _codex._rollout_id
def _table_signature(connection: sqlite3.Connection) -> tuple[bool, str | None]:
"""Accept pinned column *supersets* (live Codex adds optional columns).
Presence is required for id, rollout_path, source, cwd, and archived, but
their declared type affinity is not checked because SQLite affinity is loose
in live stores. One of updated_at_ms / updated_at must have integer affinity.
Optional title/first_user_message/git_branch may be absent (SQL SELECT still
names them — missing optional columns fail later; require the optional trio
when present or use COALESCE-compatible fixed SELECT).
"""
try:
rows = connection.execute("PRAGMA table_info(threads)").fetchall()
except sqlite3.Error:
return False, None
columns: dict[str, str] = {}
for row in rows:
if len(row) < 3 or not isinstance(row[1], str) or not isinstance(row[2], str):
return False, None
columns[row[1]] = row[2].upper().split("(", 1)[0]
required = {"id", "rollout_path", "source", "cwd", "archived"}
if not required.issubset(columns):
return False, None
# Prefer millisecond column when both exist (live state_5 has both).
if "updated_at_ms" in columns and columns["updated_at_ms"] in {"INTEGER", "INT", "BIGINT", "NUM", "NUMERIC"}:
updated = "updated_at_ms"
elif "updated_at" in columns and columns["updated_at"] in {"INTEGER", "INT", "BIGINT", "NUM", "NUMERIC"}:
updated = "updated_at"
else:
return False, None
return True, updated
def _resolve_rollout_path(root: str, raw: str, identifier: str) -> str | None:
if "\x00" in raw or any(part == ".." for part in Path(raw).parts):
return None
candidate = raw if os.path.isabs(raw) else os.path.join(root, raw)
canonical = canonicalize_cwd(candidate)
prefixes = [
canonicalize_cwd(os.path.join(root, name))
for name in ("sessions", "archived_sessions")
if os.path.isdir(os.path.join(root, name))
]
if not any(is_within(canonical, prefix) for prefix in prefixes):
return None
try:
current = os.lstat(canonical)
except OSError:
return None
if stat.S_ISLNK(current.st_mode) or not stat.S_ISREG(current.st_mode):
return None
if _rollout_id(canonical) != identifier:
alternate = canonical + ".zst"
try:
current = os.lstat(alternate)
except OSError:
return None
if stat.S_ISLNK(current.st_mode) or not stat.S_ISREG(current.st_mode) or _rollout_id(alternate) != identifier:
return None
canonical = alternate
return canonical
@contextlib.contextmanager
def _database_connection(path: str, root: str) -> Iterator[sqlite3.Connection]:
"""Prefer a bounded snapshot, then safely fall back when it stays busy."""
try:
size = os.path.getsize(path)
except OSError as error:
raise DiagnosticError("E_SOURCE_BUSY", source="codex", provider=SQLITE_FORMAT) from error
with contextlib.ExitStack() as stack:
if size > DEFAULT_BOUNDS.sqlite_snapshot_bytes:
connection = stack.enter_context(
query_only_live_sqlite(path, root=root, provider=SQLITE_FORMAT)
)
else:
try:
connection = stack.enter_context(
private_sqlite_connection(path, root=root, provider=SQLITE_FORMAT)
)
except DiagnosticError as error:
if error.code != "E_SOURCE_BUSY":
raise
connection = stack.enter_context(
query_only_live_sqlite(path, root=root, provider=SQLITE_FORMAT)
)
yield connection
def _database_summaries(
path: str, root: str, query: Query, budget: ReadBudget
) -> tuple[bool, list[SessionSummary], int]:
"""Return ``(schema_supported, summaries, unresolved_path_count)``.
``unresolved_path_count`` counts eligible SQL rows whose rollout path could
not be resolved (missing, symlink, UUID mismatch, or zstd without decoder).
Callers use it to decide read-only filesystem head fallback (#7).
"""
def _fetch_rows(connection: sqlite3.Connection) -> tuple[bool, str | None, list[tuple]]:
supported, updated_column = _table_signature(connection)
if not supported or updated_column is None:
return False, None, []
try:
info = connection.execute("PRAGMA table_info(threads)").fetchall()
present = {row[1] for row in info if isinstance(row[1], str)}
title_expr = "title" if "title" in present else "NULL"
first_expr = "first_user_message" if "first_user_message" in present else "NULL"
branch_expr = "git_branch" if "git_branch" in present else "NULL"
select = (
f"SELECT id, rollout_path, {updated_column}, source, cwd, "
f"{title_expr}, {first_expr}, archived, {branch_expr} "
"FROM threads"
)
params: list[Any] = []
clauses = ["source IN ('cli', 'vscode')"]
exact = _exact_uuid_ref(query.ref)
if exact is not None:
clauses.append("id = ?")
params.append(exact)
else:
clauses.append("archived = 0")
if query.cwd:
clauses.append("cwd = ?")
params.append(query.cwd)
if clauses:
select += " WHERE " + " AND ".join(clauses)
select += f" ORDER BY {updated_column} DESC, id ASC LIMIT ?"
params.append(DEFAULT_BOUNDS.listed_sessions)
rows = connection.execute(select, tuple(params)).fetchall()
if not rows and query.cwd and exact is None:
rows = connection.execute(
f"SELECT id, rollout_path, {updated_column}, source, cwd, "
f"{title_expr}, {first_expr}, archived, {branch_expr} "
"FROM threads WHERE source IN ('cli', 'vscode') AND archived = 0 "
f"ORDER BY {updated_column} DESC, id ASC LIMIT ?",
(DEFAULT_BOUNDS.scanned_records,),
).fetchall()
except sqlite3.Error as error:
raise DiagnosticError("E_CORRUPT_RECORD", source="codex", provider=SQLITE_FORMAT) from error
return True, updated_column, rows
with _database_connection(path, root) as connection:
supported, _updated_column, rows = _fetch_rows(connection)
if not supported:
return False, [], 0
values: list[SessionSummary] = []
unresolved = 0
exact = _exact_uuid_ref(query.ref)
for row in rows:
budget.consume_records()
if len(row) != 9:
raise DiagnosticError("E_CORRUPT_RECORD", source="codex", provider=SQLITE_FORMAT)
identifier, rollout_raw, updated_raw, source, cwd_raw, title, first_user, archived, branch = row
if not all(isinstance(value, str) for value in (identifier, rollout_raw, source, cwd_raw)):
raise DiagnosticError("E_CORRUPT_RECORD", source="codex", provider=SQLITE_FORMAT)
optional_text = (title, first_user, branch)
if any(value is not None and not isinstance(value, str) for value in optional_text):
raise DiagnosticError("E_CORRUPT_RECORD", source="codex", provider=SQLITE_FORMAT)
encoded_sizes = [len(value.encode("utf-8")) for value in (identifier, rollout_raw, source, cwd_raw)]
encoded_sizes.extend(len(value.encode("utf-8")) for value in optional_text if isinstance(value, str))
if (
encoded_sizes[0] > 64
or encoded_sizes[1] > 4096
or encoded_sizes[2] > 128
or encoded_sizes[3] > 4096
or (isinstance(title, str) and len(title.encode("utf-8")) > 64 * 1024)
or (isinstance(first_user, str) and len(first_user.encode("utf-8")) > 64 * 1024)
or (isinstance(branch, str) and len(branch.encode("utf-8")) > 4096)
):
continue
try:
budget.consume_bytes(sum(encoded_sizes))
except DiagnosticError:
break
try:
identifier = str(uuid.UUID(identifier))
cwd = canonicalize_cwd(cwd_raw)
except (ValueError, DiagnosticError):
continue
if exact is not None and identifier != exact:
continue
archived_ok = archived in {0, 1} or archived in {False, True}
archived_flag = int(archived) if archived_ok else -1
if source not in {"cli", "vscode"} or archived_flag not in {0, 1}:
continue
ref_id = _exact_uuid_ref(query.ref)
if archived_flag and ref_id != identifier and query.ref != identifier:
continue
if query.cwd is not None and not same_cwd(cwd, query.cwd):
continue
updated = _numeric_time(updated_raw)
if not _within(updated, query, identifier):
continue
rollout = _resolve_rollout_path(root, rollout_raw, identifier)
if rollout is None or (rollout.endswith(".zst") and _trusted_zstd() is None):
unresolved += 1
continue
values.append(
SessionSummary(
source="codex",
session_id=identifier,
source_path=rollout,
title=title
if isinstance(title, str) and title.strip()
else first_user
if isinstance(first_user, str)
else None,
cwd=cwd,
branch=branch if isinstance(branch, str) else None,
updated_at=updated,
provider=SQLITE_FORMAT,
)
)
return True, values, unresolved
SHA-256: 8a332f7cc76dd9dc3c3131e361d724379b218e7092d0fe3c03e606415f9492c3