feat: OpenCode and Codex JSONL connectors (F4.1 source-table completion) #28
Notifications
Due Date
No due date set.
Depends on
#26 feat: redact api keys/secrets/JWTs during session import (Privacy)
terraphim/agent-tasks
Reference: terraphim/agent-tasks#28
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem Statement
The session-search spec F4.1 (terraphim-agent-session-search-spec.md, lines 269-280) lists six supported sources, but only four have connectors today:
~/.claude/NativeClaudeConnector,ClaClaudeConnector)~/.cursor/ClaCursorConnector).aider.chat.history.md~/.cline/~/.opencode/~/.codex/Verification:
OpenCode and Codex are JSONL log formats nearly identical in shape to Terraphim AI's
~/.claude/projects/<slug>/<session-id>.jsonl. They are mentioned by name in the spec source-list but no code or open issue exists for them. Without these, agents that use OpenCode (opencode/minimax-m2.5) or ChatGPT/Codex CLI on this very repo (per CLAUDE.md "Model Rules for Bigbox Agents") cannot have their sessions searched -- the headline cross-agent capability gap.Acceptance Criteria
crates/terraphim_sessions/src/connector/opencode.rsimplementingSessionConnectorfor OpenCode JSONLcrates/terraphim_sessions/src/connector/codex.rsimplementingSessionConnectorfor Codex JSONLsource_id()returns"opencode"and"codex"respectivelydisplay_name()returns"OpenCode"and"ChatGPT Codex"default_path()resolves to~/.opencode/and~/.codex/(XDG-aware on Linux: prefer$XDG_DATA_HOME/opencodethen~/.opencode)detect()returnsAvailable { sessions_estimate }only when the directory exists AND contains at least one.jsonlfileimport(opts)walks<root>/**/*.jsonl, parses each line as a JSON value, normalises intoSession { id, source, source_id, created_at, updated_at, messages, metadata }{ "role": "user|assistant|system", "content": "...", "timestamp": "..." }-> map directly toMessage{ "type": "message", "role": "user|assistant", "content": [...] }-> flatten content blocks to text; ignoretype != "message"linesimport()resultMessageRole::from_str(case-insensitive) for role mapping; default toMessageRole::Userif missing with a debug logSessionservice::with_default_connectors()so/sessions sourcesand/sessions importdiscover them automaticallycreated_at/updated_at-- if absent, fall back to file mtime; document the fallback in code commentscrates/terraphim_sessions/tests/fixtures/opencode/andtests/fixtures/codex/:detect()returnsNotFoundcargo test -p terraphim_sessions connector::opencode connector::codexpassescargo test -p terraphim_agent --features repl-sessionspasses (existing /sessions sources/import tests still green)cargo clippy -p terraphim_sessions -- -D warningspassescrates/terraphim_sessions/README.md(or add) with a "Supported Sources" table that matches the spec verbatim plus the new connectorsProposed Approach
NativeClaudeConnector(existing): a small JSONL walker + line parser per source.serde_json,tokio::fs(for async dir walking), andwalkdir(already in workspace).parse_jsonl_messages(path, mapper)and pass per-source mappers.content: [{type: "text", text: ...}]shape, keep the mapper local to the codex module so future Codex schema changes do not affect OpenCode.tokio::fs::metadata(path).await?.modified()(already used elsewhere in the connector module).Dependencies
None. Independent of #3 (Cline), #13 (Generic MCP). Should land alongside (or after) the secret redaction issue so the new connectors pick up redaction by default.
Verification
Expected:
sources.opencode.status == "Available";imported >= 1.Scope
Single PR, ~350-450 LOC across 2 new modules + service registration + 2 fixture sets + tests. No public-api churn outside
Sessionservice::with_default_connectors.Upstream: terraphim-agent-session-search-spec.md F4.1 source-table completion (lines 269-280).